Clean code and fix minor bugs
This commit is contained in:
parent
b0ef554b35
commit
cb15bb5082
|
@ -1025,6 +1025,16 @@ sub run_odin2($ $ $) {
|
|||
chdir $cwd;
|
||||
}
|
||||
|
||||
sub run_pro_blif($ $) {
|
||||
my ($abc_blif_out_bak, $abc_blif_out) = @_;
|
||||
`perl pro_blif.pl -i $abc_blif_out_bak -o $abc_blif_out`;
|
||||
|
||||
if (!(-e $abc_blif_out)) {
|
||||
die "ERROR: Fail pro_blif.pl for benchmark $abc_blif_out.\n";
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
# Run Acitivity Estimation
|
||||
sub run_ace($ $ $ $) {
|
||||
my ($mpack_vpr_blif,$act_file,$ace_new_blif,$log) = @_;
|
||||
|
@ -1394,8 +1404,8 @@ sub run_ace_in_flow($ $ $ $ $ $ $) {
|
|||
&run_ace($tmp_blif,$act_file,$ace_new_blif ,$ace_log);
|
||||
} else {
|
||||
&run_ace($abc_blif_out,$act_file,$ace_new_blif,$ace_log);
|
||||
$abc_blif_out = $ace_new_blif;
|
||||
}
|
||||
&run_pro_blif($ace_new_blif, $abc_blif_out);
|
||||
}
|
||||
|
||||
if (("on" eq $opt_ptr->{power})&&(!(-e $act_file))) {
|
||||
|
@ -1548,35 +1558,11 @@ sub run_standard_flow($ $ $ $ $)
|
|||
$abc_blif_out = "$prefix"."abc.blif";
|
||||
$abc_blif_out_bak = "$prefix"."abc_bak.blif";
|
||||
$abc_log = "$prefix"."abc.log";
|
||||
|
||||
if ("abc_black_box" eq $flow_enhance) {
|
||||
my ($pre_abc_blif) = ("$prefix"."pre_abc.blif");
|
||||
`perl pro_blif.pl -i $abc_bm -o $pre_abc_blif`;
|
||||
&run_abc_bb_fpgamap($pre_abc_blif,$abc_blif_out_bak,$abc_log);
|
||||
} elsif ("classic" eq $flow_enhance) {
|
||||
&run_abc_fpgamap($abc_bm,$abc_blif_out_bak,$abc_log);
|
||||
}
|
||||
|
||||
`perl pro_blif.pl -i $abc_blif_out_bak -o $abc_blif_out`;
|
||||
|
||||
if (!(-e $abc_blif_out)) {
|
||||
die "ERROR: Fail pro_blif.pl for benchmark $abc_blif_out.\n";
|
||||
}
|
||||
|
||||
my ($act_file,$ace_new_blif,$ace_log) = ("$prefix"."ace.act","$prefix"."ace.blif","$prefix"."ace.log");
|
||||
if ("on" eq $opt_ptr->{power}) {
|
||||
if ("on" eq $opt_ptr->{black_box_ace}) {
|
||||
&black_box_blif($abc_blif_out,$ace_new_blif);
|
||||
&run_ace($ace_new_blif,$act_file,$prefix."ace_new.blif",$ace_log);
|
||||
} else {
|
||||
&run_ace($abc_blif_out,$act_file,$ace_new_blif,$ace_log);
|
||||
$abc_blif_out = $ace_new_blif;
|
||||
}
|
||||
|
||||
if (!(-e $act_file)) {
|
||||
die "ERROR: Fail ACE2 for benchmark $act_file.\n";
|
||||
}
|
||||
}
|
||||
my ($vpr_net,$vpr_place,$vpr_route,$vpr_reroute_log,$vpr_log);
|
||||
|
||||
$vpr_net = "$prefix"."vpr.net";
|
||||
$vpr_place = "$prefix"."vpr.place";
|
||||
|
@ -1584,81 +1570,20 @@ sub run_standard_flow($ $ $ $ $)
|
|||
$vpr_log = "$prefix"."vpr.log";
|
||||
$vpr_reroute_log = "$prefix"."vpr_reroute.log";
|
||||
|
||||
if ("on" eq $opt_ptr->{min_route_chan_width}) {
|
||||
&run_std_vpr($abc_blif_out,$benchmark,$vpr_arch,$vpr_net,$vpr_place,$vpr_route,-1,$vpr_log.".min_chan_width",$act_file);
|
||||
# Get the Minimum channel width
|
||||
my ($min_chan_width) = (&extract_min_chan_width_vpr_stats($tag,$benchmark,$vpr_log.".min_chan_width",$opt_ptr->{K_val}, $opt_ptr->{min_route_chan_width}, $parse_results));
|
||||
$min_chan_width = int($min_chan_width*$opt_ptr->{min_route_chan_width_val});
|
||||
if (0 != $min_chan_width%2) {
|
||||
$min_chan_width += 1;
|
||||
}
|
||||
# Remove previous route results
|
||||
if (-e $vpr_route) {
|
||||
`rm $vpr_route`;
|
||||
}
|
||||
# Keep increase min_chan_width until route success
|
||||
# Extract data from VPR stats
|
||||
#&run_std_vpr($abc_blif_out,$benchmark,$vpr_arch,$vpr_net,$vpr_place,$vpr_route,$min_chan_width,$vpr_log,$act_file);
|
||||
while (1) {
|
||||
&run_vpr_route($abc_blif_out,$benchmark,$vpr_arch,$vpr_net,$vpr_place,$vpr_route,$min_chan_width,$vpr_reroute_log,$act_file);
|
||||
# TODO: Only run the routing stage
|
||||
if (-e $vpr_route) {
|
||||
print "INFO: try route_chan_width($min_chan_width) success!\n";
|
||||
last; #Jump out
|
||||
} else {
|
||||
print "INFO: try route_chan_width($min_chan_width) failed! Retry with +2...\n";
|
||||
$min_chan_width += 2;
|
||||
}
|
||||
}
|
||||
if (1 == $parse_results) {
|
||||
&extract_min_chan_width_vpr_stats($tag,$benchmark,$vpr_reroute_log,$opt_ptr->{K_val}, "off", $parse_results);
|
||||
&extract_vpr_stats($tag,$benchmark,$vpr_log.".min_chan_width",$opt_ptr->{K_val});
|
||||
&extract_vpr_stats($tag,$benchmark,$vpr_reroute_log,$opt_ptr->{K_val});
|
||||
}
|
||||
} elsif ("on" eq $opt_ptr->{fix_route_chan_width}) {
|
||||
my ($fix_chan_width) = ($benchmarks_ptr->{$benchmark_file}->{fix_route_chan_width});
|
||||
# Remove previous route results
|
||||
if (-e $vpr_route) {
|
||||
`rm $vpr_route`;
|
||||
}
|
||||
# Keep increase min_chan_width until route success
|
||||
&run_std_vpr($abc_blif_out,$benchmark,$vpr_arch,$vpr_net,$vpr_place,$vpr_route,$fix_chan_width,$vpr_log,$act_file);
|
||||
while (1) {
|
||||
# TODO: Only run the routing stage
|
||||
if (-e $vpr_route) {
|
||||
print "INFO: try route_chan_width($fix_chan_width) success!\n";
|
||||
last; #Jump out
|
||||
} else {
|
||||
print "INFO: try route_chan_width($fix_chan_width) failed! Retry with +2...\n";
|
||||
$fix_chan_width += 2;
|
||||
&run_vpr_route($abc_blif_out,$benchmark,$vpr_arch,$vpr_net,$vpr_place,$vpr_route,$fix_chan_width,$vpr_reroute_log,$act_file);
|
||||
}
|
||||
}
|
||||
# Extract data from VPR stats
|
||||
if (1 == $parse_results) {
|
||||
&extract_min_chan_width_vpr_stats($tag,$benchmark,$vpr_log,$opt_ptr->{K_val}, "off", $parse_results);
|
||||
&extract_vpr_stats($tag,$benchmark,$vpr_log,$opt_ptr->{K_val});
|
||||
if (-e $vpr_reroute_log) {
|
||||
&extract_vpr_stats($tag,$benchmark,$vpr_reroute_log,$opt_ptr->{K_val});
|
||||
}
|
||||
}
|
||||
} else {
|
||||
&run_std_vpr($abc_blif_out,$benchmark,$vpr_arch,$vpr_net,$vpr_place,$vpr_route,-1,$vpr_log,$act_file);
|
||||
if (!(-e $vpr_route)) {
|
||||
die "ERROR: Route Fail for $abc_blif_out!\n";
|
||||
}
|
||||
# Get the Minimum channel width
|
||||
my ($min_chan_width) = (&extract_min_chan_width_vpr_stats($tag,$benchmark,$vpr_log,$opt_ptr->{K_val},"on",$parse_results));
|
||||
if (1 == $parse_results) {
|
||||
&extract_vpr_stats($tag,$benchmark,$vpr_log,$opt_ptr->{K_val});
|
||||
}
|
||||
|
||||
if ("abc_black_box" eq $flow_enhance) {
|
||||
my ($pre_abc_blif) = ("$prefix"."pre_abc.blif");
|
||||
&run_pro_blif($abc_bm, $pre_abc_blif);
|
||||
&run_abc_bb_fpgamap($pre_abc_blif,$abc_blif_out_bak,$abc_log);
|
||||
} elsif ("classic" eq $flow_enhance) {
|
||||
&run_abc_fpgamap($abc_bm,$abc_blif_out_bak,$abc_log);
|
||||
}
|
||||
|
||||
# Extract data from VPR Power stats
|
||||
if (("on" eq $opt_ptr->{power})
|
||||
&&(1 == $parse_results)) {
|
||||
&extract_vpr_power_esti($tag,$abc_blif_out,$benchmark,$opt_ptr->{K_val});
|
||||
}
|
||||
&run_pro_blif($abc_blif_out_bak, $abc_blif_out);
|
||||
|
||||
&run_ace_in_flow($prefix, $abc_blif_out, $act_file, $ace_new_blif, $ace_log);
|
||||
|
||||
&run_vpr_in_flow($tag, $benchmark, $benchmark_file, $abc_blif_out, $vpr_arch, $act_file, $vpr_net, $vpr_place, $vpr_route, $vpr_log, $vpr_reroute_log, $parse_results);
|
||||
|
||||
return;
|
||||
}
|
||||
|
@ -1687,12 +1612,6 @@ sub parse_standard_flow_results($ $ $ $)
|
|||
}
|
||||
|
||||
my ($act_file,$ace_new_blif,$ace_log) = ("$prefix"."ace.act","$prefix"."ace.blif","$prefix"."ace.log");
|
||||
if ("on" eq $opt_ptr->{power}) {
|
||||
if ("on" eq $opt_ptr->{black_box_ace}) {
|
||||
} else {
|
||||
$abc_blif_out = $ace_new_blif;
|
||||
}
|
||||
}
|
||||
|
||||
$vpr_net = "$prefix"."vpr.net";
|
||||
$vpr_place = "$prefix"."vpr.place";
|
||||
|
@ -2120,16 +2039,11 @@ sub run_vtr_flow($ $ $ $) {
|
|||
# RUN ABC
|
||||
&run_abc_bb_fpgamap($abc_bm,$abc_blif_out_bak,$abc_log);
|
||||
|
||||
`perl pro_blif.pl -i $abc_blif_out_bak -o $abc_blif_out`;
|
||||
if (!(-e $abc_blif_out_bak)) {
|
||||
die "ERROR: Fail pro_blif for benchmark $benchmark.\n";
|
||||
}
|
||||
&run_pro_blif($abc_blif_out_bak, $abc_blif_out);
|
||||
|
||||
# Run ABC
|
||||
my ($act_file,$ace_new_blif,$ace_log) = ("$prefix"."ace.act","$prefix"."ace.blif","$prefix"."ace.log");
|
||||
if ("on" eq $opt_ptr->{power}) {
|
||||
&run_ace($abc_blif_out,$act_file,$ace_new_blif,$ace_log);
|
||||
$abc_blif_out = $ace_new_blif;
|
||||
}
|
||||
&run_ace_in_flow($prefix, $abc_blif_out,$act_file,$ace_new_blif,$ace_log);
|
||||
|
||||
$vpr_net = "$prefix"."vpr.net";
|
||||
$vpr_place = "$prefix"."vpr.place";
|
||||
|
@ -2137,76 +2051,9 @@ sub run_vtr_flow($ $ $ $) {
|
|||
$vpr_log = "$prefix"."vpr.log";
|
||||
$vpr_reroute_log = "$prefix"."vpr_reroute.log";
|
||||
|
||||
if ("on" eq $opt_ptr->{min_route_chan_width}) {
|
||||
&run_std_vpr($abc_blif_out,$benchmark,$vpr_arch,$vpr_net,$vpr_place,$vpr_route,-1,$vpr_log.".min_chan_width",$act_file);
|
||||
# Get the Minimum channel width
|
||||
my ($min_chan_width) = (&extract_min_chan_width_vpr_stats($tag,$benchmark,$vpr_log.".min_chan_width",$opt_ptr->{K_val}, $opt_ptr->{min_route_chan_width}, $parse_results));
|
||||
$min_chan_width = int($min_chan_width*$opt_ptr->{min_route_chan_width_val});
|
||||
if (0 != $min_chan_width%2) {
|
||||
$min_chan_width += 1;
|
||||
}
|
||||
# Remove previous route results
|
||||
`rm $vpr_route`;
|
||||
# Keep increase min_chan_width until route success
|
||||
# Extract data from VPR stats
|
||||
while (1) {
|
||||
&run_vpr_route($abc_blif_out,$benchmark,$vpr_arch,$vpr_net,$vpr_place,$vpr_route,$min_chan_width,$vpr_reroute_log,$act_file);
|
||||
if (-e $vpr_route) {
|
||||
print "INFO: try route_chan_width($min_chan_width) Success!\n";
|
||||
last; #Jump out
|
||||
} else {
|
||||
print "INFO: try route_chan_width($min_chan_width) failed! Retry with +2...\n";
|
||||
$min_chan_width += 2;
|
||||
}
|
||||
}
|
||||
# Extract data from VPR stats
|
||||
if (1 == $parse_results) {
|
||||
&extract_min_chan_width_vpr_stats($tag,$benchmark,$vpr_reroute_log,$opt_ptr->{K_val}, "off", $parse_results);
|
||||
&extract_vpr_stats($tag,$benchmark,$vpr_log."min_chan_width",$opt_ptr->{K_val});
|
||||
&extract_vpr_stats($tag,$benchmark,$vpr_reroute_log,$opt_ptr->{K_val});
|
||||
}
|
||||
} elsif ("on" eq $opt_ptr->{fix_route_chan_width}) {
|
||||
my ($fix_chan_width) = ($benchmarks_ptr->{$benchmark_file}->{fix_route_chan_width});
|
||||
# Remove previous route results
|
||||
`rm $vpr_route`;
|
||||
# Keep increase min_chan_width until route success
|
||||
&run_std_vpr($abc_blif_out,$benchmark,$vpr_arch,$vpr_net,$vpr_place,$vpr_route,$fix_chan_width,$vpr_log,$act_file);
|
||||
# Extract data from VPR stats
|
||||
while (1) {
|
||||
if (-e $vpr_route) {
|
||||
print "INFO: try route_chan_width($fix_chan_width) Success!\n";
|
||||
last; #Jump out
|
||||
} else {
|
||||
print "INFO: try route_chan_width($fix_chan_width) failed! Retry with +2...\n";
|
||||
$fix_chan_width += 2;
|
||||
&run_vpr_route($abc_blif_out,$benchmark,$vpr_arch,$vpr_net,$vpr_place,$vpr_route,$fix_chan_width,$vpr_reroute_log,$act_file);
|
||||
}
|
||||
}
|
||||
if (1 == $parse_results) {
|
||||
&extract_min_chan_width_vpr_stats($tag,$benchmark,$vpr_log,$opt_ptr->{K_val}, "off", $parse_results);
|
||||
&extract_vpr_stats($tag,$benchmark,$vpr_log,$opt_ptr->{K_val});
|
||||
if (-e $vpr_reroute_log) {
|
||||
&extract_min_chan_width_vpr_stats($tag,$benchmark,$vpr_reroute_log,$opt_ptr->{K_val}, "off", $parse_results);
|
||||
&extract_vpr_stats($tag,$benchmark,$vpr_reroute_log,$opt_ptr->{K_val});
|
||||
}
|
||||
}
|
||||
} else {
|
||||
&run_std_vpr($abc_blif_out,$benchmark,$vpr_arch,$vpr_net,$vpr_place,$vpr_route,-1,$vpr_log,$act_file);
|
||||
if (!(-e $vpr_route)) {
|
||||
die "ERROR: Route Fail for $abc_blif_out!\n";
|
||||
}
|
||||
# Get the Minimum channel width
|
||||
my ($min_chan_width) = (&extract_min_chan_width_vpr_stats($tag,$benchmark,$vpr_log,$opt_ptr->{K_val},$parse_results));
|
||||
if (1 == $parse_results) {
|
||||
&extract_vpr_stats($tag,$benchmark,$vpr_log,$opt_ptr->{K_val});
|
||||
}
|
||||
}
|
||||
# Run VPR
|
||||
&run_vpr_in_flow($tag, $benchmark, $benchmark_file, $abc_blif_out, $vpr_arch, $act_file, $vpr_net, $vpr_place, $vpr_route, $vpr_log, $vpr_reroute_log, $parse_results);
|
||||
|
||||
# Extract data from VPR Power stats
|
||||
if (("on" eq $opt_ptr->{power})
|
||||
&&(1 == $parse_results)) {
|
||||
&extract_vpr_power_esti($tag,$abc_blif_out,$benchmark,$opt_ptr->{K_val});
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -2237,12 +2084,6 @@ sub parse_vtr_flow_results($ $ $) {
|
|||
rename $abc_blif_out,"$abc_blif_out".".bak";
|
||||
|
||||
my ($act_file,$ace_new_blif,$ace_log) = ("$prefix"."ace.act","$prefix"."ace.blif","$prefix"."ace.log");
|
||||
if ("on" eq $opt_ptr->{power}) {
|
||||
if ("on" eq $opt_ptr->{black_box_ace}) {
|
||||
} else {
|
||||
$abc_blif_out = $ace_new_blif;
|
||||
}
|
||||
}
|
||||
|
||||
$vpr_net = "$prefix"."vpr.net";
|
||||
$vpr_place = "$prefix"."vpr.place";
|
||||
|
@ -2344,16 +2185,11 @@ sub run_vtr_mccl_flow($ $ $ $) {
|
|||
# RUN ABC
|
||||
&run_abc_mccl_fpgamap($abc_bm,$abc_blif_out_bak,$abc_log);
|
||||
|
||||
`perl pro_blif.pl -i $abc_blif_out_bak -o $abc_blif_out`;
|
||||
if (!(-e $abc_blif_out_bak)) {
|
||||
die "ERROR: Fail pro_blif for benchmark $benchmark.\n";
|
||||
}
|
||||
&run_pro_blif($abc_blif_out_bak, $abc_blif_out);
|
||||
|
||||
# Run ACE
|
||||
my ($act_file,$ace_new_blif,$ace_log) = ("$prefix"."ace.act","$prefix"."ace.blif","$prefix"."ace.log");
|
||||
if ("on" eq $opt_ptr->{power}) {
|
||||
&run_ace($abc_blif_out,$act_file,$ace_new_blif,$ace_log);
|
||||
$abc_blif_out = $ace_new_blif;
|
||||
}
|
||||
&run_ace_in_flow($prefix,i $abc_blif_out,$act_file,$ace_new_blif,$ace_log);
|
||||
|
||||
$vpr_net = "$prefix"."vpr.net";
|
||||
$vpr_place = "$prefix"."vpr.place";
|
||||
|
@ -2361,76 +2197,9 @@ sub run_vtr_mccl_flow($ $ $ $) {
|
|||
$vpr_log = "$prefix"."vpr.log";
|
||||
$vpr_reroute_log = "$prefix"."vpr_reroute.log";
|
||||
|
||||
if ("on" eq $opt_ptr->{min_route_chan_width}) {
|
||||
&run_std_vpr($abc_blif_out,$benchmark,$vpr_arch,$vpr_net,$vpr_place,$vpr_route,-1,$vpr_log.".min_chan_width",$act_file);
|
||||
# Get the Minimum channel width
|
||||
my ($min_chan_width) = (&extract_min_chan_width_vpr_stats($tag,$benchmark,$vpr_log.".min_chan_width",$opt_ptr->{K_val}, $opt_ptr->{min_route_chan_width}, $parse_results));
|
||||
$min_chan_width = int($min_chan_width*$opt_ptr->{min_route_chan_width_val});
|
||||
if (0 != $min_chan_width%2) {
|
||||
$min_chan_width += 1;
|
||||
}
|
||||
# Remove previous route results
|
||||
`rm $vpr_route`;
|
||||
# Keep increase min_chan_width until route success
|
||||
# Extract data from VPR stats
|
||||
while (1) {
|
||||
&run_vpr_route($abc_blif_out,$benchmark,$vpr_arch,$vpr_net,$vpr_place,$vpr_route,$min_chan_width,$vpr_reroute_log,$act_file);
|
||||
if (-e $vpr_route) {
|
||||
print "INFO: try route_chan_width($min_chan_width) Success!\n";
|
||||
last; #Jump out
|
||||
} else {
|
||||
print "INFO: try route_chan_width($min_chan_width) failed! Retry with +2...\n";
|
||||
$min_chan_width += 2;
|
||||
}
|
||||
}
|
||||
# Extract data from VPR stats
|
||||
if (1 == $parse_results) {
|
||||
&extract_min_chan_width_vpr_stats($tag,$benchmark,$vpr_reroute_log,$opt_ptr->{K_val}, "off", $parse_results);
|
||||
&extract_vpr_stats($tag,$benchmark,$vpr_log."min_chan_width",$opt_ptr->{K_val});
|
||||
&extract_vpr_stats($tag,$benchmark,$vpr_reroute_log,$opt_ptr->{K_val});
|
||||
}
|
||||
} elsif ("on" eq $opt_ptr->{fix_route_chan_width}) {
|
||||
my ($fix_chan_width) = ($benchmarks_ptr->{$benchmark_file}->{fix_route_chan_width});
|
||||
# Remove previous route results
|
||||
`rm $vpr_route`;
|
||||
# Keep increase min_chan_width until route success
|
||||
&run_std_vpr($abc_blif_out,$benchmark,$vpr_arch,$vpr_net,$vpr_place,$vpr_route,$fix_chan_width,$vpr_log,$act_file);
|
||||
# Extract data from VPR stats
|
||||
while (1) {
|
||||
if (-e $vpr_route) {
|
||||
print "INFO: try route_chan_width($fix_chan_width) Success!\n";
|
||||
last; #Jump out
|
||||
} else {
|
||||
print "INFO: try route_chan_width($fix_chan_width) failed! Retry with +2...\n";
|
||||
$fix_chan_width += 2;
|
||||
&run_vpr_route($abc_blif_out,$benchmark,$vpr_arch,$vpr_net,$vpr_place,$vpr_route,$fix_chan_width,$vpr_reroute_log,$act_file);
|
||||
}
|
||||
}
|
||||
if (1 == $parse_results) {
|
||||
&extract_min_chan_width_vpr_stats($tag,$benchmark,$vpr_log,$opt_ptr->{K_val}, "off", $parse_results);
|
||||
&extract_vpr_stats($tag,$benchmark,$vpr_log,$opt_ptr->{K_val});
|
||||
if (-e $vpr_reroute_log) {
|
||||
&extract_min_chan_width_vpr_stats($tag,$benchmark,$vpr_reroute_log,$opt_ptr->{K_val}, "off", $parse_results);
|
||||
&extract_vpr_stats($tag,$benchmark,$vpr_reroute_log,$opt_ptr->{K_val});
|
||||
}
|
||||
}
|
||||
} else {
|
||||
&run_std_vpr($abc_blif_out,$benchmark,$vpr_arch,$vpr_net,$vpr_place,$vpr_route,-1,$vpr_log,$act_file);
|
||||
if (!(-e $vpr_route)) {
|
||||
die "ERROR: Route Fail for $abc_blif_out!\n";
|
||||
}
|
||||
# Get the Minimum channel width
|
||||
my ($min_chan_width) = (&extract_min_chan_width_vpr_stats($tag,$benchmark,$vpr_log,$opt_ptr->{K_val},$parse_results));
|
||||
if (1 == $parse_results) {
|
||||
&extract_vpr_stats($tag,$benchmark,$vpr_log,$opt_ptr->{K_val});
|
||||
}
|
||||
}
|
||||
|
||||
# Extract data from VPR Power stats
|
||||
if (("on" eq $opt_ptr->{power})
|
||||
&&(1 == $parse_results)) {
|
||||
&extract_vpr_power_esti($tag,$abc_blif_out,$benchmark,$opt_ptr->{K_val});
|
||||
}
|
||||
# Run VPR
|
||||
&run_vpr_in_flow($tag, $benchmark, $benchmark_file, $abc_blif_out, $vpr_arch, $act_file, $vpr_net, $vpr_place, $vpr_route, $vpr_log, $vpr_reroute_log, $parse_results);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -2456,26 +2225,11 @@ sub run_mccl_flow($ $ $ $ $)
|
|||
# RUN ABC
|
||||
&run_abc_mccl_fpgamap($abc_bm,$abc_blif_out_bak,$abc_log);
|
||||
|
||||
`perl pro_blif.pl -i $abc_blif_out_bak -o $abc_blif_out`;
|
||||
|
||||
if (!(-e $abc_blif_out)) {
|
||||
die "ERROR: Fail pro_blif.pl for benchmark $abc_blif_out.\n";
|
||||
}
|
||||
&run_pro_blif($abc_blif_out_bak, $abc_blif_out);
|
||||
|
||||
# Run ACE
|
||||
my ($act_file,$ace_new_blif,$ace_log) = ("$prefix"."ace.act","$prefix"."ace.blif","$prefix"."ace.log");
|
||||
if ("on" eq $opt_ptr->{power}) {
|
||||
if ("on" eq $opt_ptr->{black_box_ace}) {
|
||||
&black_box_blif($abc_blif_out,$ace_new_blif);
|
||||
&run_ace($ace_new_blif,$act_file,$prefix."ace_new.blif",$ace_log);
|
||||
} else {
|
||||
&run_ace($abc_blif_out,$act_file,$ace_new_blif,$ace_log);
|
||||
$abc_blif_out = $ace_new_blif;
|
||||
}
|
||||
}
|
||||
|
||||
if (!(-e $act_file)) {
|
||||
die "ERROR: Fail ACE2 for benchmark $act_file.\n";
|
||||
}
|
||||
&run_ace_in_flow($prefix,i $abc_blif_out,$act_file,$ace_new_blif,$ace_log);
|
||||
|
||||
$vpr_net = "$prefix"."vpr.net";
|
||||
$vpr_place = "$prefix"."vpr.place";
|
||||
|
@ -2483,81 +2237,8 @@ sub run_mccl_flow($ $ $ $ $)
|
|||
$vpr_log = "$prefix"."vpr.log";
|
||||
$vpr_reroute_log = "$prefix"."vpr_reroute.log";
|
||||
|
||||
if ("on" eq $opt_ptr->{min_route_chan_width}) {
|
||||
&run_std_vpr($abc_blif_out,$benchmark,$vpr_arch,$vpr_net,$vpr_place,$vpr_route,-1,$vpr_log.".min_chan_width",$act_file);
|
||||
# Get the Minimum channel width
|
||||
my ($min_chan_width) = (&extract_min_chan_width_vpr_stats($tag,$benchmark,$vpr_log.".min_chan_width",$opt_ptr->{K_val}, $opt_ptr->{min_route_chan_width}, $parse_results));
|
||||
$min_chan_width = int($min_chan_width*$opt_ptr->{min_route_chan_width_val});
|
||||
if (0 != $min_chan_width%2) {
|
||||
$min_chan_width += 1;
|
||||
}
|
||||
# Remove previous route results
|
||||
if (-e $vpr_route) {
|
||||
`rm $vpr_route`;
|
||||
}
|
||||
# Keep increase min_chan_width until route success
|
||||
# Extract data from VPR stats
|
||||
#&run_std_vpr($abc_blif_out,$benchmark,$vpr_arch,$vpr_net,$vpr_place,$vpr_route,$min_chan_width,$vpr_log,$act_file);
|
||||
while (1) {
|
||||
&run_vpr_route($abc_blif_out,$benchmark,$vpr_arch,$vpr_net,$vpr_place,$vpr_route,$min_chan_width,$vpr_reroute_log,$act_file);
|
||||
# TODO: Only run the routing stage
|
||||
if (-e $vpr_route) {
|
||||
print "INFO: try route_chan_width($min_chan_width) success!\n";
|
||||
last; #Jump out
|
||||
} else {
|
||||
print "INFO: try route_chan_width($min_chan_width) failed! Retry with +2...\n";
|
||||
$min_chan_width += 2;
|
||||
}
|
||||
}
|
||||
if (1 == $parse_results) {
|
||||
&extract_min_chan_width_vpr_stats($tag,$benchmark,$vpr_reroute_log,$opt_ptr->{K_val}, "off", $parse_results);
|
||||
&extract_vpr_stats($tag,$benchmark,$vpr_log.".min_chan_width",$opt_ptr->{K_val});
|
||||
&extract_vpr_stats($tag,$benchmark,$vpr_reroute_log,$opt_ptr->{K_val});
|
||||
}
|
||||
} elsif ("on" eq $opt_ptr->{fix_route_chan_width}) {
|
||||
my ($fix_chan_width) = ($benchmarks_ptr->{$benchmark_file}->{fix_route_chan_width});
|
||||
# Remove previous route results
|
||||
if (-e $vpr_route) {
|
||||
`rm $vpr_route`;
|
||||
}
|
||||
# Keep increase min_chan_width until route success
|
||||
&run_std_vpr($abc_blif_out,$benchmark,$vpr_arch,$vpr_net,$vpr_place,$vpr_route,$fix_chan_width,$vpr_log,$act_file);
|
||||
while (1) {
|
||||
# TODO: Only run the routing stage
|
||||
if (-e $vpr_route) {
|
||||
print "INFO: try route_chan_width($fix_chan_width) success!\n";
|
||||
last; #Jump out
|
||||
} else {
|
||||
print "INFO: try route_chan_width($fix_chan_width) failed! Retry with +2...\n";
|
||||
$fix_chan_width += 2;
|
||||
&run_vpr_route($abc_blif_out,$benchmark,$vpr_arch,$vpr_net,$vpr_place,$vpr_route,$fix_chan_width,$vpr_reroute_log,$act_file);
|
||||
}
|
||||
}
|
||||
# Extract data from VPR stats
|
||||
if (1 == $parse_results) {
|
||||
&extract_min_chan_width_vpr_stats($tag,$benchmark,$vpr_log,$opt_ptr->{K_val}, "off", $parse_results);
|
||||
&extract_vpr_stats($tag,$benchmark,$vpr_log,$opt_ptr->{K_val});
|
||||
if (-e $vpr_reroute_log) {
|
||||
&extract_vpr_stats($tag,$benchmark,$vpr_reroute_log,$opt_ptr->{K_val});
|
||||
}
|
||||
}
|
||||
} else {
|
||||
&run_std_vpr($abc_blif_out,$benchmark,$vpr_arch,$vpr_net,$vpr_place,$vpr_route,-1,$vpr_log,$act_file);
|
||||
if (!(-e $vpr_route)) {
|
||||
die "ERROR: Route Fail for $abc_blif_out!\n";
|
||||
}
|
||||
# Get the Minimum channel width
|
||||
my ($min_chan_width) = (&extract_min_chan_width_vpr_stats($tag,$benchmark,$vpr_log,$opt_ptr->{K_val},"on",$parse_results));
|
||||
if (1 == $parse_results) {
|
||||
&extract_vpr_stats($tag,$benchmark,$vpr_log,$opt_ptr->{K_val});
|
||||
}
|
||||
}
|
||||
|
||||
# Extract data from VPR Power stats
|
||||
if (("on" eq $opt_ptr->{power})
|
||||
&&(1 == $parse_results)) {
|
||||
&extract_vpr_power_esti($tag,$abc_blif_out,$benchmark,$opt_ptr->{K_val});
|
||||
}
|
||||
# Run VPR
|
||||
&run_vpr_in_flow($tag, $benchmark, $benchmark_file, $abc_blif_out, $vpr_arch, $act_file, $vpr_net, $vpr_place, $vpr_route, $vpr_log, $vpr_reroute_log, $parse_results);
|
||||
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -219,6 +219,7 @@ char* chomp_file_name_postfix(char* file_name) {
|
|||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/* Print SRAM bits, typically in a comment line */
|
||||
void fprint_commented_sram_bits(FILE* fp,
|
||||
int num_sram_bits, int* sram_bits) {
|
||||
|
@ -603,6 +604,25 @@ char* my_itoa(int input) {
|
|||
return ret;
|
||||
}
|
||||
|
||||
/* Generate a filename (string) for a grid subckt SPICE netlist,
|
||||
* with given x and y coordinates
|
||||
*/
|
||||
char* fpga_spice_create_one_subckt_filename(char* file_name_prefix,
|
||||
int subckt_x, int subckt_y,
|
||||
char* file_name_postfix) {
|
||||
char* fname = NULL;
|
||||
|
||||
fname = (char*) my_malloc(sizeof(char) * (strlen(file_name_prefix)
|
||||
+ strlen(my_itoa(subckt_x)) + strlen(my_itoa(subckt_y))
|
||||
+ strlen(file_name_postfix) + 1));
|
||||
|
||||
sprintf(fname, "%s%d_%d%s",
|
||||
file_name_prefix, subckt_x, subckt_y, file_name_postfix);
|
||||
|
||||
return fname;
|
||||
}
|
||||
|
||||
|
||||
/* With given spice_model_port, find the pb_type port with same name and type*/
|
||||
t_port* find_pb_type_port_match_spice_model_port(t_pb_type* pb_type,
|
||||
t_spice_model_port* spice_model_port) {
|
||||
|
@ -1964,15 +1984,15 @@ int recommend_num_sim_clock_cycle(float sim_window_size) {
|
|||
/* It may be more reasonable to use median
|
||||
* But, if median density is 0, we use average density
|
||||
*/
|
||||
if ((0 == median_density) && (0 == avg_density)) {
|
||||
if ((0. == median_density) && (0. == avg_density)) {
|
||||
recmd_num_sim_clock_cycle = 1;
|
||||
vpr_printf(TIO_MESSAGE_WARNING,
|
||||
"All the signal density is zero! No. of clock cycles in simulations are set to be %d!",
|
||||
recmd_num_sim_clock_cycle);
|
||||
} else if (0 == avg_density) {
|
||||
recmd_num_sim_clock_cycle = (int)(1/median_density);
|
||||
} else if (0 == median_density) {
|
||||
recmd_num_sim_clock_cycle = (int)(1/avg_density);
|
||||
} else if (0. == avg_density) {
|
||||
recmd_num_sim_clock_cycle = (int)round(1/median_density);
|
||||
} else if (0. == median_density) {
|
||||
recmd_num_sim_clock_cycle = (int)round(1/avg_density);
|
||||
} else {
|
||||
/* add a sim window size to balance the weight of average density and median density
|
||||
* In practice, we find that there could be huge difference between avereage and median values
|
||||
|
@ -5730,6 +5750,14 @@ char** assign_lut_truth_table(t_logical_block* mapped_logical_block,
|
|||
return truth_table;
|
||||
}
|
||||
|
||||
/* Get initial value of a Latch/FF output*/
|
||||
int get_ff_output_init_val(t_logical_block* ff_logical_block) {
|
||||
assert((0 == ff_logical_block->init_val)||(1 == ff_logical_block->init_val));
|
||||
|
||||
return ff_logical_block->init_val;
|
||||
}
|
||||
|
||||
/* Get initial value of a mapped LUT output*/
|
||||
int get_lut_output_init_val(t_logical_block* lut_logical_block) {
|
||||
int i;
|
||||
int* sram_bits = NULL; /* decoded SRAM bits */
|
||||
|
@ -5831,7 +5859,7 @@ int get_logical_block_output_init_val(t_logical_block* cur_logical_block) {
|
|||
/* We have no information, give a default 0 now...
|
||||
* TODO: find a smarter way!
|
||||
*/
|
||||
output_init_val = 0;
|
||||
output_init_val = get_ff_output_init_val(cur_logical_block);
|
||||
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",
|
||||
|
@ -7213,4 +7241,40 @@ int count_cb_info_num_ipin_rr_nodes(t_cb cur_cb_info) {
|
|||
return cnt;
|
||||
}
|
||||
|
||||
/* Add a subckt file name to a linked list */
|
||||
t_llist* add_one_subckt_file_name_to_llist(t_llist* cur_head,
|
||||
char* subckt_file_path) {
|
||||
t_llist* new_head = NULL;
|
||||
|
||||
if (NULL == cur_head) {
|
||||
new_head = create_llist(1);
|
||||
new_head->dptr = (void*) my_strdup(subckt_file_path);
|
||||
} else {
|
||||
new_head = insert_llist_node_before_head(cur_head);
|
||||
new_head->dptr = (void*) my_strdup(subckt_file_path);
|
||||
}
|
||||
|
||||
return new_head;
|
||||
}
|
||||
|
||||
/* Check if SPICE subckt is already created
|
||||
* (if they exist in a given linked-list
|
||||
*/
|
||||
boolean check_subckt_file_exist_in_llist(t_llist* subckt_llist_head,
|
||||
char* subckt_file_name) {
|
||||
t_llist* temp = NULL;
|
||||
|
||||
temp = subckt_llist_head;
|
||||
while (temp) {
|
||||
if (0 == strcmp(subckt_file_name, (char*)(temp->dptr))) {
|
||||
return TRUE;
|
||||
}
|
||||
temp = temp->next;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -48,6 +48,10 @@ t_spice_transistor_type* find_mosfet_tech_lib(t_spice_tech_lib tech_lib,
|
|||
|
||||
char* my_itoa(int input);
|
||||
|
||||
char* fpga_spice_create_one_subckt_filename(char* file_name_prefix,
|
||||
int subckt_x, int subckt_y,
|
||||
char* file_name_postfix);
|
||||
|
||||
char* chomp_spice_node_prefix(char* spice_node_prefix);
|
||||
|
||||
char* format_spice_node_prefix(char* spice_node_prefix);
|
||||
|
@ -450,6 +454,8 @@ int* generate_lut_sram_bits(int truth_table_len,
|
|||
char** assign_lut_truth_table(t_logical_block* mapped_logical_block,
|
||||
int* truth_table_length);
|
||||
|
||||
int get_ff_output_init_val(t_logical_block* ff_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);
|
||||
|
@ -616,3 +622,9 @@ 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);
|
||||
|
||||
t_llist* add_one_subckt_file_name_to_llist(t_llist* cur_head,
|
||||
char* subckt_file_path);
|
||||
|
||||
boolean check_subckt_file_exist_in_llist(t_llist* subckt_llist_head,
|
||||
char* subckt_file_name);
|
||||
|
|
|
@ -330,7 +330,7 @@ void vpr_print_spice_netlists(t_vpr_setup vpr_setup,
|
|||
lut_testbench_dir_path = my_strcat(spice_dir_formatted, spice_lut_tb_dir_name);
|
||||
create_dir_path(lut_testbench_dir_path);
|
||||
spice_print_lut_testbench(lut_testbench_dir_path, chomped_circuit_name, include_dir_path, subckt_dir_path,
|
||||
rr_node_indices, num_clocks, Arch, vpr_setup.FPGA_SPICE_Opts.SpiceOpts.fpga_spice_leakage_only);
|
||||
rr_node_indices, num_clocks, Arch, vpr_setup.FPGA_SPICE_Opts.SpiceOpts.fpga_spice_leakage_only);
|
||||
}
|
||||
|
||||
/* Print hardlogic testbench file if needed */
|
||||
|
|
|
@ -12,6 +12,8 @@
|
|||
/* Threshold of max transistor width for each transistor */
|
||||
float max_width_per_trans = 5.;
|
||||
|
||||
char* spice_netlist_file_postfix = ".sp";
|
||||
|
||||
char* nmos_subckt_name = "vpr_nmos";
|
||||
char* pmos_subckt_name = "vpr_pmos";
|
||||
char* io_nmos_subckt_name = "vpr_io_nmos";
|
||||
|
@ -24,13 +26,21 @@ char* basics_spice_file_name = "inv_buf_trans_gate.sp";
|
|||
char* muxes_spice_file_name = "muxes.sp";
|
||||
char* rram_veriloga_file_name = "rram_behavior.va";
|
||||
char* wires_spice_file_name = "wires.sp";
|
||||
char* logic_block_spice_file_name = "logic_blocks.sp";
|
||||
char* logic_block_spice_file_name = "grid_header.sp";
|
||||
char* luts_spice_file_name = "luts.sp";
|
||||
char* routing_spice_file_name = "routing.sp";
|
||||
char* routing_spice_file_name = "routing_header.sp";
|
||||
char* meas_header_file_name = "meas_params.sp";
|
||||
char* stimu_header_file_name = "stimulate_params.sp";
|
||||
char* design_param_header_file_name = "design_params.sp";
|
||||
|
||||
/* Prefix for subckt SPICE netlists */
|
||||
char* grid_spice_file_name_prefix = "grid_";
|
||||
char* chanx_spice_file_name_prefix = "chanx_";
|
||||
char* chany_spice_file_name_prefix = "chany_";
|
||||
char* sb_spice_file_name_prefix = "sb_";
|
||||
char* cbx_spice_file_name_prefix = "cbx_";
|
||||
char* cby_spice_file_name_prefix = "cby_";
|
||||
|
||||
/* Postfix for circuit design parameters */
|
||||
char* design_param_postfix_input_buf_size = "_input_buf_size";
|
||||
char* design_param_postfix_output_buf_size = "_output_buf_size";
|
||||
|
@ -82,6 +92,11 @@ int num_used_io_tb = 0;
|
|||
|
||||
/* linked-list for all the testbenches */
|
||||
t_llist* tb_head = NULL;
|
||||
|
||||
/* Linked-list that stores submodule Verilog file mames */
|
||||
t_llist* grid_spice_subckt_file_path_head = NULL;
|
||||
t_llist* routing_spice_subckt_file_path_head = NULL;
|
||||
|
||||
/* linked-list for heads of scan-chain */
|
||||
t_llist* scan_chain_heads = NULL;
|
||||
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
/* global parameters for SPICE support*/
|
||||
extern float max_width_per_trans;
|
||||
|
||||
extern char* spice_netlist_file_postfix;
|
||||
|
||||
extern char* nmos_subckt_name;
|
||||
extern char* pmos_subckt_name;
|
||||
extern char* io_nmos_subckt_name;
|
||||
|
@ -20,6 +22,14 @@ extern char* meas_header_file_name;
|
|||
extern char* stimu_header_file_name;
|
||||
extern char* design_param_header_file_name;
|
||||
|
||||
/* Prefix for subckt SPICE netlists */
|
||||
extern char* grid_spice_file_name_prefix;
|
||||
extern char* chanx_spice_file_name_prefix;
|
||||
extern char* chany_spice_file_name_prefix;
|
||||
extern char* sb_spice_file_name_prefix;
|
||||
extern char* cbx_spice_file_name_prefix;
|
||||
extern char* cby_spice_file_name_prefix;
|
||||
|
||||
/* Postfix for circuit design parameters */
|
||||
extern char* design_param_postfix_input_buf_size;
|
||||
extern char* design_param_postfix_output_buf_size;
|
||||
|
@ -78,7 +88,14 @@ extern int num_used_lut_tb;
|
|||
extern int num_used_dff_tb;
|
||||
extern int num_used_hardlogic_tb;
|
||||
extern int num_used_io_tb;
|
||||
|
||||
/* linked-list for all the testbenches */
|
||||
extern t_llist* tb_head;
|
||||
|
||||
/* Linked-list that stores submodule Verilog file mames */
|
||||
extern t_llist* grid_spice_subckt_file_path_head;
|
||||
extern t_llist* routing_spice_subckt_file_path_head;
|
||||
|
||||
/* Heads of scan-chain */
|
||||
extern t_llist* scan_chain_heads;
|
||||
|
||||
|
|
|
@ -452,14 +452,20 @@ int fprint_spice_one_grid_testbench(char* formatted_spice_dir,
|
|||
|
||||
/* Special subckts for Top-level SPICE netlist */
|
||||
fprintf(fp, "****** Include subckt netlists: Look-Up Tables (LUTs) *****\n");
|
||||
temp_include_file_path = my_strcat(formatted_subckt_dir_path, luts_spice_file_name);
|
||||
fprintf(fp, ".include \'%s\'\n", temp_include_file_path);
|
||||
my_free(temp_include_file_path);
|
||||
spice_print_one_include_subckt_line(fp, formatted_subckt_dir_path, luts_spice_file_name);
|
||||
|
||||
fprintf(fp, "****** Include subckt netlists: Logic Blocks *****\n");
|
||||
temp_include_file_path = my_strcat(formatted_subckt_dir_path, logic_block_spice_file_name);
|
||||
fprintf(fp, ".include \'%s\'\n", temp_include_file_path);
|
||||
my_free(temp_include_file_path);
|
||||
/* Generate filename */
|
||||
fprintf(fp, "****** Include subckt netlists: Grid[%d][%d] *****\n",
|
||||
grid_x, grid_y);
|
||||
temp_include_file_path = fpga_spice_create_one_subckt_filename(grid_spice_file_name_prefix, grid_x, grid_y, spice_netlist_file_postfix);
|
||||
/* Check if we include an existing file! */
|
||||
if (FALSE == check_subckt_file_exist_in_llist(grid_spice_subckt_file_path_head,
|
||||
my_strcat(formatted_subckt_dir_path, temp_include_file_path))) {
|
||||
vpr_printf(TIO_MESSAGE_ERROR,"(FILE:%s,LINE[%d])Intend to include a non-existed SPICE netlist %s!\n",
|
||||
__FILE__, __LINE__, temp_include_file_path);
|
||||
exit(1);
|
||||
}
|
||||
spice_print_one_include_subckt_line(fp, formatted_subckt_dir_path, temp_include_file_path);
|
||||
|
||||
/* Print simulation temperature and other options for SPICE */
|
||||
fprint_spice_options(fp, arch.spice->spice_params);
|
||||
|
@ -516,6 +522,7 @@ void spice_print_grid_testbench(char* formatted_spice_dir,
|
|||
t_arch arch,
|
||||
boolean leakage_only) {
|
||||
char* grid_testbench_name = NULL;
|
||||
char* temp_include_file_path = NULL;
|
||||
int ix, iy;
|
||||
int cnt = 0;
|
||||
int used;
|
||||
|
@ -524,6 +531,15 @@ void spice_print_grid_testbench(char* formatted_spice_dir,
|
|||
|
||||
for (ix = 1; ix < (nx+1); ix++) {
|
||||
for (iy = 1; iy < (ny+1); iy++) {
|
||||
/* Check if we include an existing subckt file! */
|
||||
temp_include_file_path = fpga_spice_create_one_subckt_filename(grid_spice_file_name_prefix, ix, iy, spice_netlist_file_postfix);
|
||||
if (FALSE == check_subckt_file_exist_in_llist(grid_spice_subckt_file_path_head,
|
||||
my_strcat(subckt_dir_path, temp_include_file_path))) {
|
||||
/* free */
|
||||
my_free(temp_include_file_path);
|
||||
continue;
|
||||
}
|
||||
/* Create a testbench for the existing subckt */
|
||||
grid_testbench_name = (char*)my_malloc(sizeof(char)*( strlen(circuit_name)
|
||||
+ 6 + strlen(my_itoa(ix)) + 1
|
||||
+ strlen(my_itoa(iy)) + 1
|
||||
|
@ -539,6 +555,7 @@ void spice_print_grid_testbench(char* formatted_spice_dir,
|
|||
}
|
||||
/* free */
|
||||
my_free(grid_testbench_name);
|
||||
my_free(temp_include_file_path);
|
||||
}
|
||||
}
|
||||
/* Update the global counter */
|
||||
|
|
|
@ -651,14 +651,20 @@ int fprint_spice_one_lut_testbench(char* formatted_spice_dir,
|
|||
|
||||
/* Special subckts for Top-level SPICE netlist */
|
||||
fprintf(fp, "****** Include subckt netlists: Look-Up Tables (LUTs) *****\n");
|
||||
temp_include_file_path = my_strcat(formatted_subckt_dir_path, luts_spice_file_name);
|
||||
fprintf(fp, ".include \'%s\'\n", temp_include_file_path);
|
||||
my_free(temp_include_file_path);
|
||||
spice_print_one_include_subckt_line(fp, formatted_subckt_dir_path, luts_spice_file_name);
|
||||
|
||||
fprintf(fp, "****** Include subckt netlists: Logic Blocks *****\n");
|
||||
temp_include_file_path = my_strcat(formatted_subckt_dir_path, logic_block_spice_file_name);
|
||||
fprintf(fp, ".include \'%s\'\n", temp_include_file_path);
|
||||
my_free(temp_include_file_path);
|
||||
/* Generate filename */
|
||||
fprintf(fp, "****** Include subckt netlists: Grid[%d][%d] *****\n",
|
||||
grid_x, grid_y);
|
||||
temp_include_file_path = fpga_spice_create_one_subckt_filename(grid_spice_file_name_prefix, grid_x, grid_y, spice_netlist_file_postfix);
|
||||
/* Check if we include an existing file! */
|
||||
if (FALSE == check_subckt_file_exist_in_llist(grid_spice_subckt_file_path_head,
|
||||
my_strcat(formatted_subckt_dir_path, temp_include_file_path))) {
|
||||
vpr_printf(TIO_MESSAGE_ERROR,"(FILE:%s,LINE[%d])Intend to include a non-existed SPICE netlist %s!\n",
|
||||
__FILE__, __LINE__, temp_include_file_path);
|
||||
exit(1);
|
||||
}
|
||||
spice_print_one_include_subckt_line(fp, formatted_subckt_dir_path, temp_include_file_path);
|
||||
|
||||
/* Print simulation temperature and other options for SPICE */
|
||||
fprint_spice_options(fp, arch.spice->spice_params);
|
||||
|
@ -705,6 +711,9 @@ int fprint_spice_one_lut_testbench(char* formatted_spice_dir,
|
|||
used = 0;
|
||||
}
|
||||
|
||||
/* Free */
|
||||
my_free(temp_include_file_path);
|
||||
|
||||
return used;
|
||||
}
|
||||
|
||||
|
@ -719,6 +728,7 @@ void spice_print_lut_testbench(char* formatted_spice_dir,
|
|||
t_arch arch,
|
||||
boolean leakage_only) {
|
||||
char* lut_testbench_name = NULL;
|
||||
char* temp_include_file_path = NULL;
|
||||
int ix, iy;
|
||||
int cnt = 0;
|
||||
int used;
|
||||
|
@ -727,6 +737,16 @@ void spice_print_lut_testbench(char* formatted_spice_dir,
|
|||
|
||||
for (ix = 1; ix < (nx+1); ix++) {
|
||||
for (iy = 1; iy < (ny+1); iy++) {
|
||||
/* Check if we include an existing subckt file! */
|
||||
temp_include_file_path = fpga_spice_create_one_subckt_filename(grid_spice_file_name_prefix, ix, iy, spice_netlist_file_postfix);
|
||||
if (FALSE == check_subckt_file_exist_in_llist(grid_spice_subckt_file_path_head,
|
||||
my_strcat(subckt_dir_path, temp_include_file_path))) {
|
||||
/* free */
|
||||
my_free(temp_include_file_path);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Create a testbench for the existing subckt */
|
||||
lut_testbench_name = (char*)my_malloc(sizeof(char)*( strlen(circuit_name)
|
||||
+ 6 + strlen(my_itoa(ix)) + 1
|
||||
+ strlen(my_itoa(iy)) + 1
|
||||
|
@ -742,6 +762,7 @@ void spice_print_lut_testbench(char* formatted_spice_dir,
|
|||
}
|
||||
/* free */
|
||||
my_free(lut_testbench_name);
|
||||
my_free(temp_include_file_path);
|
||||
}
|
||||
}
|
||||
/* Update the global counter */
|
||||
|
|
|
@ -1813,14 +1813,6 @@ int fprint_spice_one_mux_testbench(char* formatted_spice_dir,
|
|||
init_include_user_defined_netlists(*(arch.spice));
|
||||
fprint_include_user_defined_netlists(fp, *(arch.spice));
|
||||
|
||||
/* Special subckts for Top-level SPICE netlist */
|
||||
/*
|
||||
fprintf(fp, "****** Include subckt netlists: Look-Up Tables (LUTs) *****\n");
|
||||
temp_include_file_path = my_strcat(formatted_subckt_dir_path, luts_spice_file_name);
|
||||
fprintf(fp, ".include %s\n", temp_include_file_path);
|
||||
my_free(temp_include_file_path);
|
||||
*/
|
||||
|
||||
/* Print simulation temperature and other options for SPICE */
|
||||
fprint_spice_options(fp, arch.spice->spice_params);
|
||||
|
||||
|
|
|
@ -2092,9 +2092,8 @@ void fprint_io_grid_block_subckt_pins(FILE* fp,
|
|||
}
|
||||
|
||||
/* Print the SPICE netlist for a physical grid blocks */
|
||||
void fprint_grid_physical_blocks(FILE* fp,
|
||||
int ix,
|
||||
int iy,
|
||||
void fprint_grid_physical_blocks(char* subckt_dir,
|
||||
int ix, int iy,
|
||||
t_arch* arch) {
|
||||
int subckt_name_str_len = 0;
|
||||
char* subckt_name = NULL;
|
||||
|
@ -2102,13 +2101,9 @@ void fprint_grid_physical_blocks(FILE* fp,
|
|||
int iz;
|
||||
int cur_block_index = 0;
|
||||
int capacity;
|
||||
FILE* fp = NULL;
|
||||
char* fname = NULL;
|
||||
|
||||
/* Check the file handler*/
|
||||
if (NULL == fp) {
|
||||
vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid file handler.\n",
|
||||
__FILE__, __LINE__);
|
||||
exit(1);
|
||||
}
|
||||
/* Check */
|
||||
assert((!(0 > ix))&&(!(ix > (nx + 1))));
|
||||
assert((!(0 > iy))&&(!(iy > (ny + 1))));
|
||||
|
@ -2126,6 +2121,10 @@ void fprint_grid_physical_blocks(FILE* fp,
|
|||
update_spice_models_grid_index_high(ix, iy, arch->spice->num_spice_model, arch->spice->spice_models);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Create file handler */
|
||||
fp = spice_create_one_subckt_file(subckt_dir, "Phyiscal Logic Block ", grid_spice_file_name_prefix, ix, iy, &fname);
|
||||
|
||||
capacity = grid[ix][iy].type->capacity;
|
||||
assert(0 < capacity);
|
||||
|
||||
|
@ -2199,8 +2198,15 @@ void fprint_grid_physical_blocks(FILE* fp,
|
|||
|
||||
fprintf(fp, ".eom\n");
|
||||
|
||||
/* Close the file */
|
||||
fclose(fp);
|
||||
|
||||
/* Add fname to the linked list */
|
||||
grid_spice_subckt_file_path_head = add_one_subckt_file_name_to_llist(grid_spice_subckt_file_path_head, fname);
|
||||
|
||||
/* Free */
|
||||
my_free(subckt_name);
|
||||
my_free(fname);
|
||||
|
||||
return;
|
||||
}
|
||||
|
@ -2208,9 +2214,8 @@ void fprint_grid_physical_blocks(FILE* fp,
|
|||
|
||||
|
||||
/* Print the SPICE netlist for a grid blocks */
|
||||
void fprint_grid_blocks(FILE* fp,
|
||||
int ix,
|
||||
int iy,
|
||||
void fprint_grid_blocks(char* subckt_dir,
|
||||
int ix, int iy,
|
||||
t_arch* arch) {
|
||||
int subckt_name_str_len = 0;
|
||||
char* subckt_name = NULL;
|
||||
|
@ -2218,13 +2223,9 @@ void fprint_grid_blocks(FILE* fp,
|
|||
int iz;
|
||||
int cur_block_index = 0;
|
||||
int capacity;
|
||||
FILE* fp = NULL;
|
||||
char* fname = NULL;
|
||||
|
||||
/* Check the file handler*/
|
||||
if (NULL == fp) {
|
||||
vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid file handler.\n",
|
||||
__FILE__, __LINE__);
|
||||
exit(1);
|
||||
}
|
||||
/* Check */
|
||||
assert((!(0 > ix))&&(!(ix > (nx + 1))));
|
||||
assert((!(0 > iy))&&(!(iy > (ny + 1))));
|
||||
|
@ -2244,6 +2245,9 @@ void fprint_grid_blocks(FILE* fp,
|
|||
return;
|
||||
}
|
||||
|
||||
/* Create file handler */
|
||||
fp = spice_create_one_subckt_file(subckt_dir, "Logic Block", grid_spice_file_name_prefix, ix, iy, &fname);
|
||||
|
||||
capacity= grid[ix][iy].type->capacity;
|
||||
assert(0 < capacity);
|
||||
|
||||
|
@ -2330,8 +2334,15 @@ void fprint_grid_blocks(FILE* fp,
|
|||
|
||||
fprintf(fp, ".eom\n");
|
||||
|
||||
/* Close the file */
|
||||
fclose(fp);
|
||||
|
||||
/* Add fname to the linked list */
|
||||
grid_spice_subckt_file_path_head = add_one_subckt_file_name_to_llist(grid_spice_subckt_file_path_head, fname);
|
||||
|
||||
/* Free */
|
||||
my_free(subckt_name);
|
||||
my_free(fname);
|
||||
|
||||
return;
|
||||
}
|
||||
|
@ -2345,8 +2356,6 @@ void fprint_grid_blocks(FILE* fp,
|
|||
void generate_spice_logic_blocks(char* subckt_dir,
|
||||
t_arch* arch) {
|
||||
/* Create file names */
|
||||
char* sp_name = my_strcat(subckt_dir, logic_block_spice_file_name);
|
||||
FILE* fp = NULL;
|
||||
int ix, iy;
|
||||
|
||||
/* Check the grid*/
|
||||
|
@ -2357,15 +2366,6 @@ void generate_spice_logic_blocks(char* subckt_dir,
|
|||
vpr_printf(TIO_MESSAGE_INFO,"Grid size of FPGA: nx=%d ny=%d\n", nx + 1, ny + 1);
|
||||
assert(NULL != grid);
|
||||
|
||||
/* Create a file*/
|
||||
fp = fopen(sp_name, "w");
|
||||
if (NULL == fp) {
|
||||
vpr_printf(TIO_MESSAGE_ERROR,"(FILE:%s,LINE[%d])Failure in create subckt SPICE netlist %s",__FILE__, __LINE__, sp_name);
|
||||
exit(1);
|
||||
}
|
||||
/* Generate the descriptions*/
|
||||
fprint_spice_head(fp,"Logic Blocks in FPGA");
|
||||
|
||||
/* Print the core logic block one by one
|
||||
* Note ix=0 and ix = nx + 1 are IO pads. They surround the core logic blocks
|
||||
*/
|
||||
|
@ -2376,7 +2376,7 @@ void generate_spice_logic_blocks(char* subckt_dir,
|
|||
assert(IO_TYPE != grid[ix][iy].type);
|
||||
/* Ensure a valid usage */
|
||||
assert((0 == grid[ix][iy].usage)||(0 < grid[ix][iy].usage));
|
||||
fprint_grid_blocks(fp, ix, iy, arch);
|
||||
fprint_grid_blocks(subckt_dir, ix, iy, arch);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2388,7 +2388,7 @@ void generate_spice_logic_blocks(char* subckt_dir,
|
|||
/* Ensure this is a io */
|
||||
assert(IO_TYPE == grid[ix][iy].type);
|
||||
/* TODO: replace with physical block generator */
|
||||
fprint_grid_physical_blocks(fp, ix, iy, arch);
|
||||
fprint_grid_physical_blocks(subckt_dir, ix, iy, arch);
|
||||
}
|
||||
/* Right side : x = nx + 1, y = 1 .. ny*/
|
||||
ix = nx + 1;
|
||||
|
@ -2396,7 +2396,7 @@ void generate_spice_logic_blocks(char* subckt_dir,
|
|||
/* Ensure this is a io */
|
||||
assert(IO_TYPE == grid[ix][iy].type);
|
||||
/* TODO: replace with physical block generator */
|
||||
fprint_grid_physical_blocks(fp, ix, iy, arch);
|
||||
fprint_grid_physical_blocks(subckt_dir, ix, iy, arch);
|
||||
}
|
||||
/* Bottom side : x = 1 .. nx + 1, y = 0 */
|
||||
iy = 0;
|
||||
|
@ -2404,7 +2404,7 @@ void generate_spice_logic_blocks(char* subckt_dir,
|
|||
/* Ensure this is a io */
|
||||
assert(IO_TYPE == grid[ix][iy].type);
|
||||
/* TODO: replace with physical block generator */
|
||||
fprint_grid_physical_blocks(fp, ix, iy, arch);
|
||||
fprint_grid_physical_blocks(subckt_dir, ix, iy, arch);
|
||||
}
|
||||
/* Top side : x = 1 .. nx + 1, y = nx + 1 */
|
||||
iy = ny + 1;
|
||||
|
@ -2412,15 +2412,14 @@ void generate_spice_logic_blocks(char* subckt_dir,
|
|||
/* Ensure this is a io */
|
||||
assert(IO_TYPE == grid[ix][iy].type);
|
||||
/* TODO: replace with physical block generator */
|
||||
fprint_grid_physical_blocks(fp, ix, iy, arch);
|
||||
fprint_grid_physical_blocks(subckt_dir, ix, iy, arch);
|
||||
}
|
||||
|
||||
/* Output a header file for all the logic blocks */
|
||||
vpr_printf(TIO_MESSAGE_INFO,"Generating header file for grid submodules...\n");
|
||||
spice_print_subckt_header_file(grid_spice_subckt_file_path_head,
|
||||
subckt_dir,
|
||||
logic_block_spice_file_name);
|
||||
|
||||
/* Close the file */
|
||||
fclose(fp);
|
||||
|
||||
/* Free */
|
||||
my_free(sp_name);
|
||||
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -34,7 +34,7 @@
|
|||
#include "spice_routing.h"
|
||||
|
||||
|
||||
void fprint_routing_chan_subckt(FILE* fp,
|
||||
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,
|
||||
t_ivec*** LL_rr_node_indices,
|
||||
|
@ -43,13 +43,9 @@ void fprint_routing_chan_subckt(FILE* fp,
|
|||
char* chan_prefix = NULL;
|
||||
int chan_width = 0;
|
||||
t_rr_node** chan_rr_nodes = NULL;
|
||||
|
||||
/* Check the file handler*/
|
||||
if (NULL == fp) {
|
||||
vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid file handler.\n",
|
||||
__FILE__, __LINE__);
|
||||
exit(1);
|
||||
}
|
||||
FILE* fp = NULL;
|
||||
char* fname = NULL;
|
||||
|
||||
/* Check */
|
||||
assert((!(0 > x))&&(!(x > (nx + 1))));
|
||||
assert((!(0 > y))&&(!(y > (ny + 1))));
|
||||
|
@ -58,10 +54,14 @@ void fprint_routing_chan_subckt(FILE* fp,
|
|||
/* Initial chan_prefix*/
|
||||
switch (chan_type) {
|
||||
case CHANX:
|
||||
/* Create file handler */
|
||||
fp = spice_create_one_subckt_file(subckt_dir, "Channel X-direction ", chanx_spice_file_name_prefix, x, y, &fname);
|
||||
chan_prefix = "chanx";
|
||||
fprintf(fp, "***** Subckt for Channel X [%d][%d] *****\n", x, y);
|
||||
break;
|
||||
case CHANY:
|
||||
/* Create file handler */
|
||||
fp = spice_create_one_subckt_file(subckt_dir, "Channel Y-direction ", chany_spice_file_name_prefix, x, y, &fname);
|
||||
chan_prefix = "chany";
|
||||
fprintf(fp, "***** Subckt for Channel Y [%d][%d] *****\n", x, y);
|
||||
break;
|
||||
|
@ -147,8 +147,15 @@ void fprint_routing_chan_subckt(FILE* fp,
|
|||
|
||||
fprintf(fp, ".eom\n");
|
||||
|
||||
/* Close the file*/
|
||||
fclose(fp);
|
||||
|
||||
/* Add fname to the linked list */
|
||||
routing_spice_subckt_file_path_head = add_one_subckt_file_name_to_llist(routing_spice_subckt_file_path_head, fname);
|
||||
|
||||
/* Free */
|
||||
my_free(chan_rr_nodes);
|
||||
my_free(fname);
|
||||
|
||||
return;
|
||||
}
|
||||
|
@ -641,22 +648,21 @@ 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
|
||||
*/
|
||||
void fprint_routing_switch_box_subckt(FILE* fp, t_sb cur_sb_info,
|
||||
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) {
|
||||
int itrack, inode, side, ix, iy, x, y;
|
||||
|
||||
/* Check the file handler*/
|
||||
if (NULL == fp) {
|
||||
vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid file handler.\n",
|
||||
__FILE__, __LINE__);
|
||||
exit(1);
|
||||
}
|
||||
FILE* fp = NULL;
|
||||
char* fname = NULL;
|
||||
|
||||
/* Check */
|
||||
assert((!(0 > cur_sb_info.x))&&(!(cur_sb_info.x > (nx + 1))));
|
||||
assert((!(0 > cur_sb_info.y))&&(!(cur_sb_info.y > (ny + 1))));
|
||||
|
||||
/* Create file handler */
|
||||
fp = spice_create_one_subckt_file(subckt_dir, "Switch Block ", sb_spice_file_name_prefix, cur_sb_info.x, cur_sb_info.y, &fname);
|
||||
|
||||
x = cur_sb_info.x;
|
||||
y = cur_sb_info.y;
|
||||
|
||||
|
@ -734,7 +740,14 @@ void fprint_routing_switch_box_subckt(FILE* fp, t_sb cur_sb_info,
|
|||
|
||||
fprintf(fp, ".eom\n");
|
||||
|
||||
/* Close the file*/
|
||||
fclose(fp);
|
||||
|
||||
/* Add fname to the linked list */
|
||||
routing_spice_subckt_file_path_head = add_one_subckt_file_name_to_llist(routing_spice_subckt_file_path_head, fname);
|
||||
|
||||
/* Free */
|
||||
my_free(fname);
|
||||
|
||||
return;
|
||||
}
|
||||
|
@ -1024,18 +1037,31 @@ void fprint_connection_box_interc(FILE* fp,
|
|||
* | | Connection | |
|
||||
* --------------Box_Y[x][y-1]--------------
|
||||
*/
|
||||
void fprint_routing_connection_box_subckt(FILE* fp, t_cb cur_cb_info,
|
||||
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) {
|
||||
int itrack, inode, side, x, y;
|
||||
int side_cnt = 0;
|
||||
FILE* fp = NULL;
|
||||
char* fname = NULL;
|
||||
|
||||
/* Check the file handler*/
|
||||
if (NULL == fp) {
|
||||
vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid file handler.\n",
|
||||
__FILE__, __LINE__);
|
||||
/* Identify the type of connection box
|
||||
* Create file handler
|
||||
*/
|
||||
switch(cur_cb_info.type) {
|
||||
case CHANX:
|
||||
fp = spice_create_one_subckt_file(subckt_dir, "Connection Block X-channel ", cbx_spice_file_name_prefix, cur_cb_info.x, cur_cb_info.y, &fname);
|
||||
break;
|
||||
case CHANY:
|
||||
fp = spice_create_one_subckt_file(subckt_dir, "Connection Block Y-channel ", cby_spice_file_name_prefix, cur_cb_info.x, cur_cb_info.y, &fname);
|
||||
break;
|
||||
default:
|
||||
vpr_printf(TIO_MESSAGE_ERROR, "(File:%s, [LINE%d])Invalid type of connection box!\n",
|
||||
__FILE__, __LINE__);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* Check */
|
||||
assert((!(0 > cur_cb_info.x))&&(!(cur_cb_info.x > (nx + 1))));
|
||||
assert((!(0 > cur_cb_info.y))&&(!(cur_cb_info.y > (ny + 1))));
|
||||
|
@ -1167,6 +1193,15 @@ void fprint_routing_connection_box_subckt(FILE* fp, t_cb cur_cb_info,
|
|||
|
||||
fprintf(fp, ".eom\n");
|
||||
|
||||
/* Close the file*/
|
||||
fclose(fp);
|
||||
|
||||
/* Add fname to the linked list */
|
||||
routing_spice_subckt_file_path_head = add_one_subckt_file_name_to_llist(routing_spice_subckt_file_path_head, fname);
|
||||
|
||||
/* Free */
|
||||
my_free(fname);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1178,19 +1213,9 @@ void generate_spice_routing_resources(char* subckt_dir,
|
|||
t_det_routing_arch* routing_arch,
|
||||
int LL_num_rr_nodes, t_rr_node* LL_rr_node,
|
||||
t_ivec*** LL_rr_node_indices) {
|
||||
FILE* fp = NULL;
|
||||
char* sp_name = my_strcat(subckt_dir, routing_spice_file_name);
|
||||
int ix, iy;
|
||||
|
||||
assert(UNI_DIRECTIONAL == routing_arch->directionality);
|
||||
|
||||
/* Create FILE */
|
||||
fp = fopen(sp_name, "w");
|
||||
if (NULL == fp) {
|
||||
vpr_printf(TIO_MESSAGE_ERROR,"(FILE:%s,LINE[%d])Failure in create SPICE netlist %s",__FILE__, __LINE__, wires_spice_file_name);
|
||||
exit(1);
|
||||
}
|
||||
fprint_spice_head(fp,"Routing Resources");
|
||||
|
||||
/* Two major tasks:
|
||||
* 1. Generate sub-circuits for Routing Channels
|
||||
|
@ -1214,7 +1239,7 @@ void generate_spice_routing_resources(char* subckt_dir,
|
|||
vpr_printf(TIO_MESSAGE_INFO, "Writing X-direction Channels...\n");
|
||||
for (iy = 0; iy < (ny + 1); iy++) {
|
||||
for (ix = 1; ix < (nx + 1); ix++) {
|
||||
fprint_routing_chan_subckt(fp, ix, iy, CHANX,
|
||||
fprint_routing_chan_subckt(subckt_dir, ix, iy, CHANX,
|
||||
LL_num_rr_nodes, LL_rr_node, LL_rr_node_indices,
|
||||
arch.num_segments, arch.Segments);
|
||||
}
|
||||
|
@ -1223,7 +1248,7 @@ void generate_spice_routing_resources(char* subckt_dir,
|
|||
vpr_printf(TIO_MESSAGE_INFO, "Writing Y-direction Channels...\n");
|
||||
for (ix = 0; ix < (nx + 1); ix++) {
|
||||
for (iy = 1; iy < (ny + 1); iy++) {
|
||||
fprint_routing_chan_subckt(fp, ix, iy, CHANY,
|
||||
fprint_routing_chan_subckt(subckt_dir, ix, iy, CHANY,
|
||||
LL_num_rr_nodes, LL_rr_node, LL_rr_node_indices,
|
||||
arch.num_segments, arch.Segments);
|
||||
}
|
||||
|
@ -1234,7 +1259,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(fp, sb_info[ix][iy],
|
||||
fprint_routing_switch_box_subckt(subckt_dir, sb_info[ix][iy],
|
||||
LL_num_rr_nodes, LL_rr_node, LL_rr_node_indices);
|
||||
update_spice_models_routing_index_high(ix, iy, SOURCE, arch.spice->num_spice_model, arch.spice->spice_models);
|
||||
}
|
||||
|
@ -1249,7 +1274,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(fp, 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);
|
||||
}
|
||||
update_spice_models_routing_index_high(ix, iy, CHANX, arch.spice->num_spice_model, arch.spice->spice_models);
|
||||
|
@ -1262,16 +1287,18 @@ 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(fp, 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);
|
||||
}
|
||||
update_spice_models_routing_index_high(ix, iy, CHANY, arch.spice->num_spice_model, arch.spice->spice_models);
|
||||
}
|
||||
}
|
||||
|
||||
/* Close the file*/
|
||||
fclose(fp);
|
||||
|
||||
/* Output a header file for all the routing blocks */
|
||||
vpr_printf(TIO_MESSAGE_INFO,"Generating header file for routing submodules...\n");
|
||||
spice_print_subckt_header_file(routing_spice_subckt_file_path_head,
|
||||
subckt_dir,
|
||||
routing_spice_file_name);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -562,9 +562,11 @@ int fprint_spice_one_cb_testbench(char* formatted_spice_dir,
|
|||
switch (cb_type) {
|
||||
case CHANX:
|
||||
cb_tb_name = "Connection Box X-channel ";
|
||||
temp_include_file_path = fpga_spice_create_one_subckt_filename(cbx_spice_file_name_prefix, grid_x, grid_y, spice_netlist_file_postfix);
|
||||
break;
|
||||
case CHANY:
|
||||
cb_tb_name = "Connection Box Y-channel ";
|
||||
temp_include_file_path = fpga_spice_create_one_subckt_filename(cby_spice_file_name_prefix, grid_x, grid_y, spice_netlist_file_postfix);
|
||||
break;
|
||||
default:
|
||||
vpr_printf(TIO_MESSAGE_ERROR, "(File:%s, [LINE%d]) Invalid connection_box_type!\n", __FILE__, __LINE__);
|
||||
|
@ -611,15 +613,21 @@ int fprint_spice_one_cb_testbench(char* formatted_spice_dir,
|
|||
/* Quote defined Logic blocks subckts (Grids) */
|
||||
init_spice_routing_testbench_globals(*(arch.spice));
|
||||
|
||||
fprintf(fp, "****** Include subckt netlists: Routing structures (Switch Boxes, Channels, Connection Boxes) *****\n");
|
||||
temp_include_file_path = my_strcat(formatted_subckt_dir_path, routing_spice_file_name);
|
||||
fprintf(fp, ".include \'%s\'\n", temp_include_file_path);
|
||||
my_free(temp_include_file_path);
|
||||
|
||||
/* one cbx, one cby*/
|
||||
switch (cb_type) {
|
||||
case CHANX:
|
||||
case CHANY:
|
||||
/* Generate filename */
|
||||
fprintf(fp, "****** Include subckt netlists: %s [%d][%d] *****\n",
|
||||
cb_tb_name, grid_x, grid_y);
|
||||
/* Check if we include an existing file! */
|
||||
if (FALSE == check_subckt_file_exist_in_llist(routing_spice_subckt_file_path_head,
|
||||
my_strcat(formatted_subckt_dir_path, temp_include_file_path))) {
|
||||
vpr_printf(TIO_MESSAGE_ERROR,"(FILE:%s,LINE[%d])Intend to include a non-existed SPICE netlist %s!",
|
||||
__FILE__, __LINE__, temp_include_file_path);
|
||||
exit(1);
|
||||
}
|
||||
spice_print_one_include_subckt_line(fp, formatted_subckt_dir_path, temp_include_file_path);
|
||||
used = fprint_spice_routing_testbench_call_one_cb_tb(fp, *(arch.spice), cb_type, grid_x, grid_y, LL_rr_node_indices);
|
||||
break;
|
||||
default:
|
||||
|
@ -642,6 +650,9 @@ int fprint_spice_one_cb_testbench(char* formatted_spice_dir,
|
|||
max_sim_num_clock_cycles);
|
||||
used = 1;
|
||||
|
||||
/* Free */
|
||||
my_free(temp_include_file_path);
|
||||
|
||||
return used;
|
||||
}
|
||||
|
||||
|
@ -704,12 +715,22 @@ int fprint_spice_one_sb_testbench(char* formatted_spice_dir,
|
|||
/* Quote defined Logic blocks subckts (Grids) */
|
||||
init_spice_routing_testbench_globals(*(arch.spice));
|
||||
|
||||
fprintf(fp, "****** Include subckt netlists: Routing structures (Switch Boxes, Channels, Connection Boxes) *****\n");
|
||||
temp_include_file_path = my_strcat(formatted_subckt_dir_path, routing_spice_file_name);
|
||||
fprintf(fp, ".include \'%s\'\n", temp_include_file_path);
|
||||
my_free(temp_include_file_path);
|
||||
/* Generate filename */
|
||||
fprintf(fp, "****** Include subckt netlists: Switch Block[%d][%d] *****\n",
|
||||
grid_x, grid_y);
|
||||
temp_include_file_path = fpga_spice_create_one_subckt_filename(sb_spice_file_name_prefix, grid_x, grid_y, spice_netlist_file_postfix);
|
||||
/* Check if we include an existing file! */
|
||||
if (FALSE == check_subckt_file_exist_in_llist(routing_spice_subckt_file_path_head,
|
||||
my_strcat(formatted_subckt_dir_path, temp_include_file_path))) {
|
||||
vpr_printf(TIO_MESSAGE_ERROR,"(FILE:%s,LINE[%d])Intend to include a non-existed SPICE netlist %s!",
|
||||
__FILE__, __LINE__, temp_include_file_path);
|
||||
exit(1);
|
||||
}
|
||||
spice_print_one_include_subckt_line(fp, formatted_subckt_dir_path, temp_include_file_path);
|
||||
|
||||
used = fprint_spice_routing_testbench_call_one_sb_tb(fp, *(arch.spice), grid_x, grid_y, LL_rr_node_indices);
|
||||
|
||||
|
||||
/* Generate SPICE routing testbench generic stimuli*/
|
||||
fprintf_spice_routing_testbench_generic_stimuli(fp, num_clocks);
|
||||
|
||||
|
|
|
@ -49,6 +49,104 @@ void fprint_spice_head(FILE* fp,
|
|||
return;
|
||||
}
|
||||
|
||||
/* Create a file handler for a subckt SPICE netlist */
|
||||
FILE* spice_create_one_subckt_file(char* subckt_dir,
|
||||
char* subckt_name_prefix,
|
||||
char* spice_subckt_file_name_prefix,
|
||||
int grid_x, int grid_y,
|
||||
char** sp_name) {
|
||||
FILE* fp = NULL;
|
||||
char* file_description = NULL;
|
||||
(*sp_name) = my_strcat(subckt_dir,
|
||||
fpga_spice_create_one_subckt_filename(spice_subckt_file_name_prefix, grid_x, grid_y, spice_netlist_file_postfix));
|
||||
|
||||
/* Create a file*/
|
||||
fp = fopen((*sp_name), "w");
|
||||
|
||||
if (NULL == fp) {
|
||||
vpr_printf(TIO_MESSAGE_ERROR,
|
||||
"(FILE:%s,LINE[%d])Failure in create subckt SPICE netlist %s",
|
||||
__FILE__, __LINE__, (*sp_name));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* Generate the descriptions*/
|
||||
file_description = (char*) my_malloc(sizeof(char) * (strlen(subckt_name_prefix) + 2
|
||||
+ strlen(my_itoa(grid_x)) + 2 + strlen(my_itoa(grid_y))
|
||||
+ 9));
|
||||
sprintf(file_description, "%s [%d][%d] in FPGA",
|
||||
subckt_name_prefix, grid_x, grid_y);
|
||||
fprint_spice_head(fp, file_description);
|
||||
|
||||
/* Free */
|
||||
my_free(file_description);
|
||||
|
||||
return fp;
|
||||
}
|
||||
|
||||
/* Include a subckt in SPICE netlist */
|
||||
void spice_print_one_include_subckt_line(FILE* fp,
|
||||
char* subckt_dir,
|
||||
char* subckt_file_name) {
|
||||
char* temp_include_file_path = NULL;
|
||||
|
||||
if (NULL == fp) {
|
||||
vpr_printf(TIO_MESSAGE_ERROR,
|
||||
"(FILE:%s,LINE[%d])Invalid File Handler of subckt SPICE netlist %s",
|
||||
__FILE__, __LINE__);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
temp_include_file_path = my_strcat(subckt_dir, subckt_file_name);
|
||||
fprintf(fp, ".include \'%s\'\n", temp_include_file_path);
|
||||
my_free(temp_include_file_path);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* Output all the created subckt file names in a header file,
|
||||
* that can be easily imported in a top-level netlist
|
||||
*/
|
||||
void spice_print_subckt_header_file(t_llist* subckt_llist_head,
|
||||
char* subckt_dir,
|
||||
char* header_file_name) {
|
||||
FILE* fp = NULL;
|
||||
char* spice_fname = NULL;
|
||||
t_llist* temp = NULL;
|
||||
|
||||
spice_fname = my_strcat(subckt_dir,
|
||||
header_file_name);
|
||||
|
||||
/* Create a file*/
|
||||
fp = fopen(spice_fname, "w");
|
||||
|
||||
if (NULL == fp) {
|
||||
vpr_printf(TIO_MESSAGE_ERROR,
|
||||
"(FILE:%s,LINE[%d])Failure in create SPICE netlist %s",
|
||||
__FILE__, __LINE__, spice_fname);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* Generate the descriptions*/
|
||||
fprint_spice_head(fp, "Header file");
|
||||
|
||||
/* Output file names */
|
||||
temp = subckt_llist_head;
|
||||
while (temp) {
|
||||
fprintf(fp, ".include \'%s\'\n",
|
||||
(char*)(temp->dptr));
|
||||
temp = temp->next;
|
||||
}
|
||||
|
||||
/* Close fp */
|
||||
fclose(fp);
|
||||
|
||||
/* Free */
|
||||
my_free(spice_fname);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/* Print all the global ports that are stored in the linked list
|
||||
* Return the number of ports that have been dumped
|
||||
|
|
|
@ -9,11 +9,24 @@ enum e_measure_type {
|
|||
void fprint_spice_head(FILE* fp,
|
||||
char* usage);
|
||||
|
||||
FILE* spice_create_one_subckt_file(char* subckt_dir,
|
||||
char* subckt_name_prefix,
|
||||
char* spice_subckt_file_name_prefix,
|
||||
int grid_x, int grid_y,
|
||||
char** sp_name);
|
||||
|
||||
void spice_print_one_include_subckt_line(FILE* fp,
|
||||
char* subckt_dir,
|
||||
char* subckt_file_name);
|
||||
|
||||
int rec_fprint_spice_model_global_ports(FILE* fp,
|
||||
t_spice_model* cur_spice_model,
|
||||
boolean recursive);
|
||||
|
||||
void spice_print_subckt_header_file(t_llist* subckt_llist_head,
|
||||
char* subckt_dir,
|
||||
char* header_file_name);
|
||||
|
||||
int fprint_spice_global_ports(FILE* fp, t_llist* head);
|
||||
|
||||
void fprint_spice_generic_testbench_global_ports(FILE* fp,
|
||||
|
|
|
@ -8,6 +8,8 @@
|
|||
#include "fpga_spice_globals.h"
|
||||
#include "verilog_global.h"
|
||||
|
||||
char* verilog_netlist_file_postfix = ".v";
|
||||
|
||||
char* verilog_top_postfix = "_top.v";
|
||||
char* bitstream_verilog_file_postfix = ".bitstream";
|
||||
char* top_testbench_verilog_file_postfix = "_top_tb.v";
|
||||
|
@ -23,6 +25,14 @@ char* decoders_verilog_file_name = "decoders.v";
|
|||
char* verilog_mux_basis_posfix = "_basis";
|
||||
char* verilog_mux_special_basis_posfix = "_special_basis";
|
||||
|
||||
/* Prefix for subckt Verilog netlists */
|
||||
char* grid_verilog_file_name_prefix = "grid_";
|
||||
char* chanx_verilog_file_name_prefix = "chanx_";
|
||||
char* chany_verilog_file_name_prefix = "chany_";
|
||||
char* sb_verilog_file_name_prefix = "sb_";
|
||||
char* cbx_verilog_file_name_prefix = "cbx_";
|
||||
char* cby_verilog_file_name_prefix = "cby_";
|
||||
|
||||
/* SRAM SPICE MODEL should be set as global*/
|
||||
t_spice_model* sram_verilog_model = NULL;
|
||||
enum e_sram_orgz sram_verilog_orgz_type = SPICE_SRAM_STANDALONE;
|
||||
|
@ -34,4 +44,8 @@ t_spice_model* iopad_verilog_model = NULL;
|
|||
/* Linked-list that stores all the configuration bits */
|
||||
t_llist* conf_bits_head = NULL;
|
||||
|
||||
/* Linked-list that stores submodule Verilog file mames */
|
||||
t_llist* grid_verilog_subckt_file_path_head = NULL;
|
||||
t_llist* routing_verilog_subckt_file_path_head = NULL;
|
||||
|
||||
int verilog_default_signal_init_value = 0;
|
||||
|
|
|
@ -1,4 +1,7 @@
|
|||
/* global parameters for dumping synthesizable verilog */
|
||||
|
||||
extern char* verilog_netlist_file_postfix;
|
||||
|
||||
extern char* verilog_top_postfix;
|
||||
extern char* bitstream_verilog_file_postfix;
|
||||
extern char* top_testbench_verilog_file_postfix;
|
||||
|
@ -13,6 +16,14 @@ extern char* decoders_verilog_file_name;
|
|||
extern char* verilog_mux_basis_posfix;
|
||||
extern char* verilog_mux_special_basis_posfix;
|
||||
|
||||
/* Prefix for subckt Verilog netlists */
|
||||
extern char* grid_verilog_file_name_prefix;
|
||||
extern char* chanx_verilog_file_name_prefix;
|
||||
extern char* chany_verilog_file_name_prefix;
|
||||
extern char* sb_verilog_file_name_prefix;
|
||||
extern char* cbx_verilog_file_name_prefix;
|
||||
extern char* cby_verilog_file_name_prefix;
|
||||
|
||||
extern t_spice_model* sram_verilog_model;
|
||||
extern enum e_sram_orgz sram_verilog_orgz_type;
|
||||
extern t_sram_orgz_info* sram_verilog_orgz_info;
|
||||
|
@ -25,6 +36,10 @@ extern t_spice_model* iopad_verilog_model;
|
|||
/* Linked-list that stores all the configuration bits */
|
||||
extern t_llist* conf_bits_head;
|
||||
|
||||
/* Linked-list that stores submodule Verilog file mames */
|
||||
extern t_llist* grid_verilog_subckt_file_path_head;
|
||||
extern t_llist* routing_verilog_subckt_file_path_head;
|
||||
|
||||
extern int verilog_default_signal_init_value;
|
||||
|
||||
enum e_dump_verilog_port_type {
|
||||
|
|
|
@ -3135,10 +3135,9 @@ void dump_verilog_io_grid_block_subckt_pins(FILE* fp,
|
|||
}
|
||||
|
||||
/* Print the SPICE netlist for a grid blocks */
|
||||
void dump_verilog_grid_blocks(FILE* fp,
|
||||
int ix,
|
||||
int iy,
|
||||
t_arch* arch) {
|
||||
void dump_verilog_grid_blocks(char* subckt_dir,
|
||||
int ix, int iy,
|
||||
t_arch* arch) {
|
||||
int subckt_name_str_len = 0;
|
||||
char* subckt_name = NULL;
|
||||
t_block* mapped_block = NULL;
|
||||
|
@ -3152,13 +3151,9 @@ void dump_verilog_grid_blocks(FILE* fp,
|
|||
int temp_inpad_lsb, temp_inpad_msb;
|
||||
int temp_outpad_lsb, temp_outpad_msb;
|
||||
int temp_iopad_lsb, temp_iopad_msb;
|
||||
FILE* fp = NULL;
|
||||
char* fname = NULL;
|
||||
|
||||
/* Check the file handler*/
|
||||
if (NULL == fp) {
|
||||
vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid file handler.\n",
|
||||
__FILE__, __LINE__);
|
||||
exit(1);
|
||||
}
|
||||
/* Check */
|
||||
assert((!(0 > ix))&&(!(ix > (nx + 1))));
|
||||
assert((!(0 > iy))&&(!(iy > (ny + 1))));
|
||||
|
@ -3179,6 +3174,10 @@ void dump_verilog_grid_blocks(FILE* fp,
|
|||
update_spice_models_grid_index_high(ix, iy, arch->spice->num_spice_model, arch->spice->spice_models);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Create file handler */
|
||||
fp = verilog_create_one_subckt_file(subckt_dir, "Logic Block ", grid_verilog_file_name_prefix, ix, iy, &fname);
|
||||
|
||||
capacity= grid[ix][iy].type->capacity;
|
||||
assert(0 < capacity);
|
||||
|
||||
|
@ -3336,16 +3335,22 @@ void dump_verilog_grid_blocks(FILE* fp,
|
|||
|
||||
assert(temp_conf_bits_msb == get_sram_orgz_info_num_mem_bit(sram_verilog_orgz_info));
|
||||
|
||||
/* Close file*/
|
||||
fclose(fp);
|
||||
|
||||
/* Add fname to the linked list */
|
||||
grid_verilog_subckt_file_path_head = add_one_subckt_file_name_to_llist(grid_verilog_subckt_file_path_head, fname);
|
||||
|
||||
/* Free */
|
||||
my_free(subckt_name);
|
||||
my_free(fname);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* Print the SPICE netlist for a I/O grid blocks */
|
||||
void dump_verilog_physical_grid_blocks(FILE* fp,
|
||||
int ix,
|
||||
int iy,
|
||||
void dump_verilog_physical_grid_blocks(char* subckt_dir,
|
||||
int ix, int iy,
|
||||
t_arch* arch) {
|
||||
int subckt_name_str_len = 0;
|
||||
char* subckt_name = NULL;
|
||||
|
@ -3357,13 +3362,9 @@ void dump_verilog_physical_grid_blocks(FILE* fp,
|
|||
int temp_inpad_lsb, temp_inpad_msb;
|
||||
int temp_outpad_lsb, temp_outpad_msb;
|
||||
int temp_iopad_lsb, temp_iopad_msb;
|
||||
FILE* fp = NULL;
|
||||
char* fname = NULL;
|
||||
|
||||
/* Check the file handler*/
|
||||
if (NULL == fp) {
|
||||
vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid file handler.\n",
|
||||
__FILE__, __LINE__);
|
||||
exit(1);
|
||||
}
|
||||
/* Check */
|
||||
assert((!(0 > ix))&&(!(ix > (nx + 1))));
|
||||
assert((!(0 > iy))&&(!(iy > (ny + 1))));
|
||||
|
@ -3384,6 +3385,10 @@ void dump_verilog_physical_grid_blocks(FILE* fp,
|
|||
update_spice_models_grid_index_high(ix, iy, arch->spice->num_spice_model, arch->spice->spice_models);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Create file handler */
|
||||
fp = verilog_create_one_subckt_file(subckt_dir, "Physical Logic Block ", grid_verilog_file_name_prefix, ix, iy, &fname);
|
||||
|
||||
capacity= grid[ix][iy].type->capacity;
|
||||
assert(0 < capacity);
|
||||
|
||||
|
@ -3520,8 +3525,15 @@ void dump_verilog_physical_grid_blocks(FILE* fp,
|
|||
assert(temp_conf_bits_msb == get_sram_orgz_info_num_mem_bit(sram_verilog_orgz_info));
|
||||
assert(temp_iopad_msb == iopad_verilog_model->grid_index_high[ix][iy]);
|
||||
|
||||
/* Close the file */
|
||||
fclose(fp);
|
||||
|
||||
/* Add fname to the linked list */
|
||||
grid_verilog_subckt_file_path_head = add_one_subckt_file_name_to_llist(grid_verilog_subckt_file_path_head, fname);
|
||||
|
||||
/* Free */
|
||||
my_free(subckt_name);
|
||||
my_free(fname);
|
||||
|
||||
return;
|
||||
}
|
||||
|
@ -3533,9 +3545,6 @@ void dump_verilog_physical_grid_blocks(FILE* fp,
|
|||
*/
|
||||
void dump_verilog_logic_blocks(char* subckt_dir,
|
||||
t_arch* arch) {
|
||||
/* Create file names */
|
||||
char* sp_name = my_strcat(subckt_dir, logic_block_verilog_file_name);
|
||||
FILE* fp = NULL;
|
||||
int ix, iy;
|
||||
|
||||
/* Check the grid*/
|
||||
|
@ -3543,18 +3552,10 @@ void dump_verilog_logic_blocks(char* subckt_dir,
|
|||
vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid grid size (nx=%d, ny=%d)!\n", __FILE__, __LINE__, nx, ny);
|
||||
return;
|
||||
}
|
||||
|
||||
vpr_printf(TIO_MESSAGE_INFO,"Grid size of FPGA: nx=%d ny=%d\n", nx + 1, ny + 1);
|
||||
assert(NULL != grid);
|
||||
|
||||
/* Create a file*/
|
||||
fp = fopen(sp_name, "w");
|
||||
if (NULL == fp) {
|
||||
vpr_printf(TIO_MESSAGE_ERROR,"(FILE:%s,LINE[%d])Failure in create verilog netlist %s",__FILE__, __LINE__, sp_name);
|
||||
exit(1);
|
||||
}
|
||||
/* Generate the descriptions*/
|
||||
dump_verilog_file_header(fp,"Logic Blocks in FPGA");
|
||||
|
||||
/* Print the core logic block one by one
|
||||
* Note ix=0 and ix = nx + 1 are IO pads. They surround the core logic blocks
|
||||
*/
|
||||
|
@ -3565,7 +3566,7 @@ void dump_verilog_logic_blocks(char* subckt_dir,
|
|||
assert(IO_TYPE != grid[ix][iy].type);
|
||||
/* Ensure a valid usage */
|
||||
assert((0 == grid[ix][iy].usage)||(0 < grid[ix][iy].usage));
|
||||
dump_verilog_grid_blocks(fp, ix, iy, arch);
|
||||
dump_verilog_grid_blocks(subckt_dir, ix, iy, arch);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3576,36 +3577,37 @@ void dump_verilog_logic_blocks(char* subckt_dir,
|
|||
for (iy = 1; iy < (ny + 1); iy++) {
|
||||
/* Ensure this is a io */
|
||||
assert(IO_TYPE == grid[ix][iy].type);
|
||||
dump_verilog_physical_grid_blocks(fp, ix, iy, arch);
|
||||
dump_verilog_physical_grid_blocks(subckt_dir, ix, iy, arch);
|
||||
}
|
||||
/* Right side : x = nx + 1, y = 1 .. ny*/
|
||||
ix = nx + 1;
|
||||
for (iy = 1; iy < (ny + 1); iy++) {
|
||||
/* Ensure this is a io */
|
||||
assert(IO_TYPE == grid[ix][iy].type);
|
||||
dump_verilog_physical_grid_blocks(fp, ix, iy, arch);
|
||||
dump_verilog_physical_grid_blocks(subckt_dir, ix, iy, arch);
|
||||
}
|
||||
/* Bottom side : x = 1 .. nx + 1, y = 0 */
|
||||
iy = 0;
|
||||
for (ix = 1; ix < (nx + 1); ix++) {
|
||||
/* Ensure this is a io */
|
||||
assert(IO_TYPE == grid[ix][iy].type);
|
||||
dump_verilog_physical_grid_blocks(fp, ix, iy, arch);
|
||||
dump_verilog_physical_grid_blocks(subckt_dir, ix, iy, arch);
|
||||
}
|
||||
/* Top side : x = 1 .. nx + 1, y = nx + 1 */
|
||||
iy = ny + 1;
|
||||
for (ix = 1; ix < (nx + 1); ix++) {
|
||||
/* Ensure this is a io */
|
||||
assert(IO_TYPE == grid[ix][iy].type);
|
||||
dump_verilog_physical_grid_blocks(fp, ix, iy, arch);
|
||||
dump_verilog_physical_grid_blocks(subckt_dir, ix, iy, arch);
|
||||
}
|
||||
|
||||
|
||||
/* Close the file */
|
||||
fclose(fp);
|
||||
/* Output a header file for all the logic blocks */
|
||||
vpr_printf(TIO_MESSAGE_INFO,"Generating header file for grid submodules...\n");
|
||||
dump_verilog_subckt_header_file(grid_verilog_subckt_file_path_head,
|
||||
subckt_dir,
|
||||
logic_block_verilog_file_name);
|
||||
|
||||
/* Free */
|
||||
my_free(sp_name);
|
||||
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -34,7 +34,7 @@
|
|||
#include "verilog_routing.h"
|
||||
|
||||
|
||||
void dump_verilog_routing_chan_subckt(FILE* fp,
|
||||
void dump_verilog_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,
|
||||
|
@ -44,13 +44,9 @@ void dump_verilog_routing_chan_subckt(FILE* fp,
|
|||
char* chan_prefix = NULL;
|
||||
int chan_width = 0;
|
||||
t_rr_node** chan_rr_nodes = NULL;
|
||||
FILE* fp = NULL;
|
||||
char* fname = NULL;
|
||||
|
||||
/* Check the file handler*/
|
||||
if (NULL == fp) {
|
||||
vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid file handler.\n",
|
||||
__FILE__, __LINE__);
|
||||
exit(1);
|
||||
}
|
||||
/* Check */
|
||||
assert((!(0 > x))&&(!(x > (nx + 1))));
|
||||
assert((!(0 > y))&&(!(y > (ny + 1))));
|
||||
|
@ -59,11 +55,15 @@ void dump_verilog_routing_chan_subckt(FILE* fp,
|
|||
/* Initial chan_prefix*/
|
||||
switch (chan_type) {
|
||||
case CHANX:
|
||||
/* Create file handler */
|
||||
fp = verilog_create_one_subckt_file(subckt_dir, "Routing Channel - X direction ", chanx_verilog_file_name_prefix, x, y, &fname);
|
||||
chan_prefix = "chanx";
|
||||
/* Comment lines */
|
||||
fprintf(fp, "//----- Verilog Module of Channel X [%d][%d] -----\n", x, y);
|
||||
break;
|
||||
case CHANY:
|
||||
/* Create file handler */
|
||||
fp = verilog_create_one_subckt_file(subckt_dir, "Routing Channel - Y direction ", chany_verilog_file_name_prefix, x, y, &fname);
|
||||
chan_prefix = "chany";
|
||||
/* Comment lines */
|
||||
fprintf(fp, "//----- Verilog Module Channel Y [%d][%d] -----\n", x, y);
|
||||
|
@ -162,9 +162,16 @@ void dump_verilog_routing_chan_subckt(FILE* fp,
|
|||
exit(1);
|
||||
}
|
||||
|
||||
/* Close file handler */
|
||||
fclose(fp);
|
||||
|
||||
/* Add fname to the linked list */
|
||||
routing_verilog_subckt_file_path_head = add_one_subckt_file_name_to_llist(routing_verilog_subckt_file_path_head, fname);
|
||||
|
||||
/* Free */
|
||||
my_free(chan_rr_nodes);
|
||||
|
||||
my_free(fname);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1056,18 +1063,13 @@ int count_verilog_switch_box_conf_bits(t_sb* cur_sb_info) {
|
|||
* | | | |
|
||||
* -------------- --------------
|
||||
*/
|
||||
void dump_verilog_routing_switch_box_subckt(FILE* fp, t_sb* cur_sb_info,
|
||||
void dump_verilog_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) {
|
||||
int itrack, inode, side, ix, iy, x, y;
|
||||
int cur_num_sram, num_conf_bits, num_reserved_conf_bits, esti_sram_cnt;
|
||||
|
||||
/* Check the file handler*/
|
||||
if (NULL == fp) {
|
||||
vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid file handler.\n",
|
||||
__FILE__, __LINE__);
|
||||
exit(1);
|
||||
}
|
||||
FILE* fp = NULL;
|
||||
char* fname = NULL;
|
||||
|
||||
/* Check */
|
||||
assert((!(0 > cur_sb_info->x))&&(!(cur_sb_info->x > (nx + 1))));
|
||||
|
@ -1088,6 +1090,9 @@ void dump_verilog_routing_switch_box_subckt(FILE* fp, t_sb* cur_sb_info,
|
|||
cur_sb_info->conf_bits_lsb = cur_num_sram;
|
||||
cur_sb_info->conf_bits_msb = cur_num_sram + num_conf_bits;
|
||||
|
||||
/* Create file handler */
|
||||
fp = verilog_create_one_subckt_file(subckt_dir, "Switch Block ", sb_verilog_file_name_prefix, cur_sb_info->x, cur_sb_info->y, &fname);
|
||||
|
||||
/* Comment lines */
|
||||
fprintf(fp, "//----- Verilog Module of Switch Box[%d][%d] -----\n", cur_sb_info->x, cur_sb_info->y);
|
||||
/* Print the definition of subckt*/
|
||||
|
@ -1175,7 +1180,14 @@ void dump_verilog_routing_switch_box_subckt(FILE* fp, t_sb* cur_sb_info,
|
|||
/* Check */
|
||||
assert(esti_sram_cnt == get_sram_orgz_info_num_mem_bit(sram_verilog_orgz_info));
|
||||
|
||||
/* Close file handler */
|
||||
fclose(fp);
|
||||
|
||||
/* Add fname to the linked list */
|
||||
routing_verilog_subckt_file_path_head = add_one_subckt_file_name_to_llist(routing_verilog_subckt_file_path_head, fname);
|
||||
|
||||
/* Free chan_rr_nodes */
|
||||
my_free(fname);
|
||||
|
||||
return;
|
||||
}
|
||||
|
@ -1640,20 +1652,15 @@ int count_verilog_connection_box_reserved_conf_bits(t_cb* cur_cb_info) {
|
|||
* | | Connection | |
|
||||
* --------------Box_Y[x][y-1]--------------
|
||||
*/
|
||||
void dump_verilog_routing_connection_box_subckt(FILE* fp, t_cb* cur_cb_info,
|
||||
void dump_verilog_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) {
|
||||
int itrack, inode, side, x, y;
|
||||
int side_cnt = 0;
|
||||
|
||||
FILE* fp = NULL;
|
||||
char* fname = NULL;
|
||||
int cur_num_sram, num_conf_bits, num_reserved_conf_bits, esti_sram_cnt;
|
||||
|
||||
/* Check the file handler*/
|
||||
if (NULL == fp) {
|
||||
vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid file handler.\n",
|
||||
__FILE__, __LINE__);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* Check */
|
||||
assert((!(0 > cur_cb_info->x))&&(!(cur_cb_info->x > (nx + 1))));
|
||||
assert((!(0 > cur_cb_info->y))&&(!(cur_cb_info->y > (ny + 1))));
|
||||
|
@ -1665,12 +1672,16 @@ void dump_verilog_routing_connection_box_subckt(FILE* fp, t_cb* cur_cb_info,
|
|||
/* Identify the type of connection box */
|
||||
switch(cur_cb_info->type) {
|
||||
case CHANX:
|
||||
/* Create file handler */
|
||||
fp = verilog_create_one_subckt_file(subckt_dir, "Connection Block - X direction ", cbx_verilog_file_name_prefix, cur_cb_info->x, cur_cb_info->y, &fname);
|
||||
/* Comment lines */
|
||||
fprintf(fp, "//----- Verilog Module of Connection Box -X direction [%d][%d] -----\n", x, y);
|
||||
fprintf(fp, "module ");
|
||||
fprintf(fp, "cbx_%d__%d_ ", cur_cb_info->x, cur_cb_info->y);
|
||||
break;
|
||||
case CHANY:
|
||||
/* Create file handler */
|
||||
fp = verilog_create_one_subckt_file(subckt_dir, "Connection Block - Y direction ", cby_verilog_file_name_prefix, cur_cb_info->x, cur_cb_info->y, &fname);
|
||||
/* Comment lines */
|
||||
fprintf(fp, "//----- Verilog Module of Connection Box -Y direction [%d][%d] -----\n", x, y);
|
||||
fprintf(fp, "module ");
|
||||
|
@ -1804,12 +1815,18 @@ void dump_verilog_routing_connection_box_subckt(FILE* fp, t_cb* cur_cb_info,
|
|||
/* Check */
|
||||
assert(esti_sram_cnt == get_sram_orgz_info_num_mem_bit(sram_verilog_orgz_info));
|
||||
|
||||
/* Close file handler */
|
||||
fclose(fp);
|
||||
|
||||
/* Add fname to the linked list */
|
||||
routing_verilog_subckt_file_path_head = add_one_subckt_file_name_to_llist(routing_verilog_subckt_file_path_head, fname);
|
||||
|
||||
/* Free */
|
||||
my_free(fname);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/* Top Function*/
|
||||
/* Build the routing resource SPICE sub-circuits*/
|
||||
void dump_verilog_routing_resources(char* subckt_dir,
|
||||
|
@ -1817,19 +1834,9 @@ void dump_verilog_routing_resources(char* subckt_dir,
|
|||
t_det_routing_arch* routing_arch,
|
||||
int LL_num_rr_nodes, t_rr_node* LL_rr_node,
|
||||
t_ivec*** LL_rr_node_indices) {
|
||||
FILE* fp = NULL;
|
||||
char* verilog_name = my_strcat(subckt_dir, routing_verilog_file_name);
|
||||
int ix, iy;
|
||||
|
||||
assert(UNI_DIRECTIONAL == routing_arch->directionality);
|
||||
|
||||
/* Create FILE */
|
||||
fp = fopen(verilog_name, "w");
|
||||
if (NULL == fp) {
|
||||
vpr_printf(TIO_MESSAGE_ERROR,"(FILE:%s,LINE[%d])Failure in create verilog netlist %s",__FILE__, __LINE__, routing_verilog_file_name);
|
||||
exit(1);
|
||||
}
|
||||
dump_verilog_file_header(fp,"Routing Resources");
|
||||
|
||||
/* Two major tasks:
|
||||
* 1. Generate sub-circuits for Routing Channels
|
||||
|
@ -1853,7 +1860,7 @@ void dump_verilog_routing_resources(char* subckt_dir,
|
|||
vpr_printf(TIO_MESSAGE_INFO, "Writing X-direction Channels...\n");
|
||||
for (iy = 0; iy < (ny + 1); iy++) {
|
||||
for (ix = 1; ix < (nx + 1); ix++) {
|
||||
dump_verilog_routing_chan_subckt(fp, ix, iy, CHANX,
|
||||
dump_verilog_routing_chan_subckt(subckt_dir, ix, iy, CHANX,
|
||||
LL_num_rr_nodes, LL_rr_node, LL_rr_node_indices,
|
||||
arch.num_segments, arch.Segments);
|
||||
}
|
||||
|
@ -1862,7 +1869,7 @@ void dump_verilog_routing_resources(char* subckt_dir,
|
|||
vpr_printf(TIO_MESSAGE_INFO, "Writing Y-direction Channels...\n");
|
||||
for (ix = 0; ix < (nx + 1); ix++) {
|
||||
for (iy = 1; iy < (ny + 1); iy++) {
|
||||
dump_verilog_routing_chan_subckt(fp, ix, iy, CHANY,
|
||||
dump_verilog_routing_chan_subckt(subckt_dir, ix, iy, CHANY,
|
||||
LL_num_rr_nodes, LL_rr_node, LL_rr_node_indices,
|
||||
arch.num_segments, arch.Segments);
|
||||
}
|
||||
|
@ -1873,7 +1880,7 @@ void dump_verilog_routing_resources(char* subckt_dir,
|
|||
for (iy = 0; iy < (ny + 1); 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]),
|
||||
dump_verilog_routing_switch_box_subckt(subckt_dir, &(sb_info[ix][iy]),
|
||||
LL_num_rr_nodes, LL_rr_node, LL_rr_node_indices);
|
||||
update_spice_models_routing_index_high(ix, iy, SOURCE, arch.spice->num_spice_model, arch.spice->spice_models);
|
||||
}
|
||||
|
@ -1887,7 +1894,7 @@ void dump_verilog_routing_resources(char* subckt_dir,
|
|||
update_spice_models_routing_index_low(ix, iy, CHANX, arch.spice->num_spice_model, arch.spice->spice_models);
|
||||
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]),
|
||||
dump_verilog_routing_connection_box_subckt(subckt_dir, &(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);
|
||||
|
@ -1900,15 +1907,18 @@ void dump_verilog_routing_resources(char* subckt_dir,
|
|||
update_spice_models_routing_index_low(ix, iy, CHANY, arch.spice->num_spice_model, arch.spice->spice_models);
|
||||
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]),
|
||||
dump_verilog_routing_connection_box_subckt(subckt_dir, &(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);
|
||||
}
|
||||
}
|
||||
|
||||
/* Close the file*/
|
||||
fclose(fp);
|
||||
|
||||
/* Output a header file for all the routing blocks */
|
||||
vpr_printf(TIO_MESSAGE_INFO,"Generating header file for routing submodules...\n");
|
||||
dump_verilog_subckt_header_file(routing_verilog_subckt_file_path_head,
|
||||
subckt_dir,
|
||||
routing_verilog_file_name);
|
||||
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -2759,6 +2759,115 @@ void dump_verilog_top_netlist(char* circuit_name,
|
|||
return;
|
||||
}
|
||||
|
||||
/***** Print Top-level SPICE netlist *****/
|
||||
void dump_verilog_top_netlist_tile_orgz(char* circuit_name,
|
||||
char* top_netlist_name,
|
||||
char* include_dir_path,
|
||||
char* subckt_dir_path,
|
||||
int LL_num_rr_nodes,
|
||||
t_rr_node* LL_rr_node,
|
||||
t_ivec*** LL_rr_node_indices,
|
||||
int num_clock,
|
||||
t_spice verilog) {
|
||||
FILE* fp = NULL;
|
||||
char* formatted_subckt_dir_path = format_dir_path(subckt_dir_path);
|
||||
char* temp_include_file_path = NULL;
|
||||
char* title = my_strcat("FPGA Verilog Netlist for Design: ", circuit_name);
|
||||
|
||||
/* Check if the path exists*/
|
||||
fp = fopen(top_netlist_name,"w");
|
||||
if (NULL == fp) {
|
||||
vpr_printf(TIO_MESSAGE_ERROR,"(FILE:%s,LINE[%d])Failure in create top Verilog netlist %s!",__FILE__, __LINE__, top_netlist_name);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
vpr_printf(TIO_MESSAGE_INFO, "Writing FPGA Top-level Verilog Netlist for %s...\n", circuit_name);
|
||||
|
||||
/* Print the title */
|
||||
dump_verilog_file_header(fp, title);
|
||||
my_free(title);
|
||||
|
||||
/* Include user-defined sub-circuit netlist */
|
||||
fprintf(fp, "//----- Include User-defined netlists -----\n");
|
||||
init_include_user_defined_verilog_netlists(verilog);
|
||||
dump_include_user_defined_verilog_netlists(fp, verilog);
|
||||
|
||||
/* Special subckts for Top-level SPICE netlist */
|
||||
fprintf(fp, "//----- Include subckt netlists: Multiplexers -----\n");
|
||||
temp_include_file_path = my_strcat(formatted_subckt_dir_path, muxes_verilog_file_name);
|
||||
fprintf(fp, "// `include \"%s\"\n", temp_include_file_path);
|
||||
my_free(temp_include_file_path);
|
||||
|
||||
fprintf(fp, "//----- Include subckt netlists: Wires -----\n");
|
||||
temp_include_file_path = my_strcat(formatted_subckt_dir_path, wires_verilog_file_name);
|
||||
fprintf(fp, "// `include \"%s\"\n", temp_include_file_path);
|
||||
my_free(temp_include_file_path);
|
||||
|
||||
fprintf(fp, "//----- Include subckt netlists: Look-Up Tables (LUTs) -----\n");
|
||||
temp_include_file_path = my_strcat(formatted_subckt_dir_path, luts_verilog_file_name);
|
||||
fprintf(fp, "// `include \"%s\"\n", temp_include_file_path);
|
||||
my_free(temp_include_file_path);
|
||||
|
||||
fprintf(fp, "//------ Include subckt netlists: Logic Blocks -----\n");
|
||||
temp_include_file_path = my_strcat(formatted_subckt_dir_path, logic_block_verilog_file_name);
|
||||
fprintf(fp, "// `include \"%s\"\n", temp_include_file_path);
|
||||
my_free(temp_include_file_path);
|
||||
|
||||
fprintf(fp, "//----- Include subckt netlists: Routing structures (Switch Boxes, Channels, Connection Boxes) -----\n");
|
||||
temp_include_file_path = my_strcat(formatted_subckt_dir_path, routing_verilog_file_name);
|
||||
fprintf(fp, "// `include \"%s\"\n", temp_include_file_path);
|
||||
my_free(temp_include_file_path);
|
||||
|
||||
/* Include decoders if required */
|
||||
switch(sram_verilog_orgz_type) {
|
||||
case SPICE_SRAM_STANDALONE:
|
||||
case SPICE_SRAM_SCAN_CHAIN:
|
||||
break;
|
||||
case SPICE_SRAM_MEMORY_BANK:
|
||||
/* Include verilog decoder */
|
||||
fprintf(fp, "//----- Include subckt netlists: Decoders (controller for memeory bank) -----\n");
|
||||
temp_include_file_path = my_strcat(formatted_subckt_dir_path, decoders_verilog_file_name);
|
||||
fprintf(fp, "// `include \"%s\"\n", temp_include_file_path);
|
||||
my_free(temp_include_file_path);
|
||||
break;
|
||||
default:
|
||||
vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid type of SRAM organization in Verilog Generator!\n",
|
||||
__FILE__, __LINE__);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* Print all global wires*/
|
||||
dump_verilog_top_netlist_ports(fp, num_clock, circuit_name, verilog);
|
||||
|
||||
dump_verilog_top_netlist_internal_wires(fp);
|
||||
|
||||
/* Quote defined Logic blocks subckts (Grids) */
|
||||
dump_verilog_defined_grids(fp);
|
||||
|
||||
/* Quote Routing structures: Channels */
|
||||
dump_verilog_defined_channels(fp, LL_num_rr_nodes, LL_rr_node, LL_rr_node_indices);
|
||||
|
||||
/* Quote Routing structures: Conneciton Boxes */
|
||||
dump_verilog_defined_connection_boxes(fp);
|
||||
|
||||
/* Quote Routing structures: Switch Boxes */
|
||||
dump_verilog_defined_switch_boxes(fp);
|
||||
|
||||
/* Apply CLB to CLB direct connections */
|
||||
dump_verilog_clb2clb_directs(fp, num_clb2clb_directs, clb2clb_direct);
|
||||
|
||||
/* Dump configuration circuits */
|
||||
dump_verilog_configuration_circuits(fp);
|
||||
|
||||
/* verilog ends*/
|
||||
fprintf(fp, "endmodule\n");
|
||||
|
||||
/* Close the file*/
|
||||
fclose(fp);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/** Top level function 2: Testbench for the top-level netlist
|
||||
* This testbench includes a top-level module of a mapped FPGA and voltage pulses
|
||||
*/
|
||||
|
|
|
@ -9,6 +9,16 @@ void dump_verilog_top_netlist(char* circuit_name,
|
|||
int num_clock,
|
||||
t_spice spice);
|
||||
|
||||
void dump_verilog_top_netlist_tile_orgz(char* circuit_name,
|
||||
char* top_netlist_name,
|
||||
char* include_dir_path,
|
||||
char* subckt_dir_path,
|
||||
int LL_num_rr_nodes,
|
||||
t_rr_node* LL_rr_node,
|
||||
t_ivec*** LL_rr_node_indices,
|
||||
int num_clock,
|
||||
t_spice verilog);
|
||||
|
||||
void dump_verilog_top_testbench(char* circuit_name,
|
||||
char* top_netlist_name,
|
||||
int num_clock,
|
||||
|
|
|
@ -161,6 +161,85 @@ void dump_verilog_file_header(FILE* fp,
|
|||
return;
|
||||
}
|
||||
|
||||
/* Create a file handler for a subckt Verilog netlist */
|
||||
FILE* verilog_create_one_subckt_file(char* subckt_dir,
|
||||
char* subckt_name_prefix,
|
||||
char* verilog_subckt_file_name_prefix,
|
||||
int grid_x, int grid_y,
|
||||
char** verilog_fname) {
|
||||
FILE* fp = NULL;
|
||||
char* file_description = NULL;
|
||||
|
||||
(*verilog_fname) = my_strcat(subckt_dir,
|
||||
fpga_spice_create_one_subckt_filename(verilog_subckt_file_name_prefix, grid_x, grid_y, verilog_netlist_file_postfix));
|
||||
|
||||
/* Create a file*/
|
||||
fp = fopen((*verilog_fname), "w");
|
||||
|
||||
if (NULL == fp) {
|
||||
vpr_printf(TIO_MESSAGE_ERROR,
|
||||
"(FILE:%s,LINE[%d])Failure in create Verilog netlist %s",
|
||||
__FILE__, __LINE__, (*verilog_fname));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* Generate the descriptions*/
|
||||
file_description = (char*) my_malloc(sizeof(char) * (strlen(subckt_name_prefix) + 2
|
||||
+ strlen(my_itoa(grid_x)) + 2 + strlen(my_itoa(grid_y))
|
||||
+ 9));
|
||||
sprintf(file_description, "%s [%d][%d] in FPGA",
|
||||
subckt_name_prefix, grid_x, grid_y);
|
||||
dump_verilog_file_header(fp, file_description);
|
||||
|
||||
/* Free */
|
||||
my_free(file_description);
|
||||
|
||||
return fp;
|
||||
}
|
||||
|
||||
/* Output all the created subckt file names in a header file,
|
||||
* that can be easily imported in a top-level netlist
|
||||
*/
|
||||
void dump_verilog_subckt_header_file(t_llist* subckt_llist_head,
|
||||
char* subckt_dir,
|
||||
char* header_file_name) {
|
||||
FILE* fp = NULL;
|
||||
char* verilog_fname = NULL;
|
||||
t_llist* temp = NULL;
|
||||
|
||||
verilog_fname = my_strcat(subckt_dir,
|
||||
header_file_name);
|
||||
|
||||
/* Create a file*/
|
||||
fp = fopen(verilog_fname, "w");
|
||||
|
||||
if (NULL == fp) {
|
||||
vpr_printf(TIO_MESSAGE_ERROR,
|
||||
"(FILE:%s,LINE[%d])Failure in create Verilog netlist %s",
|
||||
__FILE__, __LINE__, verilog_fname);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* Generate the descriptions*/
|
||||
dump_verilog_file_header(fp, "Header file");
|
||||
|
||||
/* Output file names */
|
||||
temp = subckt_llist_head;
|
||||
while (temp) {
|
||||
fprintf(fp, "`include \"%s\"\n",
|
||||
(char*)(temp->dptr));
|
||||
temp = temp->next;
|
||||
}
|
||||
|
||||
/* Close fp */
|
||||
fclose(fp);
|
||||
|
||||
/* Free */
|
||||
my_free(verilog_fname);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* Determine the split sign for generic port */
|
||||
char determine_verilog_generic_port_split_sign(enum e_dump_verilog_port_type dump_port_type) {
|
||||
char ret;
|
||||
|
|
|
@ -10,6 +10,16 @@ void dump_include_user_defined_verilog_netlists(FILE* fp,
|
|||
void dump_verilog_file_header(FILE* fp,
|
||||
char* usage);
|
||||
|
||||
FILE* verilog_create_one_subckt_file(char* subckt_dir,
|
||||
char* subckt_name_prefix,
|
||||
char* verilog_subckt_file_name_prefix,
|
||||
int grid_x, int grid_y,
|
||||
char** verilog_fname);
|
||||
|
||||
void dump_verilog_subckt_header_file(t_llist* subckt_llist_head,
|
||||
char* subckt_dir,
|
||||
char* header_file_name);
|
||||
|
||||
char determine_verilog_generic_port_split_sign(enum e_dump_verilog_port_type dump_port_type);
|
||||
|
||||
void dump_verilog_generic_port(FILE* fp,
|
||||
|
|
Loading…
Reference in New Issue