From 44301bfd773b2c066517007e876ed8f61b12ffee Mon Sep 17 00:00:00 2001 From: tangxifan Date: Tue, 2 Jul 2019 09:01:52 -0600 Subject: [PATCH] updated SPICE generator to avoid issues on clb2clb_direct --- .../SRC/fpga_x2p/spice/spice_mux_testbench.c | 20 ++--- .../vpr/SRC/fpga_x2p/spice/spice_routing.c | 86 ++++++++++++++----- .../vpr/SRC/fpga_x2p/spice/spice_routing.h | 3 +- .../vpr/SRC/fpga_x2p/spice/spice_subckt.c | 3 +- vpr7_x2p/vpr/SRC/fpga_x2p/spice/spice_utils.c | 4 +- 5 files changed, 76 insertions(+), 40 deletions(-) diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/spice/spice_mux_testbench.c b/vpr7_x2p/vpr/SRC/fpga_x2p/spice/spice_mux_testbench.c index 88333dbd5..f28ba2ae1 100644 --- a/vpr7_x2p/vpr/SRC/fpga_x2p/spice/spice_mux_testbench.c +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/spice/spice_mux_testbench.c @@ -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) { diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/spice/spice_routing.c b/vpr7_x2p/vpr/SRC/fpga_x2p/spice/spice_routing.c index 5fb871061..78c0f18d4 100644 --- a/vpr7_x2p/vpr/SRC/fpga_x2p/spice/spice_routing.c +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/spice/spice_routing.c @@ -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 + ***********************************************************************/ diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/spice/spice_routing.h b/vpr7_x2p/vpr/SRC/fpga_x2p/spice/spice_routing.h index 291bb3c08..bc7df15d4 100644 --- a/vpr7_x2p/vpr/SRC/fpga_x2p/spice/spice_routing.h +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/spice/spice_routing.h @@ -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); diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/spice/spice_subckt.c b/vpr7_x2p/vpr/SRC/fpga_x2p/spice/spice_subckt.c index a5753caf9..09ca2854e 100644 --- a/vpr7_x2p/vpr/SRC/fpga_x2p/spice/spice_subckt.c +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/spice/spice_subckt.c @@ -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"); diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/spice/spice_utils.c b/vpr7_x2p/vpr/SRC/fpga_x2p/spice/spice_utils.c index e195d994b..d24a6bcba 100644 --- a/vpr7_x2p/vpr/SRC/fpga_x2p/spice/spice_utils.c +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/spice/spice_utils.c @@ -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;