Upload recent commit
Merge remote-tracking branch 'origin/dev' into heterogeneous
This commit is contained in:
commit
e13c703709
|
@ -20,6 +20,7 @@ my $mydate = gmctime();
|
|||
my $cwd = getcwd();
|
||||
|
||||
# Global Variants
|
||||
my ($max_route_width_retry) = (1000);
|
||||
# input Option Hash
|
||||
my %opt_h;
|
||||
my $opt_ptr = \%opt_h;
|
||||
|
@ -112,7 +113,7 @@ sub generate_path($)
|
|||
mkpath "$mypath";
|
||||
print "Path($mypath) does not exist...Create it.\n";
|
||||
}
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
# Print the usage
|
||||
|
@ -127,6 +128,7 @@ sub print_usage()
|
|||
print " -N <int> : N-LUT/Matrix\n";
|
||||
print " Other Options:\n";
|
||||
print " [ General ] \n";
|
||||
print " \t-matlab_rpt <data_name> : .m file consists of data compatible to matlab scripts. Specify the data name to be appeared in the script\n";
|
||||
print " \t-I <int> : Number of inputs of a CLB, mandatory when mpack1 flow is chosen\n";
|
||||
print " \t-K <int> : K-LUT, mandatory when standard flow is chosen\n";
|
||||
print " \t-M <int> : M-Matrix, mandatory when mpack1 flow is chosen\n";
|
||||
|
@ -269,7 +271,7 @@ sub read_opt_into_hash($ $ $)
|
|||
}
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
# Read options
|
||||
|
@ -307,6 +309,7 @@ sub opts_read()
|
|||
&read_opt_into_hash("conf","on","on");
|
||||
&read_opt_into_hash("benchmark","on","on");
|
||||
&read_opt_into_hash("rpt","on","on");
|
||||
&read_opt_into_hash("matlab_rpt","on","off"); # Add an option to output report file compatible to matlab scripts
|
||||
&read_opt_into_hash("N","on","on");
|
||||
&read_opt_into_hash("K","on","off");
|
||||
&read_opt_into_hash("I","on","off");
|
||||
|
@ -374,7 +377,7 @@ sub opts_read()
|
|||
|
||||
&print_opts();
|
||||
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
# List the options
|
||||
|
@ -385,7 +388,7 @@ sub print_opts()
|
|||
while(my ($key,$value) = each(%opt_h))
|
||||
{print "$key : $value\n";}
|
||||
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
@ -433,7 +436,7 @@ sub check_keywords_conf()
|
|||
{die "Error: Keyword($mctgy[$imcg],$sctgy[$imcg]->[$iscg]) is missing!\n";}
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
# Read the configuration file
|
||||
|
@ -471,7 +474,7 @@ sub read_conf()
|
|||
print "Checking these keywords...";
|
||||
print "Successfully\n";
|
||||
close(CONF);
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
sub read_benchmarks()
|
||||
|
@ -503,7 +506,7 @@ sub read_benchmarks()
|
|||
foreach my $temp(@benchmark_names)
|
||||
{print "$temp\n";}
|
||||
close(FCONF);
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
# Input program path is like "~/program_dir/program_name"
|
||||
|
@ -1298,7 +1301,6 @@ sub run_std_vpr($ $ $ $ $ $ $ $ $)
|
|||
{
|
||||
my ($blif,$bm,$arch,$net,$place,$route,$fix_chan_width,$log,$act_file) = @_;
|
||||
my ($vpr_dir,$vpr_name) = &split_prog_path($conf_ptr->{dir_path}->{vpr_path}->{val});
|
||||
chdir $vpr_dir;
|
||||
|
||||
my ($power_opts);
|
||||
if ("on" eq $opt_ptr->{power}) {
|
||||
|
@ -1435,6 +1437,10 @@ sub run_std_vpr($ $ $ $ $ $ $ $ $)
|
|||
if ("on" eq $opt_ptr->{vpr_max_router_iteration}) {
|
||||
$other_opt .= "--max_router_iterations $opt_ptr->{vpr_max_router_iteration_val} ";
|
||||
}
|
||||
|
||||
chdir $vpr_dir;
|
||||
print "Entering $vpr_dir\n";
|
||||
|
||||
print "./$vpr_name $arch $blif --net_file $net --place_file $place --route_file $route --full_stats --nodisp $power_opts $packer_opts $chan_width_opt $vpr_spice_opts $other_opt > $log\n";
|
||||
system("./$vpr_name $arch $blif --net_file $net --place_file $place --route_file $route --full_stats --nodisp $power_opts $packer_opts $chan_width_opt $vpr_spice_opts $other_opt > $log");
|
||||
|
||||
|
@ -1463,7 +1469,6 @@ sub run_vpr_route($ $ $ $ $ $ $ $ $)
|
|||
{
|
||||
my ($blif,$bm,$arch,$net,$place,$route,$fix_chan_width,$log,$act_file) = @_;
|
||||
my ($vpr_dir,$vpr_name) = &split_prog_path($conf_ptr->{dir_path}->{vpr_path}->{val});
|
||||
chdir $vpr_dir;
|
||||
|
||||
my ($power_opts);
|
||||
if ("on" eq $opt_ptr->{power}) {
|
||||
|
@ -1517,7 +1522,12 @@ sub run_vpr_route($ $ $ $ $ $ $ $ $)
|
|||
$other_opt .= "--router_algorithm breadth_first ";
|
||||
}
|
||||
|
||||
chdir $vpr_dir;
|
||||
print "Entering $vpr_dir\n";
|
||||
|
||||
print "./$vpr_name $arch $blif --route --blif_file $blif --net_file $net --place_file $place --route_file $route --full_stats --nodisp $power_opts $chan_width_opt $vpr_spice_opts $other_opt > $log\n";
|
||||
system("./$vpr_name $arch $blif --route --blif_file $blif --net_file $net --place_file $place --route_file $route --full_stats --nodisp $power_opts $chan_width_opt $vpr_spice_opts $other_opt > $log");
|
||||
print "\n";
|
||||
|
||||
chdir $cwd;
|
||||
}
|
||||
|
@ -1754,6 +1764,9 @@ sub run_vpr_in_flow($ $ $ $ $ $ $ $ $ $ $ $) {
|
|||
if (-e $vpr_route) {
|
||||
print "INFO: try route_chan_width($min_chan_width) success!\n";
|
||||
last; #Jump out
|
||||
} elsif ($max_route_width_retry < $min_chan_width) {
|
||||
# I set a threshold of 1000 as it is the limit of VPR
|
||||
die "ERROR: Route Fail for $abc_blif_out with a min_chan_width of $min_chan_width!\n";
|
||||
} else {
|
||||
print "INFO: try route_chan_width($min_chan_width) failed! Retry with +2...\n";
|
||||
$min_chan_width += 2;
|
||||
|
@ -1777,6 +1790,9 @@ sub run_vpr_in_flow($ $ $ $ $ $ $ $ $ $ $ $) {
|
|||
if (-e $vpr_route) {
|
||||
print "INFO: try route_chan_width($fix_chan_width) success!\n";
|
||||
last; #Jump out
|
||||
} elsif ($max_route_width_retry < $fix_chan_width) {
|
||||
# I set a threshold of 1000 as it is the limit of VPR
|
||||
die "ERROR: Route Fail for $abc_blif_out with a min_chan_width of $fix_chan_width!\n";
|
||||
} else {
|
||||
print "INFO: try route_chan_width($fix_chan_width) failed! Retry with +2...\n";
|
||||
$fix_chan_width += 2;
|
||||
|
@ -2978,6 +2994,14 @@ sub gen_csv_rpt_vtr_flow($ $)
|
|||
my @keywords;
|
||||
my ($K_val,$N_val) = ($opt_ptr->{K_val},$opt_ptr->{N_val});
|
||||
|
||||
# adapt to matlab format if the option is enabled
|
||||
if ("on" eq $opt_ptr->{matlab_rpt}) {
|
||||
# Print the data name
|
||||
print $CSVFH "$opt_ptr->{matlab_rpt_val} = [\n";
|
||||
# We will set the stats line to be commented
|
||||
print $CSVFH "%";
|
||||
}
|
||||
|
||||
# Print out Standard Stats First
|
||||
print $CSVFH "$tag";
|
||||
print $CSVFH ",LUTs";
|
||||
|
@ -3006,7 +3030,14 @@ sub gen_csv_rpt_vtr_flow($ $)
|
|||
# Check log/stats one by one
|
||||
foreach $tmp(@benchmark_names) {
|
||||
$tmp =~ s/\.v$//g;
|
||||
print $CSVFH "$tmp";
|
||||
|
||||
# For matlab script, we use {} for string
|
||||
if ("on" eq $opt_ptr->{matlab_rpt}) {
|
||||
print $CSVFH "{'$tmp'}";
|
||||
} else {
|
||||
print $CSVFH "$tmp";
|
||||
}
|
||||
|
||||
print $CSVFH ",$rpt_h{$tag}->{$tmp}->{$N_val}->{$K_val}->{LUTs}";
|
||||
if ("on" eq $opt_ptr->{min_route_chan_width}) {
|
||||
print $CSVFH ",$rpt_h{$tag}->{$tmp}->{$N_val}->{$K_val}->{min_route_chan_width}";
|
||||
|
@ -3034,7 +3065,17 @@ sub gen_csv_rpt_vtr_flow($ $)
|
|||
print $CSVFH ",$rpt_ptr->{$tag}->{$tmp}->{$N_val}->{$K_val}->{power}->{dynamic}";
|
||||
print $CSVFH ",$rpt_ptr->{$tag}->{$tmp}->{$N_val}->{$K_val}->{power}->{leakage}";
|
||||
}
|
||||
print $CSVFH "\n";
|
||||
# For matlab script, we end with a semicolumn to be compatiable to matlab
|
||||
if ("on" eq $opt_ptr->{matlab_rpt}) {
|
||||
print $CSVFH ";\n";
|
||||
} else {
|
||||
print $CSVFH "\n";
|
||||
}
|
||||
}
|
||||
|
||||
# For matlab script, we end with ];
|
||||
if ("on" eq $opt_ptr->{matlab_rpt}) {
|
||||
print $CSVFH "];\n";
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3045,6 +3086,14 @@ sub gen_csv_rpt_yosys_vpr_flow($ $)
|
|||
my @keywords;
|
||||
my ($K_val,$N_val) = ($opt_ptr->{K_val},$opt_ptr->{N_val});
|
||||
|
||||
# adapt to matlab format if the option is enabled
|
||||
if ("on" eq $opt_ptr->{matlab_rpt}) {
|
||||
# Print the data name
|
||||
print $CSVFH "$opt_ptr->{matlab_rpt_val} = [\n";
|
||||
# We will set the stats line to be commented
|
||||
print $CSVFH "%";
|
||||
}
|
||||
|
||||
# Print out Standard Stats First
|
||||
print $CSVFH "$tag";
|
||||
print $CSVFH ",LUTs";
|
||||
|
@ -3074,7 +3123,14 @@ sub gen_csv_rpt_yosys_vpr_flow($ $)
|
|||
foreach $tmp(@benchmark_names) {
|
||||
my @tokens = split('/', $tmp);
|
||||
$tmp = $tokens[0];
|
||||
print $CSVFH "$tmp";
|
||||
|
||||
# For matlab script, we use {} for string
|
||||
if ("on" eq $opt_ptr->{matlab_rpt}) {
|
||||
print $CSVFH "{'$tmp'}";
|
||||
} else {
|
||||
print $CSVFH "$tmp";
|
||||
}
|
||||
|
||||
print $CSVFH ",$rpt_h{$tag}->{$tmp}->{$N_val}->{$K_val}->{LUTs}";
|
||||
if ("on" eq $opt_ptr->{min_route_chan_width}) {
|
||||
print $CSVFH ",$rpt_h{$tag}->{$tmp}->{$N_val}->{$K_val}->{min_route_chan_width}";
|
||||
|
@ -3102,7 +3158,17 @@ sub gen_csv_rpt_yosys_vpr_flow($ $)
|
|||
print $CSVFH ",$rpt_ptr->{$tag}->{$tmp}->{$N_val}->{$K_val}->{power}->{dynamic}";
|
||||
print $CSVFH ",$rpt_ptr->{$tag}->{$tmp}->{$N_val}->{$K_val}->{power}->{leakage}";
|
||||
}
|
||||
print $CSVFH "\n";
|
||||
# For matlab script, we end with a semicolumn to be compatiable to matlab
|
||||
if ("on" eq $opt_ptr->{matlab_rpt}) {
|
||||
print $CSVFH ";\n";
|
||||
} else {
|
||||
print $CSVFH "\n";
|
||||
}
|
||||
}
|
||||
|
||||
# For matlab script, we end with ];
|
||||
if ("on" eq $opt_ptr->{matlab_rpt}) {
|
||||
print $CSVFH "];\n";
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3113,6 +3179,14 @@ sub gen_csv_rpt_standard_flow($ $)
|
|||
my @keywords;
|
||||
my ($K_val,$N_val) = ($opt_ptr->{K_val},$opt_ptr->{N_val});
|
||||
|
||||
# adapt to matlab format if the option is enabled
|
||||
if ("on" eq $opt_ptr->{matlab_rpt}) {
|
||||
# Print the data name
|
||||
print $CSVFH "$opt_ptr->{matlab_rpt_val} = [\n";
|
||||
# We will set the stats line to be commented
|
||||
print $CSVFH "%";
|
||||
}
|
||||
|
||||
# Print out Standard Stats First
|
||||
print $CSVFH "$tag";
|
||||
print $CSVFH ",LUTs";
|
||||
|
@ -3141,7 +3215,13 @@ sub gen_csv_rpt_standard_flow($ $)
|
|||
# Check log/stats one by one
|
||||
foreach $tmp(@benchmark_names) {
|
||||
$tmp =~ s/\.blif$//g;
|
||||
print $CSVFH "$tmp";
|
||||
# For matlab script, we use {} for string
|
||||
if ("on" eq $opt_ptr->{matlab_rpt}) {
|
||||
print $CSVFH "{'$tmp'}";
|
||||
} else {
|
||||
print $CSVFH "$tmp";
|
||||
}
|
||||
|
||||
print $CSVFH ",$rpt_h{$tag}->{$tmp}->{$N_val}->{$K_val}->{LUTs}";
|
||||
if ("on" eq $opt_ptr->{min_route_chan_width}) {
|
||||
print $CSVFH ",$rpt_h{$tag}->{$tmp}->{$N_val}->{$K_val}->{min_route_chan_width}";
|
||||
|
@ -3173,7 +3253,18 @@ sub gen_csv_rpt_standard_flow($ $)
|
|||
print $CSVFH ",$rpt_ptr->{$tag}->{$tmp}->{$N_val}->{$K_val}->{power}->{dynamic}";
|
||||
print $CSVFH ",$rpt_ptr->{$tag}->{$tmp}->{$N_val}->{$K_val}->{power}->{leakage}";
|
||||
}
|
||||
print $CSVFH "\n";
|
||||
|
||||
# For matlab script, we end with a semicolumn to be compatiable to matlab
|
||||
if ("on" eq $opt_ptr->{matlab_rpt}) {
|
||||
print $CSVFH ";\n";
|
||||
} else {
|
||||
print $CSVFH "\n";
|
||||
}
|
||||
}
|
||||
|
||||
# For matlab script, we end with ];
|
||||
if ("on" eq $opt_ptr->{matlab_rpt}) {
|
||||
print $CSVFH "];\n";
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3184,6 +3275,14 @@ sub gen_csv_rpt_mpack2_flow($ $)
|
|||
my @keywords;
|
||||
my ($K_val,$N_val) = ($opt_ptr->{K_val},$opt_ptr->{N_val});
|
||||
|
||||
# adapt to matlab format if the option is enabled
|
||||
if ("on" eq $opt_ptr->{matlab_rpt}) {
|
||||
# Print the data name
|
||||
print $CSVFH "$opt_ptr->{matlab_rpt_val} = [\n";
|
||||
# We will set the stats line to be commented
|
||||
print $CSVFH "%";
|
||||
}
|
||||
|
||||
# Print out Mpack stats Second
|
||||
print $CSVFH "$tag";
|
||||
if ("on" eq $opt_ptr->{min_route_chan_width}) {
|
||||
|
@ -3217,7 +3316,13 @@ sub gen_csv_rpt_mpack2_flow($ $)
|
|||
# Check log/stats one by one
|
||||
foreach $tmp(@benchmark_names) {
|
||||
$tmp =~ s/\.blif$//g;
|
||||
print $CSVFH "$tmp";
|
||||
# For matlab script, we use {} for string
|
||||
if ("on" eq $opt_ptr->{matlab_rpt}) {
|
||||
print $CSVFH "{'$tmp'}";
|
||||
} else {
|
||||
print $CSVFH "$tmp";
|
||||
}
|
||||
|
||||
if ("on" eq $opt_ptr->{min_route_chan_width}) {
|
||||
print $CSVFH ",$rpt_h{$tag}->{$tmp}->{$N_val}->{$K_val}->{min_route_chan_width}";
|
||||
print $CSVFH ",$rpt_h{$tag}->{$tmp}->{$N_val}->{$K_val}->{fix_route_chan_width}";
|
||||
|
@ -3250,7 +3355,17 @@ sub gen_csv_rpt_mpack2_flow($ $)
|
|||
print $CSVFH ",$rpt_ptr->{$tag}->{$tmp}->{$N_val}->{$K_val}->{power}->{dynamic}";
|
||||
print $CSVFH ",$rpt_ptr->{$tag}->{$tmp}->{$N_val}->{$K_val}->{power}->{leakage}";
|
||||
}
|
||||
print $CSVFH "\n";
|
||||
# For matlab script, we end with a semicolumn to be compatiable to matlab
|
||||
if ("on" eq $opt_ptr->{matlab_rpt}) {
|
||||
print $CSVFH ";\n";
|
||||
} else {
|
||||
print $CSVFH "\n";
|
||||
}
|
||||
}
|
||||
|
||||
# For matlab script, we end with ];
|
||||
if ("on" eq $opt_ptr->{matlab_rpt}) {
|
||||
print $CSVFH "];\n";
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3261,6 +3376,14 @@ sub gen_csv_rpt_mpack1_flow($ $)
|
|||
my @keywords;
|
||||
my ($N_val,$M_val) = ($opt_ptr->{N_val},$opt_ptr->{M_val});
|
||||
|
||||
# adapt to matlab format if the option is enabled
|
||||
if ("on" eq $opt_ptr->{matlab_rpt}) {
|
||||
# Print the data name
|
||||
print $CSVFH "$opt_ptr->{matlab_rpt_val} = [\n";
|
||||
# We will set the stats line to be commented
|
||||
print $CSVFH "%";
|
||||
}
|
||||
|
||||
# Print out Mpack stats Second
|
||||
print $CSVFH "$tag";
|
||||
print $CSVFH ",MATRIX";
|
||||
|
@ -3284,7 +3407,13 @@ sub gen_csv_rpt_mpack1_flow($ $)
|
|||
# Check log/stats one by one
|
||||
foreach $tmp(@benchmark_names) {
|
||||
$tmp =~ s/\.blif$//g;
|
||||
print $CSVFH "$tmp";
|
||||
# For matlab script, we use {} for string
|
||||
if ("on" eq $opt_ptr->{matlab_rpt}) {
|
||||
print $CSVFH "{'$tmp'}";
|
||||
} else {
|
||||
print $CSVFH "$tmp";
|
||||
}
|
||||
|
||||
#foreach $tmpkw(@keywords) {
|
||||
print $CSVFH ",$rpt_ptr->{$tag}->{$tmp}->{$N_val}->{$M_val}->{MATRIX}";
|
||||
@keywords = split /\|/,$conf_ptr->{csv_tags}->{mpack_tags}->{val};
|
||||
|
@ -3309,7 +3438,17 @@ sub gen_csv_rpt_mpack1_flow($ $)
|
|||
print $CSVFH ",$rpt_ptr->{$tag}->{$tmp}->{$N_val}->{$M_val}->{power}->{total}";
|
||||
print $CSVFH ",$rpt_ptr->{$tag}->{$tmp}->{$N_val}->{$M_val}->{power}->{dynamic}";
|
||||
print $CSVFH ",$rpt_ptr->{$tag}->{$tmp}->{$N_val}->{$M_val}->{power}->{leakage}";
|
||||
print $CSVFH "\n";
|
||||
# For matlab script, we end with a semicolumn to be compatiable to matlab
|
||||
if ("on" eq $opt_ptr->{matlab_rpt}) {
|
||||
print $CSVFH ";\n";
|
||||
} else {
|
||||
print $CSVFH "\n";
|
||||
}
|
||||
}
|
||||
|
||||
# For matlab script, we end with ];
|
||||
if ("on" eq $opt_ptr->{matlab_rpt}) {
|
||||
print $CSVFH "];\n";
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -29,7 +29,7 @@ sub print_usage()
|
|||
print " -add_default_clk\n";
|
||||
print " -initial_blif <input_blif_path>\n";
|
||||
print "\n";
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
sub opts_read()
|
||||
|
@ -53,7 +53,7 @@ sub opts_read()
|
|||
}
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
# Print a line of blif netlist
|
||||
|
@ -432,15 +432,15 @@ sub scan_blif()
|
|||
}
|
||||
close($FIN2);
|
||||
close($FOUT);
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
sub main()
|
||||
{
|
||||
&opts_read();
|
||||
&scan_blif();
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
&main();
|
||||
exit(1);
|
||||
exit(0);
|
||||
|
|
|
@ -90,7 +90,7 @@ sub findPath(){
|
|||
} else {
|
||||
$path = "$path"."/"."$folders[$count]";
|
||||
if($folders[$count] eq $folder_top){
|
||||
print "$path\n";
|
||||
#print "$path\n";
|
||||
return $path;
|
||||
}
|
||||
}
|
||||
|
@ -135,4 +135,4 @@ sub main()
|
|||
}
|
||||
|
||||
&main();
|
||||
exit(1);
|
||||
exit(0);
|
||||
|
|
|
@ -931,9 +931,11 @@ struct s_arch {
|
|||
bool tileable; /* Xifan TANG: tileable rr_graph support */
|
||||
t_chan_width_dist Chans;
|
||||
enum e_switch_block_type SBType;
|
||||
enum e_switch_block_type SBSubType;
|
||||
float R_minW_nmos;
|
||||
float R_minW_pmos;
|
||||
int Fs;
|
||||
int SubFs;
|
||||
float C_ipin_cblock;
|
||||
float T_ipin_cblock;
|
||||
/* mrFPGA: Xifan TANG */
|
||||
|
|
|
@ -1,4 +1,39 @@
|
|||
/* The XML parser processes an XML file into a tree data structure composed of *
|
||||
/**********************************************************
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2018 LNIS - The University of Utah
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
***********************************************************************/
|
||||
|
||||
/************************************************************************
|
||||
* Filename: rr_blocks.cpp
|
||||
* Created by: Xifan Tang
|
||||
* Change history:
|
||||
* +-------------------------------------+
|
||||
* | Date | Author | Notes
|
||||
* +-------------------------------------+
|
||||
* | 2019/07/02 | Xifan Tang | Modified to support passing_track_type for switch blocks
|
||||
* +-------------------------------------+
|
||||
***********************************************************************/
|
||||
/************************************************************************
|
||||
* The XML parser processes an XML file into a tree data structure composed of *
|
||||
* ezxml_t nodes. Each ezxml_t node represents an XML element. For example *
|
||||
* <a> <b/> </a> will generate two ezxml_t nodes. One called "a" and its *
|
||||
* child "b". Each ezxml_t node can contain various XML data such as attribute *
|
||||
|
@ -22,7 +57,7 @@
|
|||
* Because of how the XML tree traversal works, we free everything when we're *
|
||||
* done reading an architecture file to make sure that there isn't some part *
|
||||
* of the architecture file that got missed. *
|
||||
*/
|
||||
***********************************************************************/
|
||||
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
@ -2142,6 +2177,29 @@ static void ProcessDevice(INOUTP ezxml_t Node, OUTP struct s_arch *arch,
|
|||
|
||||
arch->Fs = GetIntProperty(Cur, "fs", TRUE, 3);
|
||||
|
||||
/* SubType is the switch block type of passing tracks */
|
||||
/* By default, the subType is the same as the main type */
|
||||
Prop = FindProperty(Cur, "sub_type", FALSE);
|
||||
if (NULL != Prop) {
|
||||
if (strcmp(Prop, "wilton") == 0) {
|
||||
arch->SBSubType = WILTON;
|
||||
} else if (strcmp(Prop, "universal") == 0) {
|
||||
arch->SBSubType = UNIVERSAL;
|
||||
} else if (strcmp(Prop, "subset") == 0) {
|
||||
arch->SBSubType = SUBSET;
|
||||
} else {
|
||||
vpr_printf(TIO_MESSAGE_ERROR,
|
||||
"[LINE %d] Unknown property %s for switch block type x\n",
|
||||
Cur->line, Prop);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
ezxml_set_attr(Cur, "sub_type", NULL);
|
||||
|
||||
/* SubFs is Fs for the switch block type of passing tracks */
|
||||
/* By default, the subFs is the same as the main Fs */
|
||||
arch->SubFs = GetIntProperty(Cur, "sub_fs", FALSE, arch->Fs);
|
||||
|
||||
FreeNode(Cur);
|
||||
}
|
||||
|
||||
|
@ -4132,3 +4190,6 @@ void SetupPinEquivalenceAutoDetect(ezxml_t Parent, t_type_descriptor* Type) {
|
|||
return;
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
* End of file : read_xml_arch_file.c
|
||||
***********************************************************************/
|
||||
|
|
|
@ -536,9 +536,11 @@ static void SetupRoutingArch(INP t_arch Arch,
|
|||
OUTP struct s_det_routing_arch *RoutingArch) {
|
||||
|
||||
RoutingArch->switch_block_type = Arch.SBType;
|
||||
RoutingArch->switch_block_sub_type = Arch.SBSubType;
|
||||
RoutingArch->R_minW_nmos = Arch.R_minW_nmos;
|
||||
RoutingArch->R_minW_pmos = Arch.R_minW_pmos;
|
||||
RoutingArch->Fs = Arch.Fs;
|
||||
RoutingArch->sub_Fs = Arch.SubFs;
|
||||
RoutingArch->directionality = BI_DIRECTIONAL;
|
||||
if (Arch.Segments)
|
||||
RoutingArch->directionality = Arch.Segments[0].directionality;
|
||||
|
|
|
@ -560,8 +560,10 @@ static int binary_search_place_and_route(struct s_placer_opts placer_opts,
|
|||
free_rr_graph();
|
||||
|
||||
build_rr_graph(graph_type, num_types, type_descriptors, nx, ny, grid,
|
||||
chan_width_x[0], NULL, det_routing_arch.switch_block_type,
|
||||
det_routing_arch.Fs, det_routing_arch.num_segment,
|
||||
chan_width_x[0], NULL,
|
||||
det_routing_arch.switch_block_type, det_routing_arch.Fs,
|
||||
det_routing_arch.switch_block_sub_type, det_routing_arch.sub_Fs,
|
||||
det_routing_arch.num_segment,
|
||||
det_routing_arch.num_switch, segment_inf,
|
||||
det_routing_arch.global_route_switch,
|
||||
det_routing_arch.delayless_switch, timing_inf,
|
||||
|
|
|
@ -807,6 +807,8 @@ struct s_det_routing_arch {
|
|||
enum e_directionality directionality; /* UDSD by AY */
|
||||
int Fs;
|
||||
enum e_switch_block_type switch_block_type;
|
||||
int sub_Fs;
|
||||
enum e_switch_block_type switch_block_sub_type;
|
||||
int num_segment;
|
||||
short num_switch;
|
||||
short global_route_switch;
|
||||
|
|
|
@ -506,3 +506,182 @@ void print_rr_graph_stats(const t_rr_graph& rr_graph) {
|
|||
|
||||
return;
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
* Print statistics of a rr_graph
|
||||
* 1. We print number of nodes by types
|
||||
* 2. Print the number of edges
|
||||
************************************************************************/
|
||||
void print_rr_graph_stats() {
|
||||
|
||||
/* Print number of nodes */
|
||||
vpr_printf(TIO_MESSAGE_INFO, "Statistics on number of RR nodes (by node type): \n");
|
||||
|
||||
/* Count the number of nodes */
|
||||
std::vector<size_t> num_nodes_per_type;
|
||||
num_nodes_per_type.resize(NUM_RR_TYPES);
|
||||
num_nodes_per_type.assign(NUM_RR_TYPES, 0);
|
||||
|
||||
for (int inode = 0; inode < num_rr_nodes; ++inode) {
|
||||
num_nodes_per_type[rr_node[inode].type]++;
|
||||
}
|
||||
|
||||
/* Get the largest string size of rr_node_typename */
|
||||
size_t max_str_typename = 0;
|
||||
for (int type = 0; type < NUM_RR_TYPES; ++type) {
|
||||
max_str_typename = std::max(max_str_typename, strlen(rr_node_typename[type]));
|
||||
}
|
||||
|
||||
/* Constant strings */
|
||||
char* type_str = " Type ";
|
||||
char* total_str = " Total ";
|
||||
char* node_str = " No. of nodes ";
|
||||
char* edge_str = " No. of edges ";
|
||||
|
||||
/* Count the number of characters per line:
|
||||
* we check the string length of each node type
|
||||
* Then we plus two reserved strings "type" and "total"
|
||||
*/
|
||||
size_t num_char_per_line = 0;
|
||||
for (int type = 0; type < NUM_RR_TYPES; ++type) {
|
||||
num_char_per_line += 6 + max_str_typename;
|
||||
}
|
||||
num_char_per_line += strlen(type_str);
|
||||
num_char_per_line += strlen(total_str);
|
||||
|
||||
/* Print splitter */
|
||||
for (size_t ichar = 0; ichar < num_char_per_line; ++ichar) {
|
||||
vpr_printf(TIO_MESSAGE_INFO, "-");
|
||||
}
|
||||
vpr_printf(TIO_MESSAGE_INFO, "\n");
|
||||
|
||||
/* Print node type */
|
||||
vpr_printf(TIO_MESSAGE_INFO, "%s", type_str);
|
||||
for (int type = 0; type < NUM_RR_TYPES; ++type) {
|
||||
vpr_printf(TIO_MESSAGE_INFO, " %s ", rr_node_typename[type]);
|
||||
}
|
||||
vpr_printf(TIO_MESSAGE_INFO, "%s", total_str);
|
||||
vpr_printf(TIO_MESSAGE_INFO, "\n");
|
||||
|
||||
/* Print node numbers */
|
||||
int total_num_nodes = 0;
|
||||
vpr_printf(TIO_MESSAGE_INFO, "%s", node_str);
|
||||
for (int type = 0; type < NUM_RR_TYPES; ++type) {
|
||||
vpr_printf(TIO_MESSAGE_INFO, " %10lu ", num_nodes_per_type[type]);
|
||||
total_num_nodes += num_nodes_per_type[type];
|
||||
}
|
||||
vpr_printf(TIO_MESSAGE_INFO, " %10lu ", num_rr_nodes);
|
||||
vpr_printf(TIO_MESSAGE_INFO, "\n");
|
||||
|
||||
/* Check we have the same number as stated in rr_graph */
|
||||
assert (total_num_nodes == num_rr_nodes);
|
||||
|
||||
/* Count the number of edges */
|
||||
size_t num_edges = 0;
|
||||
std::vector<size_t> num_edges_per_type;
|
||||
num_edges_per_type.resize(NUM_RR_TYPES);
|
||||
num_edges_per_type.assign(NUM_RR_TYPES, 0);
|
||||
|
||||
for (int inode = 0; inode < num_rr_nodes; ++inode) {
|
||||
num_edges_per_type[rr_node[inode].type] += rr_node[inode].num_edges;
|
||||
}
|
||||
for (int inode = 0; inode < num_rr_nodes; ++inode) {
|
||||
num_edges += rr_node[inode].num_edges;
|
||||
}
|
||||
|
||||
/* Print number of edges */
|
||||
vpr_printf(TIO_MESSAGE_INFO, "%s", edge_str);
|
||||
for (int type = 0; type < NUM_RR_TYPES; ++type) {
|
||||
vpr_printf(TIO_MESSAGE_INFO, " %10lu ", num_edges_per_type[type]);
|
||||
}
|
||||
vpr_printf(TIO_MESSAGE_INFO, " %10lu ", num_edges);
|
||||
vpr_printf(TIO_MESSAGE_INFO, "\n");
|
||||
|
||||
/* Print splitter */
|
||||
for (size_t ichar = 0; ichar < num_char_per_line; ++ichar) {
|
||||
vpr_printf(TIO_MESSAGE_INFO, "-");
|
||||
}
|
||||
vpr_printf(TIO_MESSAGE_INFO, "\n");
|
||||
|
||||
/* Print MUX size distribution */
|
||||
/* Get the maximum SB mux size */
|
||||
short max_sb_mux_size = 0;
|
||||
for (int inode = 0; inode < num_rr_nodes; ++inode) {
|
||||
/* MUX multiplexers for SBs */
|
||||
if ( (CHANX == rr_node[inode].type)
|
||||
|| (CHANY == rr_node[inode].type) ) {
|
||||
max_sb_mux_size = std::max(rr_node[inode].fan_in, max_sb_mux_size);
|
||||
}
|
||||
}
|
||||
/* Get the minimum SB mux size */
|
||||
short min_sb_mux_size = max_sb_mux_size;
|
||||
for (int inode = 0; inode < num_rr_nodes; ++inode) {
|
||||
/* MUX multiplexers for SBs */
|
||||
if ( (CHANX == rr_node[inode].type)
|
||||
|| (CHANY == rr_node[inode].type) ) {
|
||||
min_sb_mux_size = std::min(rr_node[inode].fan_in, min_sb_mux_size);
|
||||
}
|
||||
}
|
||||
|
||||
/* Get the minimum SB mux size */
|
||||
int num_sb_mux = 0;
|
||||
short avg_sb_mux_size = 0;
|
||||
for (int inode = 0; inode < num_rr_nodes; ++inode) {
|
||||
/* MUX multiplexers for SBs */
|
||||
if ( (CHANX == rr_node[inode].type)
|
||||
|| (CHANY == rr_node[inode].type) ) {
|
||||
avg_sb_mux_size += rr_node[inode].fan_in;
|
||||
num_sb_mux++;
|
||||
}
|
||||
}
|
||||
avg_sb_mux_size /= num_sb_mux;
|
||||
/* Print statistics */
|
||||
vpr_printf(TIO_MESSAGE_INFO, "------------------------------------------------\n");
|
||||
vpr_printf(TIO_MESSAGE_INFO, "Total No. of Switch Block Multiplexer size:%d\n", num_sb_mux);
|
||||
vpr_printf(TIO_MESSAGE_INFO, "Maximum Switch Block Multiplexer size:%d\n", max_sb_mux_size);
|
||||
vpr_printf(TIO_MESSAGE_INFO, "Minimum Switch Block Multiplexer size:%d\n", min_sb_mux_size);
|
||||
vpr_printf(TIO_MESSAGE_INFO, "Average Switch Block Multiplexer size:%d\n", avg_sb_mux_size);
|
||||
vpr_printf(TIO_MESSAGE_INFO, "------------------------------------------------\n");
|
||||
|
||||
/* Get the maximum SB mux size */
|
||||
short max_cb_mux_size = 0;
|
||||
for (int inode = 0; inode < num_rr_nodes; ++inode) {
|
||||
/* MUX multiplexers for SBs */
|
||||
if (IPIN == rr_node[inode].type) {
|
||||
max_cb_mux_size = std::max(rr_node[inode].fan_in, max_cb_mux_size);
|
||||
}
|
||||
}
|
||||
/* Get the minimum SB mux size */
|
||||
short min_cb_mux_size = max_cb_mux_size;
|
||||
for (int inode = 0; inode < num_rr_nodes; ++inode) {
|
||||
/* MUX multiplexers for SBs */
|
||||
if (IPIN == rr_node[inode].type) {
|
||||
min_cb_mux_size = std::min(rr_node[inode].fan_in, min_cb_mux_size);
|
||||
}
|
||||
}
|
||||
|
||||
/* Get the minimum SB mux size */
|
||||
int num_cb_mux = 0;
|
||||
short avg_cb_mux_size = 0;
|
||||
for (int inode = 0; inode < num_rr_nodes; ++inode) {
|
||||
/* MUX multiplexers for SBs */
|
||||
if (IPIN == rr_node[inode].type) {
|
||||
avg_cb_mux_size += rr_node[inode].fan_in;
|
||||
num_cb_mux++;
|
||||
}
|
||||
}
|
||||
avg_cb_mux_size /= num_cb_mux;
|
||||
vpr_printf(TIO_MESSAGE_INFO, "------------------------------------------------\n");
|
||||
vpr_printf(TIO_MESSAGE_INFO, "Total No. of Connection Block Multiplexer size:%d\n", num_cb_mux);
|
||||
vpr_printf(TIO_MESSAGE_INFO, "Maximum Connection Block Multiplexer size:%d\n", max_cb_mux_size);
|
||||
vpr_printf(TIO_MESSAGE_INFO, "Minimum Connection Block Multiplexer size:%d\n", min_cb_mux_size);
|
||||
vpr_printf(TIO_MESSAGE_INFO, "Average Connection Block Multiplexer size:%d\n", avg_cb_mux_size);
|
||||
vpr_printf(TIO_MESSAGE_INFO, "------------------------------------------------\n");
|
||||
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
* End of file : rr_graph_builder_utils.cpp
|
||||
***********************************************************************/
|
||||
|
|
|
@ -43,5 +43,7 @@ short get_track_rr_node_end_track_id(const t_rr_node* track_rr_node);
|
|||
|
||||
void print_rr_graph_stats(const t_rr_graph& rr_graph);
|
||||
|
||||
void print_rr_graph_stats();
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -31,6 +31,8 @@
|
|||
* +-------------------------------------+
|
||||
* | 2019/06/11 | Xifan Tang | Created
|
||||
* +-------------------------------------+
|
||||
* | 2019/07/02 | Xifan Tang | Modified to support SB subtype and SubFs
|
||||
* +-------------------------------------+
|
||||
***********************************************************************/
|
||||
/************************************************************************
|
||||
* This file contains a builder for the complex rr_graph data structure
|
||||
|
@ -777,7 +779,8 @@ void build_rr_graph_edges(t_rr_graph* rr_graph,
|
|||
const std::vector<size_t> device_chan_width,
|
||||
const std::vector<t_segment_inf> segment_inf,
|
||||
int** Fc_in, int** Fc_out,
|
||||
const enum e_switch_block_type sb_type, const int Fs) {
|
||||
const enum e_switch_block_type sb_type, const int Fs,
|
||||
const enum e_switch_block_type sb_subtype, const int subFs) {
|
||||
|
||||
/* Create edges for SOURCE and SINK nodes for a tileable rr_graph */
|
||||
build_rr_graph_edges_for_source_nodes(rr_graph, grids);
|
||||
|
@ -804,7 +807,7 @@ void build_rr_graph_edges(t_rr_graph* rr_graph,
|
|||
|
||||
/* adapt the switch_block_conn for the GSB nodes */
|
||||
t_track2track_map sb_conn; /* [0..from_gsb_side][0..chan_width-1][track_indices] */
|
||||
sb_conn = build_gsb_track_to_track_map(rr_graph, rr_gsb, sb_type, Fs, segment_inf);
|
||||
sb_conn = build_gsb_track_to_track_map(rr_graph, rr_gsb, sb_type, Fs, sb_subtype, subFs, segment_inf);
|
||||
|
||||
/* Build edges for a GSB */
|
||||
build_edges_for_one_tileable_rr_gsb(rr_graph, &rr_gsb,
|
||||
|
@ -904,6 +907,7 @@ void build_tileable_unidir_rr_graph(INP const int L_num_types,
|
|||
INP t_type_ptr types, INP const int L_nx, INP const int L_ny,
|
||||
INP struct s_grid_tile **L_grid, INP const int chan_width,
|
||||
INP const enum e_switch_block_type sb_type, INP const int Fs,
|
||||
INP const enum e_switch_block_type sb_subtype, INP const int subFs,
|
||||
INP const int num_seg_types,
|
||||
INP const t_segment_inf * segment_inf,
|
||||
INP const int num_switches, INP const int delayless_switch,
|
||||
|
@ -1021,7 +1025,7 @@ void build_tileable_unidir_rr_graph(INP const int L_num_types,
|
|||
/* Create edges for a tileable rr_graph */
|
||||
build_rr_graph_edges(&rr_graph, device_size, grids, device_chan_width, segment_infs,
|
||||
Fc_in, Fc_out,
|
||||
sb_type, Fs);
|
||||
sb_type, Fs, sb_subtype, subFs);
|
||||
|
||||
/************************************************************************
|
||||
* 6.2 Build direction connection lists
|
||||
|
@ -1034,7 +1038,7 @@ void build_tileable_unidir_rr_graph(INP const int L_num_types,
|
|||
build_rr_graph_direct_connections(&rr_graph, device_size, grids, delayless_switch,
|
||||
num_directs, directs, clb_to_clb_directs);
|
||||
|
||||
print_rr_graph_stats(rr_graph);
|
||||
//print_rr_graph_stats(rr_graph);
|
||||
|
||||
/* Clear driver switches of the rr_graph */
|
||||
clear_rr_graph_driver_switch(&rr_graph);
|
||||
|
|
|
@ -9,6 +9,7 @@ void build_tileable_unidir_rr_graph(INP const int L_num_types,
|
|||
INP t_type_ptr types, INP const int L_nx, INP const int L_ny,
|
||||
INP struct s_grid_tile **L_grid, INP const int chan_width,
|
||||
INP const enum e_switch_block_type sb_type, INP const int Fs,
|
||||
INP const enum e_switch_block_type sb_subtype, INP const int subFs,
|
||||
INP const int num_seg_types,
|
||||
INP const t_segment_inf * segment_inf,
|
||||
INP const int num_switches, INP const int delayless_switch,
|
||||
|
|
|
@ -475,6 +475,8 @@ t_track2track_map build_gsb_track_to_track_map(const t_rr_graph* rr_graph,
|
|||
const RRGSB& rr_gsb,
|
||||
const enum e_switch_block_type sb_type,
|
||||
const int Fs,
|
||||
const enum e_switch_block_type sb_subtype,
|
||||
const int subFs,
|
||||
const std::vector<t_segment_inf> segment_inf) {
|
||||
t_track2track_map track2track_map; /* [0..gsb_side][0..chan_width][track_indices] */
|
||||
|
||||
|
@ -555,7 +557,7 @@ t_track2track_map build_gsb_track_to_track_map(const t_rr_graph* rr_graph,
|
|||
* TODO: This can be improved with different patterns!
|
||||
*/
|
||||
build_gsb_one_group_track_to_track_map(rr_graph, rr_gsb,
|
||||
sb_type, Fs,
|
||||
sb_subtype, subFs,
|
||||
pass_tracks, start_tracks,
|
||||
&track2track_map);
|
||||
|
||||
|
|
|
@ -23,6 +23,8 @@ t_track2track_map build_gsb_track_to_track_map(const t_rr_graph* rr_graph,
|
|||
const RRGSB& rr_gsb,
|
||||
const enum e_switch_block_type sb_type,
|
||||
const int Fs,
|
||||
const enum e_switch_block_type sb_subtype,
|
||||
const int subFs,
|
||||
const std::vector<t_segment_inf> segment_inf);
|
||||
|
||||
RRGSB build_one_tileable_rr_gsb(const DeviceCoordinator& device_range,
|
||||
|
|
|
@ -1,3 +1,41 @@
|
|||
/**********************************************************
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2018 LNIS - The University of Utah
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
***********************************************************************/
|
||||
|
||||
/************************************************************************
|
||||
* Filename: fpga_x2p_bitstream_utils.c
|
||||
* Created by: Xifan Tang
|
||||
* Change history:
|
||||
* +-------------------------------------+
|
||||
* | Date | Author | Notes
|
||||
* +-------------------------------------+
|
||||
* | 2019/07/02 | Xifan Tang | Created
|
||||
* +-------------------------------------+
|
||||
***********************************************************************/
|
||||
/************************************************************************
|
||||
* This file contains most utilized functions for the bitstream generator
|
||||
***********************************************************************/
|
||||
|
||||
/***********************************/
|
||||
/* Synthesizable Verilog Dumping */
|
||||
/* Xifan TANG, EPFL/LSI */
|
||||
|
@ -30,11 +68,14 @@
|
|||
#include "fpga_x2p_mux_utils.h"
|
||||
#include "fpga_x2p_globals.h"
|
||||
|
||||
#include "fpga_x2p_bitstream_utils.h"
|
||||
|
||||
/* Determine the size of input address of a decoder */
|
||||
int determine_decoder_size(int num_addr_out) {
|
||||
return ceil(log(num_addr_out)/log(2.));
|
||||
}
|
||||
|
||||
static
|
||||
int count_num_sram_bits_one_lut_spice_model(t_spice_model* cur_spice_model) {
|
||||
int num_sram_bits = 0;
|
||||
int iport;
|
||||
|
@ -98,6 +139,7 @@ int count_num_sram_bits_one_lut_spice_model(t_spice_model* cur_spice_model) {
|
|||
return num_sram_bits;
|
||||
}
|
||||
|
||||
static
|
||||
int count_num_sram_bits_one_mux_spice_model(t_spice_model* cur_spice_model,
|
||||
int mux_size) {
|
||||
int num_sram_bits = 0;
|
||||
|
@ -162,7 +204,7 @@ int count_num_sram_bits_one_mux_spice_model(t_spice_model* cur_spice_model,
|
|||
return num_sram_bits;
|
||||
}
|
||||
|
||||
|
||||
static
|
||||
int count_num_sram_bits_one_generic_spice_model(t_spice_model* cur_spice_model) {
|
||||
int iport;
|
||||
int num_sram_bits = 0;
|
||||
|
@ -227,6 +269,7 @@ int count_num_sram_bits_one_spice_model(t_spice_model* cur_spice_model,
|
|||
return -1;
|
||||
}
|
||||
|
||||
static
|
||||
int count_num_mode_bits_one_generic_spice_model(t_spice_model* cur_spice_model) {
|
||||
int iport;
|
||||
int num_mode_bits = 0;
|
||||
|
@ -424,20 +467,7 @@ int count_num_reserved_conf_bits_one_mux_spice_model(t_spice_model* cur_spice_mo
|
|||
break;
|
||||
case SPICE_SRAM_SCAN_CHAIN:
|
||||
case SPICE_SRAM_STANDALONE:
|
||||
/* 4T1R MUX requires more configuration bits */
|
||||
if (SPICE_MODEL_STRUCTURE_TREE == cur_spice_model->design_tech_info.mux_info->structure) {
|
||||
/* For tree-structure: we need 3 times more config. bits */
|
||||
num_reserved_conf_bits = 0;
|
||||
} else if (SPICE_MODEL_STRUCTURE_MULTILEVEL == cur_spice_model->design_tech_info.mux_info->structure) {
|
||||
/* For multi-level structure: we need 1 more config. bits for each level */
|
||||
num_reserved_conf_bits = 0;
|
||||
} else {
|
||||
num_reserved_conf_bits = 0;
|
||||
}
|
||||
/* For 2:1 MUX, whatever structure, there is only one level */
|
||||
if (2 == num_input_size) {
|
||||
num_reserved_conf_bits = 0;
|
||||
}
|
||||
num_reserved_conf_bits = 0;
|
||||
break;
|
||||
default:
|
||||
vpr_printf(TIO_MESSAGE_ERROR,"(FILE:%s,LINE[%d])Invalid type of SRAM organization!\n",
|
||||
|
@ -533,7 +563,7 @@ int count_num_reserved_conf_bits_one_spice_model(t_spice_model* cur_spice_model,
|
|||
return num_reserved_conf_bits;
|
||||
}
|
||||
|
||||
|
||||
static
|
||||
int count_num_conf_bits_one_lut_spice_model(t_spice_model* cur_spice_model,
|
||||
enum e_sram_orgz cur_sram_orgz_type) {
|
||||
int num_conf_bits = 0;
|
||||
|
@ -611,7 +641,7 @@ int count_num_conf_bits_one_lut_spice_model(t_spice_model* cur_spice_model,
|
|||
return num_conf_bits;
|
||||
}
|
||||
|
||||
|
||||
static
|
||||
int count_num_conf_bits_one_mux_spice_model(t_spice_model* cur_spice_model,
|
||||
enum e_sram_orgz cur_sram_orgz_type,
|
||||
int mux_size) {
|
||||
|
@ -684,6 +714,7 @@ int count_num_conf_bits_one_mux_spice_model(t_spice_model* cur_spice_model,
|
|||
return num_conf_bits;
|
||||
}
|
||||
|
||||
static
|
||||
int count_num_conf_bits_one_generic_spice_model(t_spice_model* cur_spice_model,
|
||||
enum e_sram_orgz cur_sram_orgz_type) {
|
||||
int num_conf_bits = 0;
|
||||
|
@ -1098,9 +1129,9 @@ add_mux_conf_bits_to_llist(int mux_size,
|
|||
}
|
||||
|
||||
/* Add SCFF configutration bits to a linked list*/
|
||||
void
|
||||
add_sram_scff_conf_bits_to_llist(t_sram_orgz_info* cur_sram_orgz_info,
|
||||
int num_sram_bits, int* sram_bits) {
|
||||
static
|
||||
void add_sram_scff_conf_bits_to_llist(t_sram_orgz_info* cur_sram_orgz_info,
|
||||
int num_sram_bits, int* sram_bits) {
|
||||
int ibit, cur_mem_bit;
|
||||
t_conf_bit** sram_bit = NULL;
|
||||
t_spice_model* cur_sram_spice_model = NULL;
|
||||
|
@ -1592,3 +1623,7 @@ void add_mux_conf_bits_to_sram_orgz_info(t_sram_orgz_info* cur_sram_orgz_info,
|
|||
|
||||
return;
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
* End of file : fpga_x2p_bitstream_utils.c
|
||||
***********************************************************************/
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
#ifndef FPGA_X2P_BITSTREAM_UTILS_H
|
||||
#define FPGA_X2P_BITSTREAM_UTILS_H
|
||||
|
||||
int determine_decoder_size(int num_addr_out);
|
||||
|
||||
|
@ -24,6 +26,9 @@ int count_num_reserved_conf_bits_one_spice_model(t_spice_model* cur_spice_model,
|
|||
enum e_sram_orgz cur_sram_orgz_type,
|
||||
int mux_size);
|
||||
|
||||
int count_num_reserved_conf_bit_one_interc(t_interconnect* cur_interc,
|
||||
enum e_sram_orgz cur_sram_orgz_type);
|
||||
|
||||
void
|
||||
add_mux_scff_conf_bits_to_llist(int mux_size,
|
||||
t_sram_orgz_info* cur_sram_orgz_info,
|
||||
|
@ -78,3 +83,5 @@ void add_sram_conf_bits_to_sram_orgz_info(t_sram_orgz_info* cur_sram_orgz_info,
|
|||
|
||||
void add_mux_conf_bits_to_sram_orgz_info(t_sram_orgz_info* cur_sram_orgz_info,
|
||||
t_spice_model* mux_spice_model, int mux_size) ;
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
#ifndef FPGA_X2P_PBTYPES_UTILS_H
|
||||
#define FPGA_X2P_PBTYPES_UTILS_H
|
||||
|
||||
#include "fpga_x2p_bitstream_utils.h"
|
||||
|
||||
void check_pb_graph_edge(t_pb_graph_edge pb_graph_edge);
|
||||
|
||||
void check_pb_graph_pin_edges(t_pb_graph_pin pb_graph_pin);
|
||||
|
@ -74,9 +76,6 @@ void mark_one_pb_parasitic_nets(t_phy_pb* cur_pb);
|
|||
int count_num_conf_bit_one_interc(t_interconnect* cur_interc,
|
||||
enum e_sram_orgz cur_sram_orgz_type);
|
||||
|
||||
int count_num_reserved_conf_bit_one_interc(t_interconnect* cur_interc,
|
||||
enum e_sram_orgz cur_sram_orgz_type);
|
||||
|
||||
int count_num_conf_bits_pb_type_mode_interc(t_mode* cur_pb_type_mode,
|
||||
enum e_sram_orgz cur_sram_orgz_type);
|
||||
|
||||
|
|
|
@ -30,6 +30,8 @@
|
|||
#include "fpga_x2p_bitstream_utils.h"
|
||||
#include "fpga_bitstream_primitives.h"
|
||||
|
||||
#include "fpga_bitstream_pbtypes.h"
|
||||
|
||||
|
||||
/***** Subroutines *****/
|
||||
|
||||
|
|
|
@ -1,3 +1,41 @@
|
|||
/**********************************************************
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2018 LNIS - The University of Utah
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
***********************************************************************/
|
||||
|
||||
/************************************************************************
|
||||
* Filename: fpga_x2p_router.c
|
||||
* Created by: Xifan Tang
|
||||
* Change history:
|
||||
* +-------------------------------------+
|
||||
* | Date | Author | Notes
|
||||
* +-------------------------------------+
|
||||
* | 2019/07/02 | Xifan Tang | Created
|
||||
* +-------------------------------------+
|
||||
***********************************************************************/
|
||||
/************************************************************************
|
||||
* This file contains a breadth-first router which is tailored for packer
|
||||
***********************************************************************/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
@ -14,6 +52,8 @@
|
|||
#include "fpga_x2p_rr_graph_utils.h"
|
||||
#include "fpga_x2p_pb_rr_graph.h"
|
||||
|
||||
#include "fpga_x2p_router.h"
|
||||
|
||||
void breadth_first_expand_rr_graph_trace_segment(t_rr_graph* local_rr_graph,
|
||||
t_trace *start_ptr,
|
||||
int remaining_connections_to_sink) {
|
||||
|
@ -145,6 +185,7 @@ void breadth_first_add_source_to_rr_graph_heap(t_rr_graph* local_rr_graph,
|
|||
/* A copy of breath_first_add_source_to_heap_cluster
|
||||
* I remove all the use of global variables
|
||||
*/
|
||||
static
|
||||
void breadth_first_add_one_source_to_rr_graph_heap(t_rr_graph* local_rr_graph,
|
||||
int src_net_index,
|
||||
int src_idx) {
|
||||
|
@ -249,6 +290,7 @@ boolean breadth_first_route_one_net_pb_rr_graph(t_rr_graph* local_rr_graph,
|
|||
|
||||
/* Adapt for the multi-source rr_graph routing
|
||||
*/
|
||||
static
|
||||
boolean breadth_first_route_one_single_source_net_pb_rr_graph(t_rr_graph* local_rr_graph,
|
||||
int inet, int isrc,
|
||||
int start_isink,
|
||||
|
@ -434,6 +476,7 @@ boolean breadth_first_route_one_single_source_net_pb_rr_graph(t_rr_graph* local_
|
|||
|
||||
/* Adapt for the multi-source rr_graph routing
|
||||
*/
|
||||
static
|
||||
boolean breadth_first_route_one_multi_source_net_pb_rr_graph(t_rr_graph* local_rr_graph,
|
||||
int inet) {
|
||||
|
||||
|
@ -550,7 +593,7 @@ boolean breadth_first_route_one_multi_source_net_pb_rr_graph(t_rr_graph* local_r
|
|||
return route_success;
|
||||
}
|
||||
|
||||
|
||||
static
|
||||
boolean feasible_routing_rr_graph(t_rr_graph* local_rr_graph,
|
||||
boolean verbose) {
|
||||
|
||||
|
@ -845,5 +888,7 @@ boolean try_breadth_first_route_pb_rr_graph(t_rr_graph* local_rr_graph) {
|
|||
return (FALSE);
|
||||
}
|
||||
|
||||
|
||||
/************************************************************************
|
||||
* End of file : fpga_x2p_router.c
|
||||
***********************************************************************/
|
||||
|
||||
|
|
|
@ -80,8 +80,7 @@ static void init_spice_mux_testbench_globals(t_spice spice) {
|
|||
}
|
||||
|
||||
static
|
||||
void fprint_spice_mux_testbench_global_ports(FILE* fp,
|
||||
t_spice spice) {
|
||||
void fprint_spice_mux_testbench_global_ports(FILE* fp) {
|
||||
/* A valid file handler*/
|
||||
if (NULL == fp) {
|
||||
vpr_printf(TIO_MESSAGE_ERROR,"(FILE:%s,LINE[%d])Invalid File Handler!\n",__FILE__, __LINE__);
|
||||
|
@ -641,7 +640,6 @@ void fprint_spice_mux_testbench_pb_pin_mux(FILE* fp,
|
|||
|
||||
static
|
||||
void fprint_spice_mux_testbench_pb_graph_node_pin_interc(FILE* fp,
|
||||
enum e_spice_pin2pin_interc_type pin2pin_interc_type,
|
||||
t_pb_graph_pin* des_pb_graph_pin,
|
||||
t_mode* cur_mode,
|
||||
int select_path_id,
|
||||
|
@ -734,7 +732,6 @@ static
|
|||
void fprint_spice_mux_testbench_pb_pin_interc(FILE* fp,
|
||||
t_rr_node* pb_rr_graph,
|
||||
t_phy_pb* des_pb,
|
||||
enum e_spice_pin2pin_interc_type pin2pin_interc_type,
|
||||
t_pb_graph_pin* des_pb_graph_pin,
|
||||
t_mode* cur_mode,
|
||||
int select_path_id,
|
||||
|
@ -856,7 +853,6 @@ void fprintf_spice_mux_testbench_pb_graph_port_interc(FILE* fp,
|
|||
assert(NULL == cur_pb);
|
||||
path_id = DEFAULT_PATH_ID;
|
||||
fprint_spice_mux_testbench_pb_graph_node_pin_interc(fp,
|
||||
INPUT2INPUT_INTERC,
|
||||
&(cur_pb_graph_node->input_pins[iport][ipin]),
|
||||
cur_mode,
|
||||
path_id,
|
||||
|
@ -878,7 +874,6 @@ void fprintf_spice_mux_testbench_pb_graph_port_interc(FILE* fp,
|
|||
assert(DEFAULT_PATH_ID != path_id);
|
||||
}
|
||||
fprint_spice_mux_testbench_pb_pin_interc(fp, pb_rr_nodes, cur_pb, /* TODO: find out the child_pb*/
|
||||
INPUT2INPUT_INTERC,
|
||||
&(cur_pb_graph_node->input_pins[iport][ipin]),
|
||||
cur_mode,
|
||||
path_id,
|
||||
|
@ -896,7 +891,6 @@ void fprintf_spice_mux_testbench_pb_graph_port_interc(FILE* fp,
|
|||
assert(NULL == cur_pb);
|
||||
path_id = DEFAULT_PATH_ID;
|
||||
fprint_spice_mux_testbench_pb_graph_node_pin_interc(fp,
|
||||
OUTPUT2OUTPUT_INTERC,
|
||||
&(cur_pb_graph_node->output_pins[iport][ipin]),
|
||||
cur_mode,
|
||||
path_id,
|
||||
|
@ -918,7 +912,6 @@ void fprintf_spice_mux_testbench_pb_graph_port_interc(FILE* fp,
|
|||
assert(DEFAULT_PATH_ID != path_id);
|
||||
}
|
||||
fprint_spice_mux_testbench_pb_pin_interc(fp, pb_rr_nodes, cur_pb, /* TODO: find out the child_pb*/
|
||||
OUTPUT2OUTPUT_INTERC,
|
||||
&(cur_pb_graph_node->output_pins[iport][ipin]),
|
||||
cur_mode,
|
||||
path_id,
|
||||
|
@ -936,7 +929,6 @@ void fprintf_spice_mux_testbench_pb_graph_port_interc(FILE* fp,
|
|||
assert(NULL == cur_pb);
|
||||
path_id = DEFAULT_PATH_ID;
|
||||
fprint_spice_mux_testbench_pb_graph_node_pin_interc(fp,
|
||||
INPUT2INPUT_INTERC,
|
||||
&(cur_pb_graph_node->clock_pins[iport][ipin]),
|
||||
cur_mode,
|
||||
path_id,
|
||||
|
@ -958,7 +950,6 @@ void fprintf_spice_mux_testbench_pb_graph_port_interc(FILE* fp,
|
|||
assert(DEFAULT_PATH_ID != path_id);
|
||||
}
|
||||
fprint_spice_mux_testbench_pb_pin_interc(fp, pb_rr_nodes, cur_pb, /* TODO: find out the child_pb*/
|
||||
INPUT2INPUT_INTERC,
|
||||
&(cur_pb_graph_node->clock_pins[iport][ipin]),
|
||||
cur_mode,
|
||||
path_id,
|
||||
|
@ -1254,6 +1245,7 @@ void fprint_spice_mux_testbench_cb_one_mux(FILE* fp,
|
|||
return;
|
||||
}
|
||||
|
||||
static
|
||||
void fprint_spice_mux_testbench_cb_interc(FILE* fp,
|
||||
t_cb cur_cb_info,
|
||||
t_rr_node* src_rr_node,
|
||||
|
@ -1481,8 +1473,7 @@ int fprint_spice_mux_testbench_sb_one_mux(FILE* fp,
|
|||
|
||||
static
|
||||
int fprint_spice_mux_testbench_call_one_grid_sb_muxes(FILE* fp,
|
||||
t_sb cur_sb_info,
|
||||
t_ivec*** LL_rr_node_indices) {
|
||||
t_sb cur_sb_info) {
|
||||
int itrack, side;
|
||||
int used = 0;
|
||||
|
||||
|
@ -1672,6 +1663,7 @@ void fprint_spice_mux_testbench_measurements(FILE* fp,
|
|||
}
|
||||
|
||||
/* Top-level function in this source file */
|
||||
static
|
||||
int fprint_spice_one_mux_testbench(char* formatted_spice_dir,
|
||||
char* circuit_name,
|
||||
char* mux_testbench_name,
|
||||
|
@ -1743,7 +1735,7 @@ int fprint_spice_one_mux_testbench(char* formatted_spice_dir,
|
|||
fprint_spice_options(fp, arch.spice->spice_params);
|
||||
|
||||
/* Global nodes: Vdd for SRAMs, Logic Blocks(Include IO), Switch Boxes, Connection Boxes */
|
||||
fprint_spice_mux_testbench_global_ports(fp, *(arch.spice));
|
||||
fprint_spice_mux_testbench_global_ports(fp);
|
||||
|
||||
/* Quote defined Logic blocks subckts (Grids) */
|
||||
init_spice_mux_testbench_globals(*(arch.spice));
|
||||
|
@ -1798,7 +1790,7 @@ int fprint_spice_one_mux_testbench(char* formatted_spice_dir,
|
|||
case SPICE_SB_MUX_TB:
|
||||
total_sb_mux_input_density = 0.;
|
||||
/* Output a sb_mux testbench */
|
||||
used = fprint_spice_mux_testbench_call_one_grid_sb_muxes(fp, sb_info[grid_x][grid_y], LL_rr_node_indices);
|
||||
used = fprint_spice_mux_testbench_call_one_grid_sb_muxes(fp, sb_info[grid_x][grid_y]);
|
||||
/* Check and output info. */
|
||||
assert((0 == testbench_sb_mux_cnt)||(0 < testbench_sb_mux_cnt));
|
||||
if (0 < testbench_sb_mux_cnt) {
|
||||
|
|
|
@ -1,3 +1,45 @@
|
|||
/**********************************************************
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2018 LNIS - The University of Utah
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
***********************************************************************/
|
||||
|
||||
/************************************************************************
|
||||
* Filename: spice_routing.c
|
||||
* Created by: Xifan Tang
|
||||
* Change history:
|
||||
* +-------------------------------------+
|
||||
* | Date | Author | Notes
|
||||
* +-------------------------------------+
|
||||
* | 2019/07/02 | Xifan Tang | Created
|
||||
* +-------------------------------------+
|
||||
***********************************************************************/
|
||||
/************************************************************************
|
||||
* This file contains functions to output SPICE netlists of routing resources
|
||||
* i.e., Switch Block(SB), Connection Block (CB) and routing channels.
|
||||
* Each module will be placed in an individual subckt, which be called
|
||||
* through SPICE testbenches
|
||||
* Note that each subckt is a configured module (SB, CB or Routing channals)
|
||||
***********************************************************************/
|
||||
|
||||
/***********************************/
|
||||
/* SPICE Modeling for VPR */
|
||||
/* Xifan TANG, EPFL/LSI */
|
||||
|
@ -39,7 +81,7 @@
|
|||
#include "fpga_x2p_backannotate_utils.h"
|
||||
#include "spice_routing.h"
|
||||
|
||||
|
||||
static
|
||||
void fprint_routing_chan_subckt(char* subckt_dir,
|
||||
int x, int y, t_rr_type chan_type,
|
||||
int LL_num_rr_nodes, t_rr_node* LL_rr_node,
|
||||
|
@ -629,11 +671,9 @@ void fprint_switch_box_interc(FILE* fp,
|
|||
* For channels chanX with INC_DIRECTION on the right side, they should be marked as outputs
|
||||
* For channels chanX with DEC_DIRECTION on the right side, they should be marked as inputs
|
||||
*/
|
||||
static
|
||||
void fprint_routing_switch_box_subckt(char* subckt_dir,
|
||||
t_sb cur_sb_info,
|
||||
int LL_num_rr_nodes, t_rr_node* LL_rr_node,
|
||||
t_ivec*** LL_rr_node_indices,
|
||||
boolean compact_routing_hierarchy) {
|
||||
t_sb cur_sb_info) {
|
||||
int itrack, inode, side, ix, iy, x, y;
|
||||
FILE* fp = NULL;
|
||||
char* fname = NULL;
|
||||
|
@ -755,7 +795,15 @@ void fprint_connection_box_short_interc(FILE* fp,
|
|||
assert(1 == src_rr_node->fan_in);
|
||||
|
||||
/* Check the driver*/
|
||||
drive_rr_node = &(rr_node[src_rr_node->prev_node]);
|
||||
drive_rr_node = src_rr_node->drive_rr_nodes[0];
|
||||
/* We have OPINs since we may have direct connections:
|
||||
* These connections should be handled by other functions in the compact_netlist.c
|
||||
* So we just return here for OPINs
|
||||
*/
|
||||
if (OPIN == drive_rr_node->type) {
|
||||
return;
|
||||
}
|
||||
|
||||
assert((CHANX == drive_rr_node->type)||(CHANY == drive_rr_node->type));
|
||||
check_flag = 0;
|
||||
for (iedge = 0; iedge < drive_rr_node->num_edges; iedge++) {
|
||||
|
@ -996,11 +1044,9 @@ void fprint_connection_box_interc(FILE* fp,
|
|||
* | | Connection | |
|
||||
* --------------Box_Y[x][y-1]--------------
|
||||
*/
|
||||
static
|
||||
void fprint_routing_connection_box_subckt(char* subckt_dir,
|
||||
t_cb cur_cb_info,
|
||||
int LL_num_rr_nodes, t_rr_node* LL_rr_node,
|
||||
t_ivec*** LL_rr_node_indices,
|
||||
boolean compact_routing_hierarchy) {
|
||||
t_cb cur_cb_info) {
|
||||
|
||||
int itrack, inode, side, x, y;
|
||||
int side_cnt = 0;
|
||||
|
@ -1104,6 +1150,7 @@ void fprint_routing_connection_box_subckt(char* subckt_dir,
|
|||
fprintf(fp, "***** Head of scan-chain *****\n");
|
||||
fprintf(fp, "Rcbx[%d][%d]_sc_head cbx[%d][%d]_sc_head %s[%d]->in 0\n",
|
||||
x, y, x, y, sram_spice_model->prefix, sram_spice_model->cnt);
|
||||
break;
|
||||
case CHANY:
|
||||
fprintf(fp, "***** Head of scan-chain *****\n");
|
||||
fprintf(fp, "Rcby[%d][%d]_sc_head cby[%d][%d]_sc_head %s[%d]->in 0\n",
|
||||
|
@ -1141,6 +1188,7 @@ void fprint_routing_connection_box_subckt(char* subckt_dir,
|
|||
fprintf(fp, "***** Tail of scan-chain *****\n");
|
||||
fprintf(fp, "Rcbx[%d][%d]_sc_tail cbx[%d][%d]_sc_tail %s[%d]->in 0\n",
|
||||
x, y, x, y, sram_spice_model->prefix, sram_spice_model->cnt);
|
||||
break;
|
||||
case CHANY:
|
||||
fprintf(fp, "***** Tail of scan-chain *****\n");
|
||||
fprintf(fp, "Rcby[%d][%d]_sc_tail cby[%d][%d]_sc_tail %s[%d]->in 0\n",
|
||||
|
@ -1173,8 +1221,7 @@ void generate_spice_routing_resources(char* subckt_dir,
|
|||
t_arch arch,
|
||||
t_det_routing_arch* routing_arch,
|
||||
int LL_num_rr_nodes, t_rr_node* LL_rr_node,
|
||||
t_ivec*** LL_rr_node_indices,
|
||||
boolean compact_routing_hierarchy) {
|
||||
t_ivec*** LL_rr_node_indices) {
|
||||
int ix, iy;
|
||||
|
||||
assert(UNI_DIRECTIONAL == routing_arch->directionality);
|
||||
|
@ -1221,9 +1268,7 @@ void generate_spice_routing_resources(char* subckt_dir,
|
|||
for (ix = 0; ix < (nx + 1); ix++) {
|
||||
for (iy = 0; iy < (ny + 1); iy++) {
|
||||
update_spice_models_routing_index_low(ix, iy, SOURCE, arch.spice->num_spice_model, arch.spice->spice_models);
|
||||
fprint_routing_switch_box_subckt(subckt_dir, sb_info[ix][iy],
|
||||
LL_num_rr_nodes, LL_rr_node, LL_rr_node_indices,
|
||||
compact_routing_hierarchy);
|
||||
fprint_routing_switch_box_subckt(subckt_dir, sb_info[ix][iy]);
|
||||
update_spice_models_routing_index_high(ix, iy, SOURCE, arch.spice->num_spice_model, arch.spice->spice_models);
|
||||
}
|
||||
}
|
||||
|
@ -1237,9 +1282,7 @@ void generate_spice_routing_resources(char* subckt_dir,
|
|||
/* Check if this cby_info exists, it may be covered by a heterogenous block */
|
||||
if ((TRUE == is_cb_exist(CHANX, ix, iy))
|
||||
&&(0 < count_cb_info_num_ipin_rr_nodes(cbx_info[ix][iy]))) {
|
||||
fprint_routing_connection_box_subckt(subckt_dir, cbx_info[ix][iy],
|
||||
LL_num_rr_nodes, LL_rr_node, LL_rr_node_indices,
|
||||
compact_routing_hierarchy);
|
||||
fprint_routing_connection_box_subckt(subckt_dir, cbx_info[ix][iy]);
|
||||
}
|
||||
update_spice_models_routing_index_high(ix, iy, CHANX, arch.spice->num_spice_model, arch.spice->spice_models);
|
||||
}
|
||||
|
@ -1251,9 +1294,7 @@ void generate_spice_routing_resources(char* subckt_dir,
|
|||
/* Check if this cby_info exists, it may be covered by a heterogenous block */
|
||||
if ((TRUE == is_cb_exist(CHANY, ix, iy))
|
||||
&&(0 < count_cb_info_num_ipin_rr_nodes(cby_info[ix][iy]))) {
|
||||
fprint_routing_connection_box_subckt(subckt_dir, cby_info[ix][iy],
|
||||
LL_num_rr_nodes, LL_rr_node, LL_rr_node_indices,
|
||||
compact_routing_hierarchy);
|
||||
fprint_routing_connection_box_subckt(subckt_dir, cby_info[ix][iy]);
|
||||
}
|
||||
update_spice_models_routing_index_high(ix, iy, CHANY, arch.spice->num_spice_model, arch.spice->spice_models);
|
||||
}
|
||||
|
@ -1267,3 +1308,6 @@ void generate_spice_routing_resources(char* subckt_dir,
|
|||
return;
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
* End of file : spice_routing.c
|
||||
***********************************************************************/
|
||||
|
|
|
@ -67,6 +67,5 @@ void generate_spice_routing_resources(char* subckt_dir,
|
|||
t_arch arch,
|
||||
t_det_routing_arch* routing_arch,
|
||||
int LL_num_rr_nodes, t_rr_node* LL_rr_node,
|
||||
t_ivec*** LL_rr_node_indices,
|
||||
boolean compact_routing_hierarchy);
|
||||
t_ivec*** LL_rr_node_indices);
|
||||
|
||||
|
|
|
@ -737,8 +737,7 @@ void generate_spice_subckts(char* subckt_dir,
|
|||
/* 6. Generate Routing architecture*/
|
||||
vpr_printf(TIO_MESSAGE_INFO, "Writing Routing Resources....\n");
|
||||
generate_spice_routing_resources(subckt_dir, (*arch), routing_arch,
|
||||
num_rr_nodes, rr_node, rr_node_indices,
|
||||
compact_routing_hierarchy);
|
||||
num_rr_nodes, rr_node, rr_node_indices);
|
||||
|
||||
/* 7. Generate Logic Blocks */
|
||||
vpr_printf(TIO_MESSAGE_INFO,"Writing Logic Blocks...\n");
|
||||
|
|
|
@ -1489,6 +1489,7 @@ void fprint_spice_toplevel_one_grid_side_pin_with_given_index(FILE* fp,
|
|||
}
|
||||
|
||||
/* Apply a CLB to CLB direct connection to a SPICE netlist */
|
||||
static
|
||||
void fprint_spice_one_clb2clb_direct(FILE* fp,
|
||||
int from_grid_x, int from_grid_y,
|
||||
int to_grid_x, int to_grid_y,
|
||||
|
@ -1505,7 +1506,7 @@ void fprint_spice_one_clb2clb_direct(FILE* fp,
|
|||
|
||||
/* Check bandwidth match between from_clb and to_clb pins */
|
||||
if (0 != (cur_direct->from_clb_pin_end_index - cur_direct->from_clb_pin_start_index
|
||||
- cur_direct->to_clb_pin_end_index - cur_direct->to_clb_pin_start_index)) {
|
||||
- (cur_direct->to_clb_pin_end_index - cur_direct->to_clb_pin_start_index))) {
|
||||
vpr_printf(TIO_MESSAGE_ERROR, "(%s, [LINE%d]) Unmatch pin bandwidth in direct connection (name=%s)!\n",
|
||||
__FILE__, __LINE__, cur_direct->name);
|
||||
exit(1);
|
||||
|
@ -1619,6 +1620,7 @@ void fprint_spice_clb2clb_directs(FILE* fp,
|
|||
* 2. Their corresponding rr_node (SINK or IPIN) has 0 fan-in.
|
||||
* In these cases, we short connect them to global GND.
|
||||
*/
|
||||
static
|
||||
void fprint_grid_float_port_stimulation(FILE* fp) {
|
||||
int inode;
|
||||
int num_float_port = 0;
|
||||
|
|
|
@ -459,8 +459,10 @@ static void alloc_routing_structs(struct s_router_opts router_opts,
|
|||
}
|
||||
|
||||
build_rr_graph(graph_type, num_types, dummy_type_descriptors, nx, ny, grid,
|
||||
chan_width_x[0], NULL, det_routing_arch.switch_block_type,
|
||||
det_routing_arch.Fs, det_routing_arch.num_segment,
|
||||
chan_width_x[0], NULL,
|
||||
det_routing_arch.switch_block_type, det_routing_arch.Fs,
|
||||
det_routing_arch.switch_block_sub_type, det_routing_arch.sub_Fs,
|
||||
det_routing_arch.num_segment,
|
||||
det_routing_arch.num_switch, segment_inf,
|
||||
det_routing_arch.global_route_switch,
|
||||
det_routing_arch.delayless_switch, timing_inf,
|
||||
|
|
|
@ -297,8 +297,10 @@ boolean try_route(int width_fac, struct s_router_opts router_opts,
|
|||
/* Set up the routing resource graph defined by this FPGA architecture. */
|
||||
|
||||
build_rr_graph(graph_type, num_types, type_descriptors, nx, ny, grid,
|
||||
chan_width_x[0], NULL, det_routing_arch.switch_block_type,
|
||||
det_routing_arch.Fs, det_routing_arch.num_segment,
|
||||
chan_width_x[0], NULL,
|
||||
det_routing_arch.switch_block_type, det_routing_arch.Fs,
|
||||
det_routing_arch.switch_block_sub_type, det_routing_arch.sub_Fs,
|
||||
det_routing_arch.num_segment,
|
||||
det_routing_arch.num_switch, segment_inf,
|
||||
det_routing_arch.global_route_switch,
|
||||
det_routing_arch.delayless_switch, timing_inf,
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#include "ReadOptions.h"
|
||||
|
||||
#include "tileable_rr_graph_builder.h"
|
||||
#include "rr_graph_builder_utils.h"
|
||||
|
||||
/* Xifan TANG: SWSEG SUPPORT */
|
||||
#include "rr_graph_swseg.h"
|
||||
|
@ -211,7 +212,8 @@ void build_rr_graph(INP t_graph_type graph_type, INP int L_num_types,
|
|||
INP t_type_ptr types, INP int L_nx, INP int L_ny,
|
||||
INP struct s_grid_tile **L_grid, INP int chan_width,
|
||||
INP struct s_chan_width_dist *chan_capacity_inf,
|
||||
INP enum e_switch_block_type sb_type, INP int Fs, INP int num_seg_types,
|
||||
INP enum e_switch_block_type sb_type, INP int Fs,
|
||||
INP enum e_switch_block_type sb_sub_type, INP int sub_Fs, INP int num_seg_types,
|
||||
INP int num_switches, INP t_segment_inf * segment_inf,
|
||||
INP int global_route_switch, INP int delayless_switch,
|
||||
INP t_timing_inf timing_inf, INP int wire_to_ipin_switch,
|
||||
|
@ -225,7 +227,9 @@ void build_rr_graph(INP t_graph_type graph_type, INP int L_num_types,
|
|||
build_tileable_unidir_rr_graph(L_num_types, types,
|
||||
L_nx, L_ny, L_grid,
|
||||
chan_width,
|
||||
sb_type, Fs, num_seg_types, segment_inf,
|
||||
sb_type, Fs,
|
||||
sb_sub_type, sub_Fs,
|
||||
num_seg_types, segment_inf,
|
||||
num_switches, delayless_switch,
|
||||
timing_inf, wire_to_ipin_switch,
|
||||
base_cost_type, directs, num_directs, ignore_Fc_0, Warnings);
|
||||
|
@ -242,6 +246,9 @@ void build_rr_graph(INP t_graph_type graph_type, INP int L_num_types,
|
|||
|
||||
}
|
||||
|
||||
/* Print statistics of RR graph */
|
||||
print_rr_graph_stats();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -28,6 +28,7 @@ void build_rr_graph(INP t_graph_type graph_type,
|
|||
INP struct s_chan_width_dist *chan_capacity_inf,
|
||||
INP enum e_switch_block_type sb_type,
|
||||
INP int Fs,
|
||||
INP enum e_switch_block_type sb_sub_type, INP int sub_Fs,
|
||||
INP int num_seg_types,
|
||||
INP int num_switches,
|
||||
INP t_segment_inf * segment_inf,
|
||||
|
|
|
@ -692,8 +692,8 @@ static float trans_per_mux(int num_inputs, float trans_sram_bit,
|
|||
break;
|
||||
case SPICE_MODEL_STRUCTURE_MULTILEVEL:
|
||||
assert(1 < target_switch.switch_num_level);
|
||||
sram_trans = trans_sram_bit * target_switch.switch_num_level;
|
||||
mux_basis = determine_num_input_basis_multilevel_mux(num_inputs, target_switch.switch_num_level);
|
||||
sram_trans = trans_sram_bit * target_switch.switch_num_level * mux_basis;
|
||||
num_second_stage_trans = (int)pow((double)mux_basis, (double)(target_switch.switch_num_level - 1));
|
||||
pass_trans = ((num_second_stage_trans - 1) * mux_basis/(mux_basis-1)) * pass_trans_area
|
||||
+ num_inputs * pass_trans_area;
|
||||
|
|
Loading…
Reference in New Issue