Upload recent commit

Merge remote-tracking branch 'origin/dev' into heterogeneous
This commit is contained in:
AurelienUoU 2019-07-03 13:09:34 -06:00
commit e13c703709
29 changed files with 641 additions and 107 deletions

View File

@ -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";
}
}
@ -3044,6 +3085,14 @@ sub gen_csv_rpt_yosys_vpr_flow($ $)
my ($tmp,$ikw,$tmpkw);
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";
@ -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";
}
}
@ -3112,6 +3178,14 @@ sub gen_csv_rpt_standard_flow($ $)
my ($tmp,$ikw,$tmpkw);
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";
@ -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";
}
}

View File

@ -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);

View File

@ -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);

View File

@ -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 */

View File

@ -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
***********************************************************************/

View File

@ -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;

View File

@ -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,

View File

@ -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;

View File

@ -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
***********************************************************************/

View File

@ -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

View File

@ -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);

View File

@ -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,

View File

@ -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);

View File

@ -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,

View File

@ -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
***********************************************************************/

View File

@ -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

View File

@ -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);

View File

@ -30,6 +30,8 @@
#include "fpga_x2p_bitstream_utils.h"
#include "fpga_bitstream_primitives.h"
#include "fpga_bitstream_pbtypes.h"
/***** Subroutines *****/

View File

@ -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
***********************************************************************/

View File

@ -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) {

View File

@ -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
***********************************************************************/

View File

@ -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);

View File

@ -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");

View File

@ -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;

View File

@ -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,

View File

@ -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,

View File

@ -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;
}

View File

@ -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,

View File

@ -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;