Merge branch 'tileable_routing' of https://github.com/LNIS-Projects/OpenFPGA into explicit_verilog

This commit is contained in:
Baudouin Chauviere 2019-07-11 22:13:30 -06:00
commit 40d3460bac
7 changed files with 150 additions and 55 deletions

View File

@ -46,7 +46,8 @@ my @supported_flows = ("standard",
"mpack1",
"vtr",
"vtr_standard",
"yosys_vpr");
"yosys_vpr",
"vpr_only");
my %selected_flows;
# Configuration file keywords list
@ -761,6 +762,8 @@ sub run_abc_fpgamap($ $ $)
# Run ABC by FPGA-oriented synthesis
sub run_abc_bb_fpgamap($ $ $) {
my ($bm,$blif_out,$log) = @_;
my ($cmd_log) = ($log."cmd");
# Get ABC path
my ($abc_dir,$abc_name) = &split_prog_path($conf_ptr->{dir_path}->{abc_with_bb_support_path}->{val});
my ($lut_num) = $opt_ptr->{K_val};
@ -777,9 +780,26 @@ sub run_abc_bb_fpgamap($ $ $) {
$dump_verilog = "write_verilog $bm.v";
}
#
# Create a local copy for the commands
#
my ($ABC_CMD_FH) = (FileHandle->new);
if ($ABC_CMD_FH->open("> $cmd_log")) {
print "INFO: auto generating cmds for ABC ($cmd_log) ...\n";
} else {
die "ERROR: fail to auto generating cmds for ABC ($cmd_log) ...\n";
}
# Output the standard format (refer to VTR_flow script)
print $ABC_CMD_FH "read $bm; resyn; resyn2; $fpga_synthesis_method -K $lut_num; $abc_seq_optimize sweep; write_hie $bm $blif_out; $dump_verilog; quit;\n";
close($ABC_CMD_FH);
# Go to ABC directory and run FPGA with commands
print "Entering $abc_dir\n";
chdir $abc_dir;
# Run FPGA ABC
system("./$abc_name -c \"read $bm; resyn; resyn2; $fpga_synthesis_method -K $lut_num; $abc_seq_optimize sweep; write_hie $bm $blif_out; $dump_verilog; quit;\" > $log");
system("./$abc_name -F $cmd_log > $log");
if (!(-e $blif_out)) {
die "ERROR: Fail ABC_with_bb_support for benchmark $bm.\n";
@ -789,6 +809,7 @@ sub run_abc_bb_fpgamap($ $ $) {
die "ERROR: ABC verilog rewrite failed for benchmark $bm!\n";
}
print "Leaving $abc_dir\n";
chdir $cwd;
}
@ -2004,6 +2025,34 @@ sub parse_yosys_vpr_flow_results($ $ $ $)
return;
}
sub run_vpr_only_flow($ $ $ $ $)
{
my ($tag,$benchmark_file,$vpr_arch, $parse_results) = @_;
my ($benchmark, $rpt_dir,$prefix);
my ($vpr_net,$vpr_place,$vpr_route,$vpr_reroute_log,$vpr_log);
$benchmark = $benchmark_file;
$benchmark =~ s/\.blif$//g;
# Run Standard flow
$rpt_dir = "$conf_ptr->{dir_path}->{rpt_dir}->{val}"."/$benchmark/$tag";
&generate_path($rpt_dir);
$prefix = "$rpt_dir/$benchmark\_"."K$opt_ptr->{K_val}\_"."N$opt_ptr->{N_val}\_";
my ($input_blif) = ("$conf_ptr->{dir_path}->{benchmark_dir}->{val}"."/$benchmark".".blif");
my ($act_file,$ace_new_blif,$ace_log) = ("$prefix"."ace.act","$prefix"."ace.blif","$prefix"."ace.log");
$vpr_net = "$prefix"."vpr.net";
$vpr_place = "$prefix"."vpr.place";
$vpr_route = "$prefix"."vpr.route";
$vpr_log = "$prefix"."vpr.log";
$vpr_reroute_log = "$prefix"."vpr_reroute.log";
&run_ace_in_flow($prefix, $input_blif, $act_file, $ace_new_blif, $ace_log);
&run_vpr_in_flow($tag, $benchmark, $benchmark_file, $input_blif, $vpr_arch, $act_file, $vpr_net, $vpr_place, $vpr_route, $vpr_log, $vpr_reroute_log, $parse_results);
return;
}
sub run_standard_flow($ $ $ $ $)
{
@ -2728,6 +2777,8 @@ sub run_benchmark_selected_flow($ $ $)
&run_mig_mccl_flow("mig_mccl",$benchmark,$conf_ptr->{flow_conf}->{vpr_arch}->{val}, $parse_results);
} elsif ($flow_type eq "yosys_vpr") {
&run_yosys_vpr_flow("yosys_vpr",$benchmark,$conf_ptr->{flow_conf}->{vpr_arch}->{val}, "classic", $parse_results);
} elsif ($flow_type eq "vpr_only") {
&run_vpr_only_flow("vpr_only",$benchmark,$conf_ptr->{flow_conf}->{vpr_arch}->{val}, $parse_results);
} else {
die "ERROR: unsupported flow type ($flow_type) is chosen!\n";
}
@ -2756,6 +2807,8 @@ sub parse_benchmark_selected_flow($ $) {
&parse_standard_flow_results("mig_mccl", $benchmark, $conf_ptr->{flow_conf}->{vpr_arch}->{val}, "abc_black_box");
} elsif ($flow_type eq "yosys_vpr") {
&parse_yosys_vpr_flow_results("yosys_vpr",$benchmark,$conf_ptr->{flow_conf}->{vpr_arch}->{val},"abc_black_box");
} elsif ($flow_type eq "vpr_only") {
&parse_standard_flow_results("vpr_only",$benchmark,$conf_ptr->{flow_conf}->{vpr_arch}->{val}, "classic");
} else {
die "ERROR: unsupported flow type ($flow_type) is chosen!\n";
}
@ -3547,6 +3600,11 @@ sub gen_csv_rpt($)
print "INFO: writing yosys_vpr flow results ...\n";
&gen_csv_rpt_yosys_vpr_flow("yosys_vpr",$CSVFH);
}
} elsif ($flow_type eq "vpr_only") {
if (1 == &check_flow_all_benchmarks_done("vpr_only")) {
print "INFO: writing vpr_only flow results ...\n";
&gen_csv_rpt_standard_flow("vpr_only",$CSVFH);
}
} else {
die "ERROR: flow_type: $flow_type is not supported!\n";
}

View File

@ -147,6 +147,7 @@ sub process_blifmodel($ $) {
if ($temp eq $default_clk_name) {
$have_default_clk = 1;
$clk_num++;
print "Found 1 clock: $temp in @tokens\n";
last;
}
}

View File

@ -244,7 +244,7 @@ void load_one_grid_rr_nodes_basic_info(const DeviceCoordinator& grid_coordinator
rr_graph->rr_node[*cur_node_id].xlow = grid_coordinator.get_x();
rr_graph->rr_node[*cur_node_id].xhigh = grid_coordinator.get_x();
rr_graph->rr_node[*cur_node_id].ylow = grid_coordinator.get_y();
rr_graph->rr_node[*cur_node_id].yhigh = grid_coordinator.get_y();
rr_graph->rr_node[*cur_node_id].yhigh = grid_coordinator.get_y() + cur_grid.type->height - 1;
rr_graph->rr_node[*cur_node_id].ptc_num = opin_list[pin];
rr_graph->rr_node[*cur_node_id].capacity = 1;
rr_graph->rr_node[*cur_node_id].occ = 0;
@ -253,6 +253,15 @@ void load_one_grid_rr_nodes_basic_info(const DeviceCoordinator& grid_coordinator
/* Switch info */
rr_graph->rr_node[*cur_node_id].driver_switch = delayless_switch;
/* fill fast look-up table */
/* If height > 1, we will update fast lookup to twice:
* 1. for the x, y + height. This enable fast fast look-up for node collection in rr_gsb
* 2. for the x, y. This enables fast lookup for SOURCE and SINK nodes drive/driven by the node
*/
load_one_node_to_rr_graph_fast_lookup(rr_graph, *cur_node_id,
rr_graph->rr_node[*cur_node_id].type,
rr_graph->rr_node[*cur_node_id].xlow,
rr_graph->rr_node[*cur_node_id].ylow + height,
rr_graph->rr_node[*cur_node_id].ptc_num);
load_one_node_to_rr_graph_fast_lookup(rr_graph, *cur_node_id,
rr_graph->rr_node[*cur_node_id].type,
rr_graph->rr_node[*cur_node_id].xlow,
@ -269,7 +278,7 @@ void load_one_grid_rr_nodes_basic_info(const DeviceCoordinator& grid_coordinator
rr_graph->rr_node[*cur_node_id].xlow = grid_coordinator.get_x();
rr_graph->rr_node[*cur_node_id].xhigh = grid_coordinator.get_x();
rr_graph->rr_node[*cur_node_id].ylow = grid_coordinator.get_y();
rr_graph->rr_node[*cur_node_id].yhigh = grid_coordinator.get_y();
rr_graph->rr_node[*cur_node_id].yhigh = grid_coordinator.get_y() + cur_grid.type->height - 1;
rr_graph->rr_node[*cur_node_id].ptc_num = ipin_list[pin];
rr_graph->rr_node[*cur_node_id].capacity = 1;
rr_graph->rr_node[*cur_node_id].occ = 0;
@ -278,6 +287,15 @@ void load_one_grid_rr_nodes_basic_info(const DeviceCoordinator& grid_coordinator
/* Switch info */
rr_graph->rr_node[*cur_node_id].driver_switch = wire_to_ipin_switch;
/* fill fast look-up table */
/* If height > 1, we will update fast lookup to twice:
* 1. for the x, y + height. This enable fast fast look-up for node collection in rr_gsb
* 2. for the x, y. This enables fast lookup for SOURCE and SINK nodes drive/driven by the node
*/
load_one_node_to_rr_graph_fast_lookup(rr_graph, *cur_node_id,
rr_graph->rr_node[*cur_node_id].type,
rr_graph->rr_node[*cur_node_id].xlow,
rr_graph->rr_node[*cur_node_id].ylow + height,
rr_graph->rr_node[*cur_node_id].ptc_num);
load_one_node_to_rr_graph_fast_lookup(rr_graph, *cur_node_id,
rr_graph->rr_node[*cur_node_id].type,
rr_graph->rr_node[*cur_node_id].xlow,
@ -289,46 +307,44 @@ void load_one_grid_rr_nodes_basic_info(const DeviceCoordinator& grid_coordinator
} /* End of side enumeration */
} /* End of height enumeration */
/* Walk through the height of each grid,
/* No need to Walk through the height of each grid,
* get pins and configure the rr_nodes */
for (int height = 0; height < cur_grid.type->height; ++height) {
/* Set a SOURCE or a SINK rr_node for each class */
for (int iclass = 0; iclass < cur_grid.type->num_class; ++iclass) {
/* Set a SINK rr_node for the OPIN */
if ( DRIVER == cur_grid.type->class_inf[iclass].type) {
rr_graph->rr_node[*cur_node_id].type = SOURCE;
}
if ( RECEIVER == cur_grid.type->class_inf[iclass].type) {
rr_graph->rr_node[*cur_node_id].type = SINK;
}
rr_graph->rr_node[*cur_node_id].xlow = grid_coordinator.get_x();
rr_graph->rr_node[*cur_node_id].xhigh = grid_coordinator.get_x();
rr_graph->rr_node[*cur_node_id].ylow = grid_coordinator.get_y();
rr_graph->rr_node[*cur_node_id].yhigh = grid_coordinator.get_y();
rr_graph->rr_node[*cur_node_id].ptc_num = iclass;
/* FIXME: need to confirm if the capacity should be the number of pins in this class*/
rr_graph->rr_node[*cur_node_id].capacity = cur_grid.type->class_inf[iclass].num_pins;
rr_graph->rr_node[*cur_node_id].occ = 0;
/* cost index is a FIXED value for SOURCE and SINK */
if (SOURCE == rr_graph->rr_node[*cur_node_id].type) {
rr_graph->rr_node[*cur_node_id].cost_index = SOURCE_COST_INDEX;
}
if (SINK == rr_graph->rr_node[*cur_node_id].type) {
rr_graph->rr_node[*cur_node_id].cost_index = SINK_COST_INDEX;
}
/* Switch info */
rr_graph->rr_node[*cur_node_id].driver_switch = delayless_switch;
/* TODO: should we set pb_graph_pin here? */
/* fill fast look-up table */
load_one_node_to_rr_graph_fast_lookup(rr_graph, *cur_node_id,
rr_graph->rr_node[*cur_node_id].type,
rr_graph->rr_node[*cur_node_id].xlow,
rr_graph->rr_node[*cur_node_id].ylow,
rr_graph->rr_node[*cur_node_id].ptc_num);
/* Update node counter */
(*cur_node_id)++;
} /* End of height enumeration */
} /* End of pin_class enumeration */
/* Set a SOURCE or a SINK rr_node for each class */
for (int iclass = 0; iclass < cur_grid.type->num_class; ++iclass) {
/* Set a SINK rr_node for the OPIN */
if ( DRIVER == cur_grid.type->class_inf[iclass].type) {
rr_graph->rr_node[*cur_node_id].type = SOURCE;
}
if ( RECEIVER == cur_grid.type->class_inf[iclass].type) {
rr_graph->rr_node[*cur_node_id].type = SINK;
}
rr_graph->rr_node[*cur_node_id].xlow = grid_coordinator.get_x();
rr_graph->rr_node[*cur_node_id].xhigh = grid_coordinator.get_x();
rr_graph->rr_node[*cur_node_id].ylow = grid_coordinator.get_y();
rr_graph->rr_node[*cur_node_id].yhigh = grid_coordinator.get_y() + cur_grid.type->height - 1;
rr_graph->rr_node[*cur_node_id].ptc_num = iclass;
/* FIXME: need to confirm if the capacity should be the number of pins in this class*/
rr_graph->rr_node[*cur_node_id].capacity = cur_grid.type->class_inf[iclass].num_pins;
rr_graph->rr_node[*cur_node_id].occ = 0;
/* cost index is a FIXED value for SOURCE and SINK */
if (SOURCE == rr_graph->rr_node[*cur_node_id].type) {
rr_graph->rr_node[*cur_node_id].cost_index = SOURCE_COST_INDEX;
}
if (SINK == rr_graph->rr_node[*cur_node_id].type) {
rr_graph->rr_node[*cur_node_id].cost_index = SINK_COST_INDEX;
}
/* Switch info */
rr_graph->rr_node[*cur_node_id].driver_switch = delayless_switch;
/* TODO: should we set pb_graph_pin here? */
/* fill fast look-up table */
load_one_node_to_rr_graph_fast_lookup(rr_graph, *cur_node_id,
rr_graph->rr_node[*cur_node_id].type,
rr_graph->rr_node[*cur_node_id].xlow,
rr_graph->rr_node[*cur_node_id].ylow,
rr_graph->rr_node[*cur_node_id].ptc_num);
/* Update node counter */
(*cur_node_id)++;
} /* End of height enumeration */
return;
}
@ -640,7 +656,7 @@ void load_rr_nodes_basic_info(t_rr_graph* rr_graph,
|| (OPIN == rr_graph->rr_node[inode].type)
|| (IPIN == rr_graph->rr_node[inode].type));
assert (rr_graph->rr_node[inode].xlow == rr_graph->rr_node[inode].xhigh);
assert (rr_graph->rr_node[inode].ylow == rr_graph->rr_node[inode].yhigh);
assert (rr_graph->rr_node[inode].ylow + grids[rr_graph->rr_node[inode].xlow][rr_graph->rr_node[inode].ylow].type->height - 1 == rr_graph->rr_node[inode].yhigh);
}
}
@ -993,6 +1009,13 @@ void build_tileable_unidir_rr_graph(INP const int L_num_types,
***********************************************************************/
alloc_rr_graph_fast_lookup(device_size, &rr_graph);
/* FIXME: DEBUG CODES TO BE REMOVED
vpr_printf(TIO_MESSAGE_INFO, "estimated %lu SOURCE NODE.\n", num_rr_nodes_per_type[SOURCE]);
vpr_printf(TIO_MESSAGE_INFO, "estimated %lu SINK NODE.\n", num_rr_nodes_per_type[SINK]);
vpr_printf(TIO_MESSAGE_INFO, "estimated %lu OPIN NODE.\n", num_rr_nodes_per_type[OPIN]);
vpr_printf(TIO_MESSAGE_INFO, "estimated %lu IPIN NODE.\n", num_rr_nodes_per_type[IPIN]);
*/
load_rr_nodes_basic_info(&rr_graph, device_size, grids, device_chan_width, segment_infs,
wire_to_ipin_switch, delayless_switch);

View File

@ -373,7 +373,9 @@ void dump_verilog_pb_type_one_bus_port(FILE* fp,
fprintf(fp, ".%s(",
pb_type_port->spice_model_port->lib_name);
}
fprintf(fp, "{");
if (1 < pb_type_port->num_pins) {
fprintf(fp, "{");
}
for (int ipin = 0; ipin < pb_type_port->num_pins; ++ipin) {
if (0 < ipin) {
fprintf(fp, ", ");
@ -381,7 +383,9 @@ void dump_verilog_pb_type_one_bus_port(FILE* fp,
fprintf(fp, "%s",
gen_verilog_one_pb_type_pin_name(port_prefix, pb_type_port, ipin));
}
fprintf(fp, "}");
if (1 < pb_type_port->num_pins) {
fprintf(fp, "}");
}
if (TRUE == dump_explicit_port_map) {
fprintf(fp, ")");
}
@ -441,7 +445,7 @@ void dump_verilog_pb_type_bus_ports(FILE* fp,
}
}
dump_verilog_pb_type_one_bus_port(fp, cur_pb_type, formatted_port_prefix, "inout",
pb_type_inout_ports[iport], dump_port_type, dump_explicit_port_map);
pb_type_inout_ports[iport], dump_port_type, TRUE);
/* Update the counter */
num_dumped_port++;
@ -460,7 +464,7 @@ void dump_verilog_pb_type_bus_ports(FILE* fp,
}
}
dump_verilog_pb_type_one_bus_port(fp, cur_pb_type, formatted_port_prefix, "input",
pb_type_input_ports[iport], dump_port_type, dump_explicit_port_map);
pb_type_input_ports[iport], dump_port_type, TRUE);
/* Update the counter */
num_dumped_port++;
}
@ -478,7 +482,7 @@ void dump_verilog_pb_type_bus_ports(FILE* fp,
}
}
dump_verilog_pb_type_one_bus_port(fp, cur_pb_type, formatted_port_prefix, "output",
pb_type_output_ports[iport], dump_port_type, dump_explicit_port_map);
pb_type_output_ports[iport], dump_port_type, TRUE);
/* Update the counter */
num_dumped_port++;
}
@ -497,7 +501,7 @@ void dump_verilog_pb_type_bus_ports(FILE* fp,
}
}
dump_verilog_pb_type_one_bus_port(fp, cur_pb_type, formatted_port_prefix, "input",
pb_type_clk_ports[iport], dump_port_type, dump_explicit_port_map);
pb_type_clk_ports[iport], dump_port_type, TRUE);
/* Update the counter */
num_dumped_port++;
}

View File

@ -134,7 +134,7 @@ void dump_verilog_pb_generic_primitive(t_sram_orgz_info* cur_sram_orgz_info,
get_sram_orgz_info_num_blwl(cur_sram_orgz_info, &cur_bl, &cur_wl);
/* print ports --> input ports */
dump_verilog_pb_type_ports(fp, port_prefix, 0, prim_pb_type, TRUE, FALSE, FALSE, false);
dump_verilog_pb_type_ports(fp, port_prefix, 0, prim_pb_type, TRUE, FALSE, FALSE, true);
/* IOPADs requires a specical port to output */
if (SPICE_MODEL_IOPAD == verilog_model->type) {
fprintf(fp, ",\n");

View File

@ -667,10 +667,12 @@ void verilog_generate_sdc_constrain_one_cb_path(FILE* fp,
}
/* Check */
assert ((INC_DIRECTION == src_rr_node->direction)
||(DEC_DIRECTION == src_rr_node->direction));
if (! ((CHANX == src_rr_node->type) ||(CHANY == src_rr_node->type)))
assert ((CHANX == src_rr_node->type)
||(CHANY == src_rr_node->type));
assert ((INC_DIRECTION == src_rr_node->direction)
||(DEC_DIRECTION == src_rr_node->direction));
assert (IPIN == des_rr_node->type);
fprintf(fp, "set_max_delay");
@ -928,6 +930,13 @@ void verilog_generate_sdc_constrain_one_cb(FILE* fp,
for (size_t inode = 0; inode < rr_gsb.get_num_ipin_nodes(cb_ipin_side); ++inode) {
t_rr_node* cur_ipin_node = rr_gsb.get_ipin_node(cb_ipin_side, inode);
for (int iedge = 0; iedge < cur_ipin_node->num_drive_rr_nodes; iedge++) {
/* Skip the drivers that are not CHANX or CHANY.
* OPINs should be handled by directlist
*/
if ( (CHANX != cur_ipin_node->drive_rr_nodes[iedge]->type)
&& (CHANY != cur_ipin_node->drive_rr_nodes[iedge]->type) ) {
continue;
}
/* Get the switch delay */
int switch_id = cur_ipin_node->drive_switches[iedge];
float switch_delay = get_switch_sdc_tmax (&(switch_inf[switch_id]));

View File

@ -902,8 +902,8 @@ int rec_dump_verilog_spice_model_global_ports(FILE* fp,
/* Add explicit port mapping if required */
if (TRUE == require_explicit_port_map ) {
fprintf(fp, ".%s(",
/* cur_spice_model_port->lib_name); /* Old version*/
cur_spice_model_port->prefix);
cur_spice_model_port->lib_name);
/*cur_spice_model_port->prefix);*/
}
fprintf(fp, "%s[0:%d]",
cur_spice_model_port->prefix,