diff --git a/fpga_flow/scripts/fpga_flow.pl b/fpga_flow/scripts/fpga_flow.pl index 606692373..d8ea80bbb 100644 --- a/fpga_flow/scripts/fpga_flow.pl +++ b/fpga_flow/scripts/fpga_flow.pl @@ -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 : N-LUT/Matrix\n"; print " Other Options:\n"; print " [ General ] \n"; + print " \t-matlab_rpt : .m file consists of data compatible to matlab scripts. Specify the data name to be appeared in the script\n"; print " \t-I : Number of inputs of a CLB, mandatory when mpack1 flow is chosen\n"; print " \t-K : K-LUT, mandatory when standard flow is chosen\n"; print " \t-M : 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"; } } diff --git a/fpga_flow/scripts/pro_blif.pl b/fpga_flow/scripts/pro_blif.pl index 25d44816f..d48bc54a5 100755 --- a/fpga_flow/scripts/pro_blif.pl +++ b/fpga_flow/scripts/pro_blif.pl @@ -29,7 +29,7 @@ sub print_usage() print " -add_default_clk\n"; print " -initial_blif \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); diff --git a/fpga_flow/scripts/rewrite_path_in_file.pl b/fpga_flow/scripts/rewrite_path_in_file.pl index b65868f60..5c2248913 100644 --- a/fpga_flow/scripts/rewrite_path_in_file.pl +++ b/fpga_flow/scripts/rewrite_path_in_file.pl @@ -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); diff --git a/vpr7_x2p/libarchfpga/SRC/include/physical_types.h b/vpr7_x2p/libarchfpga/SRC/include/physical_types.h index bdc991718..6e7a064e7 100644 --- a/vpr7_x2p/libarchfpga/SRC/include/physical_types.h +++ b/vpr7_x2p/libarchfpga/SRC/include/physical_types.h @@ -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 */ diff --git a/vpr7_x2p/libarchfpga/SRC/read_xml_arch_file.c b/vpr7_x2p/libarchfpga/SRC/read_xml_arch_file.c index ff8ececa1..e93a05914 100644 --- a/vpr7_x2p/libarchfpga/SRC/read_xml_arch_file.c +++ b/vpr7_x2p/libarchfpga/SRC/read_xml_arch_file.c @@ -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 * * 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 #include @@ -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 + ***********************************************************************/ diff --git a/vpr7_x2p/vpr/SRC/base/SetupVPR.c b/vpr7_x2p/vpr/SRC/base/SetupVPR.c index 09441daa1..af240a0ea 100644 --- a/vpr7_x2p/vpr/SRC/base/SetupVPR.c +++ b/vpr7_x2p/vpr/SRC/base/SetupVPR.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; diff --git a/vpr7_x2p/vpr/SRC/base/place_and_route.c b/vpr7_x2p/vpr/SRC/base/place_and_route.c index e314e0882..f4c53e72b 100644 --- a/vpr7_x2p/vpr/SRC/base/place_and_route.c +++ b/vpr7_x2p/vpr/SRC/base/place_and_route.c @@ -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, diff --git a/vpr7_x2p/vpr/SRC/base/vpr_types.h b/vpr7_x2p/vpr/SRC/base/vpr_types.h index 02a0d3657..cd163d111 100755 --- a/vpr7_x2p/vpr/SRC/base/vpr_types.h +++ b/vpr7_x2p/vpr/SRC/base/vpr_types.h @@ -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; diff --git a/vpr7_x2p/vpr/SRC/device/rr_graph/rr_graph_builder_utils.cpp b/vpr7_x2p/vpr/SRC/device/rr_graph/rr_graph_builder_utils.cpp index 40d89ee6e..d7d2fcd34 100644 --- a/vpr7_x2p/vpr/SRC/device/rr_graph/rr_graph_builder_utils.cpp +++ b/vpr7_x2p/vpr/SRC/device/rr_graph/rr_graph_builder_utils.cpp @@ -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 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 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 + ***********************************************************************/ diff --git a/vpr7_x2p/vpr/SRC/device/rr_graph/rr_graph_builder_utils.h b/vpr7_x2p/vpr/SRC/device/rr_graph/rr_graph_builder_utils.h index 46021ee6b..c213546d5 100644 --- a/vpr7_x2p/vpr/SRC/device/rr_graph/rr_graph_builder_utils.h +++ b/vpr7_x2p/vpr/SRC/device/rr_graph/rr_graph_builder_utils.h @@ -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 diff --git a/vpr7_x2p/vpr/SRC/device/rr_graph/tileable_rr_graph_builder.cpp b/vpr7_x2p/vpr/SRC/device/rr_graph/tileable_rr_graph_builder.cpp index 697a10166..25fa5929a 100644 --- a/vpr7_x2p/vpr/SRC/device/rr_graph/tileable_rr_graph_builder.cpp +++ b/vpr7_x2p/vpr/SRC/device/rr_graph/tileable_rr_graph_builder.cpp @@ -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 device_chan_width, const std::vector 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); diff --git a/vpr7_x2p/vpr/SRC/device/rr_graph/tileable_rr_graph_builder.h b/vpr7_x2p/vpr/SRC/device/rr_graph/tileable_rr_graph_builder.h index 827adbbc8..5844a55d5 100644 --- a/vpr7_x2p/vpr/SRC/device/rr_graph/tileable_rr_graph_builder.h +++ b/vpr7_x2p/vpr/SRC/device/rr_graph/tileable_rr_graph_builder.h @@ -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, diff --git a/vpr7_x2p/vpr/SRC/device/rr_graph/tileable_rr_graph_gsb.cpp b/vpr7_x2p/vpr/SRC/device/rr_graph/tileable_rr_graph_gsb.cpp index d0eaa901f..27f111091 100755 --- a/vpr7_x2p/vpr/SRC/device/rr_graph/tileable_rr_graph_gsb.cpp +++ b/vpr7_x2p/vpr/SRC/device/rr_graph/tileable_rr_graph_gsb.cpp @@ -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 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); diff --git a/vpr7_x2p/vpr/SRC/device/rr_graph/tileable_rr_graph_gsb.h b/vpr7_x2p/vpr/SRC/device/rr_graph/tileable_rr_graph_gsb.h index 6d98e1aa8..5f5a4cb49 100755 --- a/vpr7_x2p/vpr/SRC/device/rr_graph/tileable_rr_graph_gsb.h +++ b/vpr7_x2p/vpr/SRC/device/rr_graph/tileable_rr_graph_gsb.h @@ -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 segment_inf); RRGSB build_one_tileable_rr_gsb(const DeviceCoordinator& device_range, diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/base/fpga_x2p_bitstream_utils.c b/vpr7_x2p/vpr/SRC/fpga_x2p/base/fpga_x2p_bitstream_utils.c index fde3b52c7..a300ded24 100644 --- a/vpr7_x2p/vpr/SRC/fpga_x2p/base/fpga_x2p_bitstream_utils.c +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/base/fpga_x2p_bitstream_utils.c @@ -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 + ***********************************************************************/ diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/base/fpga_x2p_bitstream_utils.h b/vpr7_x2p/vpr/SRC/fpga_x2p/base/fpga_x2p_bitstream_utils.h index a63af4565..2ce9546a5 100644 --- a/vpr7_x2p/vpr/SRC/fpga_x2p/base/fpga_x2p_bitstream_utils.h +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/base/fpga_x2p_bitstream_utils.h @@ -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 diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/base/fpga_x2p_pbtypes_utils.h b/vpr7_x2p/vpr/SRC/fpga_x2p/base/fpga_x2p_pbtypes_utils.h index 1413b0c41..34063fc95 100644 --- a/vpr7_x2p/vpr/SRC/fpga_x2p/base/fpga_x2p_pbtypes_utils.h +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/base/fpga_x2p_pbtypes_utils.h @@ -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); diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/bitstream/fpga_bitstream_pbtypes.c b/vpr7_x2p/vpr/SRC/fpga_x2p/bitstream/fpga_bitstream_pbtypes.c index c752765a5..4741521fe 100644 --- a/vpr7_x2p/vpr/SRC/fpga_x2p/bitstream/fpga_bitstream_pbtypes.c +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/bitstream/fpga_bitstream_pbtypes.c @@ -30,6 +30,8 @@ #include "fpga_x2p_bitstream_utils.h" #include "fpga_bitstream_primitives.h" +#include "fpga_bitstream_pbtypes.h" + /***** Subroutines *****/ diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/router/fpga_x2p_router.c b/vpr7_x2p/vpr/SRC/fpga_x2p/router/fpga_x2p_router.c index e2585a215..c6de5ced7 100644 --- a/vpr7_x2p/vpr/SRC/fpga_x2p/router/fpga_x2p_router.c +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/router/fpga_x2p_router.c @@ -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 #include #include @@ -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 + ***********************************************************************/ diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/spice/spice_mux_testbench.c b/vpr7_x2p/vpr/SRC/fpga_x2p/spice/spice_mux_testbench.c index 88333dbd5..f28ba2ae1 100644 --- a/vpr7_x2p/vpr/SRC/fpga_x2p/spice/spice_mux_testbench.c +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/spice/spice_mux_testbench.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) { diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/spice/spice_routing.c b/vpr7_x2p/vpr/SRC/fpga_x2p/spice/spice_routing.c index 5fb871061..73353e59d 100644 --- a/vpr7_x2p/vpr/SRC/fpga_x2p/spice/spice_routing.c +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/spice/spice_routing.c @@ -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 + ***********************************************************************/ diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/spice/spice_routing.h b/vpr7_x2p/vpr/SRC/fpga_x2p/spice/spice_routing.h index 291bb3c08..bc7df15d4 100644 --- a/vpr7_x2p/vpr/SRC/fpga_x2p/spice/spice_routing.h +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/spice/spice_routing.h @@ -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); diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/spice/spice_subckt.c b/vpr7_x2p/vpr/SRC/fpga_x2p/spice/spice_subckt.c index a5753caf9..09ca2854e 100644 --- a/vpr7_x2p/vpr/SRC/fpga_x2p/spice/spice_subckt.c +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/spice/spice_subckt.c @@ -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"); diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/spice/spice_utils.c b/vpr7_x2p/vpr/SRC/fpga_x2p/spice/spice_utils.c index e195d994b..d24a6bcba 100644 --- a/vpr7_x2p/vpr/SRC/fpga_x2p/spice/spice_utils.c +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/spice/spice_utils.c @@ -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; diff --git a/vpr7_x2p/vpr/SRC/place/timing_place_lookup.c b/vpr7_x2p/vpr/SRC/place/timing_place_lookup.c index 88a4e7a29..b0d6bdbc9 100755 --- a/vpr7_x2p/vpr/SRC/place/timing_place_lookup.c +++ b/vpr7_x2p/vpr/SRC/place/timing_place_lookup.c @@ -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, diff --git a/vpr7_x2p/vpr/SRC/route/route_common.c b/vpr7_x2p/vpr/SRC/route/route_common.c index 165b54f4a..58cbfca31 100755 --- a/vpr7_x2p/vpr/SRC/route/route_common.c +++ b/vpr7_x2p/vpr/SRC/route/route_common.c @@ -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, diff --git a/vpr7_x2p/vpr/SRC/route/rr_graph.c b/vpr7_x2p/vpr/SRC/route/rr_graph.c index ff6d76b3f..d6edcf7fd 100755 --- a/vpr7_x2p/vpr/SRC/route/rr_graph.c +++ b/vpr7_x2p/vpr/SRC/route/rr_graph.c @@ -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; } diff --git a/vpr7_x2p/vpr/SRC/route/rr_graph.h b/vpr7_x2p/vpr/SRC/route/rr_graph.h index 9e23b0187..1a84393b7 100755 --- a/vpr7_x2p/vpr/SRC/route/rr_graph.h +++ b/vpr7_x2p/vpr/SRC/route/rr_graph.h @@ -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, diff --git a/vpr7_x2p/vpr/SRC/route/rr_graph_area.c b/vpr7_x2p/vpr/SRC/route/rr_graph_area.c index 809bd4add..7790d57af 100755 --- a/vpr7_x2p/vpr/SRC/route/rr_graph_area.c +++ b/vpr7_x2p/vpr/SRC/route/rr_graph_area.c @@ -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;