updated SPICE generator to avoid issues on clb2clb_direct

This commit is contained in:
tangxifan 2019-07-02 09:01:52 -06:00
parent 5b25bbb120
commit 44301bfd77
5 changed files with 76 additions and 40 deletions

View File

@ -80,8 +80,7 @@ static void init_spice_mux_testbench_globals(t_spice spice) {
}
static
void fprint_spice_mux_testbench_global_ports(FILE* fp,
t_spice spice) {
void fprint_spice_mux_testbench_global_ports(FILE* fp) {
/* A valid file handler*/
if (NULL == fp) {
vpr_printf(TIO_MESSAGE_ERROR,"(FILE:%s,LINE[%d])Invalid File Handler!\n",__FILE__, __LINE__);
@ -641,7 +640,6 @@ void fprint_spice_mux_testbench_pb_pin_mux(FILE* fp,
static
void fprint_spice_mux_testbench_pb_graph_node_pin_interc(FILE* fp,
enum e_spice_pin2pin_interc_type pin2pin_interc_type,
t_pb_graph_pin* des_pb_graph_pin,
t_mode* cur_mode,
int select_path_id,
@ -734,7 +732,6 @@ static
void fprint_spice_mux_testbench_pb_pin_interc(FILE* fp,
t_rr_node* pb_rr_graph,
t_phy_pb* des_pb,
enum e_spice_pin2pin_interc_type pin2pin_interc_type,
t_pb_graph_pin* des_pb_graph_pin,
t_mode* cur_mode,
int select_path_id,
@ -856,7 +853,6 @@ void fprintf_spice_mux_testbench_pb_graph_port_interc(FILE* fp,
assert(NULL == cur_pb);
path_id = DEFAULT_PATH_ID;
fprint_spice_mux_testbench_pb_graph_node_pin_interc(fp,
INPUT2INPUT_INTERC,
&(cur_pb_graph_node->input_pins[iport][ipin]),
cur_mode,
path_id,
@ -878,7 +874,6 @@ void fprintf_spice_mux_testbench_pb_graph_port_interc(FILE* fp,
assert(DEFAULT_PATH_ID != path_id);
}
fprint_spice_mux_testbench_pb_pin_interc(fp, pb_rr_nodes, cur_pb, /* TODO: find out the child_pb*/
INPUT2INPUT_INTERC,
&(cur_pb_graph_node->input_pins[iport][ipin]),
cur_mode,
path_id,
@ -896,7 +891,6 @@ void fprintf_spice_mux_testbench_pb_graph_port_interc(FILE* fp,
assert(NULL == cur_pb);
path_id = DEFAULT_PATH_ID;
fprint_spice_mux_testbench_pb_graph_node_pin_interc(fp,
OUTPUT2OUTPUT_INTERC,
&(cur_pb_graph_node->output_pins[iport][ipin]),
cur_mode,
path_id,
@ -918,7 +912,6 @@ void fprintf_spice_mux_testbench_pb_graph_port_interc(FILE* fp,
assert(DEFAULT_PATH_ID != path_id);
}
fprint_spice_mux_testbench_pb_pin_interc(fp, pb_rr_nodes, cur_pb, /* TODO: find out the child_pb*/
OUTPUT2OUTPUT_INTERC,
&(cur_pb_graph_node->output_pins[iport][ipin]),
cur_mode,
path_id,
@ -936,7 +929,6 @@ void fprintf_spice_mux_testbench_pb_graph_port_interc(FILE* fp,
assert(NULL == cur_pb);
path_id = DEFAULT_PATH_ID;
fprint_spice_mux_testbench_pb_graph_node_pin_interc(fp,
INPUT2INPUT_INTERC,
&(cur_pb_graph_node->clock_pins[iport][ipin]),
cur_mode,
path_id,
@ -958,7 +950,6 @@ void fprintf_spice_mux_testbench_pb_graph_port_interc(FILE* fp,
assert(DEFAULT_PATH_ID != path_id);
}
fprint_spice_mux_testbench_pb_pin_interc(fp, pb_rr_nodes, cur_pb, /* TODO: find out the child_pb*/
INPUT2INPUT_INTERC,
&(cur_pb_graph_node->clock_pins[iport][ipin]),
cur_mode,
path_id,
@ -1254,6 +1245,7 @@ void fprint_spice_mux_testbench_cb_one_mux(FILE* fp,
return;
}
static
void fprint_spice_mux_testbench_cb_interc(FILE* fp,
t_cb cur_cb_info,
t_rr_node* src_rr_node,
@ -1481,8 +1473,7 @@ int fprint_spice_mux_testbench_sb_one_mux(FILE* fp,
static
int fprint_spice_mux_testbench_call_one_grid_sb_muxes(FILE* fp,
t_sb cur_sb_info,
t_ivec*** LL_rr_node_indices) {
t_sb cur_sb_info) {
int itrack, side;
int used = 0;
@ -1672,6 +1663,7 @@ void fprint_spice_mux_testbench_measurements(FILE* fp,
}
/* Top-level function in this source file */
static
int fprint_spice_one_mux_testbench(char* formatted_spice_dir,
char* circuit_name,
char* mux_testbench_name,
@ -1743,7 +1735,7 @@ int fprint_spice_one_mux_testbench(char* formatted_spice_dir,
fprint_spice_options(fp, arch.spice->spice_params);
/* Global nodes: Vdd for SRAMs, Logic Blocks(Include IO), Switch Boxes, Connection Boxes */
fprint_spice_mux_testbench_global_ports(fp, *(arch.spice));
fprint_spice_mux_testbench_global_ports(fp);
/* Quote defined Logic blocks subckts (Grids) */
init_spice_mux_testbench_globals(*(arch.spice));
@ -1798,7 +1790,7 @@ int fprint_spice_one_mux_testbench(char* formatted_spice_dir,
case SPICE_SB_MUX_TB:
total_sb_mux_input_density = 0.;
/* Output a sb_mux testbench */
used = fprint_spice_mux_testbench_call_one_grid_sb_muxes(fp, sb_info[grid_x][grid_y], LL_rr_node_indices);
used = fprint_spice_mux_testbench_call_one_grid_sb_muxes(fp, sb_info[grid_x][grid_y]);
/* Check and output info. */
assert((0 == testbench_sb_mux_cnt)||(0 < testbench_sb_mux_cnt));
if (0 < testbench_sb_mux_cnt) {

View File

@ -1,3 +1,45 @@
/**********************************************************
* MIT License
*
* Copyright (c) 2018 LNIS - The University of Utah
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
***********************************************************************/
/************************************************************************
* Filename: rr_blocks.cpp
* Created by: Xifan Tang
* Change history:
* +-------------------------------------+
* | Date | Author | Notes
* +-------------------------------------+
* | 2019/07/02 | Xifan Tang | Created
* +-------------------------------------+
***********************************************************************/
/************************************************************************
* This file contains functions to output SPICE netlists of routing resources
* i.e., Switch Block(SB), Connection Block (CB) and routing channels.
* Each module will be placed in an individual subckt, which be called
* through SPICE testbenches
* Note that each subckt is a configured module (SB, CB or Routing channals)
***********************************************************************/
/***********************************/
/* SPICE Modeling for VPR */
/* Xifan TANG, EPFL/LSI */
@ -39,7 +81,7 @@
#include "fpga_x2p_backannotate_utils.h"
#include "spice_routing.h"
static
void fprint_routing_chan_subckt(char* subckt_dir,
int x, int y, t_rr_type chan_type,
int LL_num_rr_nodes, t_rr_node* LL_rr_node,
@ -629,11 +671,9 @@ void fprint_switch_box_interc(FILE* fp,
* For channels chanX with INC_DIRECTION on the right side, they should be marked as outputs
* For channels chanX with DEC_DIRECTION on the right side, they should be marked as inputs
*/
static
void fprint_routing_switch_box_subckt(char* subckt_dir,
t_sb cur_sb_info,
int LL_num_rr_nodes, t_rr_node* LL_rr_node,
t_ivec*** LL_rr_node_indices,
boolean compact_routing_hierarchy) {
t_sb cur_sb_info) {
int itrack, inode, side, ix, iy, x, y;
FILE* fp = NULL;
char* fname = NULL;
@ -755,7 +795,15 @@ void fprint_connection_box_short_interc(FILE* fp,
assert(1 == src_rr_node->fan_in);
/* Check the driver*/
drive_rr_node = &(rr_node[src_rr_node->prev_node]);
drive_rr_node = src_rr_node->drive_rr_nodes[0];
/* We have OPINs since we may have direct connections:
* These connections should be handled by other functions in the compact_netlist.c
* So we just return here for OPINs
*/
if (OPIN == drive_rr_node->type) {
return;
}
assert((CHANX == drive_rr_node->type)||(CHANY == drive_rr_node->type));
check_flag = 0;
for (iedge = 0; iedge < drive_rr_node->num_edges; iedge++) {
@ -996,11 +1044,9 @@ void fprint_connection_box_interc(FILE* fp,
* | | Connection | |
* --------------Box_Y[x][y-1]--------------
*/
static
void fprint_routing_connection_box_subckt(char* subckt_dir,
t_cb cur_cb_info,
int LL_num_rr_nodes, t_rr_node* LL_rr_node,
t_ivec*** LL_rr_node_indices,
boolean compact_routing_hierarchy) {
t_cb cur_cb_info) {
int itrack, inode, side, x, y;
int side_cnt = 0;
@ -1104,6 +1150,7 @@ void fprint_routing_connection_box_subckt(char* subckt_dir,
fprintf(fp, "***** Head of scan-chain *****\n");
fprintf(fp, "Rcbx[%d][%d]_sc_head cbx[%d][%d]_sc_head %s[%d]->in 0\n",
x, y, x, y, sram_spice_model->prefix, sram_spice_model->cnt);
break;
case CHANY:
fprintf(fp, "***** Head of scan-chain *****\n");
fprintf(fp, "Rcby[%d][%d]_sc_head cby[%d][%d]_sc_head %s[%d]->in 0\n",
@ -1141,6 +1188,7 @@ void fprint_routing_connection_box_subckt(char* subckt_dir,
fprintf(fp, "***** Tail of scan-chain *****\n");
fprintf(fp, "Rcbx[%d][%d]_sc_tail cbx[%d][%d]_sc_tail %s[%d]->in 0\n",
x, y, x, y, sram_spice_model->prefix, sram_spice_model->cnt);
break;
case CHANY:
fprintf(fp, "***** Tail of scan-chain *****\n");
fprintf(fp, "Rcby[%d][%d]_sc_tail cby[%d][%d]_sc_tail %s[%d]->in 0\n",
@ -1173,8 +1221,7 @@ void generate_spice_routing_resources(char* subckt_dir,
t_arch arch,
t_det_routing_arch* routing_arch,
int LL_num_rr_nodes, t_rr_node* LL_rr_node,
t_ivec*** LL_rr_node_indices,
boolean compact_routing_hierarchy) {
t_ivec*** LL_rr_node_indices) {
int ix, iy;
assert(UNI_DIRECTIONAL == routing_arch->directionality);
@ -1221,9 +1268,7 @@ void generate_spice_routing_resources(char* subckt_dir,
for (ix = 0; ix < (nx + 1); ix++) {
for (iy = 0; iy < (ny + 1); iy++) {
update_spice_models_routing_index_low(ix, iy, SOURCE, arch.spice->num_spice_model, arch.spice->spice_models);
fprint_routing_switch_box_subckt(subckt_dir, sb_info[ix][iy],
LL_num_rr_nodes, LL_rr_node, LL_rr_node_indices,
compact_routing_hierarchy);
fprint_routing_switch_box_subckt(subckt_dir, sb_info[ix][iy]);
update_spice_models_routing_index_high(ix, iy, SOURCE, arch.spice->num_spice_model, arch.spice->spice_models);
}
}
@ -1237,9 +1282,7 @@ void generate_spice_routing_resources(char* subckt_dir,
/* Check if this cby_info exists, it may be covered by a heterogenous block */
if ((TRUE == is_cb_exist(CHANX, ix, iy))
&&(0 < count_cb_info_num_ipin_rr_nodes(cbx_info[ix][iy]))) {
fprint_routing_connection_box_subckt(subckt_dir, cbx_info[ix][iy],
LL_num_rr_nodes, LL_rr_node, LL_rr_node_indices,
compact_routing_hierarchy);
fprint_routing_connection_box_subckt(subckt_dir, cbx_info[ix][iy]);
}
update_spice_models_routing_index_high(ix, iy, CHANX, arch.spice->num_spice_model, arch.spice->spice_models);
}
@ -1251,9 +1294,7 @@ void generate_spice_routing_resources(char* subckt_dir,
/* Check if this cby_info exists, it may be covered by a heterogenous block */
if ((TRUE == is_cb_exist(CHANY, ix, iy))
&&(0 < count_cb_info_num_ipin_rr_nodes(cby_info[ix][iy]))) {
fprint_routing_connection_box_subckt(subckt_dir, cby_info[ix][iy],
LL_num_rr_nodes, LL_rr_node, LL_rr_node_indices,
compact_routing_hierarchy);
fprint_routing_connection_box_subckt(subckt_dir, cby_info[ix][iy]);
}
update_spice_models_routing_index_high(ix, iy, CHANY, arch.spice->num_spice_model, arch.spice->spice_models);
}
@ -1267,3 +1308,6 @@ void generate_spice_routing_resources(char* subckt_dir,
return;
}
/************************************************************************
* End of file : rr_blocks.cpp
***********************************************************************/

View File

@ -67,6 +67,5 @@ void generate_spice_routing_resources(char* subckt_dir,
t_arch arch,
t_det_routing_arch* routing_arch,
int LL_num_rr_nodes, t_rr_node* LL_rr_node,
t_ivec*** LL_rr_node_indices,
boolean compact_routing_hierarchy);
t_ivec*** LL_rr_node_indices);

View File

@ -737,8 +737,7 @@ void generate_spice_subckts(char* subckt_dir,
/* 6. Generate Routing architecture*/
vpr_printf(TIO_MESSAGE_INFO, "Writing Routing Resources....\n");
generate_spice_routing_resources(subckt_dir, (*arch), routing_arch,
num_rr_nodes, rr_node, rr_node_indices,
compact_routing_hierarchy);
num_rr_nodes, rr_node, rr_node_indices);
/* 7. Generate Logic Blocks */
vpr_printf(TIO_MESSAGE_INFO,"Writing Logic Blocks...\n");

View File

@ -1489,6 +1489,7 @@ void fprint_spice_toplevel_one_grid_side_pin_with_given_index(FILE* fp,
}
/* Apply a CLB to CLB direct connection to a SPICE netlist */
static
void fprint_spice_one_clb2clb_direct(FILE* fp,
int from_grid_x, int from_grid_y,
int to_grid_x, int to_grid_y,
@ -1505,7 +1506,7 @@ void fprint_spice_one_clb2clb_direct(FILE* fp,
/* Check bandwidth match between from_clb and to_clb pins */
if (0 != (cur_direct->from_clb_pin_end_index - cur_direct->from_clb_pin_start_index
- cur_direct->to_clb_pin_end_index - cur_direct->to_clb_pin_start_index)) {
- (cur_direct->to_clb_pin_end_index - cur_direct->to_clb_pin_start_index))) {
vpr_printf(TIO_MESSAGE_ERROR, "(%s, [LINE%d]) Unmatch pin bandwidth in direct connection (name=%s)!\n",
__FILE__, __LINE__, cur_direct->name);
exit(1);
@ -1619,6 +1620,7 @@ void fprint_spice_clb2clb_directs(FILE* fp,
* 2. Their corresponding rr_node (SINK or IPIN) has 0 fan-in.
* In these cases, we short connect them to global GND.
*/
static
void fprint_grid_float_port_stimulation(FILE* fp) {
int inode;
int num_float_port = 0;