get FPGA-SPICE updated for release - Clear printf and fix assert bugs

This commit is contained in:
Xifan Tang 2018-08-01 14:04:28 -06:00
parent 91f073cdc4
commit 4d7f4350de
21 changed files with 538 additions and 131 deletions

View File

@ -1468,7 +1468,9 @@ static void ProcessMode(INOUTP ezxml_t Parent, t_mode * mode,
mode->define_physical_mode = 0;
}
}
/* More option: specify if this mode is available during packing */
/* Spice Model Support: Xifan TANG
* More option: specify if this mode is available during packing
*/
mode->available_in_packing = GetBooleanProperty(Parent, "available_in_packing", FALSE, TRUE);
/* END */
@ -2447,6 +2449,9 @@ static void ProcessMemoryClass(INOUTP t_pb_type *mem_pb_type) {
&mem_pb_type->modes[0];
}
/* Xifan TANG: Memory default idle mode */
mem_pb_type->modes[0].define_idle_mode = 1;
/* Process interconnect */
i_inter = 0;
for (i = 0; i < mem_pb_type->num_ports; i++) {

View File

@ -427,6 +427,7 @@ static void ProcessSpiceTransistorType(ezxml_t Parent,
static void ProcessSpiceModelBuffer(ezxml_t Node,
t_spice_model_buffer* buffer) {
boolean read_buf_info = FALSE;
boolean read_spice_model = FALSE;
char* Prop = NULL;
/* Be smart to find all the details */
/* Find "exist"*/
@ -442,13 +443,17 @@ static void ProcessSpiceModelBuffer(ezxml_t Node,
/* If buffer existed, we need to further find the spice_model_name */
if (1 == buffer->exist) {
buffer->spice_model_name = my_strdup(FindProperty(Node, "spice_model_name", TRUE));
ezxml_set_attr(Node, "spice_model_name", NULL);
read_buf_info = FALSE;
read_spice_model = TRUE;
} else if (0 == strcmp("design_technology", Node->name)) {
/* Only under the design technology Node, this contains buffer information */
read_buf_info = TRUE;
read_spice_model = FALSE;
}
buffer->spice_model_name = my_strdup(FindProperty(Node, "spice_model_name", read_spice_model));
ezxml_set_attr(Node, "spice_model_name", NULL);
/*Find Type*/
Prop = my_strdup(FindProperty(Node, "topology", read_buf_info));
if (NULL != Prop) {

View File

@ -266,6 +266,38 @@ int get_rr_node_index_in_sb_info(t_rr_node* cur_rr_node,
return ret; /* Return an invalid value: nonthing is found*/
}
/* Check if the src_rr_node is just a wire crossing this switch box
* ---------
* | |
* ------------------>
* | |
* ---------
* Strategy:
* Check each driver rr_node of this src_rr_node,
* see if they are in the opin_rr_node, chan_rr_node lists of sb_rr_info
*/
int is_rr_node_exist_opposite_side_in_sb_info(t_sb cur_sb_info,
t_rr_node* src_rr_node,
int chan_side) {
int oppo_chan_side = -1;
int interc, index;
oppo_chan_side = get_opposite_side(chan_side);
/* See if we can find the same src_rr_node in the opposite chan_side
* if there is one, it means a shorted wire across the SB
*/
index = get_rr_node_index_in_sb_info(src_rr_node, cur_sb_info, oppo_chan_side, IN_PORT);
interc = 0;
if (-1 != index) {
interc = 1;
}
return interc;
}
/* Get the side and index of a given rr_node in a SB_info
* Return cur_rr_node_side & cur_rr_node_index
*/
@ -519,7 +551,7 @@ void backannotate_clb_nets_init_val() {
iblk = vpack_net[inet].node_block[0];
switch (logical_block[iblk].type) {
case VPACK_COMB:
vpack_net[inet].spice_net_info->init_val = get_lut_output_init_val(&(logical_block[iblk]));
vpack_net[inet].spice_net_info->init_val = get_logical_block_output_init_val(&(logical_block[iblk]));
if (logical_block[iblk].init_val != vpack_net[inet].spice_net_info->init_val) {
iter_end = 0;
}
@ -1717,6 +1749,7 @@ void build_one_switch_block_info(t_sb* cur_sb, int sb_x, int sb_y,
cur_sb->opin_rr_node_grid_side = (int**)my_malloc(sizeof(int*)*cur_sb->num_sides); /* 4 sides */
/* Find all rr_nodes of channels */
/* Side: TOP => 0, RIGHT => 1, BOTTOM => 2, LEFT => 3 */
for (side = 0; side < 4; side++) {
switch (side) {
case 0:
@ -1921,7 +1954,7 @@ void build_one_switch_block_info(t_sb* cur_sb, int sb_x, int sb_y,
/* Side: TOP => 0, RIGHT => 1, BOTTOM => 2, LEFT => 3 */
/* Alloc */
cur_sb->chan_rr_node[side] = get_chan_rr_nodes(&(cur_sb->chan_width[side]), CHANX, ix, iy,
LL_num_rr_nodes, LL_rr_node, LL_rr_node_indices);
LL_num_rr_nodes, LL_rr_node, LL_rr_node_indices);
cur_sb->chan_rr_node_direction[side] = (enum PORTS*)my_malloc(sizeof(enum PORTS)*cur_sb->chan_width[side]);
/* Collect rr_nodes for Tracks for left: chanx[x][y] */
for (itrack = 0; itrack < cur_sb->chan_width[side]; itrack++) {
@ -2352,12 +2385,15 @@ void spice_backannotate_vpr_post_route_info(t_det_routing_arch RoutingArch,
boolean parasitic_net_estimation_off) {
vpr_printf(TIO_MESSAGE_INFO, "Start backannotating post route information for SPICE modeling...\n");
/* Give spice_name_tag for each pb*/
vpr_printf(TIO_MESSAGE_INFO, "Generate SPICE name tags for pbs...\n");
gen_spice_name_tags_all_pbs();
/* Build previous node lists for each rr_node */
vpr_printf(TIO_MESSAGE_INFO, "Building previous node list for all Routing Resource Nodes...\n");
build_prev_node_list_rr_nodes(num_rr_nodes, rr_node);
/* Build driver switches for each rr_node*/
vpr_printf(TIO_MESSAGE_INFO, "Identifying driver switches for all Routing Resource Nodes...\n");
identify_rr_node_driver_switch(RoutingArch, num_rr_nodes, rr_node);
@ -2365,15 +2401,18 @@ void spice_backannotate_vpr_post_route_info(t_det_routing_arch RoutingArch,
/* Build Array for each Switch block and Connection block */
vpr_printf(TIO_MESSAGE_INFO, "Collecting detailed information for each Switch block...\n");
alloc_and_build_switch_blocks_info(RoutingArch, num_rr_nodes, rr_node, rr_node_indices);
vpr_printf(TIO_MESSAGE_INFO, "Collecting detailed information for each to Connection block...\n");
alloc_and_build_connection_blocks_info(RoutingArch, num_rr_nodes, rr_node, rr_node_indices);
/* This function should go very first because it gives all the net_num */
vpr_printf(TIO_MESSAGE_INFO,"Back annotating mapping information to global routing resource nodes...\n");
back_annotate_rr_node_map_info();
/* Update local_rr_graphs to match post-route results*/
vpr_printf(TIO_MESSAGE_INFO, "Update CLB local routing graph to match post-route results...\n");
update_grid_pbs_post_route_rr_graph();
vpr_printf(TIO_MESSAGE_INFO,"Back annotating mapping information to local routing resource nodes...\n");
back_annotate_pb_rr_node_map_info();

View File

@ -21,6 +21,10 @@ int get_rr_node_index_in_sb_info(t_rr_node* cur_rr_node,
t_sb cur_sb_info,
int chan_side, enum PORTS rr_node_direction);
int is_rr_node_exist_opposite_side_in_sb_info(t_sb cur_sb_info,
t_rr_node* src_rr_node,
int chan_side);
void get_rr_node_side_and_index_in_sb_info(t_rr_node* cur_rr_node,
t_sb cur_sb_info,
enum PORTS rr_node_direction,

View File

@ -127,7 +127,7 @@ int map_pb_type_port_to_spice_model_ports(t_pb_type* cur_pb_type,
for (iport = 0; iport < cur_pb_type->num_ports; iport++) {
if (NULL == cur_pb_type->ports[iport].spice_model_port) {
vpr_printf(TIO_MESSAGE_ERROR,
"(File:%s, [LINE%d])Pb_type(%s) Port(%s) cannot find a corresponding port in SPICE model(%s)",
"(File:%s, [LINE%d])Pb_type(%s) Port(%s) cannot find a corresponding port in SPICE model(%s)\n",
__FILE__, __LINE__, cur_pb_type->name, cur_pb_type->ports[iport].name,
cur_spice_model->name);
exit(1);
@ -209,32 +209,37 @@ void match_pb_types_spice_model_rec(t_pb_type* cur_pb_type,
vpr_printf(TIO_MESSAGE_INFO,"INFO: Link a SPICE model (%s) for Interconnect (%s)!\n",
cur_pb_type->modes[imode].interconnect[jinterc].spice_model->name, cur_pb_type->modes[imode].interconnect[jinterc].name);
if (NULL == cur_pb_type->modes[imode].interconnect[jinterc].spice_model) {
vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,LINE[%d]) Fail to find a defined SPICE model called %s, in pb_type(%s)!\n",__FILE__, __LINE__, cur_pb_type->modes[imode].interconnect[jinterc].spice_model_name, cur_pb_type->name);
vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,LINE[%d]) Fail to find a defined SPICE model called %s, in pb_type(%s)!\n",
__FILE__, __LINE__, cur_pb_type->modes[imode].interconnect[jinterc].spice_model_name, cur_pb_type->name);
exit(1);
}
switch (cur_pb_type->modes[imode].interconnect[jinterc].type) {
case DIRECT_INTERC:
if (SPICE_MODEL_WIRE != cur_pb_type->modes[imode].interconnect[jinterc].spice_model->type) {
vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,LINE[%d]) Invalid type of matched SPICE model called %s, in pb_type(%s)! Sould be wire!\n",__FILE__, __LINE__, cur_pb_type->modes[imode].interconnect[jinterc].spice_model_name, cur_pb_type->name);
vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,LINE[%d]) Invalid type of matched SPICE model called %s, in pb_type(%s)! Sould be wire!\n",
__FILE__, __LINE__, cur_pb_type->modes[imode].interconnect[jinterc].spice_model_name, cur_pb_type->name);
exit(1);
}
break;
case COMPLETE_INTERC:
if (0 == cur_pb_type->modes[imode].interconnect[jinterc].num_mux) {
if (SPICE_MODEL_WIRE != cur_pb_type->modes[imode].interconnect[jinterc].spice_model->type) {
vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,LINE[%d]) Invalid type of matched SPICE model called %s, in pb_type(%s)! Sould be wire!\n",__FILE__, __LINE__, cur_pb_type->modes[imode].interconnect[jinterc].spice_model_name, cur_pb_type->name);
vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,LINE[%d]) Invalid type of matched SPICE model called %s, in pb_type(%s)! Sould be wire!\n",
__FILE__, __LINE__, cur_pb_type->modes[imode].interconnect[jinterc].spice_model_name, cur_pb_type->name);
exit(1);
}
} else {
if (SPICE_MODEL_MUX != cur_pb_type->modes[imode].interconnect[jinterc].spice_model->type) {
vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,LINE[%d]) Invalid type of matched SPICE model called %s, in pb_type(%s)! Sould be MUX!\n",__FILE__, __LINE__, cur_pb_type->modes[imode].interconnect[jinterc].spice_model_name, cur_pb_type->name);
vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,LINE[%d]) Invalid type of matched SPICE model called %s, in pb_type(%s)! Sould be MUX!\n",
__FILE__, __LINE__, cur_pb_type->modes[imode].interconnect[jinterc].spice_model_name, cur_pb_type->name);
exit(1);
}
}
break;
case MUX_INTERC:
if (SPICE_MODEL_MUX != cur_pb_type->modes[imode].interconnect[jinterc].spice_model->type) {
vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,LINE[%d]) Invalid type of matched SPICE model called %s, in pb_type(%s)! Sould be MUX!\n",__FILE__, __LINE__, cur_pb_type->modes[imode].interconnect[jinterc].spice_model_name, cur_pb_type->name);
vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,LINE[%d]) Invalid type of matched SPICE model called %s, in pb_type(%s)! Sould be MUX!\n",
__FILE__, __LINE__, cur_pb_type->modes[imode].interconnect[jinterc].spice_model_name, cur_pb_type->name);
exit(1);
}
break;

View File

@ -1321,6 +1321,24 @@ char** my_strtok(char* str,
return ret;
}
int get_opposite_side(int side){
switch (side) {
case 0:
return 2;
case 1:
return 3;
case 2:
return 0;
case 3:
return 1;
default:
vpr_printf(TIO_MESSAGE_ERROR, "(File:%s, [LINE%d])Invalid side index. Should be [0,3].\n",
__FILE__, __LINE__);
exit(1);
}
}
char* convert_side_index_to_string(int side) {
switch (side) {
case 0:
@ -1779,14 +1797,27 @@ int find_pb_mapped_logical_block_rec(t_pb* cur_pb,
if ((pb_spice_model == cur_pb->pb_graph_node->pb_type->spice_model)
&&(0 == strcmp(cur_pb->spice_name_tag, pb_spice_name_tag))) {
/* Special for LUT... They have sub modes!!!*/
if (SPICE_MODEL_LUT == pb_spice_model->type) {
mode_index = cur_pb->mode;
/* Return the logic block we may find */
switch (pb_spice_model->type) {
case SPICE_MODEL_LUT :
/* Special for LUT... They have sub modes!!!*/
assert(NULL != cur_pb->child_pbs);
return cur_pb->child_pbs[0][0].logical_block;
case SPICE_MODEL_FF:
assert(pb_spice_model == logical_block[cur_pb->logical_block].mapped_spice_model);
return cur_pb->logical_block;
case SPICE_MODEL_HARDLOGIC:
if (NULL != cur_pb->child_pbs) {
return cur_pb->child_pbs[0][0].logical_block;
} else {
assert(pb_spice_model == logical_block[cur_pb->logical_block].mapped_spice_model);
return cur_pb->logical_block;
}
default:
vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid spice model type!\n",
__FILE__, __LINE__);
exit(1);
}
assert(pb_spice_model == logical_block[cur_pb->logical_block].mapped_spice_model);
return cur_pb->logical_block;
}
/* Go recursively ... */
@ -2156,6 +2187,7 @@ int find_pb_type_idle_mode_index(t_pb_type cur_pb_type) {
num_idle_mode++;
}
}
assert(1 == num_idle_mode);
return idle_mode_index;
@ -2691,8 +2723,8 @@ int rr_node_drive_switch_box(t_rr_node* src_rr_node,
assert((!(0 > switch_box_x))&&(!(switch_box_x > (nx + 1))));
assert((!(0 > switch_box_y))&&(!(switch_box_y > (ny + 1))));
/* Valid des_rr_node coordinator */
assert((!(switch_box_x < (des_rr_node->xlow-1)))&&(!(switch_box_x > (des_rr_node->xhigh+1))));
assert((!(switch_box_y < (des_rr_node->ylow-1)))&&(!(switch_box_y > (des_rr_node->yhigh+1))));
assert((!(switch_box_x < (des_rr_node->xlow - 1)))&&(!(switch_box_x > (des_rr_node->xhigh + 1))));
assert((!(switch_box_y < (des_rr_node->ylow - 1)))&&(!(switch_box_y > (des_rr_node->yhigh + 1))));
/* Check the src_rr_node coordinator */
switch (chan_side) {
@ -2714,14 +2746,16 @@ int rr_node_drive_switch_box(t_rr_node* src_rr_node,
case CHANX:
assert(src_rr_node->ylow == src_rr_node->yhigh);
if ((switch_box_y == src_rr_node->ylow)
&&(!(switch_box_x < (src_rr_node->xlow-1)))&&(!(switch_box_x > (src_rr_node->xhigh+1)))) {
&&(!(switch_box_x < (src_rr_node->xlow - 1)))
&&(!(switch_box_x > (src_rr_node->xhigh + 1)))) {
return 1;
}
break;
case CHANY:
assert(src_rr_node->xlow == src_rr_node->xhigh);
if ((switch_box_x == src_rr_node->xlow)
&&(!(switch_box_y < src_rr_node->ylow))&&(!(switch_box_y > src_rr_node->yhigh))) {
&&(!(switch_box_y < src_rr_node->ylow))
&&(!(switch_box_y > src_rr_node->yhigh))) {
return 1;
}
break;
@ -2757,7 +2791,8 @@ int rr_node_drive_switch_box(t_rr_node* src_rr_node,
case CHANY:
assert(src_rr_node->xlow == src_rr_node->xhigh);
if ((switch_box_x == src_rr_node->xlow)
&&(!(switch_box_y < (src_rr_node->ylow-1)))&&(!(switch_box_y > (src_rr_node->yhigh+1)))) {
&&(!(switch_box_y < (src_rr_node->ylow - 1)))
&&(!(switch_box_y > (src_rr_node->yhigh + 1)))) {
return 1;
}
break;
@ -2770,7 +2805,7 @@ int rr_node_drive_switch_box(t_rr_node* src_rr_node,
case BOTTOM:
/* Following cases:
* |
* \ /
* \ | /
* |
*/
/* The destination rr_node only have one condition!!! */
@ -2786,14 +2821,16 @@ int rr_node_drive_switch_box(t_rr_node* src_rr_node,
case CHANX:
assert(src_rr_node->ylow == src_rr_node->yhigh);
if ((switch_box_y == src_rr_node->ylow)
&&(!(switch_box_x < (src_rr_node->xlow-1)))&&(!(switch_box_x > (src_rr_node->xhigh+1)))) {
&&(!(switch_box_x < (src_rr_node->xlow - 1)))
&&(!(switch_box_x > (src_rr_node->xhigh + 1)))) {
return 1;
}
break;
case CHANY:
assert(src_rr_node->xlow == src_rr_node->xhigh);
if ((switch_box_x == src_rr_node->xlow)
&&(!((switch_box_y+1) < src_rr_node->ylow))&&(!((switch_box_y+1) > src_rr_node->yhigh))) {
&&(!((switch_box_y + 1) < src_rr_node->ylow))
&&(!((switch_box_y + 1) > src_rr_node->yhigh))) {
return 1;
}
break;
@ -2822,14 +2859,16 @@ int rr_node_drive_switch_box(t_rr_node* src_rr_node,
case CHANX:
assert(src_rr_node->ylow == src_rr_node->yhigh);
if ((switch_box_y == src_rr_node->ylow)
&&(!((switch_box_x+1) < src_rr_node->xlow))&&(!((switch_box_x+1) > src_rr_node->xhigh))) {
&&(!((switch_box_x + 1) < src_rr_node->xlow))
&&(!((switch_box_x + 1) > src_rr_node->xhigh))) {
return 1;
}
break;
case CHANY:
assert(src_rr_node->xlow == src_rr_node->xhigh);
if ((switch_box_x == src_rr_node->xlow)
&&(!(switch_box_y < (src_rr_node->ylow-1)))&&(!(switch_box_y > (src_rr_node->yhigh+1)))) {
&&(!(switch_box_y < (src_rr_node->ylow - 1)))
&&(!(switch_box_y > (src_rr_node->yhigh + 1)))) {
return 1;
}
break;
@ -2947,26 +2986,6 @@ void find_drive_rr_nodes_switch_box(int switch_box_x,
return;
}
int is_sb_interc_between_segments(int switch_box_x,
int switch_box_y,
t_rr_node* src_rr_node,
int chan_side) {
int inode;
int cur_sb_num_drive_rr_nodes = 0;
for (inode = 0; inode < src_rr_node->num_drive_rr_nodes; inode++) {
if (1 == rr_node_drive_switch_box(src_rr_node->drive_rr_nodes[inode], src_rr_node,
switch_box_x, switch_box_y, chan_side)) {
cur_sb_num_drive_rr_nodes++;
}
}
if (0 == cur_sb_num_drive_rr_nodes) {
return 1;
} else {
return 0;
}
}
/* Count the number of configuration bits of a spice model */
int count_num_sram_bits_one_spice_model(t_spice_model* cur_spice_model,
int mux_size) {
@ -3957,7 +3976,9 @@ void init_one_grid_num_conf_bits(int ix, int iy,
assert((!(0 > ix))&&(!(ix > (nx + 1))));
assert((!(0 > iy))&&(!(iy > (ny + 1))));
if ((NULL == grid[ix][iy].type)||(0 != grid[ix][iy].offset)) {
if ((NULL == grid[ix][iy].type)
||(EMPTY_TYPE == grid[ix][iy].type)
||(0 != grid[ix][iy].offset)) {
/* Empty grid, directly return */
return;
}
@ -4378,7 +4399,9 @@ void init_one_grid_num_iopads(int ix, int iy) {
assert((!(0 > ix))&&(!(ix > (nx + 1))));
assert((!(0 > iy))&&(!(iy > (ny + 1))));
if ((NULL == grid[ix][iy].type)||(0 != grid[ix][iy].offset)) {
if ((NULL == grid[ix][iy].type)
||(EMPTY_TYPE == grid[ix][iy].type)
||(0 != grid[ix][iy].offset)) {
/* Empty grid, directly return */
return;
}
@ -5723,7 +5746,9 @@ int get_lut_output_init_val(t_logical_block* lut_logical_block) {
&& ( NULL != lut_logical_block->pb->pb_graph_node)
&& ( NULL != lut_logical_block->pb->pb_graph_node->pb_type));
lut_spice_model = lut_logical_block->pb->pb_graph_node->pb_type->parent_mode->parent_pb_type->spice_model;
assert(SPICE_MODEL_LUT == lut_spice_model->type);
sram_ports = find_spice_model_ports(lut_spice_model, SPICE_MODEL_PORT_SRAM,
&num_sram_port, TRUE);
assert(1 == num_sram_port);
@ -5772,6 +5797,39 @@ int get_lut_output_init_val(t_logical_block* lut_logical_block) {
return output_init_val;
}
/* Deteremine the initial value of an output of a logical block
* The logical block could be a LUT, a memory block or a multiplier
*/
int get_logical_block_output_init_val(t_logical_block* cur_logical_block) {
int output_init_val = 0;
t_spice_model* cur_spice_model = NULL;
/* Get the spice_model of current logical_block */
assert((NULL != cur_logical_block->pb)
&& ( NULL != cur_logical_block->pb->pb_graph_node)
&& ( NULL != cur_logical_block->pb->pb_graph_node->pb_type));
cur_spice_model = cur_logical_block->pb->pb_graph_node->pb_type->parent_mode->parent_pb_type->spice_model;
/* Switch to specific cases*/
switch (cur_spice_model->type) {
case SPICE_MODEL_LUT:
/* Determine the initial value from LUT inputs */
output_init_val = get_lut_output_init_val(cur_logical_block);
break;
case SPICE_MODEL_HARDLOGIC:
/* We have no information, give a default 0 now...
* TODO: find a smarter way!
*/
output_init_val = 0;
break;
default:
vpr_printf(TIO_MESSAGE_ERROR, "(File:%s,[LINE%d])Invalid type of SPICE MODEL (name=%s) in determining the initial output value of logical block(name=%s)!\n",
__FILE__, __LINE__, cur_spice_model->name, cur_logical_block->name);
exit(1);
}
return output_init_val;
}
/* Functions to manipulate struct sram_orgz_info */
t_sram_orgz_info* alloc_one_sram_orgz_info() {
@ -6900,6 +6958,9 @@ void config_spice_models_sram_port_spice_model(int num_spice_model,
return;
}
/* Return the child_pb of a LUT pb
* Because the mapping information is stored in the child_pb!!!
*/
t_pb* get_lut_child_pb(t_pb* cur_lut_pb,
int mode_index) {
@ -6911,6 +6972,21 @@ t_pb* get_lut_child_pb(t_pb* cur_lut_pb,
return (&(cur_lut_pb->child_pbs[0][0]));
}
/* Return the child_pb of a hardlogic pb
* Because the mapping information is stored in the child_pb!!!
*/
t_pb* get_hardlogic_child_pb(t_pb* cur_hardlogic_pb,
int mode_index) {
assert(SPICE_MODEL_HARDLOGIC == cur_hardlogic_pb->pb_graph_node->pb_type->spice_model->type);
assert(1 == cur_hardlogic_pb->pb_graph_node->pb_type->modes[mode_index].num_pb_type_children);
assert(1 == cur_hardlogic_pb->pb_graph_node->pb_type->num_pb);
return (&(cur_hardlogic_pb->child_pbs[0][0]));
}
int get_grid_pin_height(int grid_x, int grid_y, int pin_index) {
int pin_height;
t_type_ptr grid_type = NULL;
@ -7010,7 +7086,7 @@ void check_spice_models_grid_tb_cnt(int num_spice_models,
if (spice_model_type_to_check != spice_model[imodel].type) {
continue;
}
assert(spice_model[imodel].tb_cnt = spice_model[imodel].grid_index_high[grid_x][grid_y]);
assert(spice_model[imodel].tb_cnt == spice_model[imodel].grid_index_high[grid_x][grid_y]);
}
return;
@ -7027,4 +7103,47 @@ boolean check_negative_variation(float avg_val,
return exist_neg_val;
}
/* Check if this cby_info exists, it may be covered by a heterogenous block */
boolean is_cb_exist(t_rr_type cb_type,
int cb_x, int cb_y) {
boolean cb_exist = TRUE;
/* Check */
assert((!(0 > cb_x))&&(!(cb_x > (nx + 1))));
assert((!(0 > cb_y))&&(!(cb_y > (ny + 1))));
switch (cb_type) {
case CHANX:
/* Border case */
/* Check the grid under this CB */
if ((NULL == grid[cb_x][cb_y].type)
||(EMPTY_TYPE == grid[cb_x][cb_y].type)
||(1 < grid[cb_x][cb_y].type->height)) {
cb_exist = FALSE;
}
break;
case CHANY:
break;
default:
vpr_printf(TIO_MESSAGE_ERROR, "(File:%s, [LINE%d])Invalid CB type! Should be CHANX or CHANY.\n",
__FILE__, __LINE__);
exit(1);
}
return cb_exist;
}
/* Count the number of IPIN rr_nodes in a CB_info struct */
int count_cb_info_num_ipin_rr_nodes(t_cb cur_cb_info) {
int side;
int cnt = 0;
for (side = 0; side < cur_cb_info.num_sides; side++) {
cnt += cur_cb_info.num_ipin_rr_nodes[side];
}
return cnt;
}

View File

@ -104,6 +104,8 @@ char** my_strtok(char* str,
char* delims,
int* len);
int get_opposite_side(int side);
char* convert_side_index_to_string(int side);
char* convert_chan_type_to_string(t_rr_type chan_type);
@ -277,11 +279,6 @@ void find_drive_rr_nodes_switch_box(int switch_box_x,
t_rr_node*** drive_rr_nodes,
int* switch_index);
int is_sb_interc_between_segments(int switch_box_x,
int switch_box_y,
t_rr_node* src_rr_node,
int chan_side);
int count_num_sram_bits_one_spice_model(t_spice_model* cur_spice_model,
int mux_size);
@ -451,6 +448,8 @@ char** assign_lut_truth_table(t_logical_block* mapped_logical_block,
int get_lut_output_init_val(t_logical_block* lut_logical_block);
int get_logical_block_output_init_val(t_logical_block* cur_logical_block);
/* Functions to manipulate structs of SRAM orgz */
t_sram_orgz_info* alloc_one_sram_orgz_info();
@ -584,6 +583,9 @@ void config_spice_models_sram_port_spice_model(int num_spice_model,
t_pb* get_lut_child_pb(t_pb* cur_lut_pb,
int mode_index);
t_pb* get_hardlogic_child_pb(t_pb* cur_hardlogic_pb,
int mode_index);
int get_grid_pin_height(int grid_x, int grid_y, int pin_index);
void determine_sb_port_coordinator(t_sb cur_sb_info, int side,
@ -603,3 +605,8 @@ void check_spice_models_grid_tb_cnt(int num_spice_models,
boolean check_negative_variation(float avg_val,
t_spice_mc_variation_params variation_params);
boolean is_cb_exist(t_rr_type cb_type,
int cb_x, int cb_y);
int count_cb_info_num_ipin_rr_nodes(t_cb cur_cb_info);

View File

@ -130,7 +130,9 @@ void fprint_spice_grid_testbench_call_one_defined_grid(FILE* fp, int ix, int iy)
}
/* if ((NULL == grid[ix][iy].type)||(0 != grid[ix][iy].offset)||(0 == grid[ix][iy].usage)) { */
if ((NULL == grid[ix][iy].type)||(0 != grid[ix][iy].offset)) {
if ((NULL == grid[ix][iy].type)
||(EMPTY_TYPE == grid[ix][iy].type)
||(0 != grid[ix][iy].offset)) {
return;
}
@ -488,7 +490,9 @@ int fprint_spice_one_grid_testbench(char* formatted_spice_dir,
fclose(fp);
if (0 < tb_num_grid) {
/*
vpr_printf(TIO_MESSAGE_INFO, "Writing Grid[%d][%d] Testbench for %s...\n", grid_x, grid_y, circuit_name);
*/
/* Push the testbench to the linked list */
tb_head = add_one_spice_tb_info_to_llist(tb_head, grid_testbench_file_path,
max_sim_num_clock_cycles);
@ -516,6 +520,8 @@ void spice_print_grid_testbench(char* formatted_spice_dir,
int cnt = 0;
int used;
vpr_printf(TIO_MESSAGE_INFO,"Generating grid testbench...\n");
for (ix = 1; ix < (nx+1); ix++) {
for (iy = 1; iy < (ny+1); iy++) {
grid_testbench_name = (char*)my_malloc(sizeof(char)*( strlen(circuit_name)

View File

@ -461,7 +461,8 @@ void fprint_spice_hardlogic_testbench_rec_pb_graph_node_hardlogics(FILE* fp,
assert(NULL != cur_pb_type);
/* Until we reach a FF */
if (NULL != cur_pb_type->spice_model) {
if (SPICE_MODEL_FF != cur_pb_type->spice_model->type) {
if ((SPICE_MODEL_FF != cur_pb_type->spice_model->type)
&&(SPICE_MODEL_HARDLOGIC != cur_pb_type->spice_model->type)) {
return;
}
/* Generate rec_prefix */
@ -572,7 +573,9 @@ void fprint_spice_hardlogic_testbench_call_one_grid_defined_hardlogics(FILE* fp,
int iblk;
char* prefix = NULL;
if (NULL == grid[ix][iy].type) {
if ((NULL == grid[ix][iy].type)
||(EMPTY_TYPE == grid[ix][iy].type)
||(0 != grid[ix][iy].offset)) {
return;
}
@ -798,8 +801,10 @@ int fprint_spice_one_hardlogic_testbench(char* formatted_spice_dir,
fclose(fp);
if (0 < tb_num_hardlogic) {
/*
vpr_printf(TIO_MESSAGE_INFO, "Writing Grid[%d][%d] SPICE Hard Logic Testbench for %s...\n",
grid_x, grid_y, circuit_name);
*/
/* Push the testbench to the linked list */
tb_head = add_one_spice_tb_info_to_llist(tb_head, hardlogic_testbench_file_path,
max_sim_num_clock_cycles);

View File

@ -263,7 +263,10 @@ void fprint_spice_lut_testbench_one_pb_graph_node_lut(FILE* fp,
if (OPEN != logical_block_index) {
logical_block[logical_block_index].temp_used = 1;
}
/* Increment the counter of the LUT spice model */
tb_num_luts++;
pb_spice_model->tb_cnt++;
/* Free */
my_free(input_net_num);
@ -402,7 +405,9 @@ void fprint_spice_lut_testbench_call_one_grid_defined_luts(FILE* fp, int ix, int
exit(1);
}
if (NULL == grid[ix][iy].type) {
if ((NULL == grid[ix][iy].type)
||(EMPTY_TYPE == grid[ix][iy].type)
||(0 != grid[ix][iy].offset)) {
return;
}
@ -623,7 +628,7 @@ int fprint_spice_one_lut_testbench(char* formatted_spice_dir,
}
/* Reset tb_cnt for all the spice models */
init_spice_models_tb_cnt(arch.spice->num_spice_model, arch.spice->spice_models);
init_spice_models_grid_tb_cnt(arch.spice->num_spice_model, arch.spice->spice_models, grid_x, grid_y);
/*vpr_printf(TIO_MESSAGE_INFO, "Writing LUT Testbench for %s...\n", circuit_name);*/
testbench_load_cnt = 0;
@ -686,8 +691,10 @@ int fprint_spice_one_lut_testbench(char* formatted_spice_dir,
fclose(fp);
if (0 < tb_num_luts) {
/*
vpr_printf(TIO_MESSAGE_INFO, "Writing Grid[%d][%d] SPICE LUT Testbench for %s...\n",
grid_x, grid_y, circuit_name);
*/
/* Push the testbench to the linked list */
tb_head = add_one_spice_tb_info_to_llist(tb_head, lut_testbench_file_path,
max_sim_num_clock_cycles);
@ -716,6 +723,8 @@ void spice_print_lut_testbench(char* formatted_spice_dir,
int cnt = 0;
int used;
vpr_printf(TIO_MESSAGE_INFO,"Generating LUT testbench...\n");
for (ix = 1; ix < (nx+1); ix++) {
for (iy = 1; iy < (ny+1); iy++) {
lut_testbench_name = (char*)my_malloc(sizeof(char)*( strlen(circuit_name)

View File

@ -26,6 +26,7 @@
#include "fpga_spice_globals.h"
#include "spice_globals.h"
#include "fpga_spice_utils.h"
#include "fpga_spice_backannotate_utils.h"
#include "spice_utils.h"
#include "spice_routing.h"
#include "spice_subckt.h"
@ -1419,7 +1420,7 @@ int fprint_spice_mux_testbench_call_one_grid_cb_muxes(FILE* fp,
static
int fprint_spice_mux_testbench_sb_one_mux(FILE* fp,
int switch_box_x, int switch_box_y,
t_sb cur_sb_info,
int chan_side,
t_rr_node* src_rr_node) {
int inode, switch_index, mux_size;
@ -1437,6 +1438,11 @@ int fprint_spice_mux_testbench_sb_one_mux(FILE* fp,
float average_sb_mux_input_density = 0.;
int switch_box_x, switch_box_y;
switch_box_x = cur_sb_info.x;
switch_box_y = cur_sb_info.y;
/* Check */
assert((!(0 > switch_box_x))&&(!(switch_box_x > (nx + 1))));
assert((!(0 > switch_box_y))&&(!(switch_box_y > (ny + 1))));
@ -1452,7 +1458,7 @@ int fprint_spice_mux_testbench_sb_one_mux(FILE* fp,
*/
/* Determine if the interc lies inside a channel wire, that is interc between segments */
if (1 == is_sb_interc_between_segments(switch_box_x, switch_box_y, src_rr_node, chan_side)) {
if (1 == is_rr_node_exist_opposite_side_in_sb_info(cur_sb_info, src_rr_node, chan_side)) {
num_drive_rr_nodes = 0;
drive_rr_nodes = NULL;
} else {
@ -1571,8 +1577,7 @@ int fprint_spice_mux_testbench_call_one_grid_sb_muxes(FILE* fp,
switch (cur_sb_info.chan_rr_node_direction[side][itrack]) {
case OUT_PORT:
fprint_spice_mux_testbench_sb_one_mux(fp,
cur_sb_info.x,
cur_sb_info.y,
cur_sb_info,
side,
cur_sb_info.chan_rr_node[side][itrack]);
used++;
@ -1607,7 +1612,9 @@ int fprint_spice_mux_testbench_call_one_grid_pb_muxes(FILE* fp, int ix, int iy,
exit(1);
}
/* Print all the grid */
if ((NULL == grid[ix][iy].type)||(0 != grid[ix][iy].offset)) {
if ((NULL == grid[ix][iy].type)
||(EMPTY_TYPE == grid[ix][iy].type)
||(0 != grid[ix][iy].offset)) {
return used;
}
/* Used blocks */
@ -1823,17 +1830,26 @@ int fprint_spice_one_mux_testbench(char* formatted_spice_dir,
switch (mux_tb_type) {
case SPICE_PB_MUX_TB:
total_pb_mux_input_density = 0.;
/* Output a pb_mux testbench */
used = fprint_spice_mux_testbench_call_one_grid_pb_muxes(fp, grid_x, grid_y, LL_rr_node_indices);
total_pb_mux_input_density = total_pb_mux_input_density/testbench_pb_mux_cnt;
/* Check and output info. */
assert((0 == testbench_pb_mux_cnt)||(0 < testbench_pb_mux_cnt));
if (0 < testbench_pb_mux_cnt) {
total_pb_mux_input_density = total_pb_mux_input_density/testbench_pb_mux_cnt;
/* Add stimulations */
fprint_spice_mux_testbench_stimulations(fp, num_clocks);
/* Add measurements */
fprint_spice_mux_testbench_measurements(fp, mux_tb_type, *(arch.spice));
}
/*
vpr_printf(TIO_MESSAGE_INFO,"Average density of PB MUX inputs is %.2g.\n", total_pb_mux_input_density);
/* Add stimulations */
fprint_spice_mux_testbench_stimulations(fp, num_clocks);
/* Add measurements */
fprint_spice_mux_testbench_measurements(fp, mux_tb_type, *(arch.spice));
*/
break;
case SPICE_CB_MUX_TB:
/* one cbx, one cby*/
/* one cbx or one cby*/
total_cb_mux_input_density = 0.;
/* Output a cb_mux testbench */
switch (cb_type) {
case CHANX:
used = fprint_spice_mux_testbench_call_one_grid_cb_muxes(fp, cbx_info[grid_x][grid_y], LL_rr_node_indices);
@ -1845,22 +1861,35 @@ int fprint_spice_one_mux_testbench(char* formatted_spice_dir,
vpr_printf(TIO_MESSAGE_ERROR, "(File:%s, [LINE%d]) Invalid connection_box_type!\n", __FILE__, __LINE__);
exit(1);
}
total_cb_mux_input_density = total_cb_mux_input_density/testbench_cb_mux_cnt;
/* Check and output info. */
assert((0 == testbench_cb_mux_cnt)||(0 < testbench_cb_mux_cnt));
if (0 < testbench_cb_mux_cnt) {
total_cb_mux_input_density = total_cb_mux_input_density/testbench_cb_mux_cnt;
/* Add stimulations */
fprint_spice_mux_testbench_stimulations(fp, num_clocks);
/* Add measurements */
fprint_spice_mux_testbench_measurements(fp, mux_tb_type, *(arch.spice));
}
/*
vpr_printf(TIO_MESSAGE_INFO,"Average density of CB MUX inputs is %.2g.\n", total_cb_mux_input_density);
/* Add stimulations */
fprint_spice_mux_testbench_stimulations(fp, num_clocks);
/* Add measurements */
fprint_spice_mux_testbench_measurements(fp, mux_tb_type, *(arch.spice));
*/
break;
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);
total_sb_mux_input_density = total_sb_mux_input_density/testbench_sb_mux_cnt;
/* Check and output info. */
assert((0 == testbench_sb_mux_cnt)||(0 < testbench_sb_mux_cnt));
if (0 < testbench_sb_mux_cnt) {
total_sb_mux_input_density = total_sb_mux_input_density/testbench_sb_mux_cnt;
/* Add stimulations */
fprint_spice_mux_testbench_stimulations(fp, num_clocks);
/* Add measurements */
fprint_spice_mux_testbench_measurements(fp, mux_tb_type, *(arch.spice));
}
/*
vpr_printf(TIO_MESSAGE_INFO,"Average density of SB MUX inputs is %.2g.\n", total_sb_mux_input_density);
/* Add stimulations */
fprint_spice_mux_testbench_stimulations(fp, num_clocks);
/* Add measurements */
fprint_spice_mux_testbench_measurements(fp, mux_tb_type, *(arch.spice));
*/
break;
default:
vpr_printf(TIO_MESSAGE_ERROR, "(File:%s, [LINE%d]) Invalid mux_tb_type!\n", __FILE__, __LINE__);
@ -1880,8 +1909,9 @@ int fprint_spice_one_mux_testbench(char* formatted_spice_dir,
free_muxes_llist(testbench_muxes_head);
if (0 < testbench_mux_cnt) {
vpr_printf(TIO_MESSAGE_INFO, "Writing Grid[%d][%d] SPICE %s Test Bench for %s...\n",
/* vpr_printf(TIO_MESSAGE_INFO, "Writing Grid[%d][%d] SPICE %s Test Bench for %s...\n",
grid_x, grid_y, mux_tb_name, circuit_name);
*/
/* Push the testbench to the linked list */
tb_head = add_one_spice_tb_info_to_llist(tb_head, mux_testbench_file_path, max_sim_num_clock_cycles);
used = 1;
@ -1907,11 +1937,13 @@ void spice_print_mux_testbench(char* formatted_spice_dir,
int ix, iy;
int cnt = 0;
int used = 0;
int bypass_cnt = 0;
/* Depend on the type of testbench, we generate the a list of testbenches */
switch (mux_tb_type) {
case SPICE_PB_MUX_TB:
cnt = 0;
vpr_printf(TIO_MESSAGE_INFO,"Generating Grid multiplexer testbench...\n");
for (ix = 1; ix < (nx+1); ix++) {
for (iy = 1; iy < (ny+1); iy++) {
mux_testbench_name = (char*)my_malloc(sizeof(char)*( strlen(circuit_name)
@ -1933,12 +1965,20 @@ void spice_print_mux_testbench(char* formatted_spice_dir,
}
/* Update the global counter */
num_used_grid_mux_tb = cnt;
vpr_printf(TIO_MESSAGE_INFO,"No. of generated PB_MUX testbench = %d\n", num_used_grid_tb);
vpr_printf(TIO_MESSAGE_INFO,"No. of generated Grid multiplexer testbench = %d\n", num_used_grid_mux_tb);
break;
case SPICE_CB_MUX_TB:
cnt = 0;
/* X-channel Connection Blocks */
vpr_printf(TIO_MESSAGE_INFO,"Generating X-channel Connection Block multiplexer testbench...\n");
for (iy = 0; iy < (ny+1); iy++) {
for (ix = 1; ix < (nx+1); ix++) {
/* Bypass non-exist CBs */
if ((FALSE == is_cb_exist(CHANX, ix, iy))
||(0 == count_cb_info_num_ipin_rr_nodes(cbx_info[ix][iy]))) {
bypass_cnt++;
continue;
}
mux_testbench_name = (char*)my_malloc(sizeof(char)*( strlen(circuit_name)
+ 4 + strlen(my_itoa(ix)) + 2 + strlen(my_itoa(iy)) + 1
+ strlen(spice_cb_mux_testbench_postfix) + 1 ));
@ -1955,8 +1995,17 @@ void spice_print_mux_testbench(char* formatted_spice_dir,
my_free(mux_testbench_name);
}
}
/* Y-channel Connection Blocks */
vpr_printf(TIO_MESSAGE_INFO,"Generating Y-channel Connection Block multiplexer testbench...\n");
for (ix = 0; ix < (nx+1); ix++) {
for (iy = 1; iy < (ny+1); iy++) {
/* Bypass non-exist CBs */
if ((FALSE == is_cb_exist(CHANY, ix, iy))
||(0 == count_cb_info_num_ipin_rr_nodes(cby_info[ix][iy]))) {
bypass_cnt++;
continue;
}
mux_testbench_name = (char*)my_malloc(sizeof(char)*( strlen(circuit_name)
+ 4 + strlen(my_itoa(ix)) + 2 + strlen(my_itoa(iy)) + 1
+ strlen(spice_cb_mux_testbench_postfix) + 1 ));
@ -1975,10 +2024,13 @@ void spice_print_mux_testbench(char* formatted_spice_dir,
}
/* Update the global counter */
num_used_cb_mux_tb = cnt;
vpr_printf(TIO_MESSAGE_INFO,"No. of generated CB_MUX testbench = %d\n", num_used_cb_mux_tb);
vpr_printf(TIO_MESSAGE_INFO,"No. of generated Connection Block multiplexer testbench = %d\n", num_used_cb_mux_tb);
vpr_printf(TIO_MESSAGE_INFO, "Bypass %d Connection Blocks that does no exist in the architecture.\n",
bypass_cnt);
break;
case SPICE_SB_MUX_TB:
cnt = 0;
vpr_printf(TIO_MESSAGE_INFO,"Generating Switch Block multiplexer testbench...\n");
for (ix = 0; ix < (nx+1); ix++) {
for (iy = 0; iy < (ny+1); iy++) {
mux_testbench_name = (char*)my_malloc(sizeof(char)*( strlen(circuit_name)
@ -1999,7 +2051,7 @@ void spice_print_mux_testbench(char* formatted_spice_dir,
}
/* Update the global counter */
num_used_sb_mux_tb = cnt;
vpr_printf(TIO_MESSAGE_INFO,"No. of generated SB_MUX testbench = %d\n", num_used_sb_mux_tb);
vpr_printf(TIO_MESSAGE_INFO,"No. of generated Switch Block multiplexer testbench = %d\n", num_used_sb_mux_tb);
break;
default:
vpr_printf(TIO_MESSAGE_ERROR, "(File:%s, [LINE%d]) Invalid mux_tb_type!\n", __FILE__, __LINE__);

View File

@ -1285,8 +1285,14 @@ void fprint_spice_pb_graph_node_rec(FILE* fp,
cur_pb, cur_pb_graph_node,
pb_type_index, cur_pb_type->spice_model, 0);
break;
case UNKNOWN_CLASS:
case MEMORY_CLASS:
child_pb = get_hardlogic_child_pb(cur_pb, mode_index);
/* Consider the num_pb, create all the subckts*/
fprint_pb_primitive_spice_model(fp, formatted_subckt_prefix,
child_pb, cur_pb_graph_node,
pb_type_index, cur_pb_type->spice_model, 0);
break;
case UNKNOWN_CLASS:
/* Consider the num_pb, create all the subckts*/
fprint_pb_primitive_spice_model(fp, formatted_subckt_prefix,
cur_pb, cur_pb_graph_node,
@ -2113,7 +2119,9 @@ void fprint_grid_physical_blocks(FILE* fp,
/* generate_grid_subckt, type_descriptor of each grid defines the capacity,
* for example, each grid may contains more than one top-level pb_types, such as I/O
*/
if ((NULL == grid[ix][iy].type)||(0 != grid[ix][iy].offset)) {
if ((NULL == grid[ix][iy].type)
||(EMPTY_TYPE == grid[ix][iy].type)
||(0 != grid[ix][iy].offset)) {
/* Update the grid_index_high for each spice_model */
update_spice_models_grid_index_high(ix, iy, arch->spice->num_spice_model, arch->spice->spice_models);
return;
@ -2227,11 +2235,15 @@ void fprint_grid_blocks(FILE* fp,
/* generate_grid_subckt, type_descriptor of each grid defines the capacity,
* for example, each grid may contains more than one top-level pb_types, such as I/O
*/
if ((NULL == grid[ix][iy].type)||(0 != grid[ix][iy].offset)) {
/* Bypass EMPTY_TYPE */
if ((NULL == grid[ix][iy].type)
||(EMPTY_TYPE == grid[ix][iy].type)
||(0 != grid[ix][iy].offset)) {
/* Update the grid_index_high for each spice_model */
update_spice_models_grid_index_high(ix, iy, arch->spice->num_spice_model, arch->spice->spice_models);
return;
}
capacity= grid[ix][iy].type->capacity;
assert(0 < capacity);

View File

@ -175,14 +175,14 @@ void fprint_grid_side_pin_with_given_index(FILE* fp,
assert((!(0 > side))&&(!(side > 3)));
/* Output the pins on the side*/
height = grid[x][y].offset;
height = get_grid_pin_height(x, y, pin_index);
class_id = type->pin_class[pin_index];
if ((1 == type->pinloc[height][side][pin_index])) {
/* Not sure if we need to plus a height */
/* fprintf(fp, "grid[%d][%d]_pin[%d][%d][%d] ", x, y, height, side, pin_index); */
fprintf(fp, "grid[%d][%d]_pin[%d][%d][%d] ", x, y + height, height, side, pin_index);
} else {
vpr_printf(TIO_MESSAGE_ERROR, "(File:%s, [LINE%d])Fail to print a grid pin (x=%d, y=%d, height=%d, side=%d, index=%d)",
vpr_printf(TIO_MESSAGE_ERROR, "(File:%s, [LINE%d])Fail to print a grid pin (x=%d, y=%d, height=%d, side=%d, index=%d)\n",
__FILE__, __LINE__, x, y, height, side, pin_index);
exit(1);
}
@ -228,8 +228,8 @@ void fprint_grid_side_pins(FILE* fp,
}
/* Output the pins on the side*/
height = grid[x][y].offset;
for (ipin = 0; ipin < type->num_pins; ipin++) {
height = get_grid_pin_height(x, y, ipin);
class_id = type->pin_class[ipin];
if ((1 == type->pinloc[height][side][ipin])&&(pin_class_type == type->class_inf[class_id].type)) {
/* Not sure if we need to plus a height */
@ -412,7 +412,9 @@ void fprint_switch_box_mux(FILE* fp,
/* Search all the sides of a SB, see this drive_rr_node is an INPUT of this SB */
get_rr_node_side_and_index_in_sb_info(drive_rr_nodes[inode], cur_sb_info, IN_PORT, &side, &index);
/* We need to be sure that drive_rr_node is part of the SB */
if (!((-1 != index)&&(-1 != side))) {
assert((-1 != index)&&(-1 != side));
}
/* Find grid_x and grid_y */
grid_x = drive_rr_nodes[inode]->xlow;
grid_y = drive_rr_nodes[inode]->ylow; /*Plus the offset in function fprint_grid_side_pin_with_given_index */
@ -564,7 +566,7 @@ void fprint_switch_box_interc(FILE* fp,
*/
/* Determine if the interc lies inside a channel wire, that is interc between segments */
if (1 == is_sb_interc_between_segments(sb_x, sb_y, cur_rr_node, chan_side)) {
if (1 == is_rr_node_exist_opposite_side_in_sb_info(cur_sb_info, cur_rr_node, chan_side)) {
num_drive_rr_nodes = 0;
drive_rr_nodes = NULL;
} else {
@ -1237,8 +1239,12 @@ void generate_spice_routing_resources(char* subckt_dir,
for (iy = 0; iy < (ny + 1); iy++) {
for (ix = 1; ix < (nx + 1); ix++) {
update_spice_models_routing_index_low(ix, iy, CHANX, arch.spice->num_spice_model, arch.spice->spice_models);
fprint_routing_connection_box_subckt(fp, cbx_info[ix][iy],
LL_num_rr_nodes, LL_rr_node, LL_rr_node_indices);
/* 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(fp, cbx_info[ix][iy],
LL_num_rr_nodes, LL_rr_node, LL_rr_node_indices);
}
update_spice_models_routing_index_high(ix, iy, CHANX, arch.spice->num_spice_model, arch.spice->spice_models);
}
}
@ -1246,8 +1252,12 @@ void generate_spice_routing_resources(char* subckt_dir,
for (ix = 0; ix < (nx + 1); ix++) {
for (iy = 1; iy < (ny + 1); iy++) {
update_spice_models_routing_index_low(ix, iy, CHANY, arch.spice->num_spice_model, arch.spice->spice_models);
fprint_routing_connection_box_subckt(fp, cby_info[ix][iy],
LL_num_rr_nodes, LL_rr_node, LL_rr_node_indices);
/* 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(fp, cby_info[ix][iy],
LL_num_rr_nodes, LL_rr_node, LL_rr_node_indices);
}
update_spice_models_routing_index_high(ix, iy, CHANY, arch.spice->num_spice_model, arch.spice->spice_models);
}
}

View File

@ -322,10 +322,14 @@ int fprint_spice_routing_testbench_call_one_cb_tb(FILE* fp,
/* print average cb input density */
switch(chan_type) {
case CHANX:
/*
vpr_printf(TIO_MESSAGE_INFO,"Average density of CBX[%d][%d] inputs is %.2g.\n", x, y, average_cb_input_density);
*/
break;
case CHANY:
/*
vpr_printf(TIO_MESSAGE_INFO,"Average density of CBY[%d][%d] inputs is %.2g.\n", x, y, average_cb_input_density);
*/
break;
default:
vpr_printf(TIO_MESSAGE_ERROR, "(File:%s, [LINE%d])Invalid type of channel!\n", __FILE__, __LINE__);
@ -527,7 +531,9 @@ int fprint_spice_routing_testbench_call_one_sb_tb(FILE* fp,
fprintf(fp, ".meas tran energy_per_cycle_sram_sb param='dynamic_power_sram_sb*clock_period'\n");
/* print average sb input density */
/*
vpr_printf(TIO_MESSAGE_INFO,"Average density of SB[%d][%d] inputs is %.2g.\n", x, y, average_sb_input_density);
*/
/* Free */
@ -735,8 +741,15 @@ void spice_print_cb_testbench(char* formatted_spice_dir,
int cnt = 0;
int used = 0;
/* X-channel Connection Blocks */
vpr_printf(TIO_MESSAGE_INFO,"Generating X-channel Connection Block testbench...\n");
for (iy = 0; iy < (ny+1); iy++) {
for (ix = 1; ix < (nx+1); ix++) {
/* Bypass non-exist CBs */
if ((FALSE == is_cb_exist(CHANX, ix, iy))
||(0 == count_cb_info_num_ipin_rr_nodes(cbx_info[ix][iy]))) {
continue;
}
cb_testbench_name = (char*)my_malloc(sizeof(char)*( strlen(circuit_name)
+ 4 + strlen(my_itoa(ix)) + 2 + strlen(my_itoa(iy)) + 1
+ strlen(spice_cb_testbench_postfix) + 1 ));
@ -753,8 +766,16 @@ void spice_print_cb_testbench(char* formatted_spice_dir,
my_free(cb_testbench_name);
}
}
/* Y-channel Connection Blocks */
vpr_printf(TIO_MESSAGE_INFO,"Generating Y-channel Connection Block testbench...\n");
for (ix = 0; ix < (nx+1); ix++) {
for (iy = 1; iy < (ny+1); iy++) {
/* Bypass non-exist CBs */
if ((FALSE == is_cb_exist(CHANY, ix, iy))
||(0 == count_cb_info_num_ipin_rr_nodes(cby_info[ix][iy]))) {
continue;
}
cb_testbench_name = (char*)my_malloc(sizeof(char)*( strlen(circuit_name)
+ 4 + strlen(my_itoa(ix)) + 2 + strlen(my_itoa(iy)) + 1
+ strlen(spice_cb_testbench_postfix) + 1 ));
@ -773,7 +794,7 @@ void spice_print_cb_testbench(char* formatted_spice_dir,
}
/* Update the global counter */
num_used_cb_tb = cnt;
vpr_printf(TIO_MESSAGE_INFO,"No. of generated CB testbench = %d\n", num_used_cb_tb);
vpr_printf(TIO_MESSAGE_INFO,"No. of generated Connection Block testbench = %d\n", num_used_cb_tb);
return;
@ -794,6 +815,8 @@ void spice_print_sb_testbench(char* formatted_spice_dir,
int cnt = 0;
int used = 0;
vpr_printf(TIO_MESSAGE_INFO,"Generating Switch Block testbench...\n");
for (ix = 0; ix < (nx+1); ix++) {
for (iy = 0; iy < (ny+1); iy++) {
sb_testbench_name = (char*)my_malloc(sizeof(char)*( strlen(circuit_name)
@ -814,7 +837,7 @@ void spice_print_sb_testbench(char* formatted_spice_dir,
}
/* Update the global counter */
num_used_sb_tb = cnt;
vpr_printf(TIO_MESSAGE_INFO,"No. of generated SB testbench = %d\n", num_used_sb_tb);
vpr_printf(TIO_MESSAGE_INFO,"No. of generated Switch Block testbench = %d\n", num_used_sb_tb);
return;
}

View File

@ -891,6 +891,10 @@ void fprint_call_defined_grids(FILE* fp) {
/* Normal Grids */
for (ix = 1; ix < (nx + 1); ix++) {
for (iy = 1; iy < (ny + 1); iy++) {
/* Bypass EMPTY grid */
if (EMPTY_TYPE == grid[ix][iy].type) {
continue;
}
assert(IO_TYPE != grid[ix][iy].type);
fprintf(fp, "Xgrid[%d][%d] ", ix, iy);
fprintf(fp, "\n");
@ -904,6 +908,10 @@ void fprint_call_defined_grids(FILE* fp) {
/* LEFT side */
ix = 0;
for (iy = 1; iy < (ny + 1); iy++) {
/* Bypass EMPTY grid */
if (EMPTY_TYPE == grid[ix][iy].type) {
continue;
}
assert(IO_TYPE == grid[ix][iy].type);
fprintf(fp, "Xgrid[%d][%d] ", ix, iy);
fprintf(fp, "\n");
@ -916,6 +924,10 @@ void fprint_call_defined_grids(FILE* fp) {
/* RIGHT side */
ix = nx + 1;
for (iy = 1; iy < (ny + 1); iy++) {
/* Bypass EMPTY grid */
if (EMPTY_TYPE == grid[ix][iy].type) {
continue;
}
assert(IO_TYPE == grid[ix][iy].type);
fprintf(fp, "Xgrid[%d][%d] ", ix, iy);
fprintf(fp, "\n");
@ -928,6 +940,10 @@ void fprint_call_defined_grids(FILE* fp) {
/* BOTTOM side */
iy = 0;
for (ix = 1; ix < (nx + 1); ix++) {
/* Bypass EMPTY grid */
if (EMPTY_TYPE == grid[ix][iy].type) {
continue;
}
assert(IO_TYPE == grid[ix][iy].type);
fprintf(fp, "Xgrid[%d][%d] ", ix, iy);
fprintf(fp, "\n");
@ -940,6 +956,10 @@ void fprint_call_defined_grids(FILE* fp) {
/* TOP side */
iy = ny + 1;
for (ix = 1; ix < (nx + 1); ix++) {
/* Bypass EMPTY grid */
if (EMPTY_TYPE == grid[ix][iy].type) {
continue;
}
assert(IO_TYPE == grid[ix][iy].type);
fprintf(fp, "Xgrid[%d][%d] ", ix, iy);
fprintf(fp, "\n");
@ -1210,13 +1230,19 @@ void fprint_call_defined_connection_boxes(FILE* fp) {
/* X - channels [1...nx][0..ny]*/
for (iy = 0; iy < (ny + 1); iy++) {
for (ix = 1; ix < (nx + 1); ix++) {
fprint_call_defined_one_connection_box(fp, cbx_info[ix][iy]);
if ((TRUE == is_cb_exist(CHANX, ix, iy))
&&(0 < count_cb_info_num_ipin_rr_nodes(cbx_info[ix][iy]))) {
fprint_call_defined_one_connection_box(fp, cbx_info[ix][iy]);
}
}
}
/* Y - channels [1...ny][0..nx]*/
for (ix = 0; ix < (nx + 1); ix++) {
for (iy = 1; iy < (ny + 1); iy++) {
fprint_call_defined_one_connection_box(fp, cby_info[ix][iy]);
if ((TRUE == is_cb_exist(CHANY, ix, iy))
&&(0 < count_cb_info_num_ipin_rr_nodes(cby_info[ix][iy]))) {
fprint_call_defined_one_connection_box(fp, cby_info[ix][iy]);
}
}
}
@ -2086,6 +2112,10 @@ void fprint_stimulate_dangling_grid_pins(FILE* fp) {
/* Normal Grids */
for (ix = 1; ix < (nx + 1); ix++) {
for (iy = 1; iy < (ny + 1); iy++) {
/* Bypass EMPTY grid */
if (EMPTY_TYPE == grid[ix][iy].type) {
continue;
}
assert(IO_TYPE != grid[ix][iy].type);
/* zero-fan-in CLB IPIN*/
fprint_stimulate_dangling_normal_grid_pins(fp, ix, iy);
@ -2096,6 +2126,10 @@ void fprint_stimulate_dangling_grid_pins(FILE* fp) {
/* LEFT side */
ix = 0;
for (iy = 1; iy < (ny + 1); iy++) {
/* Bypass EMPTY grid */
if (EMPTY_TYPE == grid[ix][iy].type) {
continue;
}
assert(IO_TYPE == grid[ix][iy].type);
fprint_stimulate_dangling_io_grid_pins(fp, ix, iy);
}
@ -2103,6 +2137,10 @@ void fprint_stimulate_dangling_grid_pins(FILE* fp) {
/* RIGHT side */
ix = nx + 1;
for (iy = 1; iy < (ny + 1); iy++) {
/* Bypass EMPTY grid */
if (EMPTY_TYPE == grid[ix][iy].type) {
continue;
}
assert(IO_TYPE == grid[ix][iy].type);
fprint_stimulate_dangling_io_grid_pins(fp, ix, iy);
}
@ -2110,6 +2148,10 @@ void fprint_stimulate_dangling_grid_pins(FILE* fp) {
/* BOTTOM side */
iy = 0;
for (ix = 1; ix < (nx + 1); ix++) {
/* Bypass EMPTY grid */
if (EMPTY_TYPE == grid[ix][iy].type) {
continue;
}
assert(IO_TYPE == grid[ix][iy].type);
fprint_stimulate_dangling_io_grid_pins(fp, ix, iy);
}
@ -2117,6 +2159,10 @@ void fprint_stimulate_dangling_grid_pins(FILE* fp) {
/* TOP side */
iy = ny + 1;
for (ix = 1; ix < (nx + 1); ix++) {
/* Bypass EMPTY grid */
if (EMPTY_TYPE == grid[ix][iy].type) {
continue;
}
assert(IO_TYPE == grid[ix][iy].type);
fprint_stimulate_dangling_io_grid_pins(fp, ix, iy);
}
@ -2892,8 +2938,10 @@ char* fprint_spice_testbench_rr_node_load_version(FILE* fp, int* testbench_load_
to_node = rr_node[cur_rr_node.edges[iedge]];
switch (to_node.type) {
case IPIN:
/* The assert only works for homogeneous blocks
assert(to_node.xhigh == to_node.xlow);
assert(to_node.yhigh == to_node.ylow);
*/
if (((cur_x == to_node.xlow)&&(cur_y == to_node.ylow))
||((cur_x == to_node.xlow)&&((cur_y + 1) == to_node.ylow))) {
/* We find a CB! */
@ -2976,8 +3024,10 @@ char* fprint_spice_testbench_rr_node_load_version(FILE* fp, int* testbench_load_
to_node = rr_node[cur_rr_node.edges[iedge]];
switch (to_node.type) {
case IPIN:
/* The assert only works for homogeneous blocks
assert(to_node.xhigh == to_node.xlow);
assert(to_node.yhigh == to_node.ylow);
*/
if (((cur_y == to_node.ylow)&&(cur_x == to_node.xlow))
||((cur_y == to_node.xlow)&&((cur_x + 1) == to_node.xlow))) {
/* We find a CB! */
@ -3055,8 +3105,10 @@ void fprint_spice_testbench_one_cb_mux_loads(FILE* fp, int* testbench_load_cnt,
t_pb* cb_out_pb = NULL;
assert(IPIN == src_rr_node->type);
/* The assert only works for homogeneous blocks
assert(src_rr_node->xlow == src_rr_node->xhigh);
assert(src_rr_node->ylow == src_rr_node->yhigh);
*/
cb_out_grid_type = grid[src_rr_node->xlow][src_rr_node->ylow].type;
assert(NULL != cb_out_grid_type);

View File

@ -2013,18 +2013,30 @@ void dump_verilog_pb_graph_node_rec(FILE* fp,
assert(0 == cur_pb_type->num_modes);
/* Consider the num_pb, create all the subckts*/
dump_verilog_pb_primitive_verilog_model(fp, formatted_subckt_prefix,
cur_pb, cur_pb_graph_node, pb_type_index, cur_pb_type->spice_model, 0);
cur_pb, cur_pb_graph_node,
pb_type_index, cur_pb_type->spice_model, 0);
/* update the number of SRAM, I/O pads */
/* update stamped iopad counter */
stamped_iopad_cnt += cur_pb->num_iopads;
/* update stamped sram counter */
stamped_sram_cnt += cur_pb->num_conf_bits;
break;
case UNKNOWN_CLASS:
case MEMORY_CLASS:
child_pb = get_hardlogic_child_pb(cur_pb, mode_index);
/* Consider the num_pb, create all the subckts*/
dump_verilog_pb_primitive_verilog_model(fp, formatted_subckt_prefix,
cur_pb, cur_pb_graph_node, pb_type_index, cur_pb_type->spice_model, 0);
child_pb, cur_pb_graph_node,
pb_type_index, cur_pb_type->spice_model, 0);
/* update the number of SRAM, I/O pads */
/* update stamped iopad counter */
stamped_iopad_cnt += cur_pb->num_iopads;
/* update stamped sram counter */
stamped_sram_cnt += cur_pb->num_conf_bits;
break;
case UNKNOWN_CLASS:
/* Consider the num_pb, create all the subckts*/
dump_verilog_pb_primitive_verilog_model(fp, formatted_subckt_prefix,
cur_pb, cur_pb_graph_node, pb_type_index, cur_pb_type->spice_model, 0);
/* update the number of SRAM, I/O pads */
/* update stamped iopad counter */
stamped_iopad_cnt += cur_pb->num_iopads;
@ -3160,7 +3172,9 @@ void dump_verilog_grid_blocks(FILE* fp,
/* generate_grid_subckt, type_descriptor of each grid defines the capacity,
* for example, each grid may contains more than one top-level pb_types, such as I/O
*/
if ((NULL == grid[ix][iy].type)||(0 != grid[ix][iy].offset)) {
if ((NULL == grid[ix][iy].type)
||(EMPTY_TYPE == grid[ix][iy].type)
||(0 != grid[ix][iy].offset)) {
/* Update the grid_index_high for each spice_model */
update_spice_models_grid_index_high(ix, iy, arch->spice->num_spice_model, arch->spice->spice_models);
return;
@ -3363,7 +3377,9 @@ void dump_verilog_physical_grid_blocks(FILE* fp,
/* generate_grid_subckt, type_descriptor of each grid defines the capacity,
* for example, each grid may contains more than one top-level pb_types, such as I/O
*/
if ((NULL == grid[ix][iy].type)||(0 != grid[ix][iy].offset)) {
if ((NULL == grid[ix][iy].type)
||(EMPTY_TYPE == grid[ix][iy].type)
||(0 != grid[ix][iy].offset)) {
/* Update the grid_index_high for each spice_model */
update_spice_models_grid_index_high(ix, iy, arch->spice->num_spice_model, arch->spice->spice_models);
return;

View File

@ -269,7 +269,7 @@ void dump_verilog_grid_side_pin_with_given_index(FILE* fp, t_rr_type pin_type,
}
/* Output the pins on the side*/
height = grid[x][y].offset;
height = get_grid_pin_height(x, y, pin_index);
if (1 == type->pinloc[height][side][pin_index]) {
/* Not sure if we need to plus a height */
/* fprintf(fp, "grid_%d__%d__pin_%d__%d__%d_ ", x, y, height, side, pin_index); */
@ -281,7 +281,7 @@ void dump_verilog_grid_side_pin_with_given_index(FILE* fp, t_rr_type pin_type,
fprintf(fp, ",\n");
}
} else {
vpr_printf(TIO_MESSAGE_ERROR, "(File:%s, [LINE%d])Fail to print a grid pin (x=%d, y=%d, height=%d, side=%d, index=%d)",
vpr_printf(TIO_MESSAGE_ERROR, "(File:%s, [LINE%d])Fail to print a grid pin (x=%d, y=%d, height=%d, side=%d, index=%d)\n",
__FILE__, __LINE__, x, y, height, side, pin_index);
exit(1);
}
@ -331,7 +331,7 @@ void dump_verilog_grid_side_pins(FILE* fp,
}
/* Output the pins on the side*/
height = grid[x][y].offset;
height = get_grid_pin_height(x, y, ipin);
for (ipin = 0; ipin < type->num_pins; ipin++) {
class_id = type->pin_class[ipin];
if ((1 == type->pinloc[height][side][ipin])&&(pin_class_type == type->class_inf[class_id].type)) {
@ -834,7 +834,7 @@ void dump_verilog_switch_box_mux(FILE* fp,
}
/* Count the number of configuration bits of a rr_node*/
int count_verilog_switch_box_interc_conf_bits(int switch_box_x, int switch_box_y, int chan_side,
int count_verilog_switch_box_interc_conf_bits(t_sb cur_sb_info, int chan_side,
t_rr_node* cur_rr_node) {
int num_conf_bits = 0;
int switch_idx = 0;
@ -848,7 +848,7 @@ int count_verilog_switch_box_interc_conf_bits(int switch_box_x, int switch_box_y
}
/* Determine if the interc lies inside a channel wire, that is interc between segments */
if (1 == is_sb_interc_between_segments(switch_box_x, switch_box_y, cur_rr_node, chan_side)) {
if (1 == is_rr_node_exist_opposite_side_in_sb_info(cur_sb_info, cur_rr_node, chan_side)) {
num_drive_rr_nodes = 0;
} else {
num_drive_rr_nodes = cur_rr_node->num_drive_rr_nodes;
@ -869,7 +869,7 @@ int count_verilog_switch_box_interc_conf_bits(int switch_box_x, int switch_box_y
}
/* Count the number of reserved configuration bits of a rr_node*/
int count_verilog_switch_box_interc_reserved_conf_bits(int switch_box_x, int switch_box_y, int chan_side,
int count_verilog_switch_box_interc_reserved_conf_bits(t_sb cur_sb_info, int chan_side,
t_rr_node* cur_rr_node) {
int num_reserved_conf_bits = 0;
int switch_idx = 0;
@ -883,7 +883,7 @@ int count_verilog_switch_box_interc_reserved_conf_bits(int switch_box_x, int swi
}
/* Determine if the interc lies inside a channel wire, that is interc between segments */
if (1 == is_sb_interc_between_segments(switch_box_x, switch_box_y, cur_rr_node, chan_side)) {
if (1 == is_rr_node_exist_opposite_side_in_sb_info(cur_sb_info, cur_rr_node, chan_side)) {
num_drive_rr_nodes = 0;
} else {
num_drive_rr_nodes = cur_rr_node->num_drive_rr_nodes;
@ -932,7 +932,7 @@ void dump_verilog_switch_box_interc(FILE* fp,
*/
/* Determine if the interc lies inside a channel wire, that is interc between segments */
if (1 == is_sb_interc_between_segments(sb_x, sb_y, cur_rr_node, chan_side)) {
if (1 == is_rr_node_exist_opposite_side_in_sb_info(*cur_sb_info, cur_rr_node, chan_side)) {
num_drive_rr_nodes = 0;
drive_rr_nodes = NULL;
} else {
@ -971,7 +971,7 @@ int count_verilog_switch_box_reserved_conf_bits(t_sb* cur_sb_info) {
switch (cur_sb_info->chan_rr_node_direction[side][itrack]) {
case OUT_PORT:
temp_num_reserved_conf_bits =
count_verilog_switch_box_interc_reserved_conf_bits(cur_sb_info->x, cur_sb_info->y, side,
count_verilog_switch_box_interc_reserved_conf_bits(*cur_sb_info, side,
cur_sb_info->chan_rr_node[side][itrack]);
/* Always select the largest number of reserved conf_bits */
if (temp_num_reserved_conf_bits > num_reserved_conf_bits) {
@ -1000,7 +1000,7 @@ int count_verilog_switch_box_conf_bits(t_sb* cur_sb_info) {
for (itrack = 0; itrack < cur_sb_info->chan_width[side]; itrack++) {
switch (cur_sb_info->chan_rr_node_direction[side][itrack]) {
case OUT_PORT:
num_conf_bits += count_verilog_switch_box_interc_conf_bits(cur_sb_info->x, cur_sb_info->y, side,
num_conf_bits += count_verilog_switch_box_interc_conf_bits(*cur_sb_info, side,
cur_sb_info->chan_rr_node[side][itrack]);
break;
case IN_PORT:
@ -1864,7 +1864,7 @@ void dump_verilog_routing_resources(char* subckt_dir,
/* Switch Boxes*/
for (ix = 0; ix < (nx + 1); ix++) {
for (iy = 0; iy < (ny + 1); iy++) {
vpr_printf(TIO_MESSAGE_INFO, "Writing Switch Boxes[%d][%d]...\n", ix, iy);
/* vpr_printf(TIO_MESSAGE_INFO, "Writing Switch Boxes[%d][%d]...\n", ix, iy); */
update_spice_models_routing_index_low(ix, iy, SOURCE, arch.spice->num_spice_model, arch.spice->spice_models);
dump_verilog_routing_switch_box_subckt(fp, &(sb_info[ix][iy]),
LL_num_rr_nodes, LL_rr_node, LL_rr_node_indices);
@ -1876,20 +1876,26 @@ void dump_verilog_routing_resources(char* subckt_dir,
/* X - channels [1...nx][0..ny]*/
for (iy = 0; iy < (ny + 1); iy++) {
for (ix = 1; ix < (nx + 1); ix++) {
vpr_printf(TIO_MESSAGE_INFO, "Writing X-direction Connection Boxes[%d][%d]...\n", ix, iy);
/* vpr_printf(TIO_MESSAGE_INFO, "Writing X-direction Connection Boxes[%d][%d]...\n", ix, iy); */
update_spice_models_routing_index_low(ix, iy, CHANX, arch.spice->num_spice_model, arch.spice->spice_models);
dump_verilog_routing_connection_box_subckt(fp, &(cbx_info[ix][iy]),
LL_num_rr_nodes, LL_rr_node, LL_rr_node_indices);
if ((TRUE == is_cb_exist(CHANX, ix, iy))
&&(0 < count_cb_info_num_ipin_rr_nodes(cbx_info[ix][iy]))) {
dump_verilog_routing_connection_box_subckt(fp, &(cbx_info[ix][iy]),
LL_num_rr_nodes, LL_rr_node, LL_rr_node_indices);
}
update_spice_models_routing_index_high(ix, iy, CHANX, arch.spice->num_spice_model, arch.spice->spice_models);
}
}
/* Y - channels [1...ny][0..nx]*/
for (ix = 0; ix < (nx + 1); ix++) {
for (iy = 1; iy < (ny + 1); iy++) {
vpr_printf(TIO_MESSAGE_INFO, "Writing Y-direction Connection Boxes[%d][%d]...\n", ix, iy);
/* vpr_printf(TIO_MESSAGE_INFO, "Writing Y-direction Connection Boxes[%d][%d]...\n", ix, iy); */
update_spice_models_routing_index_low(ix, iy, CHANY, arch.spice->num_spice_model, arch.spice->spice_models);
dump_verilog_routing_connection_box_subckt(fp, &(cby_info[ix][iy]),
LL_num_rr_nodes, LL_rr_node, LL_rr_node_indices);
if ((TRUE == is_cb_exist(CHANY, ix, iy))
&&(0 < count_cb_info_num_ipin_rr_nodes(cby_info[ix][iy]))) {
dump_verilog_routing_connection_box_subckt(fp, &(cby_info[ix][iy]),
LL_num_rr_nodes, LL_rr_node, LL_rr_node_indices);
}
update_spice_models_routing_index_high(ix, iy, CHANY, arch.spice->num_spice_model, arch.spice->spice_models);
}
}

View File

@ -35,10 +35,10 @@ void dump_verilog_switch_box_mux(FILE* fp,
t_rr_node** drive_rr_nodes,
int switch_index);
int count_verilog_switch_box_interc_conf_bits(int switch_box_x, int switch_box_y, int chan_side,
int count_verilog_switch_box_interc_conf_bits(t_sb cur_sb_info, int chan_side,
t_rr_node* cur_rr_node);
int count_verilog_switch_box_interc_reserved_conf_bits(int switch_box_x, int switch_box_y, int chan_side,
int count_verilog_switch_box_interc_reserved_conf_bits(t_sb cur_sb_info, int chan_side,
t_rr_node* cur_rr_node);
void dump_verilog_switch_box_interc(FILE* fp,

View File

@ -582,6 +582,10 @@ void dump_verilog_defined_grids(FILE* fp) {
/* Normal Grids */
for (ix = 1; ix < (nx + 1); ix++) {
for (iy = 1; iy < (ny + 1); iy++) {
/* Bypass EMPTY grid */
if (EMPTY_TYPE == grid[ix][iy].type) {
continue;
}
assert(IO_TYPE != grid[ix][iy].type);
dump_verilog_defined_one_grid(fp, ix, iy);
}
@ -591,6 +595,10 @@ void dump_verilog_defined_grids(FILE* fp) {
/* LEFT side */
ix = 0;
for (iy = 1; iy < (ny + 1); iy++) {
/* Bypass EMPTY grid */
if (EMPTY_TYPE == grid[ix][iy].type) {
continue;
}
assert(IO_TYPE == grid[ix][iy].type);
dump_verilog_defined_one_grid(fp, ix, iy);
}
@ -598,6 +606,10 @@ void dump_verilog_defined_grids(FILE* fp) {
/* RIGHT side */
ix = nx + 1;
for (iy = 1; iy < (ny + 1); iy++) {
/* Bypass EMPTY grid */
if (EMPTY_TYPE == grid[ix][iy].type) {
continue;
}
assert(IO_TYPE == grid[ix][iy].type);
dump_verilog_defined_one_grid(fp, ix, iy);
}
@ -605,6 +617,10 @@ void dump_verilog_defined_grids(FILE* fp) {
/* BOTTOM side */
iy = 0;
for (ix = 1; ix < (nx + 1); ix++) {
/* Bypass EMPTY grid */
if (EMPTY_TYPE == grid[ix][iy].type) {
continue;
}
assert(IO_TYPE == grid[ix][iy].type);
dump_verilog_defined_one_grid(fp, ix, iy);
}
@ -612,6 +628,10 @@ void dump_verilog_defined_grids(FILE* fp) {
/* TOP side */
iy = ny + 1;
for (ix = 1; ix < (nx + 1); ix++) {
/* Bypass EMPTY grid */
if (EMPTY_TYPE == grid[ix][iy].type) {
continue;
}
assert(IO_TYPE == grid[ix][iy].type);
dump_verilog_defined_one_grid(fp, ix, iy);
}
@ -937,13 +957,19 @@ void dump_verilog_defined_connection_boxes(FILE* fp) {
/* X - channels [1...nx][0..ny]*/
for (iy = 0; iy < (ny + 1); iy++) {
for (ix = 1; ix < (nx + 1); ix++) {
dump_verilog_defined_one_connection_box(fp, cbx_info[ix][iy]);
if ((TRUE == is_cb_exist(CHANX, ix, iy))
&&(0 < count_cb_info_num_ipin_rr_nodes(cbx_info[ix][iy]))) {
dump_verilog_defined_one_connection_box(fp, cbx_info[ix][iy]);
}
}
}
/* Y - channels [1...ny][0..nx]*/
for (ix = 0; ix < (nx + 1); ix++) {
for (iy = 1; iy < (ny + 1); iy++) {
dump_verilog_defined_one_connection_box(fp, cby_info[ix][iy]);
if ((TRUE == is_cb_exist(CHANY, ix, iy))
&&(0 < count_cb_info_num_ipin_rr_nodes(cby_info[ix][iy]))) {
dump_verilog_defined_one_connection_box(fp, cby_info[ix][iy]);
}
}
}

View File

@ -1617,8 +1617,8 @@ count_verilog_connection_box_one_side_conf_bits syn_verilog/verilog_routing.c /^
count_verilog_connection_box_one_side_reserved_conf_bits syn_verilog/verilog_routing.c /^int count_verilog_connection_box_one_side_reserved_conf_bits(int num_ipin_rr_nodes,$/;" f
count_verilog_connection_box_reserved_conf_bits syn_verilog/verilog_routing.c /^int count_verilog_connection_box_reserved_conf_bits(t_cb* cur_cb_info) {$/;" f
count_verilog_switch_box_conf_bits syn_verilog/verilog_routing.c /^int count_verilog_switch_box_conf_bits(t_sb* cur_sb_info) {$/;" f
count_verilog_switch_box_interc_conf_bits syn_verilog/verilog_routing.c /^int count_verilog_switch_box_interc_conf_bits(int switch_box_x, int switch_box_y, int chan_side, $/;" f
count_verilog_switch_box_interc_reserved_conf_bits syn_verilog/verilog_routing.c /^int count_verilog_switch_box_interc_reserved_conf_bits(int switch_box_x, int switch_box_y, int chan_side, $/;" f
count_verilog_switch_box_interc_conf_bits syn_verilog/verilog_routing.c /^int count_verilog_switch_box_interc_conf_bits(t_sb cur_sb_info, int chan_side, $/;" f
count_verilog_switch_box_interc_reserved_conf_bits syn_verilog/verilog_routing.c /^int count_verilog_switch_box_interc_reserved_conf_bits(t_sb cur_sb_info, int chan_side, $/;" f
count_verilog_switch_box_reserved_conf_bits syn_verilog/verilog_routing.c /^int count_verilog_switch_box_reserved_conf_bits(t_sb* cur_sb_info) {$/;" f
cpd base/vpr_types.h /^ float ** cpd;$/;" m struct:s_timing_stats
cpt_subckt_name spice/spice_globals.c /^char* cpt_subckt_name = "cpt";$/;" v
@ -2310,7 +2310,6 @@ fprint_spice_hardlogic_testbench_rec_pb_graph_node_hardlogics spice/spice_hardlo
fprint_spice_hardlogic_testbench_rec_pb_hardlogics spice/spice_hardlogic_testbench.c /^void fprint_spice_hardlogic_testbench_rec_pb_hardlogics(FILE* fp, $/;" f
fprint_spice_hardlogic_testbench_stimulations spice/spice_hardlogic_testbench.c /^void fprint_spice_hardlogic_testbench_stimulations(FILE* fp, int grid_x, int grid_y, $/;" f file:
fprint_spice_head spice/spice_utils.c /^void fprint_spice_head(FILE* fp,$/;" f
fprint_spice_headers spice/spice_heads.c /^void fprint_spice_headers(char* include_dir_path,$/;" f
fprint_spice_idle_block spice/spice_pbtypes.c /^void fprint_spice_idle_block(FILE* fp,$/;" f
fprint_spice_idle_pb_graph_node_rec spice/spice_pbtypes.c /^void fprint_spice_idle_pb_graph_node_rec(FILE* fp,$/;" f
fprint_spice_include_key_subckts spice/spice_utils.c /^void fprint_spice_include_key_subckts(FILE* fp,$/;" f
@ -2605,6 +2604,7 @@ get_grid_pin_height fpga_spice/fpga_spice_utils.c /^int get_grid_pin_height(int
get_grid_side_pin_rr_nodes fpga_spice/fpga_spice_backannotate_utils.c /^t_rr_node** get_grid_side_pin_rr_nodes(int* num_pin_rr_nodes,$/;" f
get_grid_side_pins route/rr_graph_opincb.c /^void get_grid_side_pins(int grid_x, int grid_y, $/;" f file:
get_grid_testbench_one_grid_num_sim_clock_cycles spice/spice_grid_testbench.c /^int get_grid_testbench_one_grid_num_sim_clock_cycles(FILE* fp, $/;" f
get_hardlogic_child_pb fpga_spice/fpga_spice_utils.c /^t_pb* get_hardlogic_child_pb(t_pb* cur_hardlogic_pb,$/;" f
get_hash_entry util/hash.c /^get_hash_entry(struct s_hash **hash_table, char *name) {$/;" f
get_hash_stats util/hash.c /^void get_hash_stats(struct s_hash **hash_table, char *hash_table_name){$/;" f
get_heap_head route/route_common.c /^get_heap_head(void) {$/;" f
@ -2616,6 +2616,7 @@ get_int_list_length mrfpga/buffer_insertion.c /^static int get_int_list_length(
get_ipin_switch_index route/rr_graph_opincb.c /^int get_ipin_switch_index(t_rr_node* ipin) {$/;" f file:
get_keypress_input base/graphics.c /^static bool get_keypress_input, get_mouse_move_input;$/;" v file:
get_length_and_bends_stats base/stats.c /^void get_length_and_bends_stats(void) {$/;" f
get_logical_block_output_init_val fpga_spice/fpga_spice_utils.c /^int get_logical_block_output_init_val(t_logical_block* cur_logical_block) {$/;" f
get_longest_segment_length place/timing_place_lookup.c /^static int get_longest_segment_length($/;" f file:
get_lut_child_pb fpga_spice/fpga_spice_utils.c /^t_pb* get_lut_child_pb(t_pb* cur_lut_pb,$/;" f
get_lut_output_init_val fpga_spice/fpga_spice_utils.c /^int get_lut_output_init_val(t_logical_block* lut_logical_block) {$/;" f
@ -2640,6 +2641,7 @@ get_non_updateable_bb place/place.c /^static void get_non_updateable_bb(int inet
get_num_bends_and_length base/stats.c /^void get_num_bends_and_length(int inet, int *bends_ptr, int *len_ptr,$/;" f
get_num_conn base/check_netlist.c /^static int get_num_conn(int bnum) {$/;" f file:
get_opin_direct_connecions route/rr_graph.c /^static int get_opin_direct_connecions(int x, int y, int opin, INOUTP t_linked_edge ** edge_list_ptr, INP t_ivec *** L_rr_node_indices, $/;" f file:
get_opposite_side fpga_spice/fpga_spice_utils.c /^int get_opposite_side(int side){$/;" f
get_pb_graph_node_pin_from_block_pin util/vpr_utils.c /^t_pb_graph_pin* get_pb_graph_node_pin_from_block_pin(int iblock, int ipin) {$/;" f
get_pb_graph_node_pin_from_clb_net util/vpr_utils.c /^t_pb_graph_pin* get_pb_graph_node_pin_from_clb_net(int inet, int ipin) {$/;" f
get_pb_graph_node_pin_from_model_port_pin util/vpr_utils.c /^t_pb_graph_pin* get_pb_graph_node_pin_from_model_port_pin(t_model_ports *model_port, int model_pin, t_pb_graph_node *pb_graph_node) {$/;" f
@ -2923,6 +2925,7 @@ is_accurate ../../libarchfpga/include/arch_types_mrfpga.h /^ boolean is_accurat
is_any_but timing/slre.c /^static int is_any_but(const unsigned char *p, int len, const char *s,$/;" f file:
is_any_of timing/slre.c /^static int is_any_of(const unsigned char *p, int len, const char *s, int *ofs) {$/;" f file:
is_block_optional ../../libarchfpga/include/cad_types.h /^ boolean *is_block_optional; \/* [0..num_blocks-1] is the block_id in this pattern mandatory or optional to form a molecule *\/$/;" m struct:s_pack_patterns
is_cb_exist fpga_spice/fpga_spice_utils.c /^boolean is_cb_exist(t_rr_type cb_type,$/;" f
is_cbox route/rr_graph2.c /^boolean is_cbox(INP int chan, INP int seg, INP int track,$/;" f
is_chain ../../libarchfpga/include/cad_types.h /^ boolean is_chain; \/* Does this pattern chain across logic blocks *\/$/;" m struct:s_pack_patterns
is_clock ../../libarchfpga/include/logic_types.h /^ boolean is_clock; \/* clock? *\/$/;" m struct:s_model_ports
@ -2959,7 +2962,7 @@ is_opin_in_direct_list route/pb_pin_eq_auto_detect.c /^boolean is_opin_in_direct
is_pin_open pack/cluster_legality.c /^boolean is_pin_open(int i) {$/;" f
is_prog ../../libarchfpga/fpga_spice_include/spice_types.h /^ boolean is_prog;$/;" m struct:s_spice_model_port
is_reset ../../libarchfpga/fpga_spice_include/spice_types.h /^ boolean is_reset;$/;" m struct:s_spice_model_port
is_sb_interc_between_segments fpga_spice/fpga_spice_utils.c /^int is_sb_interc_between_segments(int switch_box_x, $/;" f
is_rr_node_exist_opposite_side_in_sb_info fpga_spice/fpga_spice_backannotate_utils.c /^int is_rr_node_exist_opposite_side_in_sb_info(t_sb cur_sb_info,$/;" f
is_sbox route/rr_graph2.c /^boolean is_sbox(INP int chan, INP int wire_seg, INP int sb_seg, INP int track,$/;" f
is_set ../../libarchfpga/fpga_spice_include/spice_types.h /^ boolean is_set;$/;" m struct:s_spice_model_port
is_show_pass_trans ../../libarchfpga/include/arch_types_mrfpga.h /^ boolean is_show_pass_trans;$/;" m struct:s_arch_mrfpga
@ -4395,6 +4398,7 @@ spice_print_grid_testbench base/vpr_types.h /^ boolean spice_print_grid_testben
spice_print_grid_testbench spice/spice_grid_testbench.c /^void spice_print_grid_testbench(char* formatted_spice_dir,$/;" f
spice_print_hardlogic_testbench base/vpr_types.h /^ boolean spice_print_hardlogic_testbench; $/;" m struct:s_spice_opts
spice_print_hardlogic_testbench spice/spice_hardlogic_testbench.c /^void spice_print_hardlogic_testbench(char* formatted_spice_dir,$/;" f
spice_print_headers spice/spice_heads.c /^void spice_print_headers(char* include_dir_path,$/;" f
spice_print_lut_testbench base/vpr_types.h /^ boolean spice_print_lut_testbench; $/;" m struct:s_spice_opts
spice_print_lut_testbench spice/spice_lut_testbench.c /^void spice_print_lut_testbench(char* formatted_spice_dir,$/;" f
spice_print_mux_testbench spice/spice_mux_testbench.c /^void spice_print_mux_testbench(char* formatted_spice_dir,$/;" f
@ -4981,6 +4985,7 @@ vpr_init_pre_place_and_route base/vpr_api.c /^void vpr_init_pre_place_and_route(
vpr_pack base/vpr_api.c /^void vpr_pack(INP t_vpr_setup vpr_setup, INP t_arch arch) {$/;" f
vpr_place_and_route base/vpr_api.c /^void vpr_place_and_route(INP t_vpr_setup vpr_setup, INP t_arch arch) {$/;" f
vpr_power_estimation base/vpr_api.c /^void vpr_power_estimation(t_vpr_setup vpr_setup, t_arch Arch) {$/;" f
vpr_print_spice_netlists spice/spice_api.c /^void vpr_print_spice_netlists(t_vpr_setup vpr_setup,$/;" f
vpr_print_title base/vpr_api.c /^void vpr_print_title(void) {$/;" f
vpr_print_usage base/vpr_api.c /^void vpr_print_usage(void) {$/;" f
vpr_printf ../../libarchfpga/util.c /^messagelogger vpr_printf = PrintHandlerMessage;$/;" v
@ -4990,7 +4995,6 @@ vpr_resync_post_route_netlist_to_TI_CLAY_v1_architecture base/vpr_api.c /^t_trac
vpr_set_output_file_name base/vpr_api.c /^void vpr_set_output_file_name(enum e_output_files ename, const char *name,$/;" f
vpr_setup_vpr base/vpr_api.c /^void vpr_setup_vpr(INP t_options *Options, INP boolean TimingEnabled,$/;" f
vpr_show_setup base/vpr_api.c /^void vpr_show_setup(INP t_options options, INP t_vpr_setup vpr_setup) {$/;" f
vpr_spice_print_netlists spice/spice_api.c /^void vpr_spice_print_netlists(t_vpr_setup vpr_setup,$/;" f
vpr_to_phy_track route/rr_graph2.c /^static int vpr_to_phy_track(INP int itrack, INP int chan_num, INP int seg_num,$/;" f file:
watch_edges route/rr_graph.c /^void watch_edges(int inode, t_linked_edge * edge_list_head) {$/;" f
which_button base/graphics.c /^static int which_button (Window win) $/;" f file:

View File

@ -3,5 +3,7 @@
# Pack, place, and route a heterogeneous FPGA
# Packing uses the AAPack algorithm
./vpr ../../fpga_flow/arch/fpga_spice/k6_N10_sram_tsmc40nm_TT.xml Circuits/s298_prevpr.blif --full_stats --nodisp --activity_file Circuits/s298_prevpr.act --route_chan_width 30 --fpga_spice --fpga_spice_rename_illegal_port --spice_dir ./spice_test --spice_print_top_testbench --fpga_syn_verilog --fpga_syn_verilog_dir ./verilog_test
./vpr ../../fpga_flow/arch/fpga_spice/k6_N10_sram_tsmc40nm_TT.xml Circuits/s298_prevpr.blif --full_stats --nodisp --activity_file Circuits/s298_prevpr.act --route_chan_width 30 --fpga_spice --fpga_spice_rename_illegal_port --spice_dir ./spice_test --spice_print_top_testbench --spice_print_grid_testbench --spice_print_cb_testbench --spice_print_sb_testbench --spice_print_lut_testbench --spice_print_hardlogic_testbench --spice_print_pb_mux_testbench --spice_print_cb_mux_testbench --spice_print_sb_mux_testbench --fpga_syn_verilog --fpga_syn_verilog_dir ./verilog_test