URL
https://opencores.org/ocsvn/an-fpga-implementation-of-low-latency-noc-based-mpsoc/an-fpga-implementation-of-low-latency-noc-based-mpsoc/trunk
Subversion Repositories an-fpga-implementation-of-low-latency-noc-based-mpsoc
Compare Revisions
- This comparison shows the changes necessary to convert path
/an-fpga-implementation-of-low-latency-noc-based-mpsoc/trunk/mpsoc
- from Rev 31 to Rev 32
- ↔ Reverse comparison
Rev 31 → Rev 32
/change.log
1,6 → 1,11
All notable changes to this project will be documented in this file. |
|
|
##[1.6.0] - 6-3-2017 |
## Added |
- NoC GUI simulator (using Verilator) |
|
|
##[1.5.2] - 22-2-2017 |
## changed |
- fixed bug in wishbone bus |
/perl_gui/ProNoC.pl
20,11 → 20,12
require "soc_gen.pl"; |
require "mpsoc_gen.pl"; |
require "emulator.pl"; |
require "simulator.pl"; |
|
|
|
|
our $VERSION = '1.5.2'; |
our $VERSION = '1.6.0'; |
|
sub main{ |
|
70,6 → 71,10
my $mpsocgen =mpsocgen_main(); |
$notebook->append_page ($mpsocgen,Gtk2::Label->new_with_mnemonic (" _NoC based MPSoC generator ")); |
|
|
my $simulator =simulator_main(); |
$notebook->append_page ($simulator,Gtk2::Label->new_with_mnemonic (" _NoC simulator ")); |
|
my $emulator =emulator_main(); |
$notebook->append_page ($emulator,Gtk2::Label->new_with_mnemonic (" _NoC emulator ")); |
|
111,9 → 116,10
["/_Help/_About", "F1", \&about , 0, undef ], |
["/_Help/_intf_gen", "F2", \&intfc_help, 0, undef ], |
["/_Help/_ip_gen", "F3", \&ip_help , 0, undef ], |
["/_Help/_pt_gen", "F4", \>_help , 0, undef ], |
["/_Help/_pt_gen", "F4", \&pt_help , 0, undef ], |
["/_Help/_sim_help", "F5", \&sim_help , 0, undef ], |
["/_Help/_Tutorial_1", undef, \&Tutorial_1 , 0, undef ], |
["/_Help/_Tutorial_2", undef, \&Tutorial_2 , 0, undef ], |
["/_Help/_Tutorial_2", undef, \&Tutorial_2 , 0, undef ], |
|
|
|
245,6 → 251,15
return; |
} |
|
|
sub sim_help{ |
my $dir = Cwd::getcwd(); |
my $help="$dir/doc/ProNoC_simulator.pdf"; |
system qq (xdg-open $help); |
return; |
} |
|
|
sub Tutorial_1{ |
my $dir = Cwd::getcwd(); |
my $help="$dir/doc/ProNoC_Tutorial1.pdf"; |
/perl_gui/doc/ProNoC_Tutorial2.pdf
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
/perl_gui/doc/ProNoC_simulator.pdf
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
perl_gui/doc/ProNoC_simulator.pdf
Property changes :
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Index: perl_gui/lib/perl/emulator.pl
===================================================================
--- perl_gui/lib/perl/emulator.pl (revision 31)
+++ perl_gui/lib/perl/emulator.pl (revision 32)
@@ -69,6 +69,7 @@
{ label=>"legend placement", param_name=>"legend_placement", type=>'Combo-box', default_val=>'BL', content=>"BL,BC,BR,RT,RC,RB", info=>$legend_info, param_parent=>'graph_param', ref_delay=>undef},
{ label=>"Y min", param_name=>"Y_MIN", type=>'Spin-button', default_val=>0, content=>"0,1024,1", info=>"Y axix minimum value", param_parent=>'graph_param', ref_delay=> 5},
{ label=>"X min", param_name=>"X_MIN", type=>'Spin-button', default_val=>0, content=>"0,1024,1", info=>"X axix minimum value", param_parent=>'graph_param', ref_delay=> 5},
+{ label=>"X max", param_name=>"X_MAX", type=>'Spin-button', default_val=>100, content=>"0,1024,1", info=>"X axix maximum value", param_parent=>'graph_param', ref_delay=> 5},
{ label=>"Line Width", param_name=>"LINEw", type=>'Spin-button', default_val=>3, content=>"1,20,1", info=>undef, param_parent=>'graph_param', ref_delay=> 5},
@@ -93,12 +94,21 @@
}
}#for
- my @x1;
- @x1 = uniq(sort {$a<=>$b} @x) if (scalar @x);
+ my @x2;
+ @x2 = uniq(sort {$a<=>$b} @x) if (scalar @x);
+
+ my @x1; #remove x values larger than x_max
+ my $x_max= $emulate->object_get_attribute( 'graph_param','X_MAX');
+ foreach my $p (@x2){
+ if(defined $x_max) {push (@x1,$p) if($p<$x_max);}
+ else {push (@x1,$p);}
+ }
+
#print "\@x1=@x1\n";
if (scalar @x1){
$results[0]=\@x1;
- for (my $i=1;$i<=$sample_num; $i++) {
+ my $i;
+ for ($i=1;$i<=$sample_num; $i++) {
my $j=0;
my $ref=$emulate->object_get_attribute ("sample$i","result");
if(defined $ref){
@@ -113,14 +123,26 @@
else {
$results[$i][$j]=undef;
- }
+ }
+
}#$i
+
+
}#if
-
my $max_y=$min_y*$scale;
+ my $s=scalar @x1;
+ # all results which is larger than ymax will be changed to ymax,
+ for (my $i=1;$i<=$sample_num; $i++) {
+ for (my $j=1;$j<=$s; $j++) {
+ $results[$i][$j]=($results[$i][$j]>$max_y)? $max_y: $results[$i][$j] if (defined $results[$i][$j]);
+ }
+ }
+
+
+
my $graphs_info;
foreach my $d ( @ginfo){
@@ -135,11 +157,15 @@
y_label => $graphs_info->{Y_Title},
y_max_value => $max_y,
y_min_value => $graphs_info->{Y_MIN},
- x_min_value => $graphs_info->{X_MIN}, # dosent work?
+ y_tick_number => 8,
+ # x_min_value => $graphs_info->{X_MIN}, # dosent work?
title => $graphs_info->{G_Title},
bar_spacing => 1,
shadowclr => 'dred',
- transparent => 0,
+
+ box_axis => 0,
+ skip_undef=> 1,
+ transparent => 1,
line_width => $graphs_info->{LINEw},
cycle_clrs => 'blue',
legend_placement => $graphs_info->{legend_placement},
@@ -149,16 +175,23 @@
$graph->set_legend(@legend_keys);
+
+
+
+
+
my $data = GD::Graph::Data->new(\@results) or die GD::Graph::Data->error;
+ $data->make_strict();
+
my $image = my_get_image($emulate,$graph,$data);
+
+ # print Data::Dumper->Dump ([\@results],['ttt']);
-
-
my $table = Gtk2::Table->new (25, 10, FALSE);
@@ -284,13 +317,18 @@
my ($emulate,$self, $data) = @_;
$self->{graphdata} = $data;
my $graph = $self->{graph};
- my $gd1=$graph->plot($data) or warn $graph->error;
+ my $gd2=$graph->plot($data) or warn $graph->error;
my $loader = Gtk2::Gdk::PixbufLoader->new;
+ #cut the upper side of the image to remove the stright line created by chaanging large results to ymax
+
- #my $gd2=$graph->plot([[0],[0]]) or warn $graph->error;
- #$gd2->copy( $gd1, 0, 20, 0, 20, 500, 230 );
+ my $gd1= GD::Image->new($gd2->getBounds);
+ my $white= $gd1->colorAllocate(255,255,254);
+ my ($x,$h)=$gd2->getBounds;
+ $gd1->transparent($white);
+ $gd1->copy( $gd2, 0, 0, 0, ,$h*0.05, $x ,$h*.95 );
$loader->write ($gd1->png);
@@ -303,11 +341,11 @@
my $ext=$emulate->object_get_attribute("graph_save","extension");
$emulate->object_add_attribute("graph_save","save",0);
-
+ #image
open(my $out, '>', $file);
if (tell $out )
{
- warn "Cannot open '$file' for write: $!";
+ warn "Cannot open '$file' to write: $!";
}else
{
#my @extens=$graph->export_format();
@@ -316,12 +354,43 @@
#print $out $gd1->gif if($ext eq 'gif');
close $out;
}
+ #text_file
+ open( $out, '>', "$file.txt");
+ if (tell $out )
+ {
+ warn "Cannot open $file.txt to write: $!";
+ }
+ else
+ {
+ my $sample_num=$emulate->object_get_attribute("emulate_num",undef);
+ if (defined $sample_num){
+ for (my $i=1;$i<=$sample_num; $i++) {
+ my $l_name= $emulate->object_get_attribute("sample$i","line_name");
+ my $ref=$emulate->object_get_attribute ("sample$i","result");
+ my @x;
+ if(defined $ref) {
+
+ print $out "$l_name\n";
+ foreach my $x (sort {$a<=>$b} keys $ref) {
+ my $y=$ref->{$x};
+ print $out "\t$x , $y\n";
+ }
+ print $out "\n\n";
+ }
+ }#for
+ }
+
+ close $out;
+ }
+
}
my $image = Gtk2::Image->new_from_pixbuf($loader->get_pixbuf);
+
+
$self->{graphimage} = $image;
my $hotspotlist;
if ($self->{graphtype} eq 'bars' or
@@ -515,22 +584,26 @@
sub get_noc_configuration{
- my ($emulate,$n) =@_;
- my($width,$hight)=max_win_size();
- my $win=def_popwin_size($width/2.5,$hight*.8,"NoC configuration setting");
+ my ($emulate,$mode,$n,$set_win) =@_;
+
my $table=def_table(10,2,FALSE);
my $row=0;
- my $traffics="tornado,transposed 1,transposed 2,bit reverse,bit complement,random"; #TODO hot spot
+ my $traffics="tornado,transposed 1,transposed 2,bit reverse,bit complement,random"; #TODO hot spot for emulator
+ my $dir = Cwd::getcwd();
+ if($mode eq "simulate"){
+ $traffics=$traffics.",hot spot";
+ my $open_in = abs_path("$ENV{PRONOC_WORK}/simulate");
+ attach_widget_to_table ($table,$row,gen_label_in_left("Verilated file:"),gen_button_message ("Select the the verilator simulation file. Different NoC simulators can be generated using Generate NoC configuration tab.","icons/help.png"), get_file_name_object ($emulate,"sample$n","sof_file",undef,$open_in)); $row++;
- my $dir = Cwd::getcwd();
- my $open_in = abs_path("$ENV{PRONOC_WORK}/emulate/sof");
- attach_widget_to_table ($table,$row,gen_label_in_left("SoF file:"),gen_button_message ("Select the SRAM Object File (sof) for this NoC configration.","icons/help.png"), get_file_name_object ($emulate,"sample$n","sof_file",'sof',$open_in)); $row++;
+ }else{
+
+ my $open_in = abs_path("$ENV{PRONOC_WORK}/emulate/sof");
+ attach_widget_to_table ($table,$row,gen_label_in_left("SoF file:"),gen_button_message ("Select the SRAM Object File (sof) for this NoC configration.","icons/help.png"), get_file_name_object ($emulate,"sample$n","sof_file",'sof',$open_in)); $row++;
+ }
-
-
- my @siminfo = (
+ my @emulateinfo = (
{ label=>'Configuration name:', param_name=>'line_name', type=>'Entry', default_val=>"NoC$n", content=>undef, info=>"NoC configration name. This name will be shown in load-latency graph for this configuration", param_parent=>"sample$n", ref_delay=> undef},
{ label=>"Traffic name", param_name=>'traffic', type=>'Combo-box', default_val=>'random', content=>$traffics, info=>"Select traffic pattern", param_parent=>"sample$n", ref_delay=>undef},
@@ -537,19 +610,67 @@
{ label=>"Packet size in flit:", param_name=>'PCK_SIZE', type=>'Spin-button', default_val=>4, content=>"2,".MAX_PCK_SIZ.",1", info=>undef, param_parent=>"sample$n", ref_delay=>undef},
- { label=>"Packet number limit:", param_name=>'PCK_NUM_LIMIT', type=>'Spin-button', default_val=>1000000, content=>"2,".MAX_PCK_NUM.",1", info=>"Each node stops sending packets when it reaches packet number limit or simulation clock number limit", param_parent=>"sample$n", ref_delay=>undef},
+ { label=>"Packet number limit per node:", param_name=>'PCK_NUM_LIMIT', type=>'Spin-button', default_val=>1000000, content=>"2,".MAX_PCK_NUM.",1", info=>"Each node stops sending packets when it reaches packet number limit or simulation clock number limit", param_parent=>"sample$n", ref_delay=>undef},
{ label=>"Emulation clocks limit:", param_name=>'SIM_CLOCK_LIMIT', type=>'Spin-button', default_val=>MAX_SIM_CLKs, content=>"2,".MAX_SIM_CLKs.",1", info=>"Each node stops sending packets when it reaches packet number limit or simulation clock number limit", param_parent=>"sample$n", ref_delay=>undef},
-);
- foreach my $d ( @siminfo) {
- $row=noc_param_widget ($emulate, $d->{label}, $d->{param_name}, $d->{default_val}, $d->{type}, $d->{content}, $d->{info}, $table,$row,1, $d->{param_parent}, $d->{ref_delay});
-}
+);
+ my @siminfo = (
+ { label=>'Configuration name:', param_name=>'line_name', type=>'Entry', default_val=>"NoC$n", content=>undef, info=>"NoC configration name. This name will be shown in load-latency graph for this configuration", param_parent=>"sample$n", ref_delay=> undef, new_status=>undef},
+ { label=>"Traffic name", param_name=>'traffic', type=>'Combo-box', default_val=>'random', content=>$traffics, info=>"Select traffic pattern", param_parent=>"sample$n", ref_delay=>1, new_status=>'ref_set_win'},
+
+ { label=>"Packet size in flit:", param_name=>'PCK_SIZE', type=>'Spin-button', default_val=>4, content=>"2,".MAX_PCK_SIZ.",1", info=>undef, param_parent=>"sample$n", ref_delay=>undef},
+
+ { label=>"Total packet number limit:", param_name=>'PCK_NUM_LIMIT', type=>'Spin-button', default_val=>200000, content=>"2,".MAX_PCK_NUM.",1", info=>"Simulation will stop when total numbr of sent packets by all nodes reaches packet number limit or total simulation clock reach its limit", param_parent=>"sample$n", ref_delay=>undef, new_status=>undef},
+
+ { label=>"Simulator clocks limit:", param_name=>'SIM_CLOCK_LIMIT', type=>'Spin-button', default_val=>100000, content=>"2,".MAX_SIM_CLKs.",1", info=>"Each node stops sending packets when it reaches packet number limit or simulation clock number limit", param_parent=>"sample$n", ref_delay=>undef, new_status=>undef},
+ );
+
+my @hotspot_info=(
+ { label=>'Hot Spot num:', param_name=>'HOTSPOT_NUM', type=>'Spin-button', default_val=>1,
+ content=>"1,5,1", info=>"Number of hot spot nodes in the network",
+ param_parent=>"sample$n", ref_delay=> 1, new_status=>'ref_set_win'},
+ { label=>'Hot Spot traffic percentage:', param_name=>'HOTSPOT_PERCENTAGE', type=>'Spin-button', default_val=>1,
+ content=>"1,20,1", info=>"If it is set as n then each node sends n % of its traffic to each hotspot node",
+ param_parent=>"sample$n", ref_delay=> undef, new_status=>undef},
+
+ );
+
+
+
+
+
+
+ my @info= ($mode eq "simulate")? @siminfo : @emulateinfo;
+
+
+ foreach my $d ( @info) {
+ $row=noc_param_widget ($emulate, $d->{label}, $d->{param_name}, $d->{default_val}, $d->{type}, $d->{content}, $d->{info}, $table,$row,1, $d->{param_parent}, $d->{ref_delay}, $d->{new_status});
+ }
+ my $traffic=$emulate->object_get_attribute("sample$n","traffic");
+
+ if ($traffic eq 'hot spot'){
+ foreach my $d ( @hotspot_info) {
+ $row=noc_param_widget ($emulate, $d->{label}, $d->{param_name}, $d->{default_val}, $d->{type}, $d->{content}, $d->{info}, $table,$row,1, $d->{param_parent}, $d->{ref_delay}, $d->{new_status});
+ }
+ my $num=$emulate->object_get_attribute("sample$n","HOTSPOT_NUM");
+ for (my $i=0;$i<$num;$i++){
+ my $m=$i+1;
+ $row=noc_param_widget ($emulate, "Hotspot $m tile num:", "HOTSPOT_CORE_$m", 0, 'Spin-button', "0,256,1",
+ "Defne the tile number which is hotspt. All other nodes will send [Hot Spot traffic percentage] of their traffic to this node ", $table,$row,1,"sample$n" );
+
+
+ }
+
+ }
+
+
+
my $l= "Define injection ratios. You can define individual ratios seprating by comma (\',\') or define a range of injection ratios with \$min:\$max:\$step format.
As an example defining 2,3,4:10:2 will result in (2,3,4,6,8,10) injection ratios." ;
my $u=get_injection_ratios ($emulate,"sample$n","ratios");
@@ -566,13 +687,16 @@
$mtable->attach_defaults($scrolled_win,0,1,0,9);
$mtable-> attach ($ok , 0, 1, 9, 10,'expand','shrink',2,2);
- $win->add ($mtable);
- $win->show_all();
+ $set_win->add ($mtable);
+ $set_win->show_all();
+ $set_win ->signal_connect (destroy => sub{
+
+ $emulate->object_add_attribute("active_setting",undef,undef);
+ });
-
@@ -587,14 +711,16 @@
#check if injection ratios are valid
my $r=$emulate->object_get_attribute("sample$n","ratios");
if(defined $s && defined $r) {
- $win->destroy;
+ $set_win->destroy;
+ #$emulate->object_add_attribute("active_setting",undef,undef);
set_gui_status($emulate,"ref",1);
} else {
if(!defined $s){
- message_dialog("Please select sof file!")
+ my $m=($mode eq 'simulate') ? "Please select NoC verilated file" : "Please select sof file!";
+ message_dialog($m);
} else {
- message_dialog("Please define valid injection ratio(s)!")
+ message_dialog("Please define valid injection ratio(s)!");
}
}
});
@@ -602,7 +728,7 @@
-
+
@@ -617,38 +743,56 @@
###################
sub gen_emulation_column {
- my ($emulate,$title, $row_num,$info)=@_;
+ my ($emulate,$mode, $row_num,$info)=@_;
my $table=def_table($row_num,10,FALSE);
my $scrolled_win = new Gtk2::ScrolledWindow (undef, undef);
+ my($width,$hight)=max_win_size();
+ my $set_win=def_popwin_size($width/2.5,$hight*.8,"NoC configuration setting");
+
$scrolled_win->set_policy( "automatic", "automatic" );
$scrolled_win->add_with_viewport($table);
my $row=0;
+
#title
- if(defined $title){
- my $title=gen_label_in_center($title);
- my $box=def_vbox(FALSE, 1);
- $box->pack_start( $title, FALSE, FALSE, 3);
- my $separator = Gtk2::HSeparator->new;
- $box->pack_start( $separator, FALSE, FALSE, 3);
- $table->attach_defaults ($box , 0, 10, $row, $row+1); $row++;
- }
+ my $title_l =($mode eq "simulate" ) ? "NoC Simulator" : "NoC Emulator";
+ my $title=gen_label_in_center($title_l);
+ my $box=def_vbox(FALSE, 1);
+ $box->pack_start( $title, FALSE, FALSE, 3);
+ my $separator = Gtk2::HSeparator->new;
+ $box->pack_start( $separator, FALSE, FALSE, 3);
+ $table->attach_defaults ($box , 0, 10, $row, $row+1); $row++;
- my $lb=gen_label_in_left("Number of emulations");
+
+ my $lb=($mode ne "simulate" ) ? gen_label_in_left("Number of emulations"): gen_label_in_left("Number of simulations");
my $spin= gen_spin_object ($emulate,"emulate_num",undef,"1,100,1",1,'ref','1');
- $table->attach_defaults ($lb, 0, 2, $row, $row+1);
- $table->attach_defaults ($spin, 2, 4, $row, $row+1);$row++;
+ $table->attach ($lb, 0, 2, $row, $row+1,'expand','shrink',2,2);
+ $table->attach ($spin, 2, 4, $row, $row+1,'expand','shrink',2,2);
-
+ #my $mod=gen_combobox_object ($emulate,'mode',undef, 'Emulation,Simulation','Emulation','ref','1');
+
+
+
+ #$table->attach ($lb, 4, 6, $row, $row+1,'expand','shrink',2,2);
+ #$table->attach ($mod, 6, 8, $row, $row+1,'expand','shrink',2,2);
+$row++;
+
+
+
+
+
+ $separator = Gtk2::HSeparator->new;
+ $table->attach_defaults ($separator , 0, 10, $row, $row+1); $row++;
+
my @positions=(0,1,2,3,6,7);
my $col=0;
- my @title=(" NoC configuration", "Line's color", "Clear Graph"," ");
+ my @title=(" Name", " Configuration Setting ", "Line's color", "Clear Graph"," ");
foreach my $t (@title){
- $table->attach_defaults (gen_label_in_center($title[$col]), $positions[$col], $positions[$col+1], $row, $row+1);$col++;
+ $table->attach (gen_label_in_left($title[$col]), $positions[$col], $positions[$col+1], $row, $row+1,'fill','shrink',2,2);$col++;
}
my $traffics="Random,Transposed 1,Transposed 2,Tornado";
@@ -663,6 +807,7 @@
$emulate->object_add_attribute("emulate_num",undef,1);
}
my $i=0;
+ my $active=$emulate->object_get_attribute("active_setting",undef);
for ($i=1;$i<=$sample_num; $i++){
$col=0;
my $sample="sample$i";
@@ -670,16 +815,29 @@
my $set=def_image_button("icons/setting.png");
my $name=$emulate->object_get_attribute($sample,"line_name");
my $l;
- if (defined $name){
- $l=gen_label_in_left($name);
+ my $s=$emulate->object_get_attribute("sample$n","sof_file");
+ #check if injection ratios are valid
+ my $r=$emulate->object_get_attribute("sample$n","ratios");
+ if(defined $s && defined $r && defined $name){
+ $l=gen_label_in_left(" $i- ".$name);
} else {
- $l=gen_label_in_center("Define NoC configuration");
+ $l=gen_label_in_left("Define NoC configuration");
$l->set_markup("Define NoC configuration");
}
- my $box=def_pack_hbox(FALSE,0,(gen_label_in_left("$i- "),$l,$set));
- $table->attach ($box, $positions[$col], $positions[$col+1], $row, $row+1,'expand','shrink',2,2);$col++;
+ #my $box=def_pack_hbox(FALSE,0,(gen_label_in_left("$i- "),$l,$set));
+ $table->attach ($l, $positions[$col], $positions[$col+1], $row, $row+1,'fill','shrink',2,2);$col++;
+ $table->attach ($set, $positions[$col], $positions[$col+1], $row, $row+1,'shrink','shrink',2,2);$col++;
+
+
+ if(defined $active){#The setting windows ask for refershing so open it again
+ get_noc_configuration($emulate,$mode,$n,$set_win) if ($active ==$n);
+ }
+
+
+
$set->signal_connect("clicked"=> sub{
- get_noc_configuration($emulate,$n);
+ $emulate->object_add_attribute("active_setting",undef,$n);
+ get_noc_configuration($emulate,$mode,$n,$set_win);
});
@@ -717,7 +875,8 @@
my $status= $emulate->object_get_attribute('status',undef);
if($status ne 'run'){
- run_emulator($emulate,$info);
+ run_emulator($emulate,$info) if($mode eq 'emulate');
+ run_simulator($emulate,$info) if($mode eq 'simulate');
set_gui_status($emulate,"ref",2);
}
@@ -738,7 +897,7 @@
- return $scrolled_win;
+ return ($scrolled_win,$set_win);
}
@@ -1017,21 +1176,24 @@
sub process_notebook_gen{
- my ($emulate,$info)=@_;
+ my ($emulate,$info,$mode)=@_;
my $notebook = Gtk2::Notebook->new;
$notebook->set_tab_pos ('left');
$notebook->set_scrollable(TRUE);
$notebook->can_focus(FALSE);
- my $page1=gen_emulation_column($emulate,"NoC Configuration",10,$info);
- $notebook->append_page ($page1,Gtk2::Label->new_with_mnemonic (" _Run emulator "));
+
+ my ($page1,$set_win)=gen_emulation_column($emulate, $mode,10,$info);
+ $notebook->append_page ($page1,Gtk2::Label->new_with_mnemonic (" _Run emulator ")) if($mode eq "emulate");
+ $notebook->append_page ($page1,Gtk2::Label->new_with_mnemonic (" _Run simulator ")) if($mode eq "simulate");
- my $page2=get_noc_setting_gui ($emulate,$info);
- my $pp=$notebook->append_page ($page2,Gtk2::Label->new_with_mnemonic (" _Generate sof "));
+ my $page2=get_noc_setting_gui ($emulate,$info,$mode);
+ my $pp=$notebook->append_page ($page2,Gtk2::Label->new_with_mnemonic (" _Generate NoC \n Configuration"));
+
my $scrolled_win = new Gtk2::ScrolledWindow (undef, undef);
$scrolled_win->set_policy( "automatic", "automatic" );
$scrolled_win->add_with_viewport($notebook);
@@ -1043,13 +1205,13 @@
});
- return $scrolled_win;
+ return ($scrolled_win,$set_win);
}
sub get_noc_setting_gui {
- my ($emulate,$info_text)=@_;
+ my ($emulate,$info_text,$mode)=@_;
my $table=def_table(20,10,FALSE);# my ($row,$col,$homogeneous)=@_;
my $scrolled_win = new Gtk2::ScrolledWindow (undef, undef);
$scrolled_win->set_policy( "automatic", "automatic" );
@@ -1067,21 +1229,39 @@
}
-
+my @fpgainfo;
+ if($mode eq "emulate"){
-
- my @fpgainfo = (
+ @fpgainfo = (
{ label=>'FPGA board', param_name=>'FPGA_BOARD', type=>'Combo-box', default_val=>undef, content=>$fpgas, info=>undef, param_parent=>'fpga_param', ref_delay=> undef},
{ label=>'Save as:', param_name=>'SAVE_NAME', type=>"Entry", default_val=>'emulate1', content=>undef, info=>undef, param_parent=>'fpga_param', ref_delay=>undef},
{ label=>"Project directory", param_name=>"SOF_DIR", type=>"DIR_path", default_val=>"$ENV{'PRONOC_WORK'}/emulate", content=>undef, info=>"Define the working directory for generating .sof file", param_parent=>'fpga_param',ref_delay=>undef },
);
- foreach my $d (@fpgainfo) {
+
+}
+else {
+
+@fpgainfo = (
+ #{ label=>'FPGA board', param_name=>'FPGA_BOARD', type=>'Combo-box', default_val=>undef, content=>$fpgas, info=>undef, param_parent=>'fpga_param', ref_delay=> undef},
+ { label=>'Save as:', param_name=>'SAVE_NAME', type=>"Entry", default_val=>'simulate1', content=>undef, info=>undef, param_parent=>'sim_param', ref_delay=>undef},
+ { label=>"Project directory", param_name=>"BIN_DIR", type=>"DIR_path", default_val=>"$ENV{'PRONOC_WORK'}/simulate", content=>undef, info=>"Define the working directory for generating simulation executable binarry file", param_parent=>'sim_param',ref_delay=>undef },
+
+);
+}
+
+
+
+
+foreach my $d (@fpgainfo) {
$row=noc_param_widget ($emulate, $d->{label}, $d->{param_name}, $d->{default_val}, $d->{type}, $d->{content}, $d->{info}, $table,$row,1, $d->{param_parent}, $d->{ref_delay});
}
-
+
+
+
+
@@ -1092,7 +1272,8 @@
$table->attach ($generate, 0,3, $row, $row+1,'expand','shrink',2,2);
$generate->signal_connect ('clicked'=> sub{
- generate_sof_file($emulate,$info_text);
+ generate_sof_file($emulate,$info_text) if($mode eq "emulate");
+ generate_sim_bin_file($emulate,$info_text) if($mode eq "simulate");
});
@@ -1127,6 +1308,9 @@
my $dir = Cwd::getcwd();
my $project_dir = abs_path("$dir/../../");
my ($stdout,$exit)=run_cmd_in_back_ground_get_stdout("mkdir -p $dir_name/src/" );
+
+
+
copy_file_and_folders(\@files,$project_dir,"$dir_name/src/");
foreach my $f(@files){
@@ -1290,7 +1474,7 @@
- my $conf_box=process_notebook_gen($emulate,\$info);
+ my ($conf_box,$set_win)=process_notebook_gen($emulate,\$info,"emulate");
my $chart =gen_chart ($emulate);
@@ -1342,10 +1526,12 @@
$conf_box->destroy();
+ $set_win->destroy();
$chart->destroy();
$image->destroy();
$image = get_status_gif($emulate);
- $conf_box=process_notebook_gen($emulate,\$info);
+
+ ($conf_box,$set_win)=process_notebook_gen($emulate,\$info,"emulate");
$chart =gen_chart ($emulate);
$left_table->attach_defaults ($image , 0, 6, 20, 24);
$left_table->attach_defaults ($conf_box , 0, 6, 0, 12);
@@ -1369,6 +1555,16 @@
set_gui_status($emulate,$state,$timeout);
}
+ elsif($state eq 'ref_set_win'){
+ my $s=$emulate->object_get_attribute("active_setting",undef);
+ $set_win->destroy();
+ $emulate->object_add_attribute("active_setting",undef,$s);
+ $refresh->clicked;
+ #my $saved_name=$mpsoc->mpsoc_get_mpsoc_name();
+ #if(defined $saved_name) {$entry->set_text($saved_name);}
+ set_gui_status($emulate,"ideal",0);
+
+ }
elsif( $state ne "ideal" ){
$refresh->clicked;
#my $saved_name=$mpsoc->mpsoc_get_mpsoc_name();
@@ -1421,3 +1617,104 @@
+
+
+
+
+############
+# run_simulator
+###########
+
+sub run_simulator {
+ my ($simulate,$info)=@_;
+ #return if(!check_samples($emulate,$info));
+ $simulate->object_add_attribute('status',undef,'run');
+ set_gui_status($simulate,"ref",1);
+ show_info($info, "Start Simulation\n");
+
+ my $sample_num=$simulate->object_get_attribute("emulate_num",undef);
+ for (my $i=1; $i<=$sample_num; $i++){
+ my $status=$simulate->object_get_attribute ("sample$i","status");
+ next if($status ne "run");
+ next if(!check_sample($simulate,$i,$info));
+ my $r= $simulate->object_get_attribute("sample$i","ratios");
+ my @ratios=@{check_inserted_ratios($r)};
+ #$emulate->object_add_attribute ("sample$i","status","run");
+ my $bin=$simulate->object_get_attribute ("sample$i","sof_file");
+
+ #load traffic configuration
+ my $patern=$simulate->object_get_attribute ("sample$i",'traffic');
+ my $PCK_SIZE=$simulate->object_get_attribute ("sample$i","PCK_SIZE");
+ my $PCK_NUM_LIMIT=$simulate->object_get_attribute ("sample$i","PCK_NUM_LIMIT");
+ my $SIM_CLOCK_LIMIT=$simulate->object_get_attribute ("sample$i","SIM_CLOCK_LIMIT");
+
+
+ my $HOTSPOT_PERCENTAGE=$simulate->object_get_attribute ("sample$i",'HOTSPOT_PERCENTAGE');
+ my $HOTSPOT_NUM=$simulate->object_get_attribute ("sample$i","HOTSPOT_NUM");
+ my $HOTSPOT_CORE_1=$simulate->object_get_attribute ("sample$i","HOTSPOT_CORE_1");
+ my $HOTSPOT_CORE_2=$simulate->object_get_attribute ("sample$i","HOTSPOT_CORE_2");
+ my $HOTSPOT_CORE_3=$simulate->object_get_attribute ("sample$i","HOTSPOT_CORE_3");
+ my $HOTSPOT_CORE_4=$simulate->object_get_attribute ("sample$i","HOTSPOT_CORE_4");
+ my $HOTSPOT_CORE_5=$simulate->object_get_attribute ("sample$i","HOTSPOT_CORE_5");
+
+ $HOTSPOT_PERCENTAGE = 0 if (!defined $HOTSPOT_PERCENTAGE);
+ $HOTSPOT_NUM=0 if (!defined $HOTSPOT_NUM);
+ $HOTSPOT_CORE_1=0 if (!defined $HOTSPOT_CORE_1);
+ $HOTSPOT_CORE_2=0 if (!defined $HOTSPOT_CORE_2);
+ $HOTSPOT_CORE_3=0 if (!defined $HOTSPOT_CORE_3);
+ $HOTSPOT_CORE_4=0 if (!defined $HOTSPOT_CORE_4);
+ $HOTSPOT_CORE_5=0 if (!defined $HOTSPOT_CORE_5);
+
+
+
+
+
+
+
+ foreach my $ratio_in (@ratios){
+
+ add_info($info, "Run $bin with injection ratio of $ratio_in \% \n");
+ my $cmd="$bin -t \"$patern\" -s $PCK_SIZE -n $PCK_NUM_LIMIT -c $SIM_CLOCK_LIMIT -i $ratio_in -p \"100,0,0,0,0\" -h \"$HOTSPOT_PERCENTAGE,$HOTSPOT_NUM,$HOTSPOT_CORE_1,$HOTSPOT_CORE_2,$HOTSPOT_CORE_3,$HOTSPOT_CORE_4,$HOTSPOT_CORE_5\"";
+ add_info($info, "$cmd \n");
+ my ($stdout,$exit,$stderr)=run_cmd_in_back_ground_get_stdout("$cmd");
+ if($exit){
+ add_info($info, "Error in running simulation: $stderr \n");
+ return;
+ }
+ my @q =split (/average latency =/,$stdout);
+ my $d=$q[1];
+ @q =split (/\n/,$d);
+ my $avg=$q[0];
+ #my $avg = sprintf("%.1f", $avg);
+
+
+
+
+ next if (!defined $avg);
+ my $ref=$simulate->object_get_attribute ("sample$i","result");
+ my %results;
+ %results= %{$ref} if(defined $ref);
+ #push(@results,$avg);
+ $results{$ratio_in}=$avg;
+ $simulate->object_add_attribute ("sample$i","result",\%results);
+ set_gui_status($simulate,"ref",2);
+
+
+
+
+
+
+ }
+ $simulate->object_add_attribute ("sample$i","status","done");
+
+ }
+
+ add_info($info, "Simulation is done!\n");
+ $simulate->object_add_attribute('status',undef,'ideal');
+ set_gui_status($simulate,"ref",1);
+}
+
+
+
+
+
/perl_gui/lib/perl/mpsoc_gen.pl
42,7 → 42,7
|
|
sub noc_param_widget{ |
my ($mpsoc,$name,$param, $default,$type,$content,$info, $table,$row,$show,$attribut1,$ref_delay)=@_; |
my ($mpsoc,$name,$param, $default,$type,$content,$info, $table,$row,$show,$attribut1,$ref_delay,$new_status)=@_; |
my $label =gen_label_in_left(" $name"); |
my $widget; |
my $value=$mpsoc->object_get_attribute($attribut1,$param); |
51,13 → 51,15
$mpsoc->object_add_attribute_order($attribut1,$param); |
$value=$default; |
} |
|
if(! defined $new_status){ |
$new_status='ref'; |
} |
if ($type eq "Entry"){ |
$widget=gen_entry($value); |
$widget-> signal_connect("changed" => sub{ |
my $new_param_value=$widget->get_text(); |
$mpsoc->object_add_attribute($attribut1,$param,$new_param_value); |
set_gui_status($mpsoc,"ref",$ref_delay) if(defined $ref_delay); |
set_gui_status($mpsoc,$new_status,$ref_delay) if(defined $ref_delay); |
|
|
}); |
77,7 → 79,7
$widget-> signal_connect("changed" => sub{ |
my $new_param_value=$widget->get_active_text(); |
$mpsoc->object_add_attribute($attribut1,$param,$new_param_value); |
set_gui_status($mpsoc,"ref",$ref_delay) if(defined $ref_delay); |
set_gui_status($mpsoc,$new_status,$ref_delay) if(defined $ref_delay); |
|
|
}); |
94,7 → 96,7
$widget-> signal_connect("value_changed" => sub{ |
my $new_param_value=$widget->get_value_as_int(); |
$mpsoc->object_add_attribute($attribut1,$param,$new_param_value); |
set_gui_status($mpsoc,"ref",$ref_delay) if(defined $ref_delay); |
set_gui_status($mpsoc,$new_status,$ref_delay) if(defined $ref_delay); |
|
}); |
|
137,7 → 139,7
} |
$mpsoc->object_add_attribute($attribut1,$param,$new_val); |
#print "\$new_val=$new_val\n"; |
set_gui_status($mpsoc,"ref",$ref_delay) if(defined $ref_delay); |
set_gui_status($mpsoc,$new_status,$ref_delay) if(defined $ref_delay); |
}); |
} |
|
147,7 → 149,7
} |
elsif ( $type eq "DIR_path"){ |
$widget =get_dir_in_object ($mpsoc,$attribut1,$param,$value,'ref',10); |
set_gui_status($mpsoc,"ref",$ref_delay) if(defined $ref_delay); |
set_gui_status($mpsoc,$new_status,$ref_delay) if(defined $ref_delay); |
} |
|
|
893,7 → 895,7
|
#Fully and partially adaptive routing setting |
my $route=$mpsoc->object_get_attribute('noc_param',"ROUTE_NAME"); |
if($route ne '"XY"' and $route ne '"TRANC_XY"' ){ |
|
$label="Congestion index"; |
$param="CONGESTION_INDEX"; |
$type="Spin-button"; |
900,11 → 902,14
$content="0,12,1"; |
$info="Congestion index determines how congestion information is collected from neighboring routers. Please refer to the usere manual for more information"; |
$default=3; |
if($route ne '"XY"' and $route ne '"TRANC_XY"' ){ |
$row=noc_param_widget ($mpsoc,$label,$param, $default,$type,$content,$info, $table,$row,$adv_set,'noc_param',undef); |
|
} else { |
$row=noc_param_widget ($mpsoc,$label,$param, $default,$type,$content,$info, $table,$row,0,'noc_param',undef); |
} |
#Fully adaptive routing setting |
if( $route eq '"TRANC_DUATO"' or $route eq '"DUATO"' ){ |
|
my $v=$mpsoc->object_get_attribute('noc_param',"V"); |
$label="Select Escap VC"; |
$param="ESCAP_VC_MASK"; |
916,9 → 921,13
|
|
$info="Select the escap VC for fully adaptive routing."; |
if( $route eq '"TRANC_DUATO"' or $route eq '"DUATO"' ){ |
$row=noc_param_widget ($mpsoc,$label,$param, $default,$type,$content,$info, $table,$row,$adv_set, 'noc_param',undef); |
|
} |
else{ |
$row=noc_param_widget ($mpsoc,$label,$param, $default,$type,$content,$info, $table,$row,0, 'noc_param',undef); |
} |
|
# VC reallocation type |
$label=($router_type eq '"VC_BASED"')? 'VC reallocation type': 'Queue reallocation type'; |
932,7 → 941,7
|
|
|
if ($router_type eq '"VC_BASED"'){ |
|
#vc/sw allocator type |
$label = 'VC/SW combination type'; |
$param='COMBINATION_TYPE'; |
939,9 → 948,13
$default='"COMB_NONSPEC"'; |
$content='"BASELINE","COMB_SPEC1","COMB_SPEC2","COMB_NONSPEC"'; |
$type='Combo-box'; |
$info="The joint VC/ switch allocator type. using canonical combination is not recommanded"; |
$info="The joint VC/ switch allocator type. using canonical combination is not recommanded"; |
if ($router_type eq '"VC_BASED"'){ |
$row=noc_param_widget ($mpsoc,$label,$param, $default,$type,$content,$info, $table,$row,$adv_set,'noc_param',undef); |
|
} else{ |
$row=noc_param_widget ($mpsoc,$label,$param, $default,$type,$content,$info, $table,$row,0,'noc_param',undef); |
|
} |
|
# Crossbar mux type |
/perl_gui/lib/perl/mpsoc_verilog_gen.pl
210,8 → 210,55
} |
|
|
sub gen_noc_param_h{ |
my $mpsoc=shift; |
my $param_h="\n\n//NoC parameters\n"; |
|
my @params=$mpsoc->object_get_attribute_order('noc_param'); |
foreach my $p (@params){ |
my $val=$mpsoc->object_get_attribute('noc_param',$p); |
add_text_to_string (\$param_h,"\t#define $p\t$val\n"); |
|
#print "$p:$val\n"; |
|
} |
my $class=$mpsoc->object_get_attribute('noc_param',"C"); |
my $str; |
if( $class > 1){ |
for (my $i=0; $i<=$class-1; $i++){ |
my $n="Cn_$i"; |
my $val=$mpsoc->object_get_attribute('class_param',$n); |
add_text_to_string (\$param_h,"\t#define $n\t$val\n"); |
} |
$str="CLASS_SETTING {"; |
for (my $i=$class-1; $i>=0;$i--){ |
$str=($i==0)? "${str}Cn_0};\n " : "${str}Cn_$i,"; |
} |
}else { |
$str="CLASS_SETTING={V{1\'b1}}\n"; |
} |
#add_text_to_string (\$param_h,"\t#define $str"); |
|
my $v=$mpsoc->object_get_attribute('noc_param',"V")-1; |
my $escape=$mpsoc->object_get_attribute('noc_param',"ESCAP_VC_MASK"); |
if (! defined $escape){ |
#add_text_to_string (\$param_h,"\tlocalparam [$v :0] ESCAP_VC_MASK=1;\n"); |
#add_text_to_string (\$pass_param,".ESCAP_VC_MASK(ESCAP_VC_MASK),\n"); |
} |
#add_text_to_string (\$param_h," \tlocalparam CVw=(C==0)? V : C * V;\n"); |
#add_text_to_string (\$pass_param,".CVw(CVw)\n"); |
|
|
return $param_h; |
|
|
|
} |
|
|
|
|
|
sub gen_noc_v{ |
my $pass_param = shift; |
|
/perl_gui/lib/perl/simulator.pl
0,0 → 1,375
#! /usr/bin/perl -w |
use Glib qw/TRUE FALSE/; |
use strict; |
use warnings; |
use Gtk2; |
use Gtk2::Ex::Graph::GD; |
use GD::Graph::Data; |
use emulator; |
use IO::CaptureOutput qw(capture qxx qxy); |
use GD::Graph::colour qw/:colours/; |
use Proc::Background; |
use Time::HiRes qw( usleep ualarm gettimeofday tv_interval nanosleep clock_gettime clock_getres clock_nanosleep clock stat ); |
|
use File::Basename; |
use File::Path qw/make_path/; |
use File::Copy; |
use File::Find::Rule; |
|
require "widget.pl"; |
require "mpsoc_gen.pl"; |
require "emulator.pl"; |
require "mpsoc_verilog_gen.pl"; |
require "readme_gen.pl"; |
|
use List::MoreUtils qw(uniq); |
|
|
|
|
sub generate_sim_bin_file() { |
my ($simulate,$info_text) =@_; |
my $dir = Cwd::getcwd(); |
my $project_dir = abs_path("$dir/.."); |
my $src_verilator_dir="$project_dir/src_verilator"; |
my $script_dir="$project_dir/script"; |
# save parameters inside parameter.v file in src_verilator folder |
my ($noc_param,$pass_param)=gen_noc_param_v($simulate); |
open(FILE, ">$src_verilator_dir/parameter.v") || die "Can not open: $!"; |
print FILE " \`ifdef INCLUDE_PARAM \n \n |
$noc_param |
localparam P=(TOPOLOGY==\"RING\")? 3 : 5; |
localparam ROUTE_TYPE = (ROUTE_NAME == \"XY\" || ROUTE_NAME == \"TRANC_XY\" )? \"DETERMINISTIC\" : |
(ROUTE_NAME == \"DUATO\" || ROUTE_NAME == \"TRANC_DUATO\" )? \"FULL_ADAPTIVE\": \"PAR_ADAPTIVE\"; |
|
//simulation parameter |
localparam MAX_PCK_NUM = ".MAX_SIM_CLKs."; |
localparam MAX_PCK_SIZ = ".MAX_PCK_SIZ."; |
localparam MAX_SIM_CLKs= ".MAX_SIM_CLKs."; |
localparam TIMSTMP_FIFO_NUM = 16; |
\n \n \`endif" ; |
close FILE; |
|
|
|
|
#verilate the noc |
|
add_info($info_text, "verilate the NoC and make the library files"); |
my $command = "cd \"$script_dir/\" \n xterm -l -lf logfile1.txt -e sh verilator_compile_hw.sh"; |
my ($stdout,$exit)=run_cmd_in_back_ground_get_stdout( $command); |
if($exit != 0){ |
print "Verilator compilation failed !\n"; |
add_info($info_text, "Verilator compilation failed !\n$command\n $stdout\n"); |
return; |
} |
|
|
|
#compile the testbench |
my $param_h=gen_noc_param_h($simulate); |
$param_h =~ s/\d\'b/ /g; |
open(FILE, ">$src_verilator_dir/parameter.h") || die "Can not open: $!"; |
print FILE " |
#ifndef INCLUDE_PARAM |
#define INCLUDE_PARAM \n \n |
|
$param_h |
|
int P=(strcmp (TOPOLOGY,\"RING\")==0) ? 3 : 5; |
|
|
//simulation parameter |
#define AVG_LATENCY_METRIC \"HEAD_2_TAIL\" |
#define TIMSTMP_FIFO_NUM 16 |
\n \n \#endif" ; |
close FILE; |
|
$command = "cd \"$script_dir/\" \n xterm -l -lf logfile2.txt -e sh verilator_compile_simulator.sh"; |
($stdout,$exit)=run_cmd_in_back_ground_get_stdout( $command); |
if($exit != 0){ |
print "Verilator compilation failed !\n"; |
add_info($info_text, "Verilator compilation failed !\n$command\n $stdout\n"); |
return; |
} |
|
|
|
|
#save the binarry file |
my $bin= "$ENV{PRONOC_WORK}/verilator/work/processed_rtl/obj_dir/testbench"; |
my $path=$simulate->object_get_attribute ('sim_param',"BIN_DIR"); |
my $name=$simulate->object_get_attribute ('sim_param',"SAVE_NAME"); |
|
#create project didrectory if its not exist |
($stdout,$exit)=run_cmd_in_back_ground_get_stdout("mkdir -p $path" ); |
if($exit != 0 ){ print "$stdout\n"; message_dialog($stdout); return;} |
|
#move the log file |
move("$script_dir/logfile1.txt" , "$path/$name.log1"); |
move("$script_dir/logfile2.txt" , "$path/$name.log2"); |
|
#check if the verilation was successful |
if ((-e $bin)==0) {#something goes wrong |
message_dialog("Verilator compilation was unsuccessful please check the $path/$name.log files for more information"); |
return; |
} |
|
|
#copy ($bin,"$path/$name") or die "Can not copy: $!"; |
($stdout,$exit)=run_cmd_in_back_ground_get_stdout("cp -f $bin $path/$name"); |
if($exit != 0 ){ print "$stdout\n"; message_dialog($stdout); return;} |
|
#save noc info |
open(FILE, ">$path/$name.inf") || die "Can not open: $!"; |
print FILE perl_file_header("$name.inf"); |
my %pp; |
$pp{'noc_param'}= $simulate->{'noc_param'}; |
$pp{'sim_param'}= $simulate->{'sim_param'}; |
print FILE Data::Dumper->Dump([\%pp],["emulate_info"]); |
close(FILE) || die "Error closing file: $!"; |
|
message_dialog("The simulation binary file has been successfully generated in $path!"); |
|
|
#make project dir |
#my $dir= $simulate->object_get_attribute ("sim_param","BIN_DIR"); |
#my $name=$simulate->object_get_attribute ("sim_param","SAVE_NAME"); |
#my $path= "$dir/$name"; |
#add_info($info_text, "$src_verilator_dir!\n"); |
#mkpath("$path",1,01777); |
|
|
|
|
|
} |
|
|
########## |
# save_emulation |
########## |
sub save_simulation { |
my ($simulate)=@_; |
# read emulation name |
my $name=$simulate->object_get_attribute ("simulate_name",undef); |
my $s= (!defined $name)? 0 : (length($name)==0)? 0 :1; |
if ($s == 0){ |
message_dialog("Please set Simulation name!"); |
return 0; |
} |
# Write object file |
open(FILE, ">lib/simulate/$name.SIM") || die "Can not open: $!"; |
print FILE perl_file_header("$name.SIM"); |
print FILE Data::Dumper->Dump([\%$simulate],[$name]); |
close(FILE) || die "Error closing file: $!"; |
message_dialog("Simulation has saved as lib/simulate/$name.SIM!"); |
return 1; |
} |
|
############# |
# load_emulation |
############ |
|
sub load_simulation { |
my ($simulate,$info)=@_; |
my $file; |
my $dialog = Gtk2::FileChooserDialog->new( |
'Select a File', undef, |
'open', |
'gtk-cancel' => 'cancel', |
'gtk-ok' => 'ok', |
); |
|
my $filter = Gtk2::FileFilter->new(); |
$filter->set_name("SIM"); |
$filter->add_pattern("*.SIM"); |
$dialog->add_filter ($filter); |
my $dir = Cwd::getcwd(); |
$dialog->set_current_folder ("$dir/lib/simulate"); |
|
|
if ( "ok" eq $dialog->run ) { |
$file = $dialog->get_filename; |
my ($name,$path,$suffix) = fileparse("$file",qr"\..[^.]*$"); |
if($suffix eq '.SIM'){ |
my $pp= eval { do $file }; |
if ($@ || !defined $pp){ |
add_info($info,"**Error reading $file file: $@\n"); |
$dialog->destroy; |
return; |
} |
#deactivate running simulations |
$pp->object_add_attribute('status',undef,'ideal'); |
my $sample_num=$pp->object_get_attribute("emulate_num",undef); |
for (my $i=1; $i<=$sample_num; $i++){ |
my $st=$pp->object_get_attribute ("sample$i","status"); |
$pp->object_add_attribute ("sample$i","status",'done');# if ($st eq "run"); |
} |
clone_obj($simulate,$pp); |
#message_dialog("done!"); |
} |
} |
$dialog->destroy; |
} |
|
|
############ |
# main |
############ |
sub simulator_main{ |
|
add_color_to_gd(); |
my $simulate= emulator->emulator_new(); |
set_gui_status($simulate,"ideal",0); |
my $left_table = Gtk2::Table->new (25, 6, FALSE); |
my $right_table = Gtk2::Table->new (25, 6, FALSE); |
|
my $main_table = Gtk2::Table->new (25, 12, FALSE); |
my ($infobox,$info)= create_text(); |
my $refresh = Gtk2::Button->new_from_stock('ref'); |
|
|
|
|
|
my ($conf_box,$set_win)=process_notebook_gen($simulate,\$info,"simulate"); |
my $chart =gen_chart ($simulate); |
|
|
|
$main_table->set_row_spacings (4); |
$main_table->set_col_spacings (1); |
|
#my $device_win=show_active_dev($soc,$soc,$infc,$soc_state,\$refresh,$info); |
|
|
my $generate = def_image_button('icons/forward.png','Run all'); |
my $open = def_image_button('icons/browse.png','Load'); |
|
|
|
|
my ($entrybox,$entry) = def_h_labeled_entry('Save as:',undef); |
$entry->signal_connect( 'changed'=> sub{ |
my $name=$entry->get_text(); |
$simulate->object_add_attribute ("simulate_name",undef,$name); |
}); |
my $save = def_image_button('icons/save.png','Save'); |
$entrybox->pack_end($save, FALSE, FALSE,0); |
|
|
#$table->attach_defaults ($event_box, $col, $col+1, $row, $row+1); |
my $image = get_status_gif($simulate); |
|
|
|
|
|
$left_table->attach_defaults ($conf_box , 0, 6, 0, 20); |
$left_table->attach_defaults ($image , 0, 6, 20, 24); |
$left_table->attach ($open,0, 3, 24,25,'expand','shrink',2,2); |
$left_table->attach ($entrybox,3, 6, 24,25,'expand','shrink',2,2); |
$right_table->attach_defaults ($infobox , 0, 6, 0,12); |
$right_table->attach_defaults ($chart , 0, 6, 12, 24); |
$right_table->attach ($generate, 4, 6, 24,25,'expand','shrink',2,2); |
$main_table->attach_defaults ($left_table , 0, 6, 0, 25); |
$main_table->attach_defaults ($right_table , 6, 12, 0, 25); |
|
|
|
#referesh the mpsoc generator |
$refresh-> signal_connect("clicked" => sub{ |
my $name=$simulate->object_get_attribute ("simulate_name",undef); |
$entry->set_text($name) if(defined $name); |
|
|
$conf_box->destroy(); |
$chart->destroy(); |
$image->destroy(); |
$image = get_status_gif($simulate); |
($conf_box,$set_win)=process_notebook_gen($simulate,\$info,"simulate"); |
$chart =gen_chart ($simulate); |
$left_table->attach_defaults ($image , 0, 6, 20, 24); |
$left_table->attach_defaults ($conf_box , 0, 6, 0, 12); |
$right_table->attach_defaults ($chart , 0, 6, 12, 24); |
|
$conf_box->show_all(); |
$main_table->show_all(); |
|
|
}); |
|
|
|
#check soc status every 0.5 second. referesh device table if there is any changes |
Glib::Timeout->add (100, sub{ |
|
my ($state,$timeout)= get_gui_status($simulate); |
|
if ($timeout>0){ |
$timeout--; |
set_gui_status($simulate,$state,$timeout); |
|
} |
elsif($state eq 'ref_set_win'){ |
|
my $s=$simulate->object_get_attribute("active_setting",undef); |
$set_win->destroy(); |
$simulate->object_add_attribute("active_setting",undef,$s); |
$refresh->clicked; |
set_gui_status($simulate,"ideal",0); |
|
} |
elsif( $state ne "ideal" ){ |
$refresh->clicked; |
#my $saved_name=$mpsoc->mpsoc_get_mpsoc_name(); |
#if(defined $saved_name) {$entry->set_text($saved_name);} |
set_gui_status($simulate,"ideal",0); |
|
} |
return TRUE; |
|
} ); |
|
|
$generate-> signal_connect("clicked" => sub{ |
my $sample_num=$simulate->object_get_attribute("emulate_num",undef); |
for (my $i=1; $i<=$sample_num; $i++){ |
$simulate->object_add_attribute ("sample$i","status","run"); |
} |
run_simulator($simulate,\$info); |
#set_gui_status($emulate,"ideal",2); |
|
}); |
|
# $wb-> signal_connect("clicked" => sub{ |
# wb_address_setting($mpsoc); |
# |
# }); |
|
$open-> signal_connect("clicked" => sub{ |
|
load_simulation($simulate,\$info); |
set_gui_status($simulate,"ref",5); |
|
}); |
|
$save-> signal_connect("clicked" => sub{ |
save_simulation($simulate); |
set_gui_status($simulate,"ref",5); |
|
|
}); |
|
my $sc_win = new Gtk2::ScrolledWindow (undef, undef); |
$sc_win->set_policy( "automatic", "automatic" ); |
$sc_win->add_with_viewport($main_table); |
|
return $sc_win; |
|
|
} |
|
|
|
perl_gui/lib/perl/simulator.pl
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: perl_gui/lib/perl/widget.pl
===================================================================
--- perl_gui/lib/perl/widget.pl (revision 31)
+++ perl_gui/lib/perl/widget.pl (revision 32)
@@ -1104,7 +1104,7 @@
} else {
$lable=gen_label_in_center("Selecet a $extension file");
- $lable->set_markup("Selecet a sof file");
+ $lable->set_markup("No file has been selected yet");
}
my $entry=gen_entry();
my $browse= get_file_name($object,undef,$entry,$attribute1,$attribute2,$extension,$lable,$open_in);
/script/parameter.sh
1,7 → 1,7
#!/bin/sh |
|
CORE_NUM(){ |
# local variable x and y with passed args |
# local variable x and y with passed args |
local x=$1 |
local y=$2 |
|
10,14 → 10,14
|
|
# NoC parameters: |
V=2 # number of VC per port |
TOPOLOGY="MESH" #"MESH" or "TORUS" |
V=2 # number of VC per port |
TOPOLOGY="MESH" #"MESH" or "TORUS" |
P="(TOPOLOGY==\"RING\")? 3 : 5" # number of port per router |
B=4 # buffer space :flit per VC |
NX=8 # number of node in x axis |
NY=8 # number of node in y axis |
C=1 # number of flit class |
Fpay=32 #flit payload width |
Fpay=32 #flit payload width |
MUX_TYPE="ONE_HOT" #crossbar multiplexer type : "ONE_HOT" or "BINARY" |
VC_REALLOCATION_TYPE="NONATOMIC" # "ATOMIC" or "NONATOMIC" |
COMBINATION_TYPE="COMB_NONSPEC" # "BASELINE" or "COMB_SPEC1" or "COMB_SPEC2" or "COMB_NONSPEC" |
24,17 → 24,17
FIRST_ARBITER_EXT_P_EN=0 |
|
ROUTE_NAME="XY" # Routing algorithm |
# mesh : "XY" , "WEST_FIRST" , "NORTH_LAST" , "NEGETIVE_FIRST" , "DUATO" |
# mesh : "XY" , "WEST_FIRST" , "NORTH_LAST" , "NEGETIVE_FIRST" , "DUATO" |
# torus: "TRANC_XY" , "TRANC_WEST_FIRST", "TRANC_NORTH_LAST", "TRANC_NEGETIVE_FIRST", "TRANC_DUATO" |
|
|
CLASS_SETTING="{CVw{1'b1}}" |
|
SSA_EN="NO" |
|
CLASS_SETTING="{CVw{1'b1}}" |
|
SSA_EN="NO" |
|
|
ADD_PIPREG_AFTER_CROSSBAR=0 |
|
|
ADD_PIPREG_AFTER_CROSSBAR=0 |
|
#simulation parameters: |
C0_p=100 # the percentage of injected packets with class 0 |
C1_p=0 |
44,13 → 44,13
|
|
# Simulation parameters: |
AVG_LATENCY_METRIC="HEAD_2_TAIL" |
# HEAD_2_TAIL : The average latency is calculated based on the time when the head flit is injected until the tail flit is received |
# HEAD_2_HEAD : The average latency is calculated based on the time when the head flit is injected until it reachs the destination |
AVG_LATENCY_METRIC="HEAD_2_TAIL" |
# HEAD_2_TAIL : The average latency is calculated based on the time when the head flit is injected until the tail flit is received |
# HEAD_2_HEAD : The average latency is calculated based on the time when the head flit is injected until it reachs the destination |
TRAFFIC="TRANSPOSE2" # "RANDOM", "TRANSPOSE1","TRANSPOSE2", "HOTSPOT"; |
#Hotspot Traffic setting |
HOTSPOT_PERCENTAGE=3 #maximum 20 |
HOTSOPT_NUM=4 #maximum 5 |
HOTSPOT_PERCENTAGE=3 #maximum 20 |
HOTSOPT_NUM=4 #maximum 5 |
HOTSPOT_CORE_1=$(CORE_NUM 1 1) |
HOTSPOT_CORE_2=$(CORE_NUM 1 3) |
HOTSPOT_CORE_3=$(CORE_NUM 3 1) |
60,124 → 60,124
|
|
|
MAX_PCK_NUM=128000 |
MAX_PCK_NUM=128000 |
MAX_SIM_CLKs=100000 |
MAX_PCK_SIZ=10 # maximum flit number in a single packet |
MAX_PCK_SIZ=10 # maximum flit number in a single packet |
TIMSTMP_FIFO_NUM=64 |
|
|
|
ESCAP_VC_MASK="1" # mask escape vc |
DEBUG_EN=1 |
|
CONGESTION_INDEX=3 # 0: packets are routed to the ports with more available VCs |
# 1: packets are routed to the ports with more available credits |
# 2: packets are routed to the ports connected to the routers with less active ivc requests |
# 3: packets are routed to the ports connected to the routers with less active ivc requests that are not granted |
ESCAP_VC_MASK="1" # mask escape vc |
DEBUG_EN=1 |
|
CONGESTION_INDEX=3 # 0: packets are routed to the ports with more available VCs |
# 1: packets are routed to the ports with more available credits |
# 2: packets are routed to the ports connected to the routers with less active ivc requests |
# 3: packets are routed to the ports connected to the routers with less active ivc requests that are not granted |
|
|
|
|
|
# Simulation C file constant: |
PACKET_SIZE=2 # packet size in flit. Minimum is 2 |
PACKET_SIZE=2 # packet size in flit. Minimum is 2 |
|
|
# |
ROUTE_SUBFUNC="NORTH_LAST" # "NORTH_LAST" ,"XY" |
AVC_ATOMIC_EN=0 |
STND_DEV_EN=0 # 1: generate standard devision |
|
ROUTE_SUBFUNC="NORTH_LAST" # "NORTH_LAST" ,"XY" |
AVC_ATOMIC_EN=0 |
STND_DEV_EN=0 # 1: generate standard devision |
|
generate_parameter_v (){ |
printf " \`ifdef INCLUDE_PARAM \n\n" >> parameter.v |
printf " parameter V=$V;\n" >> parameter.v |
printf " parameter TOPOLOGY=\"$TOPOLOGY\";\n" >> parameter.v |
printf " parameter P=$P;\n" >> parameter.v |
printf " parameter B=$B;\n" >> parameter.v |
printf " parameter NX=$NX;\n" >> parameter.v |
printf " parameter NY=$NY;\n" >> parameter.v |
printf " parameter C=$C;\n" >> parameter.v |
printf " parameter Fpay=$Fpay;\n" >> parameter.v |
printf " parameter MUX_TYPE=\"$MUX_TYPE\";\n" >> parameter.v |
printf " parameter VC_REALLOCATION_TYPE=\"$VC_REALLOCATION_TYPE\";\n" >> parameter.v |
printf " parameter COMBINATION_TYPE=\"$COMBINATION_TYPE\";\n" >> parameter.v |
printf " parameter FIRST_ARBITER_EXT_P_EN=$FIRST_ARBITER_EXT_P_EN;\n" >> parameter.v |
|
printf " parameter ROUTE_NAME=\"$ROUTE_NAME\";\n" >> parameter.v |
printf " parameter CONGESTION_INDEX=$CONGESTION_INDEX;\n" >> parameter.v |
printf " parameter C0_p=$C0_p;\n" >> parameter.v |
printf " \`ifdef INCLUDE_PARAM \n\n" >> parameter.v |
printf " parameter V=$V;\n" >> parameter.v |
printf " parameter TOPOLOGY=\"$TOPOLOGY\";\n" >> parameter.v |
printf " parameter P=$P;\n" >> parameter.v |
printf " parameter B=$B;\n" >> parameter.v |
printf " parameter NX=$NX;\n" >> parameter.v |
printf " parameter NY=$NY;\n" >> parameter.v |
printf " parameter C=$C;\n" >> parameter.v |
printf " parameter Fpay=$Fpay;\n" >> parameter.v |
printf " parameter MUX_TYPE=\"$MUX_TYPE\";\n" >> parameter.v |
printf " parameter VC_REALLOCATION_TYPE=\"$VC_REALLOCATION_TYPE\";\n" >> parameter.v |
printf " parameter COMBINATION_TYPE=\"$COMBINATION_TYPE\";\n" >> parameter.v |
printf " parameter FIRST_ARBITER_EXT_P_EN=$FIRST_ARBITER_EXT_P_EN;\n" >> parameter.v |
|
printf " parameter ROUTE_NAME=\"$ROUTE_NAME\";\n" >> parameter.v |
printf " parameter CONGESTION_INDEX=$CONGESTION_INDEX;\n" >> parameter.v |
printf " parameter C0_p=$C0_p;\n" >> parameter.v |
printf " parameter C1_p=$C1_p;\n" >> parameter.v |
printf " parameter C2_p=$C2_p;\n" >> parameter.v |
printf " parameter C3_p=$C3_p;\n" >> parameter.v |
printf " parameter TRAFFIC=\"$TRAFFIC\";\n" >> parameter.v |
printf " parameter HOTSPOT_PERCENTAGE=$HOTSPOT_PERCENTAGE;\n" >> parameter.v |
printf " parameter HOTSOPT_NUM=$HOTSOPT_NUM;\n" >> parameter.v |
printf " parameter HOTSPOT_CORE_1=$HOTSPOT_CORE_1;\n" >> parameter.v |
printf " parameter HOTSPOT_CORE_2=$HOTSPOT_CORE_2;\n" >> parameter.v |
printf " parameter HOTSPOT_CORE_3=$HOTSPOT_CORE_3;\n" >> parameter.v |
printf " parameter HOTSPOT_CORE_4=$HOTSPOT_CORE_4;\n" >> parameter.v |
printf " parameter HOTSPOT_CORE_5=$HOTSPOT_CORE_5;\n" >> parameter.v |
printf " parameter MAX_PCK_NUM=$MAX_PCK_NUM;\n" >> parameter.v |
printf " parameter MAX_SIM_CLKs=$MAX_SIM_CLKs;\n" >> parameter.v |
printf " parameter MAX_PCK_SIZ=$MAX_PCK_SIZ;\n" >> parameter.v |
printf " parameter TIMSTMP_FIFO_NUM=$TIMSTMP_FIFO_NUM;\n" >> parameter.v |
printf " parameter ROUTE_TYPE = (ROUTE_NAME == \"XY\" || ROUTE_NAME == \"TRANC_XY\" )? \"DETERMINISTIC\" : \n" >> parameter.v |
printf " (ROUTE_NAME == \"DUATO\" || ROUTE_NAME == \"TRANC_DUATO\" )? \"FULL_ADAPTIVE\": \"PAR_ADAPTIVE\"; \n" >> parameter.v |
printf " parameter DEBUG_EN=$DEBUG_EN;\n" >> parameter.v |
printf " parameter ROUTE_SUBFUNC= \"$ROUTE_SUBFUNC\";\n">> parameter.v |
printf " parameter AVC_ATOMIC_EN= $AVC_ATOMIC_EN;\n">> parameter.v |
printf " parameter AVG_LATENCY_METRIC= \"$AVG_LATENCY_METRIC\";\n">> parameter.v |
printf " parameter ADD_PIPREG_AFTER_CROSSBAR= $ADD_PIPREG_AFTER_CROSSBAR;\n" >> parameter.v |
printf " parameter CVw=(C==0)? V : C * V;\n" >> parameter.v |
printf " parameter [CVw-1: 0] CLASS_SETTING = $CLASS_SETTING;\n">> parameter.v |
printf " parameter [V-1 : 0] ESCAP_VC_MASK=$ESCAP_VC_MASK;\n" >> parameter.v |
printf " parameter SSA_EN= \"$SSA_EN\";\n">> parameter.v |
printf " \n\n \`endif " >> parameter.v |
|
|
printf " parameter TRAFFIC=\"$TRAFFIC\";\n" >> parameter.v |
printf " parameter HOTSPOT_PERCENTAGE=$HOTSPOT_PERCENTAGE;\n" >> parameter.v |
printf " parameter HOTSOPT_NUM=$HOTSOPT_NUM;\n" >> parameter.v |
printf " parameter HOTSPOT_CORE_1=$HOTSPOT_CORE_1;\n" >> parameter.v |
printf " parameter HOTSPOT_CORE_2=$HOTSPOT_CORE_2;\n" >> parameter.v |
printf " parameter HOTSPOT_CORE_3=$HOTSPOT_CORE_3;\n" >> parameter.v |
printf " parameter HOTSPOT_CORE_4=$HOTSPOT_CORE_4;\n" >> parameter.v |
printf " parameter HOTSPOT_CORE_5=$HOTSPOT_CORE_5;\n" >> parameter.v |
printf " parameter MAX_PCK_NUM=$MAX_PCK_NUM;\n" >> parameter.v |
printf " parameter MAX_SIM_CLKs=$MAX_SIM_CLKs;\n" >> parameter.v |
printf " parameter MAX_PCK_SIZ=$MAX_PCK_SIZ;\n" >> parameter.v |
printf " parameter TIMSTMP_FIFO_NUM=$TIMSTMP_FIFO_NUM;\n" >> parameter.v |
printf " parameter ROUTE_TYPE = (ROUTE_NAME == \"XY\" || ROUTE_NAME == \"TRANC_XY\" )? \"DETERMINISTIC\" : \n" >> parameter.v |
printf " (ROUTE_NAME == \"DUATO\" || ROUTE_NAME == \"TRANC_DUATO\" )? \"FULL_ADAPTIVE\": \"PAR_ADAPTIVE\"; \n" >> parameter.v |
printf " parameter DEBUG_EN=$DEBUG_EN;\n" >> parameter.v |
printf " parameter ROUTE_SUBFUNC= \"$ROUTE_SUBFUNC\";\n">> parameter.v |
printf " parameter AVC_ATOMIC_EN= $AVC_ATOMIC_EN;\n">> parameter.v |
printf " parameter AVG_LATENCY_METRIC= \"$AVG_LATENCY_METRIC\";\n">> parameter.v |
printf " parameter ADD_PIPREG_AFTER_CROSSBAR= $ADD_PIPREG_AFTER_CROSSBAR;\n" >> parameter.v |
printf " parameter CVw=(C==0)? V : C * V;\n" >> parameter.v |
printf " parameter [CVw-1: 0] CLASS_SETTING = $CLASS_SETTING;\n">> parameter.v |
printf " parameter [V-1 : 0] ESCAP_VC_MASK=$ESCAP_VC_MASK;\n" >> parameter.v |
printf " parameter SSA_EN= \"$SSA_EN\";\n">> parameter.v |
printf " \n\n \`endif " >> parameter.v |
|
|
} |
|
generate_parameter_h (){ |
printf " #ifndef INCLUDE_PARAM\n " >> parameter.h |
printf " #define INCLUDE_PARAM\n\n" >> parameter.h |
printf "\t #define V $V\n" >> parameter.h |
printf "\t #define B $B\n" >> parameter.h |
printf "\t #define NX $NX\n" >> parameter.h |
printf "\t #define NY $NY\n" >> parameter.h |
printf "\t #define C $C\n" >> parameter.h |
printf "\t #define Fpay $Fpay\n" >> parameter.h |
printf "\t #define MUX_TYPE \"$MUX_TYPE\"\n" >> parameter.h |
printf "\t #define VC_REALLOCATION_TYPE \"$VC_REALLOCATION_TYPE\"\n" >> parameter.h |
printf "\t #define COMBINATION_TYPE \"$COMBINATION_TYPE\"\n" >> parameter.h |
printf "\t #define FIRST_ARBITER_EXT_P_EN $FIRST_ARBITER_EXT_P_EN\n" >> parameter.h |
printf "\t #define TOPOLOGY \"$TOPOLOGY\"\n" >> parameter.h |
printf "\t #define ROUTE_NAME \"$ROUTE_NAME\"\n" >> parameter.h |
printf "\t #define C0_p $C0_p\n" >> parameter.h |
printf "\t #define C1_p $C1_p\n" >> parameter.h |
printf "\t #define C2_p $C2_p\n" >> parameter.h |
printf "\t #define C3_p $C3_p\n" >> parameter.h |
printf "\t #define TRAFFIC \"$TRAFFIC\"\n" >> parameter.h |
printf "\t #define HOTSPOT_PERCENTAGE $HOTSPOT_PERCENTAGE\n" >> parameter.h |
printf "\t #define HOTSOPT_NUM $HOTSOPT_NUM\n" >> parameter.h |
printf "\t #define HOTSPOT_CORE_1 $HOTSPOT_CORE_1\n" >> parameter.h |
printf "\t #define HOTSPOT_CORE_2 $HOTSPOT_CORE_2\n" >> parameter.h |
printf "\t #define HOTSPOT_CORE_3 $HOTSPOT_CORE_3\n" >> parameter.h |
printf "\t #define HOTSPOT_CORE_4 $HOTSPOT_CORE_4\n" >> parameter.h |
printf "\t #define HOTSPOT_CORE_5 $HOTSPOT_CORE_5\n" >> parameter.h |
printf "\t #define MAX_PCK_NUM $MAX_PCK_NUM\n" >> parameter.h |
printf "\t #define MAX_SIM_CLKs $MAX_SIM_CLKs\n" >> parameter.h |
printf "\t #define MAX_PCK_SIZ $MAX_PCK_SIZ\n" >> parameter.h |
printf "\t #define TIMSTMP_FIFO_NUM $TIMSTMP_FIFO_NUM\n" >> parameter.h |
printf "\t #define PACKET_SIZE $PACKET_SIZE\n" >> parameter.h |
printf "\t #define DEBUG_EN $DEBUG_EN\n" >> parameter.h |
printf "\t #define ROUTE_SUBFUNC \"$ROUTE_SUBFUNC\"\n" >> parameter.h |
printf "\t #define AVC_ATOMIC_EN $AVC_ATOMIC_EN\n" >> parameter.h |
printf "\t #define CONGESTION_INDEX $CONGESTION_INDEX\n">>parameter.h |
printf "\t #define STND_DEV_EN $STND_DEV_EN\n">> parameter.h |
printf "\t #define AVG_LATENCY_METRIC \"$AVG_LATENCY_METRIC\"\n">> parameter.h |
printf "\t #define ADD_PIPREG_AFTER_CROSSBAR $ADD_PIPREG_AFTER_CROSSBAR\n" >> parameter.h |
printf "\t #define CVw (C==0)? V : C * V\n" >> parameter.h |
printf "\t #define CLASS_SETTING \"$CLASS_SETTING\"\n">> parameter.h |
printf "\t #define ESCAP_VC_MASK $ESCAP_VC_MASK\n">> parameter.h |
printf "\t #define SSA_EN \"$SSA_EN\"\n" >> parameter.h |
printf " \n\n #endif " >> parameter.h |
|
printf " #ifndef INCLUDE_PARAM\n " >> parameter.h |
printf " #define INCLUDE_PARAM\n\n" >> parameter.h |
printf "\t #define V $V\n" >> parameter.h |
printf "\t #define B $B\n" >> parameter.h |
printf "\t #define NX $NX\n" >> parameter.h |
printf "\t #define NY $NY\n" >> parameter.h |
printf "\t #define C $C\n" >> parameter.h |
printf "\t #define Fpay $Fpay\n" >> parameter.h |
printf "\t #define MUX_TYPE \"$MUX_TYPE\"\n" >> parameter.h |
printf "\t #define VC_REALLOCATION_TYPE \"$VC_REALLOCATION_TYPE\"\n" >> parameter.h |
printf "\t #define COMBINATION_TYPE \"$COMBINATION_TYPE\"\n" >> parameter.h |
printf "\t #define FIRST_ARBITER_EXT_P_EN $FIRST_ARBITER_EXT_P_EN\n" >> parameter.h |
printf "\t #define TOPOLOGY \"$TOPOLOGY\"\n" >> parameter.h |
printf "\t #define ROUTE_NAME \"$ROUTE_NAME\"\n" >> parameter.h |
printf "\t #define C0_p $C0_p\n" >> parameter.h |
printf "\t #define C1_p $C1_p\n" >> parameter.h |
printf "\t #define C2_p $C2_p\n" >> parameter.h |
printf "\t #define C3_p $C3_p\n" >> parameter.h |
printf "\t #define TRAFFIC \"$TRAFFIC\"\n" >> parameter.h |
printf "\t #define HOTSPOT_PERCENTAGE $HOTSPOT_PERCENTAGE\n" >> parameter.h |
printf "\t #define HOTSOPT_NUM $HOTSOPT_NUM\n" >> parameter.h |
printf "\t #define HOTSPOT_CORE_1 $HOTSPOT_CORE_1\n" >> parameter.h |
printf "\t #define HOTSPOT_CORE_2 $HOTSPOT_CORE_2\n" >> parameter.h |
printf "\t #define HOTSPOT_CORE_3 $HOTSPOT_CORE_3\n" >> parameter.h |
printf "\t #define HOTSPOT_CORE_4 $HOTSPOT_CORE_4\n" >> parameter.h |
printf "\t #define HOTSPOT_CORE_5 $HOTSPOT_CORE_5\n" >> parameter.h |
printf "\t #define MAX_PCK_NUM $MAX_PCK_NUM\n" >> parameter.h |
printf "\t #define MAX_SIM_CLKs $MAX_SIM_CLKs\n" >> parameter.h |
printf "\t #define MAX_PCK_SIZ $MAX_PCK_SIZ\n" >> parameter.h |
printf "\t #define TIMSTMP_FIFO_NUM $TIMSTMP_FIFO_NUM\n" >> parameter.h |
printf "\t #define PACKET_SIZE $PACKET_SIZE\n" >> parameter.h |
printf "\t #define DEBUG_EN $DEBUG_EN\n" >> parameter.h |
printf "\t #define ROUTE_SUBFUNC \"$ROUTE_SUBFUNC\"\n" >> parameter.h |
printf "\t #define AVC_ATOMIC_EN $AVC_ATOMIC_EN\n" >> parameter.h |
printf "\t #define CONGESTION_INDEX $CONGESTION_INDEX\n">>parameter.h |
printf "\t #define STND_DEV_EN $STND_DEV_EN\n">> parameter.h |
printf "\t #define AVG_LATENCY_METRIC \"$AVG_LATENCY_METRIC\"\n">> parameter.h |
printf "\t #define ADD_PIPREG_AFTER_CROSSBAR $ADD_PIPREG_AFTER_CROSSBAR\n" >> parameter.h |
printf "\t #define CVw (C==0)? V : C * V\n" >> parameter.h |
printf "\t #define CLASS_SETTING \"$CLASS_SETTING\"\n">> parameter.h |
printf "\t #define ESCAP_VC_MASK $ESCAP_VC_MASK\n">> parameter.h |
printf "\t #define SSA_EN \"$SSA_EN\"\n" >> parameter.h |
printf " \n\n #endif " >> parameter.h |
|
} |
/script/verilator_compile_simulator.sh
0,0 → 1,26
#!/bin/sh |
|
set -e |
# Any subsequent commands which fail will cause the shell script to exit immediately |
|
script_path=$(pwd) |
path=$script_path/.. |
src_noc_path=$path/src_noc |
src_modelsim_path=$path/src_modelsim |
src_verilator_path=$path/src_verilator |
comp_path=$path/../mpsoc_work/verilator |
work_path=$comp_path/work |
obj_dir_path=$work_path/processed_rtl/obj_dir/ |
|
mkdir -p $work_path/bin |
rm -rf $work_path/bin/testbench |
|
cp Makefile $obj_dir_path |
cp $src_verilator_path/simulator.cpp $obj_dir_path/testbench.cpp |
cp $src_verilator_path/parameter.h $obj_dir_path |
cd $obj_dir_path |
make sim |
cp testbench $work_path/bin |
echo done! |
|
|
script/verilator_compile_simulator.sh
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: src_modelsim/random.v
===================================================================
--- src_modelsim/random.v (revision 31)
+++ src_modelsim/random.v (revision 32)
@@ -1,168 +1,170 @@
-`timescale 1ns/1ps
+`timescale 1ns/1ps
module pseudo_hotspot_no_core #(
- parameter MAX_RND = 10,
- parameter MAX_CORE = 10,
- parameter MAX_NUM = 10,
- parameter MAX_RND_WIDTH =log2(MAX_RND+1),
- parameter HOTSPOT_PERCENTAGE = 8, //maximum 20%
- parameter HOTSOPT_NUM = 5, //maximum 5
- parameter [MAX_RND_WIDTH-1 :0] HOTSPOT_CORE_1 = 2,
- parameter [MAX_RND_WIDTH-1 :0] HOTSPOT_CORE_2 = 3,
- parameter [MAX_RND_WIDTH-1 :0] HOTSPOT_CORE_3 = 4,
- parameter [MAX_RND_WIDTH-1 :0] HOTSPOT_CORE_4 = 5,
- parameter [MAX_RND_WIDTH-1 :0] HOTSPOT_CORE_5 = 6,
+ parameter MAX_RND = 10,
+ parameter MAX_CORE = 10,
+ parameter MAX_NUM = 10,
+ parameter MAX_RND_WIDTH =log2(MAX_RND+1),
+ parameter HOTSPOT_PERCENTAGE = 8, //maximum 20%
+ parameter HOTSOPT_NUM = 5, //maximum 5
+ parameter [MAX_RND_WIDTH-1 :0] HOTSPOT_CORE_1 = 2,
+ parameter [MAX_RND_WIDTH-1 :0] HOTSPOT_CORE_2 = 3,
+ parameter [MAX_RND_WIDTH-1 :0] HOTSPOT_CORE_3 = 4,
+ parameter [MAX_RND_WIDTH-1 :0] HOTSPOT_CORE_4 = 5,
+ parameter [MAX_RND_WIDTH-1 :0] HOTSPOT_CORE_5 = 6,
-
- parameter MAX_CORE_WIDTH =log2(MAX_CORE+1),
- parameter MAX_NUM_WIDTH =log2(MAX_NUM+1)
+
+ parameter MAX_CORE_WIDTH =log2(MAX_CORE+1),
+ parameter MAX_NUM_WIDTH =log2(MAX_NUM+1)
)(
-
- input [MAX_CORE_WIDTH-1 : 0] core,
- input [MAX_NUM_WIDTH-1 : 0] num,
- output reg [MAX_RND_WIDTH-1 : 0] rnd,
- input rnd_en,
- input reset,
- input clk
-
+
+ input [MAX_CORE_WIDTH-1 : 0] core,
+ input [MAX_NUM_WIDTH-1 : 0] num,
+ output reg [MAX_RND_WIDTH-1 : 0] rnd,
+ input rnd_en,
+ input reset,
+ input clk
+
);
- function integer log2;
- input integer number; begin
- log2=0;
- while(2**log2 1) && (hotspot_rnd >= 20 ) && (hotspot_rnd < (20+HOTSPOT_PERCENTAGE)) && core!=HOTSPOT_CORE_2 ) rnd = HOTSPOT_CORE_2;
- else if((HOTSOPT_NUM > 2) && (hotspot_rnd >= 40) && (hotspot_rnd < (40+HOTSPOT_PERCENTAGE)) && core!=HOTSPOT_CORE_3 ) rnd = HOTSPOT_CORE_3;
- else if((HOTSOPT_NUM > 3) && (hotspot_rnd >= 60) && (hotspot_rnd < (60+HOTSPOT_PERCENTAGE)) && core!=HOTSPOT_CORE_4 ) rnd = HOTSPOT_CORE_4;
- else if((HOTSOPT_NUM > 4) && (hotspot_rnd >= 80) && (hotspot_rnd < (80+HOTSPOT_PERCENTAGE)) && core!=HOTSPOT_CORE_5 ) rnd = HOTSPOT_CORE_5;
+ function integer log2;
+ input integer number; begin
+ log2=(number <=1) ? 1: 0;
+ while(2**log2 1) && (hotspot_rnd >= 20 ) && (hotspot_rnd < (20+HOTSPOT_PERCENTAGE)) && core!=HOTSPOT_CORE_2 ) rnd = HOTSPOT_CORE_2;
+ else if((HOTSOPT_NUM > 2) && (hotspot_rnd >= 40) && (hotspot_rnd < (40+HOTSPOT_PERCENTAGE)) && core!=HOTSPOT_CORE_3 ) rnd = HOTSPOT_CORE_3;
+ else if((HOTSOPT_NUM > 3) && (hotspot_rnd >= 60) && (hotspot_rnd < (60+HOTSPOT_PERCENTAGE)) && core!=HOTSPOT_CORE_4 ) rnd = HOTSPOT_CORE_4;
+ else if((HOTSOPT_NUM > 4) && (hotspot_rnd >= 80) && (hotspot_rnd < (80+HOTSPOT_PERCENTAGE)) && core!=HOTSPOT_CORE_5 ) rnd = HOTSPOT_CORE_5;
+ else rnd = uniform_rnd;
+ end
+
endmodule
module pseudo_hotspot #(
- parameter MAX_RND = 10,
- parameter MAX_CORE = 10,
- parameter MAX_NUM = 10,
- parameter MAX_RND_WIDTH =log2(MAX_RND+1),
- parameter HOTSPOT_PERCENTAGE = 8, //maximum 20%
- parameter HOTSOPT_NUM = 5, //maximum 5
- parameter [MAX_RND_WIDTH-1 :0] HOTSPOT_CORE_1 = 2,
- parameter [MAX_RND_WIDTH-1 :0] HOTSPOT_CORE_2 = 3,
- parameter [MAX_RND_WIDTH-1 :0] HOTSPOT_CORE_3 = 4,
- parameter [MAX_RND_WIDTH-1 :0] HOTSPOT_CORE_4 = 5,
- parameter [MAX_RND_WIDTH-1 :0] HOTSPOT_CORE_5 = 6,
+ parameter MAX_RND = 10,
+ parameter MAX_CORE = 10,
+ parameter MAX_NUM = 10,
+ parameter MAX_RND_WIDTH =log2(MAX_RND+1),
+ parameter HOTSPOT_PERCENTAGE = 8, //maximum 20%
+ parameter HOTSOPT_NUM = 5, //maximum 5
+ parameter [MAX_RND_WIDTH-1 :0] HOTSPOT_CORE_1 = 2,
+ parameter [MAX_RND_WIDTH-1 :0] HOTSPOT_CORE_2 = 3,
+ parameter [MAX_RND_WIDTH-1 :0] HOTSPOT_CORE_3 = 4,
+ parameter [MAX_RND_WIDTH-1 :0] HOTSPOT_CORE_4 = 5,
+ parameter [MAX_RND_WIDTH-1 :0] HOTSPOT_CORE_5 = 6,
-
- parameter MAX_CORE_WIDTH =log2(MAX_CORE+1),
- parameter MAX_NUM_WIDTH =log2(MAX_NUM+1)
+
+ parameter MAX_CORE_WIDTH =log2(MAX_CORE+1),
+ parameter MAX_NUM_WIDTH =log2(MAX_NUM+1)
)(
-
- input [MAX_CORE_WIDTH-1 : 0] core,
- input [MAX_NUM_WIDTH-1 : 0] num,
- output reg [MAX_RND_WIDTH-1 : 0] rnd,
- input rnd_en,
- input reset,
- input clk
-
+
+ input [MAX_CORE_WIDTH-1 : 0] core,
+ input [MAX_NUM_WIDTH-1 : 0] num,
+ output reg [MAX_RND_WIDTH-1 : 0] rnd,
+ input rnd_en,
+ input reset,
+ input clk
+
);
- function integer log2;
- input integer number; begin
- log2=0;
- while(2**log2 1) && (hotspot_rnd >= 20 ) && (hotspot_rnd < (20+HOTSPOT_PERCENTAGE)) ) rnd = HOTSPOT_CORE_2;
- else if((HOTSOPT_NUM > 2) && (hotspot_rnd >= 40) && (hotspot_rnd < (40+HOTSPOT_PERCENTAGE)) ) rnd = HOTSPOT_CORE_3;
- else if((HOTSOPT_NUM > 3) && (hotspot_rnd >= 60) && (hotspot_rnd < (60+HOTSPOT_PERCENTAGE)) ) rnd = HOTSPOT_CORE_4;
- else if((HOTSOPT_NUM > 4) && (hotspot_rnd >= 80) && (hotspot_rnd < (80+HOTSPOT_PERCENTAGE)) ) rnd = HOTSPOT_CORE_5;
+ // generate a random num between 0 to 100
+ pseudo_random #(
+ .MAX_RND (100),
+ .MAX_CORE (MAX_CORE),
+ .MAX_NUM (MAX_NUM)
+ )hotspot_rnd_gen
+ (
+ .core (core),
+ .num (num),
+ .rnd (hotspot_rnd),
+ .rnd_en (rnd_en),
+ .reset (reset),
+ .clk (clk)
+ );
+
+ always @(*) begin
+ if(hotspot_rnd < HOTSPOT_PERCENTAGE ) rnd = HOTSPOT_CORE_1;
+ else if((HOTSOPT_NUM > 1) && (hotspot_rnd >= 20 ) && (hotspot_rnd < (20+HOTSPOT_PERCENTAGE)) ) rnd = HOTSPOT_CORE_2;
+ else if((HOTSOPT_NUM > 2) && (hotspot_rnd >= 40) && (hotspot_rnd < (40+HOTSPOT_PERCENTAGE)) ) rnd = HOTSPOT_CORE_3;
+ else if((HOTSOPT_NUM > 3) && (hotspot_rnd >= 60) && (hotspot_rnd < (60+HOTSPOT_PERCENTAGE)) ) rnd = HOTSPOT_CORE_4;
+ else if((HOTSOPT_NUM > 4) && (hotspot_rnd >= 80) && (hotspot_rnd < (80+HOTSPOT_PERCENTAGE)) ) rnd = HOTSPOT_CORE_5;
- else rnd = uniform_rnd;
- end
+ else rnd = uniform_rnd;
+ end
endmodule
@@ -170,162 +172,163 @@
module pseudo_random #(
- parameter MAX_RND = 10,
- parameter MAX_CORE = 10,
- parameter MAX_NUM = 10,
- parameter MAX_RND_WIDTH =log2(MAX_RND+1),
- parameter MAX_CORE_WIDTH =log2(MAX_CORE+1),
- parameter MAX_NUM_WIDTH =log2(MAX_NUM+1)
+ parameter MAX_RND = 10,
+ parameter MAX_CORE = 10,
+ parameter MAX_NUM = 10,
+ parameter MAX_RND_WIDTH =log2(MAX_RND+1),
+ parameter MAX_CORE_WIDTH =log2(MAX_CORE+1),
+ parameter MAX_NUM_WIDTH =log2(MAX_NUM+1)
)(
-
- input [MAX_CORE_WIDTH-1 : 0] core,
- input [MAX_NUM_WIDTH-1 : 0] num,
- output[MAX_RND_WIDTH-1 : 0] rnd,
- input rnd_en,
- input reset,
- input clk
-
+
+ input [MAX_CORE_WIDTH-1 : 0] core,
+ input [MAX_NUM_WIDTH-1 : 0] num,
+ output[MAX_RND_WIDTH-1 : 0] rnd,
+ input rnd_en,
+ input reset,
+ input clk
+
);
- function integer log2;
- input integer number; begin
- log2=0;
- while(2**log2 MAX_RND [MAX_RND_WIDTH-1 : 0]) ? rnd_max_width - MAX_RND[MAX_RND_WIDTH-1 : 0] : rnd_max_width;
+assign rnd = (rnd_max_width > MAX_RND [MAX_RND_WIDTH-1 : 0]) ? rnd_max_width - MAX_RND[MAX_RND_WIDTH-1 : 0] : rnd_max_width;
assign valid = (rnd_max_width <= MAX_RND [MAX_RND_WIDTH-1 : 0]);
@@ -369,98 +372,99 @@
// The output of random generator is not the core num
module pseudo_random_no_core #(
- parameter MAX_RND = 10,
- parameter MAX_CORE = 10,
- parameter MAX_NUM = 10,
- parameter MAX_RND_WIDTH =log2(MAX_RND+1),
- parameter MAX_CORE_WIDTH =log2(MAX_CORE+1),
- parameter MAX_NUM_WIDTH =log2(MAX_NUM+1)
+ parameter MAX_RND = 10,
+ parameter MAX_CORE = 10,
+ parameter MAX_NUM = 10,
+ parameter MAX_RND_WIDTH =log2(MAX_RND+1),
+ parameter MAX_CORE_WIDTH =log2(MAX_CORE+1),
+ parameter MAX_NUM_WIDTH =log2(MAX_NUM+1)
)(
-
- input [MAX_CORE_WIDTH-1 : 0] core,
- input [MAX_NUM_WIDTH-1 : 0] num,
- output[MAX_RND_WIDTH-1 : 0] rnd,
- input rnd_en,
- input reset,
- input clk
+
+ input [MAX_CORE_WIDTH-1 : 0] core,
+ input [MAX_NUM_WIDTH-1 : 0] num,
+ output[MAX_RND_WIDTH-1 : 0] rnd,
+ input rnd_en,
+ input reset,
+ input clk
);
- function integer log2;
- input integer number; begin
- log2=0;
- while(2**log2
/src_modelsim/testbench_modelsim.v
6,14 → 6,15
parameter MAX_PCK_SIZ =10 , |
PCK_SIZw = log2(MAX_PCK_SIZ+1); |
|
function integer log2; |
|
function integer log2; |
input integer number; begin |
log2=0; |
log2=(number <=1) ? 1: 0; |
while(2**log2<number) begin |
log2=log2+1; |
end |
end |
end |
endfunction // log2 |
endfunction // log2 |
|
localparam RATIOw=log2(100); |
|
89,8 → 90,8
module testbench_sub #( |
parameter V=2, |
parameter B=5, |
parameter NX=4, |
parameter NY=4, |
parameter NX=6, |
parameter NY=1, |
parameter C=2, |
parameter Fpay=32, |
parameter MUX_TYPE="ONE_HOT", |
106,7 → 107,7
parameter CVw=(C==0)? V : C * V, |
parameter [CVw-1: 0] CLASS_SETTING = 4'b1111, // shows how each class can use VCs |
parameter [V-1 : 0] ESCAP_VC_MASK = 2'b10, // mask scape vc, valid only for full adaptive |
parameter SSA_EN="YES", // "YES" , "NO" |
parameter SSA_EN= "NO",//"YES", // "YES" , "NO" |
|
parameter C0_p=50, |
parameter C1_p=50, |
113,7 → 114,7
parameter C2_p=0, |
parameter C3_p=0, |
// parameter TRAFFIC="TRANSPOSE1", |
parameter TRAFFIC="RANDOM", |
parameter TRAFFIC="RANDOM",//"RANDOM", |
//parameter TRAFFIC="CUSTOM", |
parameter HOTSPOT_PERCENTAGE=4, |
parameter HOTSOPT_NUM=4, |
126,7 → 127,7
parameter MAX_SIM_CLKs=1000000, |
parameter MAX_PCK_SIZ=10, |
parameter TIMSTMP_FIFO_NUM=2, |
parameter ROUTE_TYPE = (ROUTE_NAME == "XY" || ROUTE_NAME == "TRANC_XY" )? "DETERMINISTIC" : |
parameter ROUTE_TYPE = (ROUTE_NAME == "XY" || ROUTE_NAME == "TRANC_XY" )? "DETERMINISTIC" : |
(ROUTE_NAME == "DUATO" || ROUTE_NAME == "TRANC_DUATO" )? "FULL_ADAPTIVE": "PAR_ADAPTIVE", |
parameter DEBUG_EN=1, |
parameter AVG_LATENCY_METRIC= "HEAD_2_TAIL" |
157,12 → 158,12
|
function integer log2; |
input integer number; begin |
log2=0; |
log2=(number <=1) ? 1: 0; |
while(2**log2<number) begin |
log2=log2+1; |
end |
end |
end |
endfunction // log2 |
endfunction // log2 |
|
function integer CORE_NUM; |
input integer x,y; |
/src_modelsim/testbench_router.v
1,31 → 1,50
`timescale 1ns/1ps |
|
|
module testbench_router; |
|
|
parameter V = 4, // V |
P = 5, // router port num |
B = 4, // buffer space :flit per VC |
NX = 4, // number of node in x axis |
NY = 4, // number of node in y axis |
X = 2, //router x addr |
Y = 2, // router y addr |
C = 4, // number of flit class |
Fpay = 32, |
MUX_TYPE="ONE_HOT", //"ONE_HOT" or "BINARY" |
VC_REALLOCATION_TYPE = "NONATOMIC",// "ATOMIC" , "NONATOMIC" |
COMBINATION_TYPE= "BASELINE",// "BASELINE", "COMB_SPEC1", "COMB_SPEC2", "COMB_NONSPEC" |
TOTAL_PKT_PER_PORT = 100; |
|
parameter V = 2; // V |
parameter B = 4; // buffer space :flit per VC |
parameter NX = 8; // The number of node in x axis of mesh or torus. For ring topology is total number of nodes in ring. |
parameter NY = 8; // The number of node in y axis of mesh or torus. Not used in ring topology. |
parameter C = 4; // number of flit class |
parameter Fpay = 32; |
parameter MUX_TYPE = "BINARY"; //"ONE_HOT" or "BINARY" |
parameter VC_REALLOCATION_TYPE = "NONATOMIC";// "ATOMIC" ; "NONATOMIC" |
parameter COMBINATION_TYPE= "COMB_NONSPEC";// "BASELINE"; "COMB_SPEC1"; "COMB_SPEC2"; "COMB_NONSPEC" |
parameter FIRST_ARBITER_EXT_P_EN = 1; |
parameter TOPOLOGY = "MESH";//"MESH";"TORUS";"RING" |
parameter ROUTE_NAME = "XY"; |
parameter CONGESTION_INDEX = 2; |
parameter DEBUG_EN = 0; |
parameter ROUTE_SUBFUNC ="XY"; |
parameter AVC_ATOMIC_EN=1; |
parameter ADD_PIPREG_AFTER_CROSSBAR=0; |
parameter CVw=(C==0)? V : C * V; |
parameter [CVw-1: 0] CLASS_SETTING = {CVw{1'b1}}; // shows how each class can use VCs |
parameter [V-1 : 0] ESCAP_VC_MASK = 4'b1000; // mask scape vc; valid only for full adaptive |
parameter SSA_EN="YES"; // "YES" ; "NO" |
|
localparam ROUTE_TYPE = (ROUTE_NAME == "XY" || ROUTE_NAME == "TRANC_XY" )? "DETERMINISTIC" : |
(ROUTE_NAME == "DUATO" || ROUTE_NAME == "TRANC_DUATO" )? "FULL_ADAPTIVE": "PAR_ADAPTIVE"; |
|
localparam P=5; |
|
localparam CONGw= (CONGESTION_INDEX==3)? 3: |
(CONGESTION_INDEX==5)? 3: |
(CONGESTION_INDEX==7)? 3: |
(CONGESTION_INDEX==9)? 3: |
(CONGESTION_INDEX==10)? 4: |
(CONGESTION_INDEX==12)? 3:2; |
localparam CONG_ALw = CONGw *P; // congestion width per router |
function integer log2; |
input integer number; begin |
log2=0; |
while(2**log2<number) begin |
log2=log2+1; |
end |
end |
endfunction // log2 |
input integer number; begin |
log2=0; |
while(2**log2<number) begin |
log2=log2+1; |
end |
end |
endfunction // log2 |
|
localparam PV = V * P, |
VV = V * V, |
52,419 → 71,203
X_Y_IN_HDR_WIDTH =4; |
|
|
//routers input/output ports |
|
reg clk; |
reg reset; |
reg report; |
reg [Pw-1 :0] P_bin [P-1 : 0]; |
reg [CLASS_IN_HDR_WIDTH-1 :0] C_bin [P-1 : 0]; |
reg [P-1 :0] inject_en; |
|
wire [PFw-1 :0] flit_in_all; |
reg [P-1 :0] flit_in_we_all; |
|
|
|
wire [31 :0] time_stamp [P-1 : 0]; |
wire [31 :0] distance [P-1 : 0]; |
|
// router_pck_gen interfaces |
wire [Fw-1 :0] gen_flit_out [P-1 : 0]; |
wire gen_flit_out_wr [P-1 : 0]; |
wire [V-1 :0] gen_credit_in [P-1 : 0]; |
|
wire [Fw-1 :0] gen_flit_in [P-1 : 0]; |
wire gen_flit_in_wr [P-1 : 0]; |
wire [V-1 :0] gen_credit_out [P-1 : 0]; |
|
wire [P-1 :0] flit_in_we_all; |
wire [PFw-1 :0] flit_in_all; |
wire [PV-1 :0] credit_out_all; |
wire [P-1 :0] flit_out_we_all; |
wire [PFw-1 :0] flit_out_all; |
wire [PFw-1 :0] flit_out_all; |
wire [PV-1 :0] credit_in_all; |
|
|
wire [P-1 :0] sent_done; |
wire [P-1 :0] update ; |
|
integer pck_counter [P-1 : 0]; |
reg [P-1 :0] done,done_reg; |
reg count_en; |
wire all_generator_done; |
reg start; |
reg [15 :0] pck_size [P-1 :0]; |
wire [Pw-1 :0] rnd_port [P-1 :0]; |
wire [CLASS_IN_HDR_WIDTH-1:0] rnd_class [P-1 :0]; |
|
|
|
|
|
|
|
|
router # ( |
.V (V), |
.P (P), |
.B (B), |
.NX (NX), |
.NY (NY), |
.X (X), |
.Y (Y), |
.C (C), |
.Fpay (Fpay), |
.VC_REALLOCATION_TYPE(VC_REALLOCATION_TYPE), |
.COMBINATION_TYPE (COMBINATION_TYPE), |
.MUX_TYPE (MUX_TYPE) |
|
) |
router |
( |
.flit_in_all (flit_in_all), |
.flit_in_we_all (flit_in_we_all), |
.credit_out_all (credit_out_all), |
|
.flit_out_all (flit_out_all), |
.flit_out_we_all (flit_out_we_all), |
.credit_in_all (credit_in_all), |
|
.clk (clk), |
.reset (reset) |
|
); |
|
|
// seperate IO per port |
reg [Fw-1 :0] flit_in [P-1 : 0]; |
wire [V-1 :0] credit_out [P-1 : 0]; |
wire [Fw-1 :0] flit_out [P-1 : 0]; |
reg [V-1 :0] credit_in [P-1 : 0]; |
|
localparam NUM_WIDTH = log2(TOTAL_PKT_PER_PORT); |
|
|
// asssign seperate IO to the routers port |
genvar i; |
generate |
for (i=0;i<P; i=i+1'b1) begin :lp |
generate |
for (i=0;i<P;i=i+1) begin : ports_blk |
assign flit_in_all [Fw*(i+1)-1: i*Fw] = flit_in[i]; |
assign credit_in_all [V*(i+1)-1 : i*V ] = credit_in[i]; |
assign flit_out [i] = flit_out_all [Fw*(i+1)-1 : i*Fw]; |
assign credit_out [i] = credit_out_all[V*(i+1)-1 : i*V ]; |
|
router_pck_gen #( |
.V (V), |
.Fpay (Fpay ), |
.B (B), |
.SW_LOC (i), |
.P (P), |
.NX (5), |
.NY (5), |
.X (0), |
.Y (0) |
|
) |
pck_gen_inst |
( |
.reset (reset) , // input reset |
.clk (clk) , // input clk |
.inject_en (inject_en[i]) , // input inject_en |
.pck_size (pck_size[i]) , // input [15:0] pck_size |
.wr_des_x_addr (4'd0) , // input [3:0] des_x_addr |
.wr_des_y_addr (4'd1) , // input [3:0] des_y_addr |
.update (update[i]) , // output update |
.time_stamp (time_stamp[i]) , // output [31:0] time_stamp |
//.distance(distance[i]) , // output [31:0] distance |
.flit_out (gen_flit_out[i]) , // output [Fw-1:0] flit_out |
.flit_out_wr (gen_flit_out_wr[i]) , // output flit_out_wr |
.credit_in (gen_credit_in[i]) , // input [V-1:0] credit_in |
.flit_in (gen_flit_in[i]) , // input [Fw-1:0] flit_in |
.flit_in_wr (gen_flit_in_wr[i]) , // input flit_in_wr |
.credit_out (gen_credit_out[i]) , // output [V-1:0] credit_out |
.sent_done (sent_done[i]) , // output sent_done |
.report (report) , // input report |
.P_bin (P_bin[i]), // input [LK_PORT_SEL_WIDTH-1:0] port_sel |
.wr_class_hdr (C_bin[i]) |
); |
end |
endgenerate |
|
pseudo_random_no_core #( |
.MAX_RND (P-1 ), |
.MAX_CORE (P-1 ), |
.MAX_NUM (TOTAL_PKT_PER_PORT) |
)rnd_port_gen |
( |
.core (i[Pw-1 :0]), |
.num (pck_counter[i][NUM_WIDTH-1 :0]), |
.rnd (rnd_port [i]), |
.rnd_en (1'b1), |
.reset (reset), |
.clk (clk) |
); |
|
pseudo_random #( |
.MAX_RND (V), |
.MAX_CORE (V), |
.MAX_NUM (TOTAL_PKT_PER_PORT) |
) |
rnd_gen |
( |
|
.core (i[Pw-1 :0]), |
.num (pck_counter[i][NUM_WIDTH-1 :0]), |
.rnd (rnd_class [i]), |
.rnd_en (1'b1), |
.reset (reset), |
.clk (clk) |
|
|
); |
|
|
assign flit_in_all[(i+1)*Fw-1 : i*Fw] = gen_flit_out [i]; |
assign flit_in_we_all[i]= gen_flit_out_wr[i]; |
assign gen_credit_in[i]= credit_out_all[(i+1)*V-1: i*V]; |
|
assign gen_flit_in [i] = flit_out_all[(i+1)*Fw-1 : i*Fw]; |
assign gen_flit_in_wr[i] =flit_out_we_all[i]; |
assign credit_in_all[(i+1)*V-1: i*V]= gen_credit_out[i]; |
router #( |
.V(V), |
.P(P), |
.B(B), |
.NX(NX), |
.NY(NY), |
.C(C), |
.Fpay(Fpay), |
.TOPOLOGY(TOPOLOGY), |
.MUX_TYPE(MUX_TYPE), |
.VC_REALLOCATION_TYPE(VC_REALLOCATION_TYPE), |
.COMBINATION_TYPE(COMBINATION_TYPE), |
.FIRST_ARBITER_EXT_P_EN(FIRST_ARBITER_EXT_P_EN), |
.ROUTE_TYPE(ROUTE_TYPE), |
.ROUTE_NAME(ROUTE_NAME), |
.CONGESTION_INDEX(CONGESTION_INDEX), |
.DEBUG_EN(DEBUG_EN), |
.ROUTE_SUBFUNC(ROUTE_SUBFUNC), |
.AVC_ATOMIC_EN(AVC_ATOMIC_EN), |
.CONGw(CONGw), |
.ADD_PIPREG_AFTER_CROSSBAR(ADD_PIPREG_AFTER_CROSSBAR), |
.CVw(CVw), |
.CLASS_SETTING(CLASS_SETTING), |
.ESCAP_VC_MASK(ESCAP_VC_MASK), |
.SSA_EN(SSA_EN) ) |
the_router |
|
( |
|
.current_x(3'd3), |
.current_y(3'd3), |
.flit_in_all (flit_in_all), |
.flit_in_we_all (flit_in_we_all), |
.credit_out_all (credit_out_all), |
.congestion_in_all (0), |
|
.flit_out_all (flit_out_all), |
.flit_out_we_all (flit_out_we_all), |
.credit_in_all (credit_in_all), |
.congestion_out_all ( ), |
|
|
end |
.clk (clk), |
.reset (reset) |
|
endgenerate |
); |
|
//synthesis translate_off |
assign all_generator_done = &done; |
initial begin |
clk =0; |
forever clk= #10 ~clk; |
end |
|
initial begin |
reset =1; |
start =0; |
#100 |
@(posedge clk) reset =0; |
#100 |
@(posedge clk) start =1; |
@(posedge clk) start =0; |
end |
//synthesis translate_on |
reg [31 : 0] clk_counter; |
|
always @ (posedge clk or posedge reset)begin |
if (reset ) begin clk_counter <= 0; done_reg <= 0; end |
else begin |
if (count_en) clk_counter <= clk_counter+1'b1; |
done_reg <= done; |
end |
end |
|
always @(posedge clk) begin |
if (reset) count_en <=1'b0; |
else if(start) count_en <=1'b1; |
else if(all_generator_done) count_en <=1'b0; |
initial begin |
clk=1'b0; |
forever clk= #10 ~clk; |
end |
|
//synthesis translate_off |
|
initial begin |
report =1'b0; |
#200 |
integer k; |
|
@(posedge all_generator_done); |
#100 |
@(posedge clk) report =1'b1; |
@(posedge clk) report =1'b0; |
initial begin |
//reset |
reset=1'b1; |
flit_in_we_all ={P{1'b0}}; |
for (k=0;k<P;k=k+1) begin |
flit_in[k]= {Fw{1'b0}}; |
credit_in[k]= {V{1'b0}}; |
end |
|
|
//deassert the reset |
|
#200 |
@(posedge clk)#1 |
reset=1'b0; |
|
#200 |
//send a packet from port zero (local) to the south |
@(posedge clk)#1 |
|
// send header flit |
flit_in_we_all[0] = 1'b1; |
flit_in[0][Fw-1:Fw-2]=2'b10; // header flag |
flit_in[0][Fpay+V-1:Fpay]=1; // inputport VC |
//header flit payload |
flit_in[0][Fpay-1 :0]= { /*/{reserved & wr_class_hdr}[7:0]*/ 8'd0, /*reserved [3:0]*/ 4'd0, /*wr_destport_hdr[P-2:0]*/4'b1000,/*wr_des_x_addr[3:0]*/4'd4,/*wr_des_y_addr[3:0]*/4'd4,/*wr_src_x_addr[3:0]*/4'd3,/*wr_src_y_addr[3:0]*/4'd3}; |
|
end |
|
|
parameter ST_NUMBER = 5; |
parameter IDEAL_ST = 1; |
parameter WARM_UP = 2; |
parameter SEND_ST = 4; |
parameter DELAY_ST = 8; |
parameter END_ST = 16; |
|
reg[ST_NUMBER-1:0] ps [P-1 :0]; |
|
integer clk_delay_counter [P-1 :0]; |
reg[8 :0] rndnum_loc [P-1 :0]; |
/* |
destport_hd: |
in deterministic routing: |
is a one-hot code showing the position of output port. The sender port position must be removed from the one-hot code |
|
port order :{south,west,north,east,local} |
e.g : send packet from north port to west: one_hot code including all ports {5'b01000} then removing north bit : 4'b0100; |
|
in partially/fully adaptive: |
destport = {x,y,a,b}; |
x= (dest_x > current_x); |
y= (dest_y > current_y); |
a= if is one packet can be sent from x dimention to reach its destination |
b= if is one packet can be sent from y dimention to reach its destination |
if both a and b are packet can be delivered from any of x or y dimention |
if both a and b one zero packet will be delivered to local port. |
|
e.g destport={4'b1111}: destination is located at east_south quarter and packet can sent from any of these two ports |
|
|
|
task automatic send_packet; |
input send_start; |
input integer core_num; |
input integer P_i; |
input integer C_i; |
input integer size; |
input integer pck_num; |
input integer clk_delay; |
|
//reg core_num; |
//reg [ST_NUMBER-1:0] ps; |
|
begin |
if(reset) begin |
ps[core_num]<=IDEAL_ST; |
inject_en [core_num] <= 1'b0; |
clk_delay_counter[core_num]<=0; |
done[core_num] <= 1'b0; |
pck_counter[core_num]<= 0; |
rndnum_loc[core_num] <= core_num*20; |
clk_delay_counter[core_num]<= X+Y+2; |
end else begin |
case(ps[core_num]) |
IDEAL_ST: begin |
inject_en [core_num] <= 1'b0; |
pck_size [core_num] <= size; |
P_bin[core_num] <= P_i; |
C_bin[core_num] <= C_i; |
ps[core_num]<=IDEAL_ST; |
if(send_start) begin |
ps[core_num]<=WARM_UP; |
end |
end |
WARM_UP: begin |
clk_delay_counter[core_num]<=clk_delay_counter[core_num]-1'b1; |
if(clk_delay_counter[core_num]==0) ps[core_num]<=SEND_ST; |
end |
SEND_ST: begin |
done[core_num] <= 1'b0; |
inject_en [core_num] <= 1'b1; |
clk_delay_counter[core_num] <=0; |
if( sent_done[core_num] )begin |
pck_counter[core_num] <= pck_counter[core_num]+1'b1; |
if(pck_counter[core_num]==pck_num-1'b1) begin |
ps[core_num] <= END_ST; |
inject_en [core_num] <= 1'b0; |
end |
else if(clk_delay>0) begin |
inject_en [core_num] <= 1'b0; |
ps[core_num] <= DELAY_ST; |
rndnum_loc[core_num] <= rndnum_loc[core_num]+1'b1; |
end |
end |
end |
DELAY_ST: begin |
inject_en [core_num] <= 1'b0; |
clk_delay_counter[core_num] <=clk_delay_counter[core_num] +1'b1; |
if(clk_delay_counter[core_num] >= clk_delay ) |
ps[core_num]<= SEND_ST; |
end |
END_ST: begin |
inject_en [core_num] <= 1'b0; |
clk_delay_counter[core_num] <=clk_delay_counter[core_num] +1'b1; |
ps[core_num]<= IDEAL_ST; |
done[core_num] <= 1'b1; |
end |
default ps[core_num]<=IDEAL_ST; |
endcase |
end//else |
end |
endtask |
|
|
|
task automatic send_rnd_packet( |
input send_start, |
input integer core_num, |
input integer size, |
input integer pck_num, |
input integer clk_delay |
); |
//reg core_num; |
//reg [ST_NUMBER-1:0] ps; |
*/ |
|
begin |
if(reset) begin |
ps[core_num]<=IDEAL_ST; |
inject_en [core_num] <= 1'b0; |
clk_delay_counter[core_num]<=0; |
done[core_num] <= 1'b0; |
pck_counter[core_num]<= 0; |
rndnum_loc[core_num] <= core_num*20; |
clk_delay_counter[core_num]<= X+Y+2; |
end else begin |
case(ps[core_num]) |
IDEAL_ST: begin |
inject_en [core_num] <= 1'b0; |
pck_size [core_num] <= size; |
|
P_bin[core_num] <= rnd_port [core_num]; |
C_bin[core_num] <= rnd_class[core_num]; |
ps[core_num]<=IDEAL_ST; |
if(send_start) begin |
ps[core_num]<=WARM_UP; |
end |
end |
WARM_UP: begin |
clk_delay_counter[core_num]<=clk_delay_counter[core_num]-1'b1; |
if(clk_delay_counter[core_num]==0) ps[core_num]<=SEND_ST; |
end |
SEND_ST: begin |
done[core_num] <= 1'b0; |
inject_en [core_num] <= 1'b1; |
clk_delay_counter[core_num] <=0; |
if( sent_done[core_num] )begin |
P_bin[core_num] <= rnd_port [core_num]; |
C_bin[core_num] <= rnd_class [core_num]; |
pck_counter[core_num] <= pck_counter[core_num]+1'b1; |
if(pck_counter[core_num]==pck_num-1'b1) begin |
ps[core_num] <= END_ST; |
inject_en [core_num] <= 1'b0; |
end |
else if(clk_delay>0) begin |
inject_en [core_num] <= 1'b0; |
ps[core_num] <= DELAY_ST; |
rndnum_loc[core_num] <= rndnum_loc[core_num]+1'b1; |
end |
end |
end |
DELAY_ST: begin |
inject_en [core_num] <= 1'b0; |
clk_delay_counter[core_num] <=clk_delay_counter[core_num] +1'b1; |
if(clk_delay_counter[core_num] >= clk_delay ) |
ps[core_num]<= SEND_ST; |
end |
END_ST: begin |
inject_en [core_num] <= 1'b0; |
clk_delay_counter[core_num] <=clk_delay_counter[core_num] +1'b1; |
ps[core_num]<= IDEAL_ST; |
done[core_num] <= 1'b1; |
end |
default ps[core_num]<=IDEAL_ST; |
endcase |
end//else |
end |
endtask |
|
|
|
|
|
// you can send flit from other ports in the same clock cycle here as well |
|
generate |
for(i=0;i<P;i=i+1'b1 ) begin :loo |
always @(posedge clk) begin send_rnd_packet(start,i, 5, 1000, 0); end |
end//for |
endgenerate |
|
|
/* |
generate |
for(i=0;i<P;i=i+1'b1 ) begin :loo |
if (i==0 )always @(posedge clk) begin send_packet(start,i,3,1, 5, 1000, 0); end |
else if (i==1 )always @(posedge clk) begin send_packet(start,i,3,2, 5, 1000, 0); end |
else if (i==2 )always @(posedge clk) begin send_packet(start,i,3,2, 5, 1000, 0); end |
else if (i==4 )always @(posedge clk) begin send_packet(start,i,3,1, 5, 1000, 0); end |
else always @(posedge clk) begin send_packet(0,i,0,1, 5, 1000, 0); end |
end//for |
endgenerate |
*/ |
|
@(posedge clk)#1 |
//send body flit 1 |
flit_in_we_all[0] = 1'b1; |
flit_in[0][Fw-1:Fw-2]=2'b00; // body flag |
flit_in[0][Fpay+V-1:Fpay]=1; // inputport VC |
flit_in[0][Fpay-1:0]= 32'hAB000000; // your first data to send |
|
//synthesis translate_on |
|
@(posedge clk)#1 |
//send body flit 2 |
flit_in_we_all[0] = 1'b1; |
flit_in[0][Fw-1:Fw-2]=2'b00; // body flag |
flit_in[0][Fpay+V-1:Fpay]=1; // inputport VC |
flit_in[0][Fpay-1:0]= 32'hAB000001; // your first data to send |
|
|
@(posedge clk)#1 |
//send tail flit 3 |
flit_in_we_all[0] = 1'b1; |
flit_in[0][Fw-1:Fw-2]=2'b01; // tail flag |
flit_in[0][Fpay+V-1:Fpay]=1; // inputport VC |
flit_in[0][Fpay-1:0]= 32'hAB000002; // your first data to send |
|
endmodule |
@(posedge clk)#1 |
flit_in_we_all[0] = 1'b0; |
|
#100 |
$stop; |
|
end |
|
|
// assume the credit is recived with one clock cycle delay |
always @ (posedge clk) begin |
for (k=0;k<P;k=k+1)begin |
credit_in[k]<=(flit_out_we_all[k]==1'b1)? flit_out[k][Fpay+V-1:Fpay] : {V{1'b0}}; |
end |
|
end |
|
|
|
endmodule |
|
|
/src_modelsim/traffic_pattern.v
38,12 → 38,13
|
); |
|
|
function integer log2; |
input integer number; begin |
log2=0; |
log2=(number <=1) ? 1: 0; |
while(2**log2<number) begin |
log2=log2+1; |
end |
end |
end |
endfunction // log2 |
|
92,7 → 93,8
|
*********************************/ |
|
module pck_dst_gen #( |
|
module pck_dst_gen #( |
parameter NX = 4, |
parameter NY = 4, |
parameter TOPOLOGY="MESH", |
116,18 → 118,142
dest_y, |
clk, |
reset, |
valid_dst |
valid_dst |
); |
|
|
localparam ADDR_DIMENTION = (TOPOLOGY == "MESH" || TOPOLOGY == "TORUS") ? 2 : 1; // "RING" and FULLY_CONNECT |
|
|
function integer log2; |
input integer number; begin |
log2=(number <=1) ? 1: 0; |
while(2**log2<number) begin |
log2=log2+1; |
end |
end |
endfunction // log2 |
|
|
localparam NC = (TOPOLOGY=="RING")? NX : NX*NY, //number of cores |
Xw = log2(NX), |
Yw = log2(NY), |
NCw= log2(NC), |
PCK_CNTw = log2(MAX_PCK_NUM+1); |
|
input reset,clk,en; |
input [NCw-1 : 0] core_num; |
input [PCK_CNTw-1 : 0] pck_number; |
input [Xw-1 : 0] current_x; |
input [Yw-1 : 0] current_y; |
output [Xw-1 : 0] dest_x; |
output [Yw-1 : 0] dest_y; |
output valid_dst; |
|
|
generate |
if ( ADDR_DIMENTION == 2) begin :two_dim |
|
two_dimention_pck_dst_gen #( |
.NX(NX), |
.NY(NY), |
.TOPOLOGY(TOPOLOGY), |
.TRAFFIC(TRAFFIC), |
.MAX_PCK_NUM(MAX_PCK_NUM), |
.HOTSPOT_PERCENTAGE(HOTSPOT_PERCENTAGE), |
.HOTSOPT_NUM(HOTSOPT_NUM), |
.HOTSPOT_CORE_1(HOTSPOT_CORE_1), |
.HOTSPOT_CORE_2(HOTSPOT_CORE_2), |
.HOTSPOT_CORE_3(HOTSPOT_CORE_3), |
.HOTSPOT_CORE_4(HOTSPOT_CORE_4), |
.HOTSPOT_CORE_5(HOTSPOT_CORE_5) |
) |
the_two_dimention_pck_dst_gen |
( |
.reset(reset), |
.clk(clk), |
.en(en), |
.core_num(core_num), |
.pck_number(pck_number), |
.current_x(current_x), |
.current_y(current_y), |
.dest_x(dest_x), |
.dest_y(dest_y), |
.valid_dst(valid_dst) |
); |
|
end else begin : one_dim |
|
one_dimention_pck_dst_gen #( |
.NX(NX), |
.TOPOLOGY(TOPOLOGY), |
.TRAFFIC(TRAFFIC), |
.MAX_PCK_NUM(MAX_PCK_NUM), |
.HOTSPOT_PERCENTAGE(HOTSPOT_PERCENTAGE), |
.HOTSOPT_NUM(HOTSOPT_NUM), |
.HOTSPOT_CORE_1(HOTSPOT_CORE_1), |
.HOTSPOT_CORE_2(HOTSPOT_CORE_2), |
.HOTSPOT_CORE_3(HOTSPOT_CORE_3), |
.HOTSPOT_CORE_4(HOTSPOT_CORE_4), |
.HOTSPOT_CORE_5(HOTSPOT_CORE_5) |
) |
the_one_dimention_pck_dst_gen |
( |
.reset(reset), |
.clk(clk), |
.en(en), |
.pck_number(pck_number), |
.current_x(current_x), |
.dest_x(dest_x), |
.valid_dst(valid_dst) |
); |
assign dest_y = 1'b0; |
end |
endgenerate |
|
|
|
endmodule |
|
|
|
|
|
module two_dimention_pck_dst_gen #( |
parameter NX = 4, |
parameter NY = 4, |
parameter TOPOLOGY="MESH", |
parameter TRAFFIC = "RANDOM", |
parameter MAX_PCK_NUM = 10000, |
parameter HOTSPOT_PERCENTAGE = 3, //maximum 20 |
parameter HOTSOPT_NUM = 4, //maximum 4 |
parameter HOTSPOT_CORE_1 = 10, |
parameter HOTSPOT_CORE_2 = 11, |
parameter HOTSPOT_CORE_3 = 12, |
parameter HOTSPOT_CORE_4 = 13, |
parameter HOTSPOT_CORE_5 = 14 |
|
|
)( |
en, |
current_x, |
current_y, |
core_num, |
pck_number, |
dest_x, |
dest_y, |
clk, |
reset, |
valid_dst |
); |
|
|
|
function integer log2; |
input integer number; begin |
log2=0; |
log2=(number <=1) ? 1: 0; |
while(2**log2<number) begin |
log2=log2+1; |
end |
end |
end |
endfunction // log2 |
|
230,7 → 356,10
|
assign dest_x = ~current_x; |
assign dest_y = ~current_y; |
|
end else if( TRAFFIC == "TORNADO" ) begin :tornado |
//[(x+(k/2-1)) mod k, (y+(k/2-1)) mod k], |
assign dest_x = (current_x> ((NX+1)/2))? current_x- ((NX+1)/2) -1 : (NX/2)+current_x-1; // = ((current_x + ((NX/2)-1))%NX); |
assign dest_y = (current_y> ((NY+1)/2))? current_y- ((NY+1)/2) -1 : (NY/2)+current_y-1; // = ((current_y + ((NY/2)-1))%NY); |
|
end else if(TRAFFIC == "CUSTOM" )begin |
/* |
290,6 → 419,209
endgenerate |
|
endmodule |
|
|
|
|
|
/************ |
|
************/ |
|
|
module one_dimention_pck_dst_gen #( |
parameter NX = 4, |
parameter TOPOLOGY="RING",//"FULLY_CONNECT" |
parameter TRAFFIC = "RANDOM", |
parameter MAX_PCK_NUM = 10000, |
parameter HOTSPOT_PERCENTAGE = 3, //maximum 20 |
parameter HOTSOPT_NUM = 4, //maximum 4 |
parameter HOTSPOT_CORE_1 = 10, |
parameter HOTSPOT_CORE_2 = 11, |
parameter HOTSPOT_CORE_3 = 12, |
parameter HOTSPOT_CORE_4 = 13, |
parameter HOTSPOT_CORE_5 = 14 |
|
)( |
en, |
current_x, |
pck_number, |
dest_x, |
clk, |
reset, |
valid_dst |
); |
|
|
|
function integer log2; |
input integer number; begin |
log2=(number <=1) ? 1: 0; |
while(2**log2<number) begin |
log2=log2+1; |
end |
end |
endfunction // log2 |
|
|
localparam Xw = log2(NX), |
PCK_CNTw = log2(MAX_PCK_NUM+1); |
|
input reset,clk,en; |
|
input [PCK_CNTw-1 : 0] pck_number; |
input [Xw-1 : 0] current_x; |
|
output [Xw-1 : 0] dest_x; |
|
output valid_dst; |
|
|
|
genvar i; |
|
generate |
if (TRAFFIC == "RANDOM") begin |
|
pseudo_random_no_core #( |
.MAX_RND (NX-1), |
.MAX_CORE (NX-1), |
.MAX_NUM (MAX_PCK_NUM) |
) |
rnd_dest_gen |
( |
.core (current_x), |
.num (pck_number), |
.rnd (dest_x), |
.rnd_en (en), |
.reset (reset), |
.clk (clk) |
|
); |
|
|
|
|
end else if (TRAFFIC == "HOTSPOT") begin |
|
pseudo_hotspot_no_core #( |
.MAX_RND (NX-1 ), |
.MAX_CORE (NX-1 ), |
.MAX_NUM (MAX_PCK_NUM), |
.HOTSPOT_PERCENTAGE (HOTSPOT_PERCENTAGE), //maximum 25% |
.HOTSOPT_NUM (HOTSOPT_NUM), //maximum 4 |
.HOTSPOT_CORE_1 (HOTSPOT_CORE_1), |
.HOTSPOT_CORE_2 (HOTSPOT_CORE_2), |
.HOTSPOT_CORE_3 (HOTSPOT_CORE_3), |
.HOTSPOT_CORE_4 (HOTSPOT_CORE_4), |
.HOTSPOT_CORE_5 (HOTSPOT_CORE_5) |
|
)rnd_dest_gen |
( |
|
.core (current_x), |
.num (pck_number), |
.rnd (dest_x), |
.rnd_en(en), |
.reset (reset), |
.clk (clk) |
|
); |
|
|
|
|
end else if( TRAFFIC == "TRANSPOSE1") begin :tran1 |
|
assign dest_x= NX-current_x-1; |
|
// end else if( TRAFFIC == "TRANSPOSE2") begin :transpose2 |
|
|
// assign dest_x = current_y; |
// assign dest_y = current_x; |
|
|
end else if( TRAFFIC == "BIT_REVERSE") begin :bitreverse |
|
wire [ Xw -1 : 0] reverse_addr; |
|
|
for(i=0; i<Xw; i=i+1'b1) begin :lp//reverse the address |
assign reverse_addr[i] = current_x [Xw-1-i]; |
end |
assign dest_x = reverse_addr; |
|
end else if( TRAFFIC == "BIT_COMPLEMENT") begin :bitcomp |
|
assign dest_x = ~current_x; |
end else if( TRAFFIC == "TORNADO" ) begin :tornado |
//[(x+(k/2-1)) mod k, (y+(k/2-1)) mod k], |
assign dest_x = (current_x > ((NX+1)/2))? current_x- ((NX+1)/2) -1 : (NX/2)+current_x-1; // = ((current_x + ((NX/2)-1))%NX); |
|
|
end else if(TRAFFIC == "CUSTOM" )begin |
/* |
assign send_en = (current_x==0 && current_y==0);// core (0,0) sends packets to (7,7) |
assign dest_x = 7; |
assign dest_y = 7; |
*/ |
reg [Xw-1 : 0]dest_x_reg; |
|
reg valid_dst_reg; |
|
always @(*) begin |
valid_dst_reg=1'b0; |
if( current_x==0 ) begin |
dest_x_reg= NX/2-1; valid_dst_reg=1'b1; |
end |
/* |
if((current_x==1) ) begin |
dest_x_reg= NX-1; valid_dst_reg=1'b1; |
end |
|
if((current_x==2) ) begin |
dest_x_reg= NX-1; valid_dst_reg=1'b1; |
end |
|
if((current_x==1) && (current_y== 1)) begin |
dest_x_reg= 1; dest_y_reg= 6; valid_dst_reg=1'b1; |
end |
if((current_x==1) && (current_y== 2)) begin |
dest_x_reg= 1; dest_y_reg= 5; valid_dst_reg=1'b1; |
end |
if((current_x==1) && (current_y== 3)) begin |
dest_x_reg= 1; dest_y_reg= 4; valid_dst_reg=1'b1; |
end |
*/ |
end |
/* |
0 0 1 1 |
0 1 1 2 |
1 0 1 7 |
1 1 1 6 |
1 2 1 5 |
1 3 1 4 |
*/ |
assign valid_dst = valid_dst_reg; |
|
assign dest_x = dest_x_reg; |
|
end |
|
|
//check if destination address is valid |
if(TRAFFIC != "CUSTOM" )begin |
assign valid_dst = (dest_x != current_x) & (dest_x <= (NX-1)); |
end |
|
endgenerate |
|
endmodule |
|
|
|
|
|
|
|
/src_noc/arbiter.v
1,19 → 1,19
`timescale 1ns/1ps |
`timescale 1ns/1ps |
|
|
|
/***************************************** |
|
round robin arbiter |
|
round robin arbiter |
|
|
******************************************/ |
|
module arbiter #( |
parameter ARBITER_WIDTH =8 |
|
parameter ARBITER_WIDTH =8 |
|
) |
( |
( |
clk, |
reset, |
request, |
21,61 → 21,61
any_grant |
); |
|
|
input [ARBITER_WIDTH-1 : 0] request; |
output [ARBITER_WIDTH-1 : 0] grant; |
output any_grant; |
input clk; |
input reset; |
|
input [ARBITER_WIDTH-1 : 0] request; |
output [ARBITER_WIDTH-1 : 0] grant; |
output any_grant; |
input clk; |
input reset; |
|
|
|
generate |
if(ARBITER_WIDTH==1) begin: w1 |
assign grant= request; |
assign any_grant =request; |
end else if(ARBITER_WIDTH<=4) begin: w4 |
//my own arbiter |
my_one_hot_arbiter #( |
.ARBITER_WIDTH (ARBITER_WIDTH) |
) |
one_hot_arb |
( |
.clk (clk), |
.reset (reset), |
.request (request), |
.grant (grant), |
.any_grant (any_grant) |
); |
|
end else begin : wb4 |
|
thermo_arbiter #( |
.ARBITER_WIDTH (ARBITER_WIDTH) |
) |
one_hot_arb |
( |
.clk (clk), |
.reset (reset), |
.request (request), |
.grant (grant), |
.any_grant (any_grant) |
); |
end |
endgenerate |
generate |
if(ARBITER_WIDTH==1) begin: w1 |
assign grant= request; |
assign any_grant =request; |
end else if(ARBITER_WIDTH<=4) begin: w4 |
//my own arbiter |
my_one_hot_arbiter #( |
.ARBITER_WIDTH (ARBITER_WIDTH) |
) |
one_hot_arb |
( |
.clk (clk), |
.reset (reset), |
.request (request), |
.grant (grant), |
.any_grant (any_grant) |
); |
|
end else begin : wb4 |
|
thermo_arbiter #( |
.ARBITER_WIDTH (ARBITER_WIDTH) |
) |
one_hot_arb |
( |
.clk (clk), |
.reset (reset), |
.request (request), |
.grant (grant), |
.any_grant (any_grant) |
); |
end |
endgenerate |
endmodule |
|
/***************************************** |
|
arbiter_priority_en |
arbiter_priority_en |
|
******************************************/ |
|
module arbiter_priority_en #( |
parameter ARBITER_WIDTH =8 |
|
parameter ARBITER_WIDTH =8 |
|
) |
( |
( |
clk, |
reset, |
request, |
87,183 → 87,185
|
|
|
input [ARBITER_WIDTH-1 : 0] request; |
output [ARBITER_WIDTH-1 : 0] grant; |
output any_grant; |
input clk; |
input reset; |
input priority_en; |
|
|
generate |
if(ARBITER_WIDTH==1) begin: w1 |
assign grant= request; |
assign any_grant =request; |
end else if(ARBITER_WIDTH<=4) begin: w4 |
//my own arbiter |
my_one_hot_arbiter_priority_en #( |
.ARBITER_WIDTH (ARBITER_WIDTH) |
) |
one_hot_arb |
( |
.clk (clk), |
.reset (reset), |
.request (request), |
.grant (grant), |
.any_grant (any_grant), |
.priority_en (priority_en) |
|
); |
|
end else begin :wb4 |
|
thermo_arbiter_priority_en #( |
.ARBITER_WIDTH (ARBITER_WIDTH) |
) |
one_hot_arb |
( |
.clk (clk), |
.reset (reset), |
.request (request), |
.grant (grant), |
.any_grant (any_grant), |
.priority_en (priority_en) |
); |
end |
input [ARBITER_WIDTH-1 : 0] request; |
output [ARBITER_WIDTH-1 : 0] grant; |
output any_grant; |
input clk; |
input reset; |
input priority_en; |
|
|
generate |
if(ARBITER_WIDTH==1) begin: w1 |
assign grant= request; |
assign any_grant =request; |
end else if(ARBITER_WIDTH<=4) begin: w4 |
//my own arbiter |
my_one_hot_arbiter_priority_en #( |
.ARBITER_WIDTH (ARBITER_WIDTH) |
) |
one_hot_arb |
( |
.clk (clk), |
.reset (reset), |
.request (request), |
.grant (grant), |
.any_grant (any_grant), |
.priority_en (priority_en) |
|
); |
|
end else begin :wb4 |
|
thermo_arbiter_priority_en #( |
.ARBITER_WIDTH (ARBITER_WIDTH) |
) |
one_hot_arb |
( |
.clk (clk), |
.reset (reset), |
.request (request), |
.grant (grant), |
.any_grant (any_grant), |
.priority_en (priority_en) |
); |
end |
endgenerate |
|
|
|
|
endmodule |
|
|
|
module my_one_hot_arbiter_priority_en #( |
parameter ARBITER_WIDTH =4 |
|
|
parameter ARBITER_WIDTH =4 |
|
|
) |
( |
input [ARBITER_WIDTH-1 : 0] request, |
output [ARBITER_WIDTH-1 : 0] grant, |
output any_grant, |
input clk, |
input reset, |
input priority_en |
input [ARBITER_WIDTH-1 : 0] request, |
output [ARBITER_WIDTH-1 : 0] grant, |
output any_grant, |
input clk, |
input reset, |
input priority_en |
); |
function integer log2; |
input integer number; begin |
log2=0; |
while(2**log2<number) begin |
log2=log2+1; |
end |
end |
endfunction // log2 |
|
localparam ARBITER_BIN_WIDTH= log2(ARBITER_WIDTH); |
reg [ARBITER_BIN_WIDTH-1 : 0] low_pr; |
wire [ARBITER_BIN_WIDTH-1 : 0] grant_bcd; |
|
one_hot_to_bin #( |
.ONE_HOT_WIDTH (ARBITER_WIDTH) |
)conv |
( |
.one_hot_code(grant), |
.bin_code(grant_bcd) |
); |
|
always@(posedge clk or posedge reset) begin |
if(reset) begin |
low_pr <= {ARBITER_BIN_WIDTH{1'b0}}; |
end else begin |
if(priority_en) low_pr <= grant_bcd; |
end |
end |
|
|
function integer log2; |
input integer number; begin |
log2=(number <=1) ? 1: 0; |
while(2**log2<number) begin |
log2=log2+1; |
end |
end |
endfunction // log2 |
|
localparam ARBITER_BIN_WIDTH= log2(ARBITER_WIDTH); |
reg [ARBITER_BIN_WIDTH-1 : 0] low_pr; |
wire [ARBITER_BIN_WIDTH-1 : 0] grant_bcd; |
|
one_hot_to_bin #( |
.ONE_HOT_WIDTH (ARBITER_WIDTH) |
)conv |
( |
.one_hot_code(grant), |
.bin_code(grant_bcd) |
); |
|
always@(posedge clk or posedge reset) begin |
if(reset) begin |
low_pr <= {ARBITER_BIN_WIDTH{1'b0}}; |
end else begin |
if(priority_en) low_pr <= grant_bcd; |
end |
end |
|
|
assign any_grant = | request; |
assign any_grant = | request; |
|
generate |
if(ARBITER_WIDTH ==2) begin :w2 arbiter_2_one_hot arb( .in(request) , .out(grant), .low_pr(low_pr)); end |
if(ARBITER_WIDTH ==3) begin :w3 arbiter_3_one_hot arb( .in(request) , .out(grant), .low_pr(low_pr)); end |
if(ARBITER_WIDTH ==4) begin :w4 arbiter_4_one_hot arb( .in(request) , .out(grant), .low_pr(low_pr)); end |
endgenerate |
generate |
if(ARBITER_WIDTH ==2) begin :w2 arbiter_2_one_hot arb( .in(request) , .out(grant), .low_pr(low_pr)); end |
if(ARBITER_WIDTH ==3) begin :w3 arbiter_3_one_hot arb( .in(request) , .out(grant), .low_pr(low_pr)); end |
if(ARBITER_WIDTH ==4) begin :w4 arbiter_4_one_hot arb( .in(request) , .out(grant), .low_pr(low_pr)); end |
endgenerate |
|
endmodule |
|
|
endmodule |
|
|
|
module my_one_hot_arbiter #( |
parameter ARBITER_WIDTH =4 |
|
|
parameter ARBITER_WIDTH =4 |
|
|
) |
( |
input [ARBITER_WIDTH-1 : 0] request, |
output [ARBITER_WIDTH-1 : 0] grant, |
output any_grant, |
input clk, |
input reset |
input [ARBITER_WIDTH-1 : 0] request, |
output [ARBITER_WIDTH-1 : 0] grant, |
output any_grant, |
input clk, |
input reset |
); |
function integer log2; |
input integer number; begin |
log2=0; |
while(2**log2<number) begin |
log2=log2+1; |
end |
end |
endfunction // log2 |
|
localparam ARBITER_BIN_WIDTH= log2(ARBITER_WIDTH); |
reg [ARBITER_BIN_WIDTH-1 : 0] low_pr; |
wire [ARBITER_BIN_WIDTH-1 : 0] grant_bcd; |
|
one_hot_to_bin #( |
.ONE_HOT_WIDTH (ARBITER_WIDTH) |
)conv |
( |
.one_hot_code(grant), |
.bin_code(grant_bcd) |
|
function integer log2; |
input integer number; begin |
log2=(number <=1) ? 1: 0; |
while(2**log2<number) begin |
log2=log2+1; |
end |
end |
endfunction // log2 |
|
localparam ARBITER_BIN_WIDTH= log2(ARBITER_WIDTH); |
reg [ARBITER_BIN_WIDTH-1 : 0] low_pr; |
wire [ARBITER_BIN_WIDTH-1 : 0] grant_bcd; |
|
one_hot_to_bin #( |
.ONE_HOT_WIDTH (ARBITER_WIDTH) |
)conv |
( |
.one_hot_code(grant), |
.bin_code(grant_bcd) |
|
); |
|
|
|
always@(posedge clk or posedge reset) begin |
if(reset) begin |
low_pr <= {ARBITER_BIN_WIDTH{1'b0}}; |
end else begin |
if(any_grant) low_pr <= grant_bcd; |
end |
end |
|
); |
|
|
|
always@(posedge clk or posedge reset) begin |
if(reset) begin |
low_pr <= {ARBITER_BIN_WIDTH{1'b0}}; |
end else begin |
if(any_grant) low_pr <= grant_bcd; |
end |
end |
|
|
assign any_grant = | request; |
assign any_grant = | request; |
|
generate |
if(ARBITER_WIDTH ==2) begin: w2 arbiter_2_one_hot arb( .in(request) , .out(grant), .low_pr(low_pr)); end |
if(ARBITER_WIDTH ==3) begin: w3 arbiter_3_one_hot arb( .in(request) , .out(grant), .low_pr(low_pr)); end |
if(ARBITER_WIDTH ==4) begin: w4 arbiter_4_one_hot arb( .in(request) , .out(grant), .low_pr(low_pr)); end |
endgenerate |
generate |
if(ARBITER_WIDTH ==2) begin: w2 arbiter_2_one_hot arb( .in(request) , .out(grant), .low_pr(low_pr)); end |
if(ARBITER_WIDTH ==3) begin: w3 arbiter_3_one_hot arb( .in(request) , .out(grant), .low_pr(low_pr)); end |
if(ARBITER_WIDTH ==4) begin: w4 arbiter_4_one_hot arb( .in(request) , .out(grant), .low_pr(low_pr)); end |
endgenerate |
|
endmodule |
|
|
module arbiter_2_one_hot( |
input [1 : 0] in, |
output reg[1 : 0] out, |
input low_pr |
input [1 : 0] in, |
output reg[1 : 0] out, |
input low_pr |
); |
always @(*) begin |
out=2'b00; |
case(low_pr) |
1'd0: |
if(in[1]) out=2'b10; |
else if(in[0]) out=2'b01; |
1'd1: |
if(in[0]) out=2'b01; |
else if(in[1]) out=2'b10; |
default: out=2'b00; |
endcase |
out=2'b00; |
case(low_pr) |
1'd0: |
if(in[1]) out=2'b10; |
else if(in[0]) out=2'b01; |
1'd1: |
if(in[0]) out=2'b01; |
else if(in[1]) out=2'b10; |
default: out=2'b00; |
endcase |
end |
endmodule |
|
271,61 → 273,61
|
|
module arbiter_3_one_hot( |
input [2 : 0] in, |
output reg[2 : 0] out, |
input [1 : 0] low_pr |
input [2 : 0] in, |
output reg[2 : 0] out, |
input [1 : 0] low_pr |
); |
always @(*) begin |
out=3'b000; |
case(low_pr) |
2'd0: |
if(in[1]) out=3'b010; |
else if(in[2]) out=3'b100; |
else if(in[0]) out=3'b001; |
2'd1: |
if(in[2]) out=3'b100; |
else if(in[0]) out=3'b001; |
else if(in[1]) out=3'b010; |
2'd2: |
if(in[0]) out=3'b001; |
else if(in[1]) out=3'b010; |
else if(in[2]) out=3'b100; |
default: out=3'b000; |
endcase |
case(low_pr) |
2'd0: |
if(in[1]) out=3'b010; |
else if(in[2]) out=3'b100; |
else if(in[0]) out=3'b001; |
2'd1: |
if(in[2]) out=3'b100; |
else if(in[0]) out=3'b001; |
else if(in[1]) out=3'b010; |
2'd2: |
if(in[0]) out=3'b001; |
else if(in[1]) out=3'b010; |
else if(in[2]) out=3'b100; |
default: out=3'b000; |
endcase |
end |
endmodule |
|
|
module arbiter_4_one_hot( |
input [3 : 0] in, |
output reg[3 : 0] out, |
input [1 : 0] low_pr |
input [3 : 0] in, |
output reg[3 : 0] out, |
input [1 : 0] low_pr |
); |
always @(*) begin |
out=4'b0000; |
case(low_pr) |
2'd0: |
if(in[1]) out=4'b0010; |
else if(in[2]) out=4'b0100; |
else if(in[3]) out=4'b1000; |
else if(in[0]) out=4'b0001; |
2'd1: |
if(in[2]) out=4'b0100; |
else if(in[3]) out=4'b1000; |
else if(in[0]) out=4'b0001; |
else if(in[1]) out=4'b0010; |
2'd2: |
if(in[3]) out=4'b1000; |
else if(in[0]) out=4'b0001; |
else if(in[1]) out=4'b0010; |
else if(in[2]) out=4'b0100; |
2'd3: |
if(in[0]) out=4'b0001; |
else if(in[1]) out=4'b0010; |
else if(in[2]) out=4'b0100; |
else if(in[3]) out=4'b1000; |
default: out=4'b0000; |
endcase |
case(low_pr) |
2'd0: |
if(in[1]) out=4'b0010; |
else if(in[2]) out=4'b0100; |
else if(in[3]) out=4'b1000; |
else if(in[0]) out=4'b0001; |
2'd1: |
if(in[2]) out=4'b0100; |
else if(in[3]) out=4'b1000; |
else if(in[0]) out=4'b0001; |
else if(in[1]) out=4'b0010; |
2'd2: |
if(in[3]) out=4'b1000; |
else if(in[0]) out=4'b0001; |
else if(in[1]) out=4'b0010; |
else if(in[2]) out=4'b0100; |
2'd3: |
if(in[0]) out=4'b0001; |
else if(in[1]) out=4'b0010; |
else if(in[2]) out=4'b0100; |
else if(in[3]) out=4'b1000; |
default: out=4'b0000; |
endcase |
end |
endmodule |
|
333,24 → 335,24
|
/******************* |
|
thermo_arbiter |
thermo_arbiter |
|
********************/ |
|
module thermo_gen #( |
parameter WIDTH=16 |
parameter WIDTH=16 |
|
|
)( |
input [WIDTH-1 : 0]in, |
output [WIDTH-1 : 0]out |
input [WIDTH-1 : 0]in, |
output [WIDTH-1 : 0]out |
); |
genvar i; |
generate |
for(i=0;i<WIDTH;i=i+1)begin :lp |
assign out[i]= | in[i :0]; |
end |
endgenerate |
genvar i; |
generate |
for(i=0;i<WIDTH;i=i+1)begin :lp |
assign out[i]= | in[i :0]; |
end |
endgenerate |
|
endmodule |
|
358,10 → 360,10
|
|
module thermo_arbiter #( |
parameter ARBITER_WIDTH =4 |
|
parameter ARBITER_WIDTH =4 |
|
) |
( |
( |
clk, |
reset, |
request, |
369,48 → 371,48
any_grant |
); |
|
|
|
|
|
input [ARBITER_WIDTH-1 : 0] request; |
output [ARBITER_WIDTH-1 : 0] grant; |
output any_grant; |
input reset,clk; |
|
|
wire [ARBITER_WIDTH-1 : 0] termo1,termo2,mux_out,masked_request,edge_mask; |
reg [ARBITER_WIDTH-1 : 0] pr; |
|
input [ARBITER_WIDTH-1 : 0] request; |
output [ARBITER_WIDTH-1 : 0] grant; |
output any_grant; |
input reset,clk; |
|
|
wire [ARBITER_WIDTH-1 : 0] termo1,termo2,mux_out,masked_request,edge_mask; |
reg [ARBITER_WIDTH-1 : 0] pr; |
|
|
thermo_gen #( |
.WIDTH(ARBITER_WIDTH) |
) tm1 |
( |
.in(request), |
.out(termo1) |
); |
thermo_gen #( |
.WIDTH(ARBITER_WIDTH) |
) tm1 |
( |
.in(request), |
.out(termo1) |
); |
|
|
|
|
thermo_gen #( |
.WIDTH(ARBITER_WIDTH) |
) tm2 |
( |
.in(masked_request), |
.out(termo2) |
); |
thermo_gen #( |
.WIDTH(ARBITER_WIDTH) |
) tm2 |
( |
.in(masked_request), |
.out(termo2) |
); |
|
|
|
assign mux_out=(termo2[ARBITER_WIDTH-1])? termo2 : termo1; |
assign masked_request= request & pr; |
assign any_grant=termo1[ARBITER_WIDTH-1]; |
|
always @(posedge clk or posedge reset)begin |
if(reset) pr<= {ARBITER_WIDTH{1'b1}}; |
else begin |
if(any_grant) pr<= edge_mask; |
end |
if(reset) pr<= {ARBITER_WIDTH{1'b1}}; |
else begin |
if(any_grant) pr<= edge_mask; |
end |
|
end |
|
420,16 → 422,16
|
|
endmodule |
|
|
|
|
|
|
|
module thermo_arbiter_priority_en #( |
parameter ARBITER_WIDTH =4 |
|
parameter ARBITER_WIDTH =4 |
|
) |
( |
( |
clk, |
reset, |
request, |
438,48 → 440,48
priority_en |
); |
|
|
|
|
|
input [ARBITER_WIDTH-1 : 0] request; |
output [ARBITER_WIDTH-1 : 0] grant; |
output any_grant; |
input reset,clk; |
input priority_en; |
|
wire [ARBITER_WIDTH-1 : 0] termo1,termo2,mux_out,masked_request,edge_mask; |
reg [ARBITER_WIDTH-1 : 0] pr; |
|
input [ARBITER_WIDTH-1 : 0] request; |
output [ARBITER_WIDTH-1 : 0] grant; |
output any_grant; |
input reset,clk; |
input priority_en; |
|
wire [ARBITER_WIDTH-1 : 0] termo1,termo2,mux_out,masked_request,edge_mask; |
reg [ARBITER_WIDTH-1 : 0] pr; |
|
|
thermo_gen #( |
.WIDTH(ARBITER_WIDTH) |
) tm1 |
( |
.in(request), |
.out(termo1) |
); |
thermo_gen #( |
.WIDTH(ARBITER_WIDTH) |
) tm1 |
( |
.in(request), |
.out(termo1) |
); |
|
|
|
|
thermo_gen #( |
.WIDTH(ARBITER_WIDTH) |
) tm2 |
( |
.in(masked_request), |
.out(termo2) |
); |
thermo_gen #( |
.WIDTH(ARBITER_WIDTH) |
) tm2 |
( |
.in(masked_request), |
.out(termo2) |
); |
|
|
|
assign mux_out=(termo2[ARBITER_WIDTH-1])? termo2 : termo1; |
assign masked_request= request & pr; |
assign any_grant=termo1[ARBITER_WIDTH-1]; |
|
always @(posedge clk or posedge reset)begin |
if(reset) pr<= {ARBITER_WIDTH{1'b1}}; |
else begin |
if(priority_en) pr<= edge_mask; |
end |
if(reset) pr<= {ARBITER_WIDTH{1'b1}}; |
else begin |
if(priority_en) pr<= edge_mask; |
end |
|
end |
|
489,7 → 491,7
|
|
endmodule |
|
|
|
|
|
498,10 → 500,10
|
|
module thermo_arbiter_ext_priority #( |
parameter ARBITER_WIDTH =4 |
|
parameter ARBITER_WIDTH =4 |
|
) |
( |
( |
|
request, |
grant, |
510,47 → 512,47
|
); |
|
|
|
|
|
input [ARBITER_WIDTH-1 : 0] request; |
output [ARBITER_WIDTH-1 : 0] grant; |
output any_grant; |
input [ARBITER_WIDTH-1 : 0] priority_in; |
|
input [ARBITER_WIDTH-1 : 0] request; |
output [ARBITER_WIDTH-1 : 0] grant; |
output any_grant; |
input [ARBITER_WIDTH-1 : 0] priority_in; |
|
wire [ARBITER_WIDTH-1 : 0] termo1,termo2,mux_out,masked_request,edge_mask; |
wire [ARBITER_WIDTH-1 : 0] pr; |
wire [ARBITER_WIDTH-1 : 0] termo1,termo2,mux_out,masked_request,edge_mask; |
wire [ARBITER_WIDTH-1 : 0] pr; |
|
|
thermo_gen #( |
.WIDTH(ARBITER_WIDTH) |
) tm1 |
( |
.in(request), |
.out(termo1) |
); |
thermo_gen #( |
.WIDTH(ARBITER_WIDTH) |
) tm1 |
( |
.in(request), |
.out(termo1) |
); |
|
|
|
|
thermo_gen #( |
.WIDTH(ARBITER_WIDTH) |
) tm2 |
( |
.in(masked_request), |
.out(termo2) |
); |
thermo_gen #( |
.WIDTH(ARBITER_WIDTH) |
) tm2 |
( |
.in(masked_request), |
.out(termo2) |
); |
|
|
thermo_gen #( |
.WIDTH(ARBITER_WIDTH) |
) tm3 |
( |
.in(priority_in), |
.out(pr) |
); |
thermo_gen #( |
.WIDTH(ARBITER_WIDTH) |
) tm3 |
( |
.in(priority_in), |
.out(pr) |
); |
|
|
|
assign mux_out=(termo2[ARBITER_WIDTH-1])? termo2 : termo1; |
assign masked_request= request & pr; |
assign any_grant=termo1[ARBITER_WIDTH-1]; |
562,24 → 564,24
|
|
endmodule |
|
|
|
|
/******************************** |
|
|
|
Tree arbiter |
|
|
|
Tree arbiter |
|
|
|
|
|
*******************************/ |
|
module tree_arbiter #( |
parameter GROUP_NUM =4, |
parameter ARBITER_WIDTH =16 |
parameter GROUP_NUM =4, |
parameter ARBITER_WIDTH =16 |
) |
( |
( |
clk, |
reset, |
request, |
587,14 → 589,15
any_grant |
); |
|
function integer log2; |
input integer number; begin |
log2=0; |
while(2**log2<number) begin |
log2=log2+1; |
end |
end |
endfunction // log2 |
|
function integer log2; |
input integer number; begin |
log2=(number <=1) ? 1: 0; |
while(2**log2<number) begin |
log2=log2+1; |
end |
end |
endfunction // log2 |
|
localparam N = ARBITER_WIDTH; |
localparam S = log2(ARBITER_WIDTH); // ceil of log_2 of N - put manually |
608,63 → 611,63
output any_grant; |
|
|
localparam GROUP_WIDTH = ARBITER_WIDTH/GROUP_NUM; |
localparam GROUP_WIDTH = ARBITER_WIDTH/GROUP_NUM; |
|
wire [GROUP_WIDTH-1 : 0] group_req [GROUP_NUM-1 : 0]; |
wire [GROUP_WIDTH-1 : 0] group_grant [GROUP_NUM-1 : 0]; |
wire [GROUP_WIDTH-1 : 0] grant_masked[GROUP_NUM-1 : 0]; |
wire [GROUP_WIDTH-1 : 0] group_req [GROUP_NUM-1 : 0]; |
wire [GROUP_WIDTH-1 : 0] group_grant [GROUP_NUM-1 : 0]; |
wire [GROUP_WIDTH-1 : 0] grant_masked[GROUP_NUM-1 : 0]; |
|
wire [GROUP_NUM-1 : 0] any_group_member_req; |
wire [GROUP_NUM-1 : 0] any_group_member_grant; |
wire [GROUP_NUM-1 : 0] any_group_member_req; |
wire [GROUP_NUM-1 : 0] any_group_member_grant; |
|
|
genvar i; |
generate |
for (i=0;i<GROUP_NUM;i=i+1) begin :group_lp |
|
//seprate inputs in group |
assign group_req[i] = request[(i+1)*GROUP_WIDTH-1 : i*GROUP_WIDTH]; |
|
//check if any member of qrup has request |
assign any_group_member_req[i] = | group_req[i]; |
|
//arbiterate one request from each group |
arbiter #( |
.ARBITER_WIDTH (GROUP_WIDTH) |
)group_member_arbiter |
( |
.clk (clk), |
.reset (reset), |
.request (group_req[i]), |
.grant (group_grant[i]), |
.any_grant () |
); |
|
// mask the non selected groups |
assign grant_masked [i] = (any_group_member_grant[i])? group_grant[i]: {GROUP_WIDTH{1'b0}}; |
|
//assemble the grants |
assign grant [(i+1)*GROUP_WIDTH-1 : i*GROUP_WIDTH] = grant_masked [i]; |
|
|
end |
endgenerate |
|
//select one group which has atleast one active request |
|
//arbiterate one request from each group |
arbiter #( |
.ARBITER_WIDTH (GROUP_NUM) |
)second_arbiter |
( |
.clk (clk), |
.reset (reset), |
.request (any_group_member_req), |
.grant (any_group_member_grant), |
.any_grant (any_grant) |
); |
|
|
|
genvar i; |
generate |
for (i=0;i<GROUP_NUM;i=i+1) begin :group_lp |
|
//seprate inputs in group |
assign group_req[i] = request[(i+1)*GROUP_WIDTH-1 : i*GROUP_WIDTH]; |
|
//check if any member of qrup has request |
assign any_group_member_req[i] = | group_req[i]; |
|
//arbiterate one request from each group |
arbiter #( |
.ARBITER_WIDTH (GROUP_WIDTH) |
)group_member_arbiter |
( |
.clk (clk), |
.reset (reset), |
.request (group_req[i]), |
.grant (group_grant[i]), |
.any_grant () |
); |
|
// mask the non selected groups |
assign grant_masked [i] = (any_group_member_grant[i])? group_grant[i]: {GROUP_WIDTH{1'b0}}; |
|
//assemble the grants |
assign grant [(i+1)*GROUP_WIDTH-1 : i*GROUP_WIDTH] = grant_masked [i]; |
|
|
end |
endgenerate |
|
//select one group which has atleast one active request |
|
//arbiterate one request from each group |
arbiter #( |
.ARBITER_WIDTH (GROUP_NUM) |
)second_arbiter |
( |
.clk (clk), |
.reset (reset), |
.request (any_group_member_req), |
.grant (any_group_member_grant), |
.any_grant (any_grant) |
); |
|
|
|
endmodule |
|
690,15 → 693,16
output [ARBITER_WIDTH-1 : 0] grant, |
output any_grant |
); |
|
function integer log2; |
input integer number; begin |
log2=0; |
log2=(number <=1) ? 1: 0; |
while(2**log2<number) begin |
log2=log2+1; |
end |
end |
end |
endfunction // log2 |
|
endfunction // log2 |
|
localparam ARBITER_BIN_WIDTH= log2(ARBITER_WIDTH); |
wire [ARBITER_BIN_WIDTH-1 : 0] low_pr; |
|
705,13 → 709,13
|
wire [ARBITER_WIDTH-1 : 0] low_pr_one_hot = {priority_in[0],priority_in[ARBITER_BIN_WIDTH-1:1]}; |
|
one_hot_to_bin #( |
.ONE_HOT_WIDTH (ARBITER_WIDTH) |
)conv |
( |
.one_hot_code(low_pr_one_hot), |
.bin_code(low_pr) |
); |
one_hot_to_bin #( |
.ONE_HOT_WIDTH (ARBITER_WIDTH) |
)conv |
( |
.one_hot_code(low_pr_one_hot), |
.bin_code(low_pr) |
); |
|
|
assign any_grant = | request; |
/src_noc/baseline.v
1,4 → 1,4
`timescale 1ns/1ps |
`timescale 1ns/1ps |
/************************************** |
|
baseline allocator |
6,142 → 6,142
|
*************************************/ |
|
|
|
module baseline_allocator #( |
parameter V = 4,// Virtual channel num per port |
parameter P = 5,//port number |
parameter TREE_ARBITER_EN = 0, |
parameter DEBUG_EN = 1 |
parameter V = 4,// Virtual channel num per port |
parameter P = 5,//port number |
parameter TREE_ARBITER_EN = 0, |
parameter DEBUG_EN = 1 |
) |
( |
|
dest_port_all, |
ovc_is_assigned_all, |
ivc_request_all, |
assigned_ovc_not_full_all, |
ovc_allocated_all, |
granted_ovc_num_all, |
ivc_num_getting_ovc_grant, |
ivc_num_getting_sw_grant, |
spec_first_arbiter_granted_ivc_all, |
nonspec_first_arbiter_granted_ivc_all, |
granted_dest_port_all, |
nonspec_granted_dest_port_all, |
spec_granted_dest_port_all, |
any_ivc_sw_request_granted_all, |
spec_ovc_num_all, |
masked_ovc_request_all, |
clk,reset |
|
dest_port_all, |
ovc_is_assigned_all, |
ivc_request_all, |
assigned_ovc_not_full_all, |
ovc_allocated_all, |
granted_ovc_num_all, |
ivc_num_getting_ovc_grant, |
ivc_num_getting_sw_grant, |
spec_first_arbiter_granted_ivc_all, |
nonspec_first_arbiter_granted_ivc_all, |
granted_dest_port_all, |
nonspec_granted_dest_port_all, |
spec_granted_dest_port_all, |
any_ivc_sw_request_granted_all, |
spec_ovc_num_all, |
masked_ovc_request_all, |
clk,reset |
|
); |
|
|
|
localparam PV = V * P, |
PVV = PV * V, |
P_1 = P-1 , |
PP_1 = P_1 * P, |
PVP_1 = PV * P_1; |
localparam PV = V * P, |
PVV = PV * V, |
P_1 = P-1 , |
PP_1 = P_1 * P, |
PVP_1 = PV * P_1; |
|
|
|
input [PVP_1-1 : 0] dest_port_all; |
input [PV-1 : 0] ovc_is_assigned_all; |
input [PV-1 : 0] ivc_request_all; |
input [PV-1 : 0] assigned_ovc_not_full_all; |
|
|
output [PV-1 : 0] ovc_allocated_all; |
output [PVV-1 : 0] granted_ovc_num_all; |
output [PV-1 : 0] ivc_num_getting_ovc_grant; |
output [PV-1 : 0] ivc_num_getting_sw_grant; |
output [PV-1 : 0] nonspec_first_arbiter_granted_ivc_all; |
output [PV-1 : 0] spec_first_arbiter_granted_ivc_all; |
|
output [PP_1-1 : 0] granted_dest_port_all; |
output [PP_1-1 : 0] nonspec_granted_dest_port_all; |
output [PP_1-1 : 0] spec_granted_dest_port_all; |
output [P-1 : 0] any_ivc_sw_request_granted_all; |
output [PVV-1 : 0] spec_ovc_num_all; |
|
|
input [PVP_1-1 : 0] dest_port_all; |
input [PV-1 : 0] ovc_is_assigned_all; |
input [PV-1 : 0] ivc_request_all; |
input [PV-1 : 0] assigned_ovc_not_full_all; |
|
|
output [PV-1 : 0] ovc_allocated_all; |
output [PVV-1 : 0] granted_ovc_num_all; |
output [PV-1 : 0] ivc_num_getting_ovc_grant; |
output [PV-1 : 0] ivc_num_getting_sw_grant; |
output [PV-1 : 0] nonspec_first_arbiter_granted_ivc_all; |
output [PV-1 : 0] spec_first_arbiter_granted_ivc_all; |
|
output [PP_1-1 : 0] granted_dest_port_all; |
output [PP_1-1 : 0] nonspec_granted_dest_port_all; |
output [PP_1-1 : 0] spec_granted_dest_port_all; |
output [P-1 : 0] any_ivc_sw_request_granted_all; |
output [PVV-1 : 0] spec_ovc_num_all; |
input [PVV-1 : 0] masked_ovc_request_all; |
input clk,reset; |
input clk,reset; |
|
|
wire [V-1 : 0] spec_first_arbiter_granted_ivc [P-1 : 0]; |
wire [V-1 : 0] ivc_local_num_getting_ovc_grant [P-1 : 0]; |
wire [P-1 : 0] valid_speculation; |
|
|
|
|
|
// canonical VC allocator |
|
|
canonical_vc_alloc #( |
.TREE_ARBITER_EN (TREE_ARBITER_EN), |
.V(V), |
.P(P) |
)the_canonical_VC_allocator |
( |
.granted_ovc_num_all (granted_ovc_num_all), |
.ovc_allocated_all (ovc_allocated_all), |
.ivc_num_getting_ovc_grant (ivc_num_getting_ovc_grant), |
.masked_ovc_request_all (masked_ovc_request_all), |
.dest_port_all (dest_port_all), |
.spec_ovc_num_all (spec_ovc_num_all), |
.clk (clk), |
.reset (reset) |
); |
|
//speculative switch allocator |
spec_sw_alloc_can #( |
.V(V), |
.P(P), |
.DEBUG_EN(DEBUG_EN) |
)speculative_sw_allocator |
( |
|
wire [V-1 : 0] spec_first_arbiter_granted_ivc [P-1 : 0]; |
wire [V-1 : 0] ivc_local_num_getting_ovc_grant [P-1 : 0]; |
wire [P-1 : 0] valid_speculation; |
|
|
|
|
|
// canonical VC allocator |
|
|
canonical_vc_alloc #( |
.TREE_ARBITER_EN (TREE_ARBITER_EN), |
.V(V), |
.P(P) |
)the_canonical_VC_allocator |
( |
.granted_ovc_num_all (granted_ovc_num_all), |
.ovc_allocated_all (ovc_allocated_all), |
.ivc_num_getting_ovc_grant (ivc_num_getting_ovc_grant), |
.masked_ovc_request_all (masked_ovc_request_all), |
.dest_port_all (dest_port_all), |
.spec_ovc_num_all (spec_ovc_num_all), |
.clk (clk), |
.reset (reset) |
); |
|
//speculative switch allocator |
spec_sw_alloc_can #( |
.V(V), |
.P(P), |
.DEBUG_EN(DEBUG_EN) |
)speculative_sw_allocator |
( |
|
.ivc_granted_all (ivc_num_getting_sw_grant), |
.ivc_request_all (ivc_request_all), |
.ovc_is_assigned_all (ovc_is_assigned_all), |
.assigned_ovc_not_full_all (assigned_ovc_not_full_all), |
.dest_port_all (dest_port_all), |
.granted_dest_port_all (granted_dest_port_all), |
.nonspec_granted_dest_port_all (nonspec_granted_dest_port_all), |
.spec_granted_dest_port_all (spec_granted_dest_port_all), |
.valid_speculation (valid_speculation), |
.spec_first_arbiter_granted_ivc_all (spec_first_arbiter_granted_ivc_all), |
.nonspec_first_arbiter_granted_ivc_all(nonspec_first_arbiter_granted_ivc_all), |
.any_ivc_sw_request_granted_all (any_ivc_sw_request_granted_all), |
.clk (clk), |
.reset (reset) |
|
); |
|
// check valid speculation |
genvar i; |
generate |
for(i=0;i<P; i=i+1) begin :valid_chek_lp |
|
assign spec_first_arbiter_granted_ivc[i] = spec_first_arbiter_granted_ivc_all[(i+1)*V-1 : i*V]; |
assign ivc_local_num_getting_ovc_grant[i] = ivc_num_getting_ovc_grant [(i+1)*V-1 : i*V]; |
//speculative VC request multiplexer |
one_hot_mux #( |
.IN_WIDTH (V), |
.SEL_WIDTH (V) |
) |
multiplexer |
( |
.mux_in (ivc_local_num_getting_ovc_grant [i]), |
.mux_out (valid_speculation [i]), |
.sel (spec_first_arbiter_granted_ivc [i]) |
); |
|
|
|
end//for |
endgenerate |
.ivc_granted_all (ivc_num_getting_sw_grant), |
.ivc_request_all (ivc_request_all), |
.ovc_is_assigned_all (ovc_is_assigned_all), |
.assigned_ovc_not_full_all (assigned_ovc_not_full_all), |
.dest_port_all (dest_port_all), |
.granted_dest_port_all (granted_dest_port_all), |
.nonspec_granted_dest_port_all (nonspec_granted_dest_port_all), |
.spec_granted_dest_port_all (spec_granted_dest_port_all), |
.valid_speculation (valid_speculation), |
.spec_first_arbiter_granted_ivc_all (spec_first_arbiter_granted_ivc_all), |
.nonspec_first_arbiter_granted_ivc_all(nonspec_first_arbiter_granted_ivc_all), |
.any_ivc_sw_request_granted_all (any_ivc_sw_request_granted_all), |
.clk (clk), |
.reset (reset) |
|
); |
|
// check valid speculation |
genvar i; |
generate |
for(i=0;i<P; i=i+1) begin :valid_chek_lp |
|
assign spec_first_arbiter_granted_ivc[i] = spec_first_arbiter_granted_ivc_all[(i+1)*V-1 : i*V]; |
assign ivc_local_num_getting_ovc_grant[i] = ivc_num_getting_ovc_grant [(i+1)*V-1 : i*V]; |
//speculative VC request multiplexer |
one_hot_mux #( |
.IN_WIDTH (V), |
.SEL_WIDTH (V) |
) |
multiplexer |
( |
.mux_in (ivc_local_num_getting_ovc_grant [i]), |
.mux_out (valid_speculation [i]), |
.sel (spec_first_arbiter_granted_ivc [i]) |
); |
|
|
|
end//for |
endgenerate |
|
|
endmodule |
443,7 → 443,7
assign spec_granted_dest_port_all_accepted[(i+1)*P_1-1 : i*P_1]=valid_speculation[i]? (spec_request_acceptable[(i+1)*P_1-1 : i*P_1] & spec_granted_dest_port_all_pre[(i+1)*P_1-1 : i*P_1]): {P_1{1'b0}}; |
|
//synthesis translate_off |
//synopsys translate_off |
//synopsys translate_off |
|
if(DEBUG_EN)begin :dbg |
always @(posedge clk) begin |
451,7 → 451,7
if(nonspec_ivc_granted_all [(i+1)*V-1 : i*V] >0 && spec_ivc_granted_all_accepted[(i+1)*V-1 : i*V]>0 ) $display("%t: Error: Both speculative and nonspeculative is granted for one port",$time); |
end |
end |
//synopsys translate_on |
//synopsys translate_on |
//synthesis translate_on |
|
|
/src_noc/canonical_credit_count.v
1,12 → 1,12
`timescale 1ns/1ps |
`timescale 1ns/1ps |
|
module canonical_credit_counter #( |
|
parameter V = 4, // vc_num_per_port |
parameter P = 5, // router port num |
parameter B = 4, // buffer space :flit per VC |
parameter VC_REALLOCATION_TYPE = "NONATOMIC",// "ATOMIC" , "NONATOMIC" |
parameter ROUTE_TYPE = "ADAPTIVE",// "DETERMINISTIC", "FULL_ADAPTIVE", "PAR_ADAPTIVE" |
parameter V = 4, // vc_num_per_port |
parameter P = 5, // router port num |
parameter B = 4, // buffer space :flit per VC |
parameter VC_REALLOCATION_TYPE = "NONATOMIC",// "ATOMIC" , "NONATOMIC" |
parameter ROUTE_TYPE = "ADAPTIVE",// "DETERMINISTIC", "FULL_ADAPTIVE", "PAR_ADAPTIVE" |
parameter CONGESTION_INDEX=2, |
parameter [V-1 : 0] ESCAP_VC_MASK = 4'b0001, // mask scape vc, valid only for full adaptive |
parameter DEBUG_EN = 1, |
14,97 → 14,98
parameter CONGw = 2 //congestion width per port |
|
)( |
non_ss_ovc_allocated_all, |
flit_is_tail_all, |
assigned_ovc_num_all, |
spec_ovc_num_all, |
dest_port_all, |
nonspec_granted_dest_port_all, |
spec_granted_dest_port_all, |
credit_in_all, |
nonspec_first_arbiter_granted_ivc_all, |
spec_first_arbiter_granted_ivc_all, |
ivc_num_getting_sw_grant, |
ovc_avalable_all, |
assigned_ovc_not_full_all, |
congestion_in_all, |
port_pre_sel, |
ssa_ovc_released_all, |
non_ss_ovc_allocated_all, |
flit_is_tail_all, |
assigned_ovc_num_all, |
spec_ovc_num_all, |
dest_port_all, |
nonspec_granted_dest_port_all, |
spec_granted_dest_port_all, |
credit_in_all, |
nonspec_first_arbiter_granted_ivc_all, |
spec_first_arbiter_granted_ivc_all, |
ivc_num_getting_sw_grant, |
ovc_avalable_all, |
assigned_ovc_not_full_all, |
congestion_in_all, |
port_pre_sel, |
ssa_ovc_released_all, |
ssa_ovc_allocated_all, |
ssa_decreased_credit_in_ss_ovc_all, |
reset,clk |
reset,clk |
); |
|
function integer log2; |
input integer number; begin |
log2=0; |
while(2**log2<number) begin |
log2=log2+1; |
end |
end |
endfunction // log2 |
|
localparam PV = V * P, |
|
function integer log2; |
input integer number; begin |
log2=(number <=1) ? 1: 0; |
while(2**log2<number) begin |
log2=log2+1; |
end |
end |
endfunction // log2 |
|
localparam PV = V * P, |
VV = V * V, |
PVV = PV * V, |
P_1 = P-1 , |
VP_1 = V * P_1, |
PP_1 = P_1 * P, |
PVP_1 = PV * P_1, |
Bw = log2(B), |
B_1 = B-1; |
PVV = PV * V, |
P_1 = P-1 , |
VP_1 = V * P_1, |
PP_1 = P_1 * P, |
PVP_1 = PV * P_1, |
Bw = log2(B), |
B_1 = B-1; |
|
localparam [Bw-1 : 0] Bint = B_1[Bw-1 : 0]; |
localparam NORTH = 3'd2, |
localparam [Bw-1 : 0] Bint = B_1[Bw-1 : 0]; |
localparam NORTH = 3'd2, |
SOUTH = 3'd4; |
localparam [V-1 : 0] ADAPTIVE_VC_MASK = ~ ESCAP_VC_MASK; |
localparam CONG_ALw= CONGw* P; // congestion width per router; |
localparam CONG_ALw= CONGw* P; // congestion width per router; |
|
integer k; |
input [PV-1 : 0] non_ss_ovc_allocated_all; |
input [PV-1 : 0] flit_is_tail_all; |
input [PVV-1 : 0] assigned_ovc_num_all; |
input [PVV-1 : 0] spec_ovc_num_all; |
input [PVP_1-1 : 0] dest_port_all; |
input [PP_1-1 : 0] nonspec_granted_dest_port_all; |
input [PP_1-1 : 0] spec_granted_dest_port_all; |
input [PV-1 : 0] credit_in_all; |
input [PV-1 : 0] nonspec_first_arbiter_granted_ivc_all; |
input [PV-1 : 0] spec_first_arbiter_granted_ivc_all; |
input [PV-1 : 0] ivc_num_getting_sw_grant; |
output [PV-1 : 0] ovc_avalable_all; |
output [PV-1 : 0] assigned_ovc_not_full_all; |
output [P_1-1 : 0] port_pre_sel; |
input [CONG_ALw-1 : 0] congestion_in_all; |
integer k; |
input [PV-1 : 0] non_ss_ovc_allocated_all; |
input [PV-1 : 0] flit_is_tail_all; |
input [PVV-1 : 0] assigned_ovc_num_all; |
input [PVV-1 : 0] spec_ovc_num_all; |
input [PVP_1-1 : 0] dest_port_all; |
input [PP_1-1 : 0] nonspec_granted_dest_port_all; |
input [PP_1-1 : 0] spec_granted_dest_port_all; |
input [PV-1 : 0] credit_in_all; |
input [PV-1 : 0] nonspec_first_arbiter_granted_ivc_all; |
input [PV-1 : 0] spec_first_arbiter_granted_ivc_all; |
input [PV-1 : 0] ivc_num_getting_sw_grant; |
output [PV-1 : 0] ovc_avalable_all; |
output [PV-1 : 0] assigned_ovc_not_full_all; |
output [P_1-1 : 0] port_pre_sel; |
input [CONG_ALw-1 : 0] congestion_in_all; |
|
input reset,clk; |
input reset,clk; |
//ssa |
input [PV-1 : 0] ssa_ovc_released_all; |
input [PV-1 : 0] ssa_ovc_allocated_all; |
input [PV-1 : 0] ssa_decreased_credit_in_ss_ovc_all; |
|
|
|
reg [PV-1 : 0] ovc_status; |
reg [Bw-1 : 0] credit_counter [PV-1 : 0]; |
reg [Bw-1 : 0] credit_counter_next [PV-1 : 0]; |
reg [PV-1 : 0] full_all,nearly_full_all,full_all_next,nearly_full_all_next; |
|
wire [PV-1 : 0] assigned_ovc_is_full_all; |
wire [VP_1-1 : 0] credit_decreased [P-1 : 0]; |
wire [P_1-1 : 0] credit_decreased_gen [PV-1 : 0]; |
wire [PV-1 : 0] non_ss_credit_decreased_all; |
wire [PV-1 : 0] credit_increased_all; |
wire [VP_1-1 : 0] ovc_released [P-1 : 0]; |
wire [P_1-1 : 0] ovc_released_gen [PV-1 : 0]; |
wire [PV-1 : 0] non_ss_ovc_released_all; |
wire [VP_1-1 : 0] credit_in_perport [P-1 : 0]; |
wire [VP_1-1 : 0] full_perport [P-1 : 0]; |
wire [VP_1-1 : 0] nearly_full_perport [P-1 : 0]; |
|
|
//ssa |
|
|
|
reg [PV-1 : 0] ovc_status; |
reg [Bw-1 : 0] credit_counter [PV-1 : 0]; |
reg [Bw-1 : 0] credit_counter_next [PV-1 : 0]; |
reg [PV-1 : 0] full_all,nearly_full_all,full_all_next,nearly_full_all_next; |
|
wire [PV-1 : 0] assigned_ovc_is_full_all; |
wire [VP_1-1 : 0] credit_decreased [P-1 : 0]; |
wire [P_1-1 : 0] credit_decreased_gen [PV-1 : 0]; |
wire [PV-1 : 0] non_ss_credit_decreased_all; |
wire [PV-1 : 0] credit_increased_all; |
wire [VP_1-1 : 0] ovc_released [P-1 : 0]; |
wire [P_1-1 : 0] ovc_released_gen [PV-1 : 0]; |
wire [PV-1 : 0] non_ss_ovc_released_all; |
wire [VP_1-1 : 0] credit_in_perport [P-1 : 0]; |
wire [VP_1-1 : 0] full_perport [P-1 : 0]; |
wire [VP_1-1 : 0] nearly_full_perport [P-1 : 0]; |
|
|
//ssa |
|
wire [PV-1 : 0] credit_decreased_all; |
wire [PV-1 : 0] ovc_released_all; |
wire [PV-1 : 0] ovc_allocated_all; |
113,32 → 114,32
assign ovc_released_all = non_ss_ovc_released_all | ssa_ovc_released_all; |
assign ovc_allocated_all = non_ss_ovc_allocated_all | ssa_ovc_allocated_all; |
|
|
generate |
if(VC_REALLOCATION_TYPE=="ATOMIC") begin :atomic |
reg [PV-1 : 0] empty_all,empty_all_next; |
|
always @(posedge clk or posedge reset) begin |
for(k=0; k<PV; k=k+1'b1) begin |
if(reset) begin |
empty_all[k] <= 1'b0; |
end else begin |
empty_all[k] <= empty_all_next[k]; |
end |
end//for |
end//always |
|
|
always @(*) begin |
for(k=0; k<PV; k=k+1'b1) begin |
empty_all_next[k] = (credit_counter_next[k] == Bint); |
end // for |
end//always |
|
// in atomic architecture an OVC is available if its not allocated and its empty |
assign ovc_avalable_all = ~ovc_status & empty_all; |
|
end else begin :nonatomic //NONATOMIC |
|
generate |
if(VC_REALLOCATION_TYPE=="ATOMIC") begin :atomic |
reg [PV-1 : 0] empty_all,empty_all_next; |
|
always @(posedge clk or posedge reset) begin |
for(k=0; k<PV; k=k+1'b1) begin |
if(reset) begin |
empty_all[k] <= 1'b0; |
end else begin |
empty_all[k] <= empty_all_next[k]; |
end |
end//for |
end//always |
|
|
always @(*) begin |
for(k=0; k<PV; k=k+1'b1) begin |
empty_all_next[k] = (credit_counter_next[k] == Bint); |
end // for |
end//always |
|
// in atomic architecture an OVC is available if its not allocated and its empty |
assign ovc_avalable_all = ~ovc_status & empty_all; |
|
end else begin :nonatomic //NONATOMIC |
if(ROUTE_TYPE == "FULL_ADAPTIVE") begin :full_adpt |
|
reg [PV-1 : 0] full_adaptive_ovc_mask,full_adaptive_ovc_mask_next; |
163,7 → 164,7
end // for |
end//always |
|
always @(posedge clk or posedge reset) begin |
always @(posedge clk or posedge reset) begin |
if(reset) begin |
full_adaptive_ovc_mask <= {PV{1'b0}}; |
end else begin |
170,7 → 171,7
full_adaptive_ovc_mask <= full_adaptive_ovc_mask_next; |
end |
end//always |
|
|
|
assign ovc_avalable_all = ~ovc_status & full_adaptive_ovc_mask; |
|
179,115 → 180,115
end |
end //NONATOMIC |
endgenerate |
|
|
|
assign credit_increased_all = credit_in_all; |
|
assign assigned_ovc_not_full_all = ~ assigned_ovc_is_full_all; |
|
|
genvar i,j; |
generate |
for(i=0;i<P;i=i+1 ) begin :port_lp |
|
inport_module_can #( |
.V (V), // vc_num_per_port |
.P (P) // router port num |
)inport_module |
( |
.flit_is_tail (flit_is_tail_all [(i+1)*V-1 :i*V]), |
.assigned_ovc_num (assigned_ovc_num_all [(i+1)*VV-1 :i*VV]), |
.spec_ovc_num (spec_ovc_num_all [(i+1)*VV-1 :i*VV]), |
.nonspec_granted_dest_port (nonspec_granted_dest_port_all [(i+1)*P_1-1 :i*P_1]), |
.spec_granted_dest_port (spec_granted_dest_port_all [(i+1)*P_1-1 :i*P_1]), |
.nonspec_first_arbiter_granted_ivc (nonspec_first_arbiter_granted_ivc_all [(i+1)*V-1 :i*V]), |
.spec_first_arbiter_granted_ivc (spec_first_arbiter_granted_ivc_all [(i+1)*V-1 :i*V]), |
.credit_decreased (credit_decreased [i]), |
.ovc_released (ovc_released [i]) |
|
); |
|
|
|
assign credit_increased_all = credit_in_all; |
|
assign assigned_ovc_not_full_all = ~ assigned_ovc_is_full_all; |
|
|
genvar i,j; |
generate |
for(i=0;i<P;i=i+1 ) begin :port_lp |
|
inport_module_can #( |
.V (V), // vc_num_per_port |
.P (P) // router port num |
)inport_module |
( |
.flit_is_tail (flit_is_tail_all [(i+1)*V-1 :i*V]), |
.assigned_ovc_num (assigned_ovc_num_all [(i+1)*VV-1 :i*VV]), |
.spec_ovc_num (spec_ovc_num_all [(i+1)*VV-1 :i*VV]), |
.nonspec_granted_dest_port (nonspec_granted_dest_port_all [(i+1)*P_1-1 :i*P_1]), |
.spec_granted_dest_port (spec_granted_dest_port_all [(i+1)*P_1-1 :i*P_1]), |
.nonspec_first_arbiter_granted_ivc (nonspec_first_arbiter_granted_ivc_all [(i+1)*V-1 :i*V]), |
.spec_first_arbiter_granted_ivc (spec_first_arbiter_granted_ivc_all [(i+1)*V-1 :i*V]), |
.credit_decreased (credit_decreased [i]), |
.ovc_released (ovc_released [i]) |
|
); |
|
end//for |
|
|
|
for(i=0;i< PV;i=i+1) begin :total_vc_loop2 |
for(j=0;j<P; j=j+1)begin: assign_loop2 |
if((i/V)<j )begin: jj |
assign ovc_released_gen [i][j-1] = ovc_released[j][i]; |
assign credit_decreased_gen[i][j-1] = credit_decreased [j][i]; |
end else if((i/V)>j) begin: hh |
assign ovc_released_gen [i][j] = ovc_released[j][i-V]; |
assign credit_decreased_gen[i][j] = credit_decreased[j][i-V]; |
end |
end//j |
assign non_ss_ovc_released_all [i] = |ovc_released_gen[i]; |
end//for |
|
|
|
for(i=0;i< PV;i=i+1) begin :total_vc_loop2 |
for(j=0;j<P; j=j+1)begin: assign_loop2 |
if((i/V)<j )begin: jj |
assign ovc_released_gen [i][j-1] = ovc_released[j][i]; |
assign credit_decreased_gen[i][j-1] = credit_decreased [j][i]; |
end else if((i/V)>j) begin: hh |
assign ovc_released_gen [i][j] = ovc_released[j][i-V]; |
assign credit_decreased_gen[i][j] = credit_decreased[j][i-V]; |
end |
end//j |
assign non_ss_ovc_released_all [i] = |ovc_released_gen[i]; |
assign non_ss_credit_decreased_all [i] = (|credit_decreased_gen[i])|non_ss_ovc_allocated_all[i]; |
end//i |
|
|
end//i |
|
|
|
|
|
//remove source port from the list |
for(i=0;i< P;i=i+1) begin :port_loop |
if(i==0) begin :i0 |
assign credit_in_perport [i]=credit_in_all [PV-1 : V]; |
assign full_perport [i]=full_all [PV-1 : V]; |
assign nearly_full_perport [i]=nearly_full_all [PV-1 : V]; |
end else if(i==(P-1)) begin :ip_1 |
assign credit_in_perport [i]=credit_in_all [PV-V-1 : 0]; |
assign full_perport [i]=full_all [PV-V-1 : 0]; |
assign nearly_full_perport [i]=nearly_full_all [PV-V-1 : 0]; |
end else begin : els |
assign credit_in_perport [i]={credit_in_all [PV-1 : (i+1)*V],credit_in_all [(i*V)-1 : 0]}; |
assign full_perport [i]={full_all [PV-1 : (i+1)*V],full_all [(i*V)-1 : 0]}; |
assign nearly_full_perport [i]={nearly_full_all [PV-1 : (i+1)*V],nearly_full_all[(i*V)-1 : 0]}; |
end |
end//for |
|
|
|
for(i=0;i< PV;i=i+1) begin :PV_loop2 |
sw_mask_gen_can #( |
.V (V), // vc_num_per_port |
.P (P) // router port num |
)sw_mask |
( |
.assigned_ovc_num (assigned_ovc_num_all[(i+1)*V-1 :i*V]), |
.dest_port (dest_port_all [(i+1)*P_1-1 :i*P_1]), |
.full (full_perport [i/V]), |
.credit_increased (credit_in_perport [i/V]), |
.nearly_full (nearly_full_perport [i/V]), |
.ivc_getting_sw_grant (ivc_num_getting_sw_grant[i]), |
.assigned_ovc_is_full (assigned_ovc_is_full_all[i]), |
.clk (clk), |
.reset (reset) |
); |
end//for |
|
for(i=0; i<PV; i=i+1) begin :register_loop |
always @(posedge clk or posedge reset) begin |
if(reset) begin |
credit_counter[i] <= Bint; |
ovc_status[i] <= 1'b0; |
full_all[i] <= 1'b0; |
nearly_full_all[i]<= 1'b0; |
end else begin |
credit_counter[i] <= credit_counter_next[i]; |
full_all[i] <= full_all_next[i]; |
nearly_full_all[i]<= nearly_full_all_next[i]; |
if(ovc_released_all[i] ) ovc_status[i]<=1'b0; |
if(ovc_allocated_all[i]) ovc_status[i]<=1'b1; |
end |
end//always |
end//for |
|
|
//remove source port from the list |
for(i=0;i< P;i=i+1) begin :port_loop |
if(i==0) begin :i0 |
assign credit_in_perport [i]=credit_in_all [PV-1 : V]; |
assign full_perport [i]=full_all [PV-1 : V]; |
assign nearly_full_perport [i]=nearly_full_all [PV-1 : V]; |
end else if(i==(P-1)) begin :ip_1 |
assign credit_in_perport [i]=credit_in_all [PV-V-1 : 0]; |
assign full_perport [i]=full_all [PV-V-1 : 0]; |
assign nearly_full_perport [i]=nearly_full_all [PV-V-1 : 0]; |
end else begin : els |
assign credit_in_perport [i]={credit_in_all [PV-1 : (i+1)*V],credit_in_all [(i*V)-1 : 0]}; |
assign full_perport [i]={full_all [PV-1 : (i+1)*V],full_all [(i*V)-1 : 0]}; |
assign nearly_full_perport [i]={nearly_full_all [PV-1 : (i+1)*V],nearly_full_all[(i*V)-1 : 0]}; |
end |
end//for |
|
|
|
for(i=0;i< PV;i=i+1) begin :PV_loop2 |
sw_mask_gen_can #( |
.V (V), // vc_num_per_port |
.P (P) // router port num |
)sw_mask |
( |
.assigned_ovc_num (assigned_ovc_num_all[(i+1)*V-1 :i*V]), |
.dest_port (dest_port_all [(i+1)*P_1-1 :i*P_1]), |
.full (full_perport [i/V]), |
.credit_increased (credit_in_perport [i/V]), |
.nearly_full (nearly_full_perport [i/V]), |
.ivc_getting_sw_grant (ivc_num_getting_sw_grant[i]), |
.assigned_ovc_is_full (assigned_ovc_is_full_all[i]), |
.clk (clk), |
.reset (reset) |
); |
end//for |
|
for(i=0; i<PV; i=i+1) begin :register_loop |
always @(posedge clk or posedge reset) begin |
if(reset) begin |
credit_counter[i] <= Bint; |
ovc_status[i] <= 1'b0; |
full_all[i] <= 1'b0; |
nearly_full_all[i]<= 1'b0; |
end else begin |
credit_counter[i] <= credit_counter_next[i]; |
full_all[i] <= full_all_next[i]; |
nearly_full_all[i]<= nearly_full_all_next[i]; |
if(ovc_released_all[i] ) ovc_status[i]<=1'b0; |
if(ovc_allocated_all[i]) ovc_status[i]<=1'b1; |
end |
end//always |
end//for |
|
|
|
endgenerate |
|
|
|
endgenerate |
|
port_pre_sel_gen #( |
.P(P), |
.V(V), |
309,289 → 310,289
.reset(reset), |
.clk(clk) |
|
); |
|
|
|
always @(*) begin |
for(k=0; k<PV; k=k+1) begin |
credit_counter_next[k] = credit_counter[k]; |
if(credit_increased_all[k] & ~credit_decreased_all[k]) begin |
credit_counter_next[k] = credit_counter[k]+1'b1; |
end else if (~credit_increased_all[k] & credit_decreased_all[k])begin |
credit_counter_next[k] = credit_counter[k]-1'b1; |
end |
end |
end |
|
always @(*) begin |
for(k=0; k<PV; k=k+1) begin |
full_all_next[k] = credit_counter_next[k] == {Bw{1'b0}}; |
nearly_full_all_next[k] = credit_counter_next[k] <= 1; |
end |
end |
|
|
|
//synthesis translate_off |
//synopsys translate_off |
); |
|
|
|
always @(*) begin |
for(k=0; k<PV; k=k+1) begin |
credit_counter_next[k] = credit_counter[k]; |
if(credit_increased_all[k] & ~credit_decreased_all[k]) begin |
credit_counter_next[k] = credit_counter[k]+1'b1; |
end else if (~credit_increased_all[k] & credit_decreased_all[k])begin |
credit_counter_next[k] = credit_counter[k]-1'b1; |
end |
end |
end |
|
always @(*) begin |
for(k=0; k<PV; k=k+1) begin |
full_all_next[k] = credit_counter_next[k] == {Bw{1'b0}}; |
nearly_full_all_next[k] = credit_counter_next[k] <= 1; |
end |
end |
|
|
|
//synthesis translate_off |
//synopsys translate_off |
generate |
if(DEBUG_EN) begin :dbg |
always @(posedge clk) begin |
if(!reset)begin |
for(k=0; k<PV; k=k+1'b1) begin |
if(credit_counter[k]== Bint && credit_increased_all[k]) |
$display("%t: ERROR: unexpected credit is received for an empty ovc: %m",$time); |
if(credit_counter[k]== {Bw{1'b0}} && credit_decreased_all[k]) |
$display("%t: ERROR: Attempt to send flit to a full ovc: %m",$time); |
if(ovc_released_all[k] && ovc_allocated_all[k]) |
$display("%t: ERROR: simultaneous allocation and release for an OVC: %m",$time); |
if(ovc_released_all[k] && ovc_status[k]==1'b0) |
$display("%t: ERROR: Attempt to release an unallocated OVC: %m",$time); |
if(ovc_allocated_all[k] && ovc_status[k]==1'b1) |
$display("%t: ERROR: Attempt to allocate an allocated OVC: %m",$time); |
end//for |
end |
end |
/* |
localparam NUM_WIDTH = log2(PV+1); |
wire [NUM_WIDTH-1 : 0] num1,num2; |
set_bits_counter #( |
.IN_WIDTH(PV) |
)cnt1 |
( |
.in (ovc_status), |
.out (num1) |
); |
always @(posedge clk) begin |
if(!reset)begin |
for(k=0; k<PV; k=k+1'b1) begin |
if(credit_counter[k]== Bint && credit_increased_all[k]) |
$display("%t: ERROR: unexpected credit is received for an empty ovc: %m",$time); |
if(credit_counter[k]== {Bw{1'b0}} && credit_decreased_all[k]) |
$display("%t: ERROR: Attempt to send flit to a full ovc: %m",$time); |
if(ovc_released_all[k] && ovc_allocated_all[k]) |
$display("%t: ERROR: simultaneous allocation and release for an OVC: %m",$time); |
if(ovc_released_all[k] && ovc_status[k]==1'b0) |
$display("%t: ERROR: Attempt to release an unallocated OVC: %m",$time); |
if(ovc_allocated_all[k] && ovc_status[k]==1'b1) |
$display("%t: ERROR: Attempt to allocate an allocated OVC: %m",$time); |
end//for |
end |
end |
/* |
localparam NUM_WIDTH = log2(PV+1); |
wire [NUM_WIDTH-1 : 0] num1,num2; |
set_bits_counter #( |
.IN_WIDTH(PV) |
)cnt1 |
( |
.in (ovc_status), |
.out (num1) |
); |
|
set_bits_counter #( |
.IN_WIDTH(PV) |
)cnt2 |
( |
.in (ovc_is_assigned_all), |
.out (num2) |
); |
|
always @(posedge clk) begin |
if(num1 != num2 ) $display("%t: ERROR: number of assigned IVC mismatch the number of occupied OVC: %m",$time); |
end |
*/ |
set_bits_counter #( |
.IN_WIDTH(PV) |
)cnt2 |
( |
.in (ovc_is_assigned_all), |
.out (num2) |
); |
|
always @(posedge clk) begin |
if(num1 != num2 ) $display("%t: ERROR: number of assigned IVC mismatch the number of occupied OVC: %m",$time); |
end |
*/ |
end |
endgenerate |
//synopsys translate_on |
//synthesis translate_on |
|
|
|
|
endgenerate |
//synopsys translate_on |
//synthesis translate_on |
|
|
|
|
endmodule |
|
/************************************ |
|
inport_module |
|
inport_module |
|
|
*************************************/ |
module inport_module_can #( |
parameter V = 4, // vc_num_per_port |
parameter P = 5 // router port num |
parameter V = 4, // vc_num_per_port |
parameter P = 5 // router port num |
)( |
flit_is_tail, |
assigned_ovc_num, |
spec_ovc_num, |
nonspec_granted_dest_port, |
spec_granted_dest_port, |
nonspec_first_arbiter_granted_ivc, |
spec_first_arbiter_granted_ivc, |
credit_decreased, |
ovc_released |
|
); |
|
localparam VV = V * V, |
P_1 = P-1 , |
VP_1 = V * P_1; |
|
|
|
input [V-1 : 0] flit_is_tail; |
input [VV-1 : 0] assigned_ovc_num; |
input [VV-1 : 0] spec_ovc_num; |
input [P_1-1 : 0] nonspec_granted_dest_port; |
input [P_1-1 : 0] spec_granted_dest_port; |
input [V-1 : 0] nonspec_first_arbiter_granted_ivc; |
input [V-1 : 0] spec_first_arbiter_granted_ivc; |
output[VP_1-1 : 0] credit_decreased; |
output[VP_1-1 : 0] ovc_released; |
|
|
|
wire [V-1 : 0] nonspec_muxout1,spec_muxout1; |
wire muxout2; |
wire [VP_1-1 : 0] nonspec_credit_decreased,spec_credit_decreased; |
// assigned ovc mux |
one_hot_mux #( |
.IN_WIDTH (VV), |
.SEL_WIDTH (V) |
)assigned_ovc_mux |
( |
.mux_in (assigned_ovc_num), |
.mux_out (nonspec_muxout1), |
.sel (nonspec_first_arbiter_granted_ivc) |
); |
|
|
one_hot_mux #( |
.IN_WIDTH (VV), |
.SEL_WIDTH (V) |
)spec_ovc_mux |
( |
.mux_in (spec_ovc_num), |
.mux_out (spec_muxout1), |
.sel (spec_first_arbiter_granted_ivc) |
); |
// tail mux |
one_hot_mux #( |
.IN_WIDTH (V), |
.SEL_WIDTH (V) |
)tail_mux |
( |
.mux_in (flit_is_tail), |
.mux_out (muxout2), |
.sel (nonspec_first_arbiter_granted_ivc) |
); |
|
|
one_hot_demux #( |
.IN_WIDTH (V), |
.SEL_WIDTH (P_1) |
|
) nonspecdemux |
( |
.demux_sel (nonspec_granted_dest_port),//selectore |
.demux_in (nonspec_muxout1),//repeated |
.demux_out (nonspec_credit_decreased) |
); |
|
one_hot_demux #( |
.IN_WIDTH (V), |
.SEL_WIDTH (P_1) |
|
) specdemux |
( |
.demux_sel (spec_granted_dest_port),//selectore |
.demux_in (spec_muxout1),//repeated |
.demux_out (spec_credit_decreased) |
); |
|
assign ovc_released = (muxout2)? nonspec_credit_decreased : {VP_1{1'b0}}; |
assign credit_decreased = nonspec_credit_decreased | spec_credit_decreased; |
|
flit_is_tail, |
assigned_ovc_num, |
spec_ovc_num, |
nonspec_granted_dest_port, |
spec_granted_dest_port, |
nonspec_first_arbiter_granted_ivc, |
spec_first_arbiter_granted_ivc, |
credit_decreased, |
ovc_released |
|
); |
|
localparam VV = V * V, |
P_1 = P-1 , |
VP_1 = V * P_1; |
|
|
|
input [V-1 : 0] flit_is_tail; |
input [VV-1 : 0] assigned_ovc_num; |
input [VV-1 : 0] spec_ovc_num; |
input [P_1-1 : 0] nonspec_granted_dest_port; |
input [P_1-1 : 0] spec_granted_dest_port; |
input [V-1 : 0] nonspec_first_arbiter_granted_ivc; |
input [V-1 : 0] spec_first_arbiter_granted_ivc; |
output[VP_1-1 : 0] credit_decreased; |
output[VP_1-1 : 0] ovc_released; |
|
|
|
wire [V-1 : 0] nonspec_muxout1,spec_muxout1; |
wire muxout2; |
wire [VP_1-1 : 0] nonspec_credit_decreased,spec_credit_decreased; |
// assigned ovc mux |
one_hot_mux #( |
.IN_WIDTH (VV), |
.SEL_WIDTH (V) |
)assigned_ovc_mux |
( |
.mux_in (assigned_ovc_num), |
.mux_out (nonspec_muxout1), |
.sel (nonspec_first_arbiter_granted_ivc) |
); |
|
|
one_hot_mux #( |
.IN_WIDTH (VV), |
.SEL_WIDTH (V) |
)spec_ovc_mux |
( |
.mux_in (spec_ovc_num), |
.mux_out (spec_muxout1), |
.sel (spec_first_arbiter_granted_ivc) |
); |
// tail mux |
one_hot_mux #( |
.IN_WIDTH (V), |
.SEL_WIDTH (V) |
)tail_mux |
( |
.mux_in (flit_is_tail), |
.mux_out (muxout2), |
.sel (nonspec_first_arbiter_granted_ivc) |
); |
|
|
one_hot_demux #( |
.IN_WIDTH (V), |
.SEL_WIDTH (P_1) |
|
) nonspecdemux |
( |
.demux_sel (nonspec_granted_dest_port),//selectore |
.demux_in (nonspec_muxout1),//repeated |
.demux_out (nonspec_credit_decreased) |
); |
|
one_hot_demux #( |
.IN_WIDTH (V), |
.SEL_WIDTH (P_1) |
|
) specdemux |
( |
.demux_sel (spec_granted_dest_port),//selectore |
.demux_in (spec_muxout1),//repeated |
.demux_out (spec_credit_decreased) |
); |
|
assign ovc_released = (muxout2)? nonspec_credit_decreased : {VP_1{1'b0}}; |
assign credit_decreased = nonspec_credit_decreased | spec_credit_decreased; |
|
endmodule |
|
|
/********************************** |
|
sw_mask_gen |
sw_mask_gen |
|
*********************************/ |
|
module sw_mask_gen_can #( |
parameter V = 4, // vc_num_per_port |
parameter P = 5 // router port num |
parameter V = 4, // vc_num_per_port |
parameter P = 5 // router port num |
)( |
assigned_ovc_num, |
dest_port, |
full, |
credit_increased, |
nearly_full, |
ivc_getting_sw_grant, |
assigned_ovc_is_full, |
clk,reset |
assigned_ovc_num, |
dest_port, |
full, |
credit_increased, |
nearly_full, |
ivc_getting_sw_grant, |
assigned_ovc_is_full, |
clk,reset |
); |
localparam P_1 = P-1 , |
VP_1 = V * P_1; |
|
|
input [V-1 : 0] assigned_ovc_num; |
input [P_1-1 : 0] dest_port; |
input [VP_1-1 : 0] full; |
input [VP_1-1 : 0] credit_increased; |
input [VP_1-1 : 0] nearly_full; |
input ivc_getting_sw_grant; |
output assigned_ovc_is_full; |
input clk,reset; |
localparam P_1 = P-1 , |
VP_1 = V * P_1; |
|
|
input [V-1 : 0] assigned_ovc_num; |
input [P_1-1 : 0] dest_port; |
input [VP_1-1 : 0] full; |
input [VP_1-1 : 0] credit_increased; |
input [VP_1-1 : 0] nearly_full; |
input ivc_getting_sw_grant; |
output assigned_ovc_is_full; |
input clk,reset; |
|
|
wire [VP_1-1 : 0] full_muxin1,nearly_full_muxin1; |
wire [V-1 : 0] full_muxout1,nearly_full_muxout1; |
wire full_muxout2,nearly_full_muxout2; |
reg full_reg1,full_reg1_next; |
reg full_reg2,full_reg2_next; |
|
|
assign full_muxin1 = full & (~credit_increased); |
assign nearly_full_muxin1 = nearly_full & (~credit_increased); |
|
|
// destport mux |
one_hot_mux #( |
.IN_WIDTH (VP_1), |
.SEL_WIDTH (P_1) |
)full_mux1 |
( |
.mux_in (full_muxin1), |
.mux_out (full_muxout1), |
.sel (dest_port) |
); |
|
one_hot_mux #( |
.IN_WIDTH (VP_1), |
.SEL_WIDTH (P_1) |
)nearly_full_mux1 |
( |
.mux_in (nearly_full_muxin1), |
.mux_out (nearly_full_muxout1), |
.sel (dest_port) |
); |
|
// assigned ovc mux |
one_hot_mux #( |
.IN_WIDTH (V), |
.SEL_WIDTH (V) |
)full_mux2 |
( |
.mux_in (full_muxout1), |
.mux_out (full_muxout2), |
.sel (assigned_ovc_num) |
); |
|
|
one_hot_mux #( |
.IN_WIDTH (V), |
.SEL_WIDTH (V) |
)nearlfull_mux2 |
( |
.mux_in (nearly_full_muxout1), |
.mux_out (nearly_full_muxout2), |
.sel (assigned_ovc_num) |
); |
|
always @(*) begin |
full_reg1_next = full_muxout2; |
full_reg2_next = nearly_full_muxout2 & ivc_getting_sw_grant; |
end |
|
always @(posedge clk or posedge reset) begin |
if(reset) begin |
full_reg1 <= 1'b0; |
full_reg2 <= 1'b0; |
end else begin |
full_reg1 <= full_reg1_next; |
full_reg2 <= full_reg2_next; |
end |
end//always |
|
assign assigned_ovc_is_full = full_reg1 | full_reg2; |
|
wire [VP_1-1 : 0] full_muxin1,nearly_full_muxin1; |
wire [V-1 : 0] full_muxout1,nearly_full_muxout1; |
wire full_muxout2,nearly_full_muxout2; |
reg full_reg1,full_reg1_next; |
reg full_reg2,full_reg2_next; |
|
|
assign full_muxin1 = full & (~credit_increased); |
assign nearly_full_muxin1 = nearly_full & (~credit_increased); |
|
|
// destport mux |
one_hot_mux #( |
.IN_WIDTH (VP_1), |
.SEL_WIDTH (P_1) |
)full_mux1 |
( |
.mux_in (full_muxin1), |
.mux_out (full_muxout1), |
.sel (dest_port) |
); |
|
one_hot_mux #( |
.IN_WIDTH (VP_1), |
.SEL_WIDTH (P_1) |
)nearly_full_mux1 |
( |
.mux_in (nearly_full_muxin1), |
.mux_out (nearly_full_muxout1), |
.sel (dest_port) |
); |
|
// assigned ovc mux |
one_hot_mux #( |
.IN_WIDTH (V), |
.SEL_WIDTH (V) |
)full_mux2 |
( |
.mux_in (full_muxout1), |
.mux_out (full_muxout2), |
.sel (assigned_ovc_num) |
); |
|
|
one_hot_mux #( |
.IN_WIDTH (V), |
.SEL_WIDTH (V) |
)nearlfull_mux2 |
( |
.mux_in (nearly_full_muxout1), |
.mux_out (nearly_full_muxout2), |
.sel (assigned_ovc_num) |
); |
|
always @(*) begin |
full_reg1_next = full_muxout2; |
full_reg2_next = nearly_full_muxout2 & ivc_getting_sw_grant; |
end |
|
always @(posedge clk or posedge reset) begin |
if(reset) begin |
full_reg1 <= 1'b0; |
full_reg2 <= 1'b0; |
end else begin |
full_reg1 <= full_reg1_next; |
full_reg2 <= full_reg2_next; |
end |
end//always |
|
assign assigned_ovc_is_full = full_reg1 | full_reg2; |
|
endmodule |
/src_noc/class_table.v
1,54 → 1,55
`timescale 1ns/1ps |
`timescale 1ns/1ps |
|
module class_ovc_table #( |
parameter C= 4,//number of class |
parameter V= 4, //VC number per port |
parameter CVw=(C==0)? V : C * V, |
parameter C= 4,//number of class |
parameter V= 4, //VC number per port |
parameter CVw=(C==0)? V : C * V, |
parameter [CVw-1: 0] CLASS_SETTING = {CVw{1'b1}} // shows how each class can use VCs |
|
|
) |
( |
class_in, |
candidate_ovcs |
); |
|
function integer log2; |
input integer number; begin |
log2=0; |
while(2**log2<number) begin |
log2=log2+1; |
end |
end |
endfunction // log2 |
|
localparam Cw= (C>1)? log2(C): 1; |
|
input [Cw-1 : 0] class_in; |
output[V-1 : 0] candidate_ovcs; |
|
genvar i; |
generate |
) |
( |
class_in, |
candidate_ovcs |
); |
|
|
function integer log2; |
input integer number; begin |
log2=(number <=1) ? 1: 0; |
while(2**log2<number) begin |
log2=log2+1; |
end |
end |
endfunction // log2 |
|
localparam Cw= (C>1)? log2(C): 1; |
|
input [Cw-1 : 0] class_in; |
output[V-1 : 0] candidate_ovcs; |
|
genvar i; |
generate |
if(C == 0 || C == 1) begin: no_class // |
|
assign candidate_ovcs={V{1'b1}}; |
|
end else begin: width_class |
|
wire [V-1 : 0] class_table [C-1 : 0]; |
for(i=0;i<C;i=i+1) begin : class_loop |
assign class_table[i]= CLASS_SETTING[(i+1)*V-1 : i*V]; |
end |
|
|
assign candidate_ovcs=class_table[class_in]; |
|
|
|
end |
endgenerate |
|
|
|
assign candidate_ovcs={V{1'b1}}; |
|
end else begin: width_class |
|
wire [V-1 : 0] class_table [C-1 : 0]; |
for(i=0;i<C;i=i+1) begin : class_loop |
assign class_table[i]= CLASS_SETTING[(i+1)*V-1 : i*V]; |
end |
|
|
assign candidate_ovcs=class_table[class_in]; |
|
|
|
end |
endgenerate |
|
|
endmodule |
|
|
/src_noc/comb-spec1.v
8,9 → 8,9
**********************************/ |
|
module comb_spec1_allocator #( |
parameter V = 4,// Virtual channel num per port |
parameter P = 5, |
parameter DEBUG_EN = 1 |
parameter V = 4,// Virtual channel num per port |
parameter P = 5, |
parameter DEBUG_EN = 1 |
)( |
|
dest_port_all, |
370,7 → 370,7
assign spec_granted_dest_port_all_accepted[(i+1)*P_1-1 : i*P_1]=(valid_speculation[i])? spec_request_accepted [i]: {P_1{1'b0}}; |
|
//synthesis translate_off |
//synopsys translate_off |
//synopsys translate_off |
if(DEBUG_EN)begin :dbg |
assign nonspec_check[i] = nonspec_granted_dest_port_all[(i+1)*P_1-1 : i*P_1]; |
assign spec_check[i]= spec_granted_dest_port_all_accepted[(i+1)*P_1-1 : i*P_1]; |
380,7 → 380,7
end |
end //DEBUG |
//synthesis translate_on |
//synopsys translate_on |
//synopsys translate_on |
|
|
end//i |
/src_noc/comb_nonspec.v
1,4 → 1,4
`timescale 1ns/1ps |
`timescale 1ns/1ps |
|
/*************************************** |
|
9,244 → 9,244
the beginning of switch allocation (comb-nonspec). |
|
|
************************************/ |
************************************/ |
|
|
|
module comb_nonspec_allocator #( |
parameter V = 4, |
parameter P = 5, |
parameter FIRST_ARBITER_EXT_P_EN = 1, |
parameter VC_ARBITER_TYPE="ROUND_ROBIN" |
parameter V = 4, |
parameter P = 5, |
parameter FIRST_ARBITER_EXT_P_EN = 1, |
parameter VC_ARBITER_TYPE="ROUND_ROBIN" |
|
)( |
//VC allocator |
//input |
dest_port_all, // from input port |
//VC allocator |
//input |
dest_port_all, // from input port |
ovc_is_assigned_all, // |
masked_ovc_request_all, |
lk_destination_all, |
|
|
//output |
ovc_allocated_all,//to the output port |
granted_ovc_num_all, // to the input port |
ivc_num_getting_ovc_grant, |
|
//switch_alloc |
ivc_request_all, |
assigned_ovc_not_full_all, |
|
//output |
granted_dest_port_all, |
ivc_num_getting_sw_grant, |
nonspec_first_arbiter_granted_ivc_all, |
any_ivc_sw_request_granted_all, |
any_ovc_granted_in_outport_all, |
|
// global |
clk, |
reset |
|
//output |
ovc_allocated_all,//to the output port |
granted_ovc_num_all, // to the input port |
ivc_num_getting_ovc_grant, |
|
//switch_alloc |
ivc_request_all, |
assigned_ovc_not_full_all, |
|
//output |
granted_dest_port_all, |
ivc_num_getting_sw_grant, |
nonspec_first_arbiter_granted_ivc_all, |
any_ivc_sw_request_granted_all, |
any_ovc_granted_in_outport_all, |
|
// global |
clk, |
reset |
|
); |
|
localparam P_1 = P-1, |
PV = V * P, |
VV = V * V, |
VP_1 = V * P_1, |
PP_1 = P_1* P, |
PVV = PV * V, |
PVP_1 = PV * P_1; |
localparam P_1 = P-1, |
PV = V * P, |
VV = V * V, |
VP_1 = V * P_1, |
PP_1 = P_1* P, |
PVV = PV * V, |
PVP_1 = PV * P_1; |
|
|
input [PVV-1 : 0] masked_ovc_request_all; |
input [PVP_1-1 : 0] dest_port_all; |
input [PV-1 : 0] ovc_is_assigned_all; |
output [PV-1 : 0] ovc_allocated_all; |
output [PVV-1 : 0] granted_ovc_num_all; |
output [PV-1 : 0] ivc_num_getting_ovc_grant; |
input [PV-1 : 0] ivc_request_all; |
input [PV-1 : 0] assigned_ovc_not_full_all; |
output [PP_1-1 : 0] granted_dest_port_all; |
output [PV-1 : 0] ivc_num_getting_sw_grant; |
output [P-1 : 0] any_ivc_sw_request_granted_all; |
output [P-1 : 0] any_ovc_granted_in_outport_all; |
output [PV-1 : 0] nonspec_first_arbiter_granted_ivc_all; |
input [PVP_1-1 : 0] lk_destination_all; |
input clk,reset; |
|
input [PVV-1 : 0] masked_ovc_request_all; |
input [PVP_1-1 : 0] dest_port_all; |
input [PV-1 : 0] ovc_is_assigned_all; |
output [PV-1 : 0] ovc_allocated_all; |
output [PVV-1 : 0] granted_ovc_num_all; |
output [PV-1 : 0] ivc_num_getting_ovc_grant; |
input [PV-1 : 0] ivc_request_all; |
input [PV-1 : 0] assigned_ovc_not_full_all; |
output [PP_1-1 : 0] granted_dest_port_all; |
output [PV-1 : 0] ivc_num_getting_sw_grant; |
output [P-1 : 0] any_ivc_sw_request_granted_all; |
output [P-1 : 0] any_ovc_granted_in_outport_all; |
output [PV-1 : 0] nonspec_first_arbiter_granted_ivc_all; |
input [PVP_1-1 : 0] lk_destination_all; |
input clk,reset; |
|
|
//internal wires switch allocator |
wire [PV-1 : 0] first_arbiter_granted_ivc_all; |
wire [PV-1 : 0] ivc_request_masked_all; |
wire [P-1 : 0] any_cand_ovc_exsit; |
|
assign nonspec_first_arbiter_granted_ivc_all = first_arbiter_granted_ivc_all; |
|
|
//nonspeculative switch allocator |
//internal wires switch allocator |
wire [PV-1 : 0] first_arbiter_granted_ivc_all; |
wire [PV-1 : 0] ivc_request_masked_all; |
wire [P-1 : 0] any_cand_ovc_exsit; |
|
assign nonspec_first_arbiter_granted_ivc_all = first_arbiter_granted_ivc_all; |
|
|
//nonspeculative switch allocator |
nonspec_sw_alloc #( |
.V (V), |
.P (P), |
.FIRST_ARBITER_EXT_P_EN (FIRST_ARBITER_EXT_P_EN) |
) |
nonspeculative_sw_allocator |
( |
.V (V), |
.P (P), |
.FIRST_ARBITER_EXT_P_EN (FIRST_ARBITER_EXT_P_EN) |
) |
nonspeculative_sw_allocator |
( |
|
.ivc_granted_all (ivc_num_getting_sw_grant), |
.ivc_request_masked_all (ivc_request_masked_all), |
.dest_port_all (dest_port_all), |
.granted_dest_port_all (granted_dest_port_all), |
.first_arbiter_granted_ivc_all (first_arbiter_granted_ivc_all), |
.any_ivc_granted_all (any_ivc_sw_request_granted_all), |
.any_ovc_granted_all (any_ovc_granted_in_outport_all), |
.clk (clk), |
.reset (reset) |
|
); |
|
|
|
wire [PVV-1 : 0] masked_ovc_request_all; |
wire [V-1 : 0] masked_non_assigned_request [PV-1 : 0] ; |
wire [PV-1 : 0] masked_assigned_request; |
wire [PV-1 : 0] assigned_ovc_request_all ; |
wire [VV-1 : 0] masked_candidate_ovc_per_port [P-1 : 0] ; |
wire [V-1 : 0] first_arbiter_granted_ivc_per_port[P-1 : 0] ; |
wire [V-1 : 0] candidate_ovc_local_num [P-1 : 0] ; |
wire [V-1 : 0] first_arbiter_ovc_granted [PV-1 : 0]; |
wire [P_1-1 : 0] granted_dest_port_per_port [P-1 : 0]; |
wire [VP_1-1 : 0] cand_ovc_granted [P-1 : 0]; |
wire [P_1-1 : 0] ovc_allocated_all_gen [PV-1 : 0]; |
wire [V-1 : 0] granted_ovc_local_num_per_port [P-1 : 0]; |
wire [V-1 : 0] ivc_local_num_getting_ovc_grant[P-1 : 0]; |
wire [V : 0] summ_in [PV-1 : 0]; |
wire [V-1 : 0] vc_pririty [PV-1 : 0] ; |
|
assign assigned_ovc_request_all = ivc_request_all & ovc_is_assigned_all; |
|
genvar i,j; |
|
|
generate |
// IVC loop |
for(i=0;i< PV;i=i+1) begin :total_vc_loop |
|
// mask unavailable ovc from requests |
assign masked_non_assigned_request [i] = masked_ovc_request_all [(i+1)*V-1 : i*V ]; |
assign masked_assigned_request [i] = assigned_ovc_not_full_all[i] & assigned_ovc_request_all [i]; |
|
// summing assigned and non-assigned VC requests |
assign summ_in[i] ={masked_non_assigned_request [i],masked_assigned_request [i]}; |
assign ivc_request_masked_all[i] = | summ_in[i]; |
|
|
//first level arbiter to candidate only one OVC |
if(VC_ARBITER_TYPE=="ROUND_ROBIN")begin :round_robin |
arbiter #( |
.ARBITER_WIDTH (V) |
)ovc_arbiter |
( |
.clk (clk), |
.reset (reset), |
.request (masked_non_assigned_request [i]), |
.grant (first_arbiter_ovc_granted[i]), |
.any_grant () |
); |
end else begin :fixarb |
|
.ivc_granted_all (ivc_num_getting_sw_grant), |
.ivc_request_masked_all (ivc_request_masked_all), |
.dest_port_all (dest_port_all), |
.granted_dest_port_all (granted_dest_port_all), |
.first_arbiter_granted_ivc_all (first_arbiter_granted_ivc_all), |
.any_ivc_granted_all (any_ivc_sw_request_granted_all), |
.any_ovc_granted_all (any_ovc_granted_in_outport_all), |
.clk (clk), |
.reset (reset) |
|
); |
|
|
|
wire [PVV-1 : 0] masked_ovc_request_all; |
wire [V-1 : 0] masked_non_assigned_request [PV-1 : 0] ; |
wire [PV-1 : 0] masked_assigned_request; |
wire [PV-1 : 0] assigned_ovc_request_all ; |
wire [VV-1 : 0] masked_candidate_ovc_per_port [P-1 : 0] ; |
wire [V-1 : 0] first_arbiter_granted_ivc_per_port[P-1 : 0] ; |
wire [V-1 : 0] candidate_ovc_local_num [P-1 : 0] ; |
wire [V-1 : 0] first_arbiter_ovc_granted [PV-1 : 0]; |
wire [P_1-1 : 0] granted_dest_port_per_port [P-1 : 0]; |
wire [VP_1-1 : 0] cand_ovc_granted [P-1 : 0]; |
wire [P_1-1 : 0] ovc_allocated_all_gen [PV-1 : 0]; |
wire [V-1 : 0] granted_ovc_local_num_per_port [P-1 : 0]; |
wire [V-1 : 0] ivc_local_num_getting_ovc_grant[P-1 : 0]; |
wire [V : 0] summ_in [PV-1 : 0]; |
wire [V-1 : 0] vc_pririty [PV-1 : 0] ; |
|
assign assigned_ovc_request_all = ivc_request_all & ovc_is_assigned_all; |
|
genvar i,j; |
|
|
generate |
// IVC loop |
for(i=0;i< PV;i=i+1) begin :total_vc_loop |
|
// mask unavailable ovc from requests |
assign masked_non_assigned_request [i] = masked_ovc_request_all [(i+1)*V-1 : i*V ]; |
assign masked_assigned_request [i] = assigned_ovc_not_full_all[i] & assigned_ovc_request_all [i]; |
|
// summing assigned and non-assigned VC requests |
assign summ_in[i] ={masked_non_assigned_request [i],masked_assigned_request [i]}; |
assign ivc_request_masked_all[i] = | summ_in[i]; |
|
|
//first level arbiter to candidate only one OVC |
if(VC_ARBITER_TYPE=="ROUND_ROBIN")begin :round_robin |
arbiter #( |
.ARBITER_WIDTH (V) |
)ovc_arbiter |
( |
.clk (clk), |
.reset (reset), |
.request (masked_non_assigned_request [i]), |
.grant (first_arbiter_ovc_granted[i]), |
.any_grant () |
); |
end else begin :fixarb |
|
vc_priority_based_dest_port#( |
.P(P), |
.V(V) |
) |
priority_setting |
( |
) |
priority_setting |
( |
.dest_port(lk_destination_all [((i+1)*P_1)-1 : i*P_1]), |
.vc_pririty(vc_pririty[i]) |
); |
|
|
|
.vc_pririty(vc_pririty[i]) |
); |
|
|
|
arbiter_ext_priority #( |
.ARBITER_WIDTH (V) |
.ARBITER_WIDTH (V) |
) |
ovc_arbiter |
( |
.request (masked_non_assigned_request [i]), |
.priority_in(vc_pririty[i]), |
.grant(first_arbiter_ovc_granted[i]), |
.any_grant() |
); |
|
end |
|
|
end//for |
|
|
for(i=0;i< P;i=i+1) begin :port_loop3 |
for(j=0;j< V;j=j+1) begin :vc_loop |
//merge masked_candidate_ovc in each port |
assign masked_candidate_ovc_per_port[i][(j+1)*V-1 : j*V] = first_arbiter_ovc_granted [i*V+j]; |
end//for j |
|
assign first_arbiter_granted_ivc_per_port[i]=first_arbiter_granted_ivc_all[(i+1)*V-1 : i*V]; |
assign granted_dest_port_per_port[i]=granted_dest_port_all[(i+1)*P_1-1 : i*P_1]; |
|
|
// multiplex candidate OVC of first level switch allocatore winner |
one_hot_mux #( |
.IN_WIDTH (VV), |
.SEL_WIDTH (V) |
) |
multiplexer2 |
( |
.mux_in (masked_candidate_ovc_per_port [i]), |
.mux_out (candidate_ovc_local_num [i]), |
.sel (first_arbiter_granted_ivc_per_port [i]) |
.request (masked_non_assigned_request [i]), |
.priority_in(vc_pririty[i]), |
.grant(first_arbiter_ovc_granted[i]), |
.any_grant() |
); |
|
end |
|
|
end//for |
|
|
for(i=0;i< P;i=i+1) begin :port_loop3 |
for(j=0;j< V;j=j+1) begin :vc_loop |
//merge masked_candidate_ovc in each port |
assign masked_candidate_ovc_per_port[i][(j+1)*V-1 : j*V] = first_arbiter_ovc_granted [i*V+j]; |
end//for j |
|
assign first_arbiter_granted_ivc_per_port[i]=first_arbiter_granted_ivc_all[(i+1)*V-1 : i*V]; |
assign granted_dest_port_per_port[i]=granted_dest_port_all[(i+1)*P_1-1 : i*P_1]; |
|
|
// multiplex candidate OVC of first level switch allocatore winner |
one_hot_mux #( |
.IN_WIDTH (VV), |
.SEL_WIDTH (V) |
) |
multiplexer2 |
( |
.mux_in (masked_candidate_ovc_per_port [i]), |
.mux_out (candidate_ovc_local_num [i]), |
.sel (first_arbiter_granted_ivc_per_port [i]) |
|
); |
|
assign any_cand_ovc_exsit[i] = | candidate_ovc_local_num [i]; |
|
|
//demultiplexer |
one_hot_demux #( |
.IN_WIDTH (V), |
.SEL_WIDTH (P_1) |
)demux1 |
( |
.demux_sel (granted_dest_port_per_port [i]),//selectore |
.demux_in (candidate_ovc_local_num[i]),//repeated |
.demux_out (cand_ovc_granted [i]) |
); |
|
assign granted_ovc_local_num_per_port [i]=(any_ivc_sw_request_granted_all[i] )? candidate_ovc_local_num[i] : {V{1'b0}}; |
assign ivc_local_num_getting_ovc_grant [i]= (any_ivc_sw_request_granted_all[i] && any_cand_ovc_exsit[i])? first_arbiter_granted_ivc_per_port [i] : {V{1'b0}}; |
assign ivc_num_getting_ovc_grant [(i+1)*V-1 : i*V] = ivc_local_num_getting_ovc_grant[i]; |
for(j=0;j<V; j=j+1)begin: assign_loop3 |
assign granted_ovc_num_all[(i*VV)+((j+1)*V)-1 : (i*VV)+(j*V)]=granted_ovc_local_num_per_port[i]; |
end//j |
end//i |
|
|
for(i=0;i< PV;i=i+1) begin :total_vc_loop2 |
for(j=0;j<P; j=j+1)begin: assign_loop2 |
if((i/V)<j )begin: jj |
assign ovc_allocated_all_gen[i][j-1] = cand_ovc_granted[j][i]; |
end else if((i/V)>j) begin: hh |
assign ovc_allocated_all_gen[i][j] = cand_ovc_granted[j][i-V]; |
|
end |
end//j |
|
assign ovc_allocated_all [i] = |ovc_allocated_all_gen[i]; |
|
end//i |
|
endgenerate |
|
|
endmodule |
); |
|
assign any_cand_ovc_exsit[i] = | candidate_ovc_local_num [i]; |
|
|
//demultiplexer |
one_hot_demux #( |
.IN_WIDTH (V), |
.SEL_WIDTH (P_1) |
)demux1 |
( |
.demux_sel (granted_dest_port_per_port [i]),//selectore |
.demux_in (candidate_ovc_local_num[i]),//repeated |
.demux_out (cand_ovc_granted [i]) |
); |
|
assign granted_ovc_local_num_per_port [i]=(any_ivc_sw_request_granted_all[i] )? candidate_ovc_local_num[i] : {V{1'b0}}; |
assign ivc_local_num_getting_ovc_grant [i]= (any_ivc_sw_request_granted_all[i] && any_cand_ovc_exsit[i])? first_arbiter_granted_ivc_per_port [i] : {V{1'b0}}; |
assign ivc_num_getting_ovc_grant [(i+1)*V-1 : i*V] = ivc_local_num_getting_ovc_grant[i]; |
for(j=0;j<V; j=j+1)begin: assign_loop3 |
assign granted_ovc_num_all[(i*VV)+((j+1)*V)-1 : (i*VV)+(j*V)]=granted_ovc_local_num_per_port[i]; |
end//j |
end//i |
|
|
for(i=0;i< PV;i=i+1) begin :total_vc_loop2 |
for(j=0;j<P; j=j+1)begin: assign_loop2 |
if((i/V)<j )begin: jj |
assign ovc_allocated_all_gen[i][j-1] = cand_ovc_granted[j][i]; |
end else if((i/V)>j) begin: hh |
assign ovc_allocated_all_gen[i][j] = cand_ovc_granted[j][i-V]; |
|
end |
end//j |
|
assign ovc_allocated_all [i] = |ovc_allocated_all_gen[i]; |
|
end//i |
|
endgenerate |
|
|
endmodule |
|
|
|
/src_noc/comb_spec2.v
1,6 → 1,6
`timescale 1ns/1ps |
`timescale 1ns/1ps |
|
/************************************* |
/************************************* |
comb_spec2 |
VC allocator combined with speculative switch allocator |
where the free VC availability is checked in the middle |
7,225 → 7,225
of switch allocator after first level of arbitration |
(comb-spec2). |
|
*************************************/ |
*************************************/ |
module comb_spec2_allocator #( |
parameter V = 4,// Virtual channel num per port |
parameter P = 5, |
parameter DEBUG_EN = 1 |
parameter V = 4,// Virtual channel num per port |
parameter P = 5, |
parameter DEBUG_EN = 1 |
)( |
|
dest_port_all, |
masked_ovc_request_all, |
ovc_is_assigned_all, |
ivc_request_all, |
assigned_ovc_not_full_all, |
ovc_allocated_all, |
granted_ovc_num_all, |
ivc_num_getting_ovc_grant, |
ivc_num_getting_sw_grant, |
spec_first_arbiter_granted_ivc_all, |
nonspec_first_arbiter_granted_ivc_all, |
granted_dest_port_all, |
nonspec_granted_dest_port_all, |
any_ivc_sw_request_granted_all, |
clk,reset |
|
dest_port_all, |
masked_ovc_request_all, |
ovc_is_assigned_all, |
ivc_request_all, |
assigned_ovc_not_full_all, |
ovc_allocated_all, |
granted_ovc_num_all, |
ivc_num_getting_ovc_grant, |
ivc_num_getting_sw_grant, |
spec_first_arbiter_granted_ivc_all, |
nonspec_first_arbiter_granted_ivc_all, |
granted_dest_port_all, |
nonspec_granted_dest_port_all, |
any_ivc_sw_request_granted_all, |
clk,reset |
|
); |
|
localparam PV = V * P, |
VV = V * V, |
PVV = PV * V, |
P_1 = P-1 , |
VP_1 = V * P_1, |
PP_1 = P_1 * P, |
PVP_1 = PV * P_1; |
localparam PV = V * P, |
VV = V * V, |
PVV = PV * V, |
P_1 = P-1 , |
VP_1 = V * P_1, |
PP_1 = P_1 * P, |
PVP_1 = PV * P_1; |
|
|
|
input [PVP_1-1 : 0] dest_port_all; |
input [PVV-1 : 0] masked_ovc_request_all; |
input [PV-1 : 0] ovc_is_assigned_all; |
input [PV-1 : 0] ivc_request_all; |
input [PV-1 : 0] assigned_ovc_not_full_all; |
|
output [PV-1 : 0] ovc_allocated_all; |
output [PVV-1 : 0] granted_ovc_num_all; |
output [PV-1 : 0] ivc_num_getting_ovc_grant; |
output [PV-1 : 0] ivc_num_getting_sw_grant; |
output [PV-1 : 0] nonspec_first_arbiter_granted_ivc_all; |
output [PV-1 : 0] spec_first_arbiter_granted_ivc_all; |
|
output [PP_1-1 : 0] granted_dest_port_all; |
output [PP_1-1 : 0] nonspec_granted_dest_port_all; |
output [P-1 : 0] any_ivc_sw_request_granted_all; |
|
|
input clk,reset; |
|
|
input [PVP_1-1 : 0] dest_port_all; |
input [PVV-1 : 0] masked_ovc_request_all; |
input [PV-1 : 0] ovc_is_assigned_all; |
input [PV-1 : 0] ivc_request_all; |
input [PV-1 : 0] assigned_ovc_not_full_all; |
|
output [PV-1 : 0] ovc_allocated_all; |
output [PVV-1 : 0] granted_ovc_num_all; |
output [PV-1 : 0] ivc_num_getting_ovc_grant; |
output [PV-1 : 0] ivc_num_getting_sw_grant; |
output [PV-1 : 0] nonspec_first_arbiter_granted_ivc_all; |
output [PV-1 : 0] spec_first_arbiter_granted_ivc_all; |
|
output [PP_1-1 : 0] granted_dest_port_all; |
output [PP_1-1 : 0] nonspec_granted_dest_port_all; |
output [P-1 : 0] any_ivc_sw_request_granted_all; |
|
|
input clk,reset; |
|
|
|
|
|
|
|
|
//internal wires switch allocator |
|
wire [PV-1 : 0] spec_first_arbiter_granted_ivc_all; |
wire [PP_1-1 : 0] spec_granted_dest_port_all; |
wire [P-1 : 0] spec_any_ivc_grant_valid; |
wire [PV-1 : 0] valid_speculation; |
|
|
|
//speculative switch allocator |
spec_sw_alloc2 #( |
.V (V), |
.P (P), |
.DEBUG_EN (DEBUG_EN) |
)speculative_sw_allocator |
( |
//internal wires switch allocator |
|
wire [PV-1 : 0] spec_first_arbiter_granted_ivc_all; |
wire [PP_1-1 : 0] spec_granted_dest_port_all; |
wire [P-1 : 0] spec_any_ivc_grant_valid; |
wire [PV-1 : 0] valid_speculation; |
|
|
|
//speculative switch allocator |
spec_sw_alloc2 #( |
.V (V), |
.P (P), |
.DEBUG_EN (DEBUG_EN) |
)speculative_sw_allocator |
( |
|
.ivc_granted_all (ivc_num_getting_sw_grant), |
.ivc_request_all (ivc_request_all), |
.ovc_is_assigned_all (ovc_is_assigned_all), |
.assigned_ovc_not_full_all (assigned_ovc_not_full_all), |
.dest_port_all (dest_port_all), |
.granted_dest_port_all (granted_dest_port_all), |
.nonspec_granted_dest_port_all (nonspec_granted_dest_port_all), |
.valid_speculation (valid_speculation), |
.spec_first_arbiter_granted_ivc_all (spec_first_arbiter_granted_ivc_all), |
.nonspec_first_arbiter_granted_ivc_all (nonspec_first_arbiter_granted_ivc_all), |
.spec_granted_dest_port_all (spec_granted_dest_port_all), |
.spec_any_ivc_grant_valid (spec_any_ivc_grant_valid), |
.any_ivc_sw_request_granted_all (any_ivc_sw_request_granted_all), |
.clk (clk), |
.reset (reset) |
|
); |
|
wire [V-1 : 0] masked_non_assigned_request [PV-1 : 0] ; |
wire [VV-1 : 0] masked_candidate_ovc_per_port [P-1 : 0] ; |
wire [V-1 : 0] spec_first_arbiter_granted_ivc_per_port[P-1 : 0]; |
wire [V-1 : 0] spec_first_arbiter_ovc_request [P-1 : 0]; |
wire [V-1 : 0] spec_first_arbiter_ovc_granted [P-1 : 0]; |
wire [P_1-1 : 0] spec_granted_dest_port_per_port [P-1 : 0]; |
wire [VP_1-1 : 0] cand_ovc_granted [P-1 : 0]; |
wire [P_1-1 : 0] ovc_allocated_all_gen [PV-1 : 0]; |
wire [V-1 : 0] granted_ovc_local_num_per_port [P-1 : 0]; |
wire [V-1 : 0] ivc_local_num_getting_ovc_grant [P-1 : 0]; |
.ivc_granted_all (ivc_num_getting_sw_grant), |
.ivc_request_all (ivc_request_all), |
.ovc_is_assigned_all (ovc_is_assigned_all), |
.assigned_ovc_not_full_all (assigned_ovc_not_full_all), |
.dest_port_all (dest_port_all), |
.granted_dest_port_all (granted_dest_port_all), |
.nonspec_granted_dest_port_all (nonspec_granted_dest_port_all), |
.valid_speculation (valid_speculation), |
.spec_first_arbiter_granted_ivc_all (spec_first_arbiter_granted_ivc_all), |
.nonspec_first_arbiter_granted_ivc_all (nonspec_first_arbiter_granted_ivc_all), |
.spec_granted_dest_port_all (spec_granted_dest_port_all), |
.spec_any_ivc_grant_valid (spec_any_ivc_grant_valid), |
.any_ivc_sw_request_granted_all (any_ivc_sw_request_granted_all), |
.clk (clk), |
.reset (reset) |
|
); |
|
wire [V-1 : 0] masked_non_assigned_request [PV-1 : 0] ; |
wire [VV-1 : 0] masked_candidate_ovc_per_port [P-1 : 0] ; |
wire [V-1 : 0] spec_first_arbiter_granted_ivc_per_port[P-1 : 0]; |
wire [V-1 : 0] spec_first_arbiter_ovc_request [P-1 : 0]; |
wire [V-1 : 0] spec_first_arbiter_ovc_granted [P-1 : 0]; |
wire [P_1-1 : 0] spec_granted_dest_port_per_port [P-1 : 0]; |
wire [VP_1-1 : 0] cand_ovc_granted [P-1 : 0]; |
wire [P_1-1 : 0] ovc_allocated_all_gen [PV-1 : 0]; |
wire [V-1 : 0] granted_ovc_local_num_per_port [P-1 : 0]; |
wire [V-1 : 0] ivc_local_num_getting_ovc_grant [P-1 : 0]; |
|
genvar i,j; |
generate |
genvar i,j; |
generate |
|
// IVC loop |
for(i=0;i< PV;i=i+1) begin :total_vc_loop |
|
// mask unavailable ovc from requests |
assign masked_non_assigned_request [i] = masked_ovc_request_all [(i+1)*V-1 : i*V ]; |
assign valid_speculation [i] = | masked_non_assigned_request [i]; |
// IVC loop |
for(i=0;i< PV;i=i+1) begin :total_vc_loop |
|
// mask unavailable ovc from requests |
assign masked_non_assigned_request [i] = masked_ovc_request_all [(i+1)*V-1 : i*V ]; |
assign valid_speculation [i] = | masked_non_assigned_request [i]; |
|
end//for |
|
for(i=0;i< P;i=i+1) begin :port_loop3 |
for(j=0;j< V;j=j+1) begin :vc_loop |
//merge masked_candidate_ovc in each port |
assign masked_candidate_ovc_per_port[i][(j+1)*V-1 : j*V] = masked_non_assigned_request [i*V+j]; |
|
end//for j |
|
assign spec_first_arbiter_granted_ivc_per_port[i] =spec_first_arbiter_granted_ivc_all[(i+1)*V-1 : i*V]; |
assign spec_granted_dest_port_per_port[i] =spec_granted_dest_port_all[(i+1)*P_1-1 : i*P_1]; |
// multiplex candidate OVC of first level switch allocatore winner |
|
one_hot_mux #( |
.IN_WIDTH (VV), |
.SEL_WIDTH (V) |
) |
multiplexer2 |
( |
.mux_in (masked_candidate_ovc_per_port [i]), |
.mux_out (spec_first_arbiter_ovc_request [i]), |
.sel (spec_first_arbiter_granted_ivc_per_port [i]) |
end//for |
|
for(i=0;i< P;i=i+1) begin :port_loop3 |
for(j=0;j< V;j=j+1) begin :vc_loop |
//merge masked_candidate_ovc in each port |
assign masked_candidate_ovc_per_port[i][(j+1)*V-1 : j*V] = masked_non_assigned_request [i*V+j]; |
|
end//for j |
|
assign spec_first_arbiter_granted_ivc_per_port[i] =spec_first_arbiter_granted_ivc_all[(i+1)*V-1 : i*V]; |
assign spec_granted_dest_port_per_port[i] =spec_granted_dest_port_all[(i+1)*P_1-1 : i*P_1]; |
// multiplex candidate OVC of first level switch allocatore winner |
|
one_hot_mux #( |
.IN_WIDTH (VV), |
.SEL_WIDTH (V) |
) |
multiplexer2 |
( |
.mux_in (masked_candidate_ovc_per_port [i]), |
.mux_out (spec_first_arbiter_ovc_request [i]), |
.sel (spec_first_arbiter_granted_ivc_per_port [i]) |
|
); |
|
|
//first level arbiter to candidate only one OVC |
arbiter #( |
.ARBITER_WIDTH (V) |
)second_arbiter |
( |
.clk (clk), |
.reset (reset), |
.request (spec_first_arbiter_ovc_request[i]), |
.grant (spec_first_arbiter_ovc_granted[i]), |
.any_grant () |
); |
|
|
//demultiplexer |
|
one_hot_demux #( |
.IN_WIDTH (V), |
.SEL_WIDTH (P_1) |
)demux1 |
( |
.demux_sel (spec_granted_dest_port_per_port [i]),//selectore |
.demux_in (spec_first_arbiter_ovc_granted[i]),//repeated |
.demux_out (cand_ovc_granted[i]) |
); |
); |
|
|
//first level arbiter to candidate only one OVC |
arbiter #( |
.ARBITER_WIDTH (V) |
)second_arbiter |
( |
.clk (clk), |
.reset (reset), |
.request (spec_first_arbiter_ovc_request[i]), |
.grant (spec_first_arbiter_ovc_granted[i]), |
.any_grant () |
); |
|
|
//demultiplexer |
|
one_hot_demux #( |
.IN_WIDTH (V), |
.SEL_WIDTH (P_1) |
)demux1 |
( |
.demux_sel (spec_granted_dest_port_per_port [i]),//selectore |
.demux_in (spec_first_arbiter_ovc_granted[i]),//repeated |
.demux_out (cand_ovc_granted[i]) |
); |
|
|
|
//assign cand_ovc_granted [i] = (spec_any_ivc_grant_valid[i])? cand_ovc_demuxed[i]: {VP_1{1'b0}}; |
assign granted_ovc_local_num_per_port[i]=(spec_any_ivc_grant_valid[i])? spec_first_arbiter_ovc_granted[i] : {V{1'b0}}; |
assign ivc_local_num_getting_ovc_grant[i]= (spec_any_ivc_grant_valid[i])? spec_first_arbiter_granted_ivc_per_port [i] : {V{1'b0}}; |
assign ivc_num_getting_ovc_grant[(i+1)*V-1 : i*V] = ivc_local_num_getting_ovc_grant[i]; |
for(j=0;j<V; j=j+1)begin: assign_loop3 |
assign granted_ovc_num_all[(i*VV)+((j+1)*V)-1 : (i*VV)+(j*V)]=granted_ovc_local_num_per_port[i]; |
|
end//j |
end//i |
|
//wire [PORT_SEL-1 : 0] ovc_allocated_all_gen [PV-1 : 0]; |
//wire [VP_1-1 : 0] cand_ovc_granted [P-1 : 0]; |
wire [PV-1 : 0] result; |
for(i=0;i< PV;i=i+1) begin :total_vc_loop2 |
for(j=0;j<P; j=j+1)begin: assign_loop2 |
if((i/V)<j )begin: jj |
assign ovc_allocated_all_gen[i][j-1] = cand_ovc_granted[j][i]; |
end else if((i/V)>j) begin: hh |
assign ovc_allocated_all_gen[i][j] = cand_ovc_granted[j][i-V]; |
|
end |
end//j |
|
assign ovc_allocated_all [i] = |ovc_allocated_all_gen[i]; |
|
//synthesis translate_off |
//synopsys translate_off |
|
|
//assign cand_ovc_granted [i] = (spec_any_ivc_grant_valid[i])? cand_ovc_demuxed[i]: {VP_1{1'b0}}; |
assign granted_ovc_local_num_per_port[i]=(spec_any_ivc_grant_valid[i])? spec_first_arbiter_ovc_granted[i] : {V{1'b0}}; |
assign ivc_local_num_getting_ovc_grant[i]= (spec_any_ivc_grant_valid[i])? spec_first_arbiter_granted_ivc_per_port [i] : {V{1'b0}}; |
assign ivc_num_getting_ovc_grant[(i+1)*V-1 : i*V] = ivc_local_num_getting_ovc_grant[i]; |
for(j=0;j<V; j=j+1)begin: assign_loop3 |
assign granted_ovc_num_all[(i*VV)+((j+1)*V)-1 : (i*VV)+(j*V)]=granted_ovc_local_num_per_port[i]; |
|
end//j |
end//i |
|
//wire [PORT_SEL-1 : 0] ovc_allocated_all_gen [PV-1 : 0]; |
//wire [VP_1-1 : 0] cand_ovc_granted [P-1 : 0]; |
wire [PV-1 : 0] result; |
for(i=0;i< PV;i=i+1) begin :total_vc_loop2 |
for(j=0;j<P; j=j+1)begin: assign_loop2 |
if((i/V)<j )begin: jj |
assign ovc_allocated_all_gen[i][j-1] = cand_ovc_granted[j][i]; |
end else if((i/V)>j) begin: hh |
assign ovc_allocated_all_gen[i][j] = cand_ovc_granted[j][i-V]; |
|
end |
end//j |
|
assign ovc_allocated_all [i] = |ovc_allocated_all_gen[i]; |
|
//synthesis translate_off |
//synopsys translate_off |
if(DEBUG_EN)begin :dbg |
check_single_bit_assertation #( |
.IN_WIDTH(P_1) |
|
|
)check_ovc_allocated |
( |
.in (ovc_allocated_all_gen[i]), |
.result (result[i]) |
|
( |
.in (ovc_allocated_all_gen[i]), |
.result (result[i]) |
|
); |
|
|
always @(posedge clk ) begin |
if(~result[i]) $display("%t,Error: An OVC is assigned to more than one IVC %m",$time); |
end |
end //DEBUG |
//synopsys translate_on |
//synthesis translate_on |
|
end//i |
|
|
endgenerate |
|
endmodule |
if(~result[i]) $display("%t,Error: An OVC is assigned to more than one IVC %m",$time); |
end |
end //DEBUG |
//synopsys translate_on |
//synthesis translate_on |
|
end//i |
|
|
endgenerate |
|
endmodule |
|
/*************************** |
|
375,7 → 375,7
assign spec_granted_dest_port_all_accepted[(i+1)*P_1-1 : i*P_1]= spec_request_accepted [i]; |
|
//synthesis translate_off |
//synopsys translate_off |
//synopsys translate_off |
if(DEBUG_EN)begin :dbg |
assign nonspec_check[i] = nonspec_granted_dest_port_all[(i+1)*P_1-1 : i*P_1]; |
assign spec_check[i]= spec_granted_dest_port_all_accepted[(i+1)*P_1-1 : i*P_1]; |
384,7 → 384,7
if(nonspec_ivc_granted_all [(i+1)*V-1 : i*V] >0 && spec_ivc_granted_all_accepted[(i+1)*V-1 : i*V]>0 ) $display("%t: Error: Both speculative and nonspeculative is granted for one port",$time); |
end//always |
end // DEBUG |
//synopsys translate_on |
//synopsys translate_on |
//synthesis translate_on |
|
|
/src_noc/combined_vc_sw_alloc.v
1,36 → 1,36
`timescale 1ns/1ps |
`timescale 1ns/1ps |
|
module combined_vc_sw_alloc #( |
parameter V = 4, //VC number per port |
parameter P = 5, //port number |
parameter COMBINATION_TYPE = "BASELINE",// "BASELINE", "COMB_SPEC1", "COMB_SPEC2", "COMB_NONSPEC" |
parameter FIRST_ARBITER_EXT_P_EN = 1, |
parameter ROUTE_TYPE = "DETERMINISTIC",// "DETERMINISTIC", "FULL_ADAPTIVE", "PAR_ADAPTIVE" |
parameter V = 4, //VC number per port |
parameter P = 5, //port number |
parameter COMBINATION_TYPE = "BASELINE",// "BASELINE", "COMB_SPEC1", "COMB_SPEC2", "COMB_NONSPEC" |
parameter FIRST_ARBITER_EXT_P_EN = 1, |
parameter ROUTE_TYPE = "DETERMINISTIC",// "DETERMINISTIC", "FULL_ADAPTIVE", "PAR_ADAPTIVE" |
parameter [V-1 : 0] ESCAP_VC_MASK = 4'b1000, // mask scape vc, valid only for full adaptive |
parameter DEBUG_EN = 1 |
) |
( |
|
dest_port_all, |
masked_ovc_request_all, |
ovc_is_assigned_all, |
ivc_request_all, |
assigned_ovc_not_full_all, |
ovc_allocated_all, |
granted_ovc_num_all, |
ivc_num_getting_ovc_grant, |
ivc_num_getting_sw_grant, |
spec_first_arbiter_granted_ivc_all, |
nonspec_first_arbiter_granted_ivc_all, |
granted_dest_port_all, |
nonspec_granted_dest_port_all, |
spec_granted_dest_port_all, |
any_ivc_sw_request_granted_all, |
any_ovc_granted_in_outport_all, |
spec_ovc_num_all, |
lk_destination_all, |
clk, |
reset |
dest_port_all, |
masked_ovc_request_all, |
ovc_is_assigned_all, |
ivc_request_all, |
assigned_ovc_not_full_all, |
ovc_allocated_all, |
granted_ovc_num_all, |
ivc_num_getting_ovc_grant, |
ivc_num_getting_sw_grant, |
spec_first_arbiter_granted_ivc_all, |
nonspec_first_arbiter_granted_ivc_all, |
granted_dest_port_all, |
nonspec_granted_dest_port_all, |
spec_granted_dest_port_all, |
any_ivc_sw_request_granted_all, |
any_ovc_granted_in_outport_all, |
spec_ovc_num_all, |
lk_destination_all, |
clk, |
reset |
|
); |
|
37,182 → 37,182
|
|
|
localparam PV = V * P, |
PVV = PV * V, |
P_1 = P-1 , |
PP_1 = P_1 * P, |
PVP_1 = PV * P_1; |
localparam PV = V * P, |
PVV = PV * V, |
P_1 = P-1 , |
PP_1 = P_1 * P, |
PVP_1 = PV * P_1; |
|
|
|
input [PVP_1-1 : 0] dest_port_all; |
input [PVV-1 : 0] masked_ovc_request_all; |
input [PV-1 : 0] ovc_is_assigned_all; |
input [PV-1 : 0] ivc_request_all; |
input [PV-1 : 0] assigned_ovc_not_full_all; |
|
|
output [PV-1 : 0] ovc_allocated_all; |
output [PVV-1 : 0] granted_ovc_num_all; |
output [PV-1 : 0] ivc_num_getting_ovc_grant; |
output [PV-1 : 0] ivc_num_getting_sw_grant; |
output [PV-1 : 0] nonspec_first_arbiter_granted_ivc_all; |
output [PV-1 : 0] spec_first_arbiter_granted_ivc_all; |
output [P-1 : 0] any_ivc_sw_request_granted_all; |
output [P-1 : 0] any_ovc_granted_in_outport_all; |
output [PP_1-1 : 0] granted_dest_port_all; |
output [PP_1-1 : 0] nonspec_granted_dest_port_all; |
output [PP_1-1 : 0] spec_granted_dest_port_all; |
output [PVV-1 : 0] spec_ovc_num_all; |
input [PVP_1-1 : 0] lk_destination_all; |
|
input clk,reset; |
|
|
input [PVP_1-1 : 0] dest_port_all; |
input [PVV-1 : 0] masked_ovc_request_all; |
input [PV-1 : 0] ovc_is_assigned_all; |
input [PV-1 : 0] ivc_request_all; |
input [PV-1 : 0] assigned_ovc_not_full_all; |
|
|
output [PV-1 : 0] ovc_allocated_all; |
output [PVV-1 : 0] granted_ovc_num_all; |
output [PV-1 : 0] ivc_num_getting_ovc_grant; |
output [PV-1 : 0] ivc_num_getting_sw_grant; |
output [PV-1 : 0] nonspec_first_arbiter_granted_ivc_all; |
output [PV-1 : 0] spec_first_arbiter_granted_ivc_all; |
output [P-1 : 0] any_ivc_sw_request_granted_all; |
output [P-1 : 0] any_ovc_granted_in_outport_all; |
output [PP_1-1 : 0] granted_dest_port_all; |
output [PP_1-1 : 0] nonspec_granted_dest_port_all; |
output [PP_1-1 : 0] spec_granted_dest_port_all; |
output [PVV-1 : 0] spec_ovc_num_all; |
input [PVP_1-1 : 0] lk_destination_all; |
|
input clk,reset; |
|
generate |
if(COMBINATION_TYPE == "BASELINE") begin : canonical_comb_gen |
generate |
if(COMBINATION_TYPE == "BASELINE") begin : canonical_comb_gen |
|
baseline_allocator #( |
.V(V), |
.P(P), |
.TREE_ARBITER_EN(1), |
.DEBUG_EN(DEBUG_EN) |
) |
the_base_line |
( |
.dest_port_all(dest_port_all), |
.masked_ovc_request_all(masked_ovc_request_all), |
.ovc_is_assigned_all(ovc_is_assigned_all), |
.ivc_request_all(ivc_request_all), |
.assigned_ovc_not_full_all(assigned_ovc_not_full_all), |
.ovc_allocated_all(ovc_allocated_all), |
.granted_ovc_num_all(granted_ovc_num_all), |
.ivc_num_getting_ovc_grant(ivc_num_getting_ovc_grant), |
.ivc_num_getting_sw_grant(ivc_num_getting_sw_grant), |
.spec_first_arbiter_granted_ivc_all(spec_first_arbiter_granted_ivc_all), |
.nonspec_first_arbiter_granted_ivc_all(nonspec_first_arbiter_granted_ivc_all), |
.granted_dest_port_all(granted_dest_port_all), |
.nonspec_granted_dest_port_all(nonspec_granted_dest_port_all), |
.spec_granted_dest_port_all(spec_granted_dest_port_all), |
.any_ivc_sw_request_granted_all(any_ivc_sw_request_granted_all), |
.spec_ovc_num_all(spec_ovc_num_all), |
.clk(clk), |
.reset(reset) |
|
); |
baseline_allocator #( |
.V(V), |
.P(P), |
.TREE_ARBITER_EN(1), |
.DEBUG_EN(DEBUG_EN) |
) |
the_base_line |
( |
.dest_port_all(dest_port_all), |
.masked_ovc_request_all(masked_ovc_request_all), |
.ovc_is_assigned_all(ovc_is_assigned_all), |
.ivc_request_all(ivc_request_all), |
.assigned_ovc_not_full_all(assigned_ovc_not_full_all), |
.ovc_allocated_all(ovc_allocated_all), |
.granted_ovc_num_all(granted_ovc_num_all), |
.ivc_num_getting_ovc_grant(ivc_num_getting_ovc_grant), |
.ivc_num_getting_sw_grant(ivc_num_getting_sw_grant), |
.spec_first_arbiter_granted_ivc_all(spec_first_arbiter_granted_ivc_all), |
.nonspec_first_arbiter_granted_ivc_all(nonspec_first_arbiter_granted_ivc_all), |
.granted_dest_port_all(granted_dest_port_all), |
.nonspec_granted_dest_port_all(nonspec_granted_dest_port_all), |
.spec_granted_dest_port_all(spec_granted_dest_port_all), |
.any_ivc_sw_request_granted_all(any_ivc_sw_request_granted_all), |
.spec_ovc_num_all(spec_ovc_num_all), |
.clk(clk), |
.reset(reset) |
|
); |
|
end else if(COMBINATION_TYPE == "COMB_SPEC1") begin : spec1 |
|
comb_spec1_allocator #( |
.V(V), |
.P(P), |
.DEBUG_EN(DEBUG_EN) |
) |
the_comb_spec1 |
( |
.dest_port_all(dest_port_all), |
.masked_ovc_request_all(masked_ovc_request_all), |
.ovc_is_assigned_all(ovc_is_assigned_all), |
.ivc_request_all(ivc_request_all), |
.assigned_ovc_not_full_all(assigned_ovc_not_full_all), |
.ovc_allocated_all(ovc_allocated_all), |
.granted_ovc_num_all(granted_ovc_num_all), |
.ivc_num_getting_ovc_grant(ivc_num_getting_ovc_grant), |
.ivc_num_getting_sw_grant(ivc_num_getting_sw_grant), |
.spec_first_arbiter_granted_ivc_all(spec_first_arbiter_granted_ivc_all), |
.nonspec_first_arbiter_granted_ivc_all(nonspec_first_arbiter_granted_ivc_all), |
.granted_dest_port_all(granted_dest_port_all), |
.nonspec_granted_dest_port_all(nonspec_granted_dest_port_all), |
.any_ivc_sw_request_granted_all(any_ivc_sw_request_granted_all), |
.clk(clk), |
.reset(reset) |
); |
|
|
assign spec_granted_dest_port_all = {PP_1{1'bx}}; |
assign spec_ovc_num_all = {PVV{1'bx}}; |
end else if (COMBINATION_TYPE == "COMB_SPEC2") begin :spec2 |
end else if(COMBINATION_TYPE == "COMB_SPEC1") begin : spec1 |
|
comb_spec1_allocator #( |
.V(V), |
.P(P), |
.DEBUG_EN(DEBUG_EN) |
) |
the_comb_spec1 |
( |
.dest_port_all(dest_port_all), |
.masked_ovc_request_all(masked_ovc_request_all), |
.ovc_is_assigned_all(ovc_is_assigned_all), |
.ivc_request_all(ivc_request_all), |
.assigned_ovc_not_full_all(assigned_ovc_not_full_all), |
.ovc_allocated_all(ovc_allocated_all), |
.granted_ovc_num_all(granted_ovc_num_all), |
.ivc_num_getting_ovc_grant(ivc_num_getting_ovc_grant), |
.ivc_num_getting_sw_grant(ivc_num_getting_sw_grant), |
.spec_first_arbiter_granted_ivc_all(spec_first_arbiter_granted_ivc_all), |
.nonspec_first_arbiter_granted_ivc_all(nonspec_first_arbiter_granted_ivc_all), |
.granted_dest_port_all(granted_dest_port_all), |
.nonspec_granted_dest_port_all(nonspec_granted_dest_port_all), |
.any_ivc_sw_request_granted_all(any_ivc_sw_request_granted_all), |
.clk(clk), |
.reset(reset) |
); |
|
|
assign spec_granted_dest_port_all = {PP_1{1'bx}}; |
assign spec_ovc_num_all = {PVV{1'bx}}; |
end else if (COMBINATION_TYPE == "COMB_SPEC2") begin :spec2 |
|
comb_spec2_allocator #( |
.V(V), |
.P(P), |
.DEBUG_EN(DEBUG_EN) |
)the_comb_spec2 |
( |
.dest_port_all(dest_port_all), |
.masked_ovc_request_all(masked_ovc_request_all), |
.ovc_is_assigned_all(ovc_is_assigned_all), |
.ivc_request_all(ivc_request_all), |
.assigned_ovc_not_full_all(assigned_ovc_not_full_all), |
.ovc_allocated_all(ovc_allocated_all), |
.granted_ovc_num_all(granted_ovc_num_all), |
.ivc_num_getting_ovc_grant(ivc_num_getting_ovc_grant), |
.ivc_num_getting_sw_grant(ivc_num_getting_sw_grant), |
.spec_first_arbiter_granted_ivc_all(spec_first_arbiter_granted_ivc_all), |
.nonspec_first_arbiter_granted_ivc_all(nonspec_first_arbiter_granted_ivc_all), |
.granted_dest_port_all(granted_dest_port_all), |
.nonspec_granted_dest_port_all(nonspec_granted_dest_port_all), |
.any_ivc_sw_request_granted_all(any_ivc_sw_request_granted_all), |
.clk(clk), |
.reset(reset) |
); |
assign spec_granted_dest_port_all = {PP_1{1'bx}}; |
assign spec_ovc_num_all = {PVV{1'bx}}; |
comb_spec2_allocator #( |
.V(V), |
.P(P), |
.DEBUG_EN(DEBUG_EN) |
)the_comb_spec2 |
( |
.dest_port_all(dest_port_all), |
.masked_ovc_request_all(masked_ovc_request_all), |
.ovc_is_assigned_all(ovc_is_assigned_all), |
.ivc_request_all(ivc_request_all), |
.assigned_ovc_not_full_all(assigned_ovc_not_full_all), |
.ovc_allocated_all(ovc_allocated_all), |
.granted_ovc_num_all(granted_ovc_num_all), |
.ivc_num_getting_ovc_grant(ivc_num_getting_ovc_grant), |
.ivc_num_getting_sw_grant(ivc_num_getting_sw_grant), |
.spec_first_arbiter_granted_ivc_all(spec_first_arbiter_granted_ivc_all), |
.nonspec_first_arbiter_granted_ivc_all(nonspec_first_arbiter_granted_ivc_all), |
.granted_dest_port_all(granted_dest_port_all), |
.nonspec_granted_dest_port_all(nonspec_granted_dest_port_all), |
.any_ivc_sw_request_granted_all(any_ivc_sw_request_granted_all), |
.clk(clk), |
.reset(reset) |
); |
assign spec_granted_dest_port_all = {PP_1{1'bx}}; |
assign spec_ovc_num_all = {PVV{1'bx}}; |
|
|
end else begin : nonspec |
if(V>7)begin :cmb_v2 |
comb_nonspec_v2_allocator #( |
.V(V), |
.P(P), |
.FIRST_ARBITER_EXT_P_EN(FIRST_ARBITER_EXT_P_EN) |
)nonspec_comb |
( |
.dest_port_all(dest_port_all), |
.masked_ovc_request_all(masked_ovc_request_all), |
.ovc_is_assigned_all(ovc_is_assigned_all), |
.ivc_request_all(ivc_request_all), |
.assigned_ovc_not_full_all(assigned_ovc_not_full_all), |
.ovc_allocated_all(ovc_allocated_all), |
.granted_ovc_num_all(granted_ovc_num_all), |
.ivc_num_getting_ovc_grant(ivc_num_getting_ovc_grant), |
.ivc_num_getting_sw_grant(ivc_num_getting_sw_grant), |
.nonspec_first_arbiter_granted_ivc_all(nonspec_first_arbiter_granted_ivc_all), |
.granted_dest_port_all(granted_dest_port_all), |
.any_ivc_sw_request_granted_all(any_ivc_sw_request_granted_all), |
.any_ovc_granted_in_outport_all(any_ovc_granted_in_outport_all), |
.clk(clk), |
.reset(reset) |
); |
end else begin :cmb_v1 |
comb_nonspec_allocator #( |
.V(V), |
.P(P), |
.FIRST_ARBITER_EXT_P_EN(FIRST_ARBITER_EXT_P_EN) |
) |
nonspec_comb |
( |
.dest_port_all(dest_port_all), |
.masked_ovc_request_all(masked_ovc_request_all), |
.ovc_is_assigned_all(ovc_is_assigned_all), |
.ivc_request_all(ivc_request_all), |
.assigned_ovc_not_full_all(assigned_ovc_not_full_all), |
.ovc_allocated_all(ovc_allocated_all), |
.granted_ovc_num_all(granted_ovc_num_all), |
.ivc_num_getting_ovc_grant(ivc_num_getting_ovc_grant), |
.ivc_num_getting_sw_grant(ivc_num_getting_sw_grant), |
.nonspec_first_arbiter_granted_ivc_all(nonspec_first_arbiter_granted_ivc_all), |
.granted_dest_port_all(granted_dest_port_all), |
.any_ivc_sw_request_granted_all(any_ivc_sw_request_granted_all), |
.any_ovc_granted_in_outport_all(any_ovc_granted_in_outport_all), |
.lk_destination_all(lk_destination_all), |
.clk(clk), |
.reset(reset) |
); |
end |
assign nonspec_granted_dest_port_all = granted_dest_port_all; |
assign spec_granted_dest_port_all = {PP_1{1'bx}}; |
assign spec_ovc_num_all = {PVV{1'bx}}; |
assign spec_first_arbiter_granted_ivc_all = nonspec_first_arbiter_granted_ivc_all ; |
end |
|
end else begin : nonspec |
if(V>7)begin :cmb_v2 |
comb_nonspec_v2_allocator #( |
.V(V), |
.P(P), |
.FIRST_ARBITER_EXT_P_EN(FIRST_ARBITER_EXT_P_EN) |
)nonspec_comb |
( |
.dest_port_all(dest_port_all), |
.masked_ovc_request_all(masked_ovc_request_all), |
.ovc_is_assigned_all(ovc_is_assigned_all), |
.ivc_request_all(ivc_request_all), |
.assigned_ovc_not_full_all(assigned_ovc_not_full_all), |
.ovc_allocated_all(ovc_allocated_all), |
.granted_ovc_num_all(granted_ovc_num_all), |
.ivc_num_getting_ovc_grant(ivc_num_getting_ovc_grant), |
.ivc_num_getting_sw_grant(ivc_num_getting_sw_grant), |
.nonspec_first_arbiter_granted_ivc_all(nonspec_first_arbiter_granted_ivc_all), |
.granted_dest_port_all(granted_dest_port_all), |
.any_ivc_sw_request_granted_all(any_ivc_sw_request_granted_all), |
.any_ovc_granted_in_outport_all(any_ovc_granted_in_outport_all), |
.clk(clk), |
.reset(reset) |
); |
end else begin :cmb_v1 |
comb_nonspec_allocator #( |
.V(V), |
.P(P), |
.FIRST_ARBITER_EXT_P_EN(FIRST_ARBITER_EXT_P_EN) |
) |
nonspec_comb |
( |
.dest_port_all(dest_port_all), |
.masked_ovc_request_all(masked_ovc_request_all), |
.ovc_is_assigned_all(ovc_is_assigned_all), |
.ivc_request_all(ivc_request_all), |
.assigned_ovc_not_full_all(assigned_ovc_not_full_all), |
.ovc_allocated_all(ovc_allocated_all), |
.granted_ovc_num_all(granted_ovc_num_all), |
.ivc_num_getting_ovc_grant(ivc_num_getting_ovc_grant), |
.ivc_num_getting_sw_grant(ivc_num_getting_sw_grant), |
.nonspec_first_arbiter_granted_ivc_all(nonspec_first_arbiter_granted_ivc_all), |
.granted_dest_port_all(granted_dest_port_all), |
.any_ivc_sw_request_granted_all(any_ivc_sw_request_granted_all), |
.any_ovc_granted_in_outport_all(any_ovc_granted_in_outport_all), |
.lk_destination_all(lk_destination_all), |
.clk(clk), |
.reset(reset) |
); |
end |
assign nonspec_granted_dest_port_all = granted_dest_port_all; |
assign spec_granted_dest_port_all = {PP_1{1'bx}}; |
assign spec_ovc_num_all = {PVV{1'bx}}; |
assign spec_first_arbiter_granted_ivc_all = nonspec_first_arbiter_granted_ivc_all ; |
end |
endgenerate |
endmodule |
/src_noc/congestion_analyzer.v
24,12 → 24,13
port_pre_sel |
); |
|
|
function integer log2; |
input integer number; begin |
log2=0; |
log2=(number <=1) ? 1: 0; |
while(2**log2<number) begin |
log2=log2+1; |
end |
end |
end |
endfunction // log2 |
|
129,12 → 130,13
reset |
); |
|
function integer log2; |
|
function integer log2; |
input integer number; begin |
log2=0; |
log2=(number <=1) ? 1: 0; |
while(2**log2<number) begin |
log2=log2+1; |
end |
end |
end |
endfunction // log2 |
|
590,12 → 592,13
reset |
|
); |
function integer log2; |
|
function integer log2; |
input integer number; begin |
log2=0; |
log2=(number <=1) ? 1: 0; |
while(2**log2<number) begin |
log2=log2+1; |
end |
end |
end |
endfunction // log2 |
|
1055,12 → 1058,13
|
); |
|
|
function integer log2; |
input integer number; begin |
log2=0; |
log2=(number <=1) ? 1: 0; |
while(2**log2<number) begin |
log2=log2+1; |
end |
end |
end |
endfunction // log2 |
|
1182,12 → 1186,13
out |
|
); |
|
function integer log2; |
input integer number; begin |
log2=0; |
log2=(number <=1) ? 1: 0; |
while(2**log2<number) begin |
log2=log2+1; |
end |
end |
end |
endfunction // log2 |
|
1236,12 → 1241,13
|
); |
|
|
function integer log2; |
input integer number; begin |
log2=0; |
log2=(number <=1) ? 1: 0; |
while(2**log2<number) begin |
log2=log2+1; |
end |
end |
end |
endfunction // log2 |
|
1472,12 → 1478,13
|
); |
|
|
function integer log2; |
input integer number; begin |
log2=0; |
log2=(number <=1) ? 1: 0; |
while(2**log2<number) begin |
log2=log2+1; |
end |
end |
end |
endfunction // log2 |
|
/src_noc/credit_count.v
1,105 → 1,106
`timescale 1ns/1ps |
`timescale 1ns/1ps |
|
module credit_counter #( |
|
parameter V = 4, // vc_num_per_port |
parameter P = 5, // router port num |
parameter B = 4, // buffer space :flit per VC |
parameter VC_REALLOCATION_TYPE = "NONATOMIC",// "ATOMIC" , "NONATOMIC" |
parameter ROUTE_TYPE = "PAR_ADAPTIVE",// "DETERMINISTIC", "FULL_ADAPTIVE", "PAR_ADAPTIVE" |
parameter CONGESTION_INDEX = 2,//0,1,2 |
parameter [V-1 : 0] ESCAP_VC_MASK = 4'b0001, // mask scape vc, valid only for full adaptive |
parameter DEBUG_EN = 1, |
parameter AVC_ATOMIC_EN=0, |
parameter CONGw = 2 //congestion width per port |
|
parameter V = 4, // vc_num_per_port |
parameter P = 5, // router port num |
parameter B = 4, // buffer space :flit per VC |
parameter VC_REALLOCATION_TYPE = "NONATOMIC",// "ATOMIC" , "NONATOMIC" |
parameter ROUTE_TYPE = "PAR_ADAPTIVE",// "DETERMINISTIC", "FULL_ADAPTIVE", "PAR_ADAPTIVE" |
parameter CONGESTION_INDEX = 2,//0,1,2 |
parameter [V-1 : 0] ESCAP_VC_MASK = 4'b0001, // mask scape vc, valid only for full adaptive |
parameter DEBUG_EN = 1, |
parameter AVC_ATOMIC_EN=0, |
parameter CONGw = 2 //congestion width per port |
|
)( |
non_ss_ovc_allocated_all, |
flit_is_tail_all, |
assigned_ovc_num_all, |
ovc_is_assigned_all, |
dest_port_all, |
nonspec_granted_dest_port_all, |
credit_in_all, |
nonspec_first_arbiter_granted_ivc_all, |
ivc_num_getting_sw_grant, |
ovc_avalable_all, |
assigned_ovc_not_full_all, |
port_pre_sel, |
congestion_in_all, |
ssa_ovc_released_all, |
ssa_ovc_allocated_all, |
ssa_decreased_credit_in_ss_ovc_all, |
reset,clk |
non_ss_ovc_allocated_all, |
flit_is_tail_all, |
assigned_ovc_num_all, |
ovc_is_assigned_all, |
dest_port_all, |
nonspec_granted_dest_port_all, |
credit_in_all, |
nonspec_first_arbiter_granted_ivc_all, |
ivc_num_getting_sw_grant, |
ovc_avalable_all, |
assigned_ovc_not_full_all, |
port_pre_sel, |
congestion_in_all, |
ssa_ovc_released_all, |
ssa_ovc_allocated_all, |
ssa_decreased_credit_in_ss_ovc_all, |
reset,clk |
); |
|
function integer log2; |
input integer number; begin |
log2=0; |
while(2**log2<number) begin |
log2=log2+1; |
end |
end |
endfunction // log2 |
|
localparam PV = V * P, |
|
function integer log2; |
input integer number; begin |
log2=(number <=1) ? 1: 0; |
while(2**log2<number) begin |
log2=log2+1; |
end |
end |
endfunction // log2 |
|
localparam PV = V * P, |
VV = V * V, |
PVV = PV * V, |
P_1 = P-1 , |
VP_1 = V * P_1, |
PP_1 = P_1 * P, |
PVP_1 = PV * P_1, |
Bw = log2(B), |
B_1 = B-1; |
PVV = PV * V, |
P_1 = P-1 , |
VP_1 = V * P_1, |
PP_1 = P_1 * P, |
PVP_1 = PV * P_1, |
Bw = log2(B), |
B_1 = B-1; |
|
localparam [Bw-1 : 0] Bint = B_1[Bw-1 : 0]; |
localparam [Bw-1 : 0] Bint = B_1[Bw-1 : 0]; |
|
localparam NORTH = 3'd2, |
SOUTH = 3'd4; |
localparam [V-1 : 0] ADAPTIVE_VC_MASK = ~ ESCAP_VC_MASK; |
localparam CONG_ALw= CONGw * P; // congestion width per router; |
|
input [PV-1 : 0] non_ss_ovc_allocated_all; |
input [PV-1 : 0] flit_is_tail_all; |
input [PVV-1 : 0] assigned_ovc_num_all; |
input [PV-1 : 0] ovc_is_assigned_all; |
input [PVP_1-1 : 0] dest_port_all; |
input [PP_1-1 : 0] nonspec_granted_dest_port_all; |
input [PV-1 : 0] credit_in_all; |
input [PV-1 : 0] nonspec_first_arbiter_granted_ivc_all; |
input [PV-1 : 0] ivc_num_getting_sw_grant; |
output [PV-1 : 0] ovc_avalable_all; |
output [PV-1 : 0] assigned_ovc_not_full_all; |
input reset,clk; |
output [P_1-1 : 0] port_pre_sel; |
input [CONG_ALw-1 : 0] congestion_in_all; |
//ssa |
input [PV-1 : 0] ssa_ovc_released_all; |
input [PV-1 : 0] ssa_ovc_allocated_all; |
input [PV-1 : 0] ssa_decreased_credit_in_ss_ovc_all; |
|
|
reg [PV-1 : 0] ovc_status; |
reg [Bw-1 : 0] credit_counter [PV-1 : 0]; |
reg [Bw-1 : 0] credit_counter_next [PV-1 : 0]; |
reg [PV-1 : 0] full_all,nearly_full_all,full_all_next,nearly_full_all_next; |
|
wire [PV-1 : 0] assigned_ovc_is_full_all; |
wire [VP_1-1 : 0] credit_decreased [P-1 : 0]; |
wire [P_1-1 : 0] credit_decreased_gen [PV-1 : 0]; |
wire [PV-1 : 0] non_ss_credit_decreased_all; |
wire [PV-1 : 0] credit_increased_all; |
wire [VP_1-1 : 0] ovc_released [P-1 : 0]; |
wire [P_1-1 : 0] ovc_released_gen [PV-1 : 0]; |
wire [PV-1 : 0] non_ss_ovc_released_all; |
wire [VP_1-1 : 0] credit_in_perport [P-1 : 0]; |
wire [VP_1-1 : 0] full_perport [P-1 : 0]; |
wire [VP_1-1 : 0] nearly_full_perport [P-1 : 0]; |
|
|
//ssa |
|
wire [PV-1 : 0] credit_decreased_all; |
|
input [PV-1 : 0] non_ss_ovc_allocated_all; |
input [PV-1 : 0] flit_is_tail_all; |
input [PVV-1 : 0] assigned_ovc_num_all; |
input [PV-1 : 0] ovc_is_assigned_all; |
input [PVP_1-1 : 0] dest_port_all; |
input [PP_1-1 : 0] nonspec_granted_dest_port_all; |
input [PV-1 : 0] credit_in_all; |
input [PV-1 : 0] nonspec_first_arbiter_granted_ivc_all; |
input [PV-1 : 0] ivc_num_getting_sw_grant; |
output [PV-1 : 0] ovc_avalable_all; |
output [PV-1 : 0] assigned_ovc_not_full_all; |
input reset,clk; |
output [P_1-1 : 0] port_pre_sel; |
input [CONG_ALw-1 : 0] congestion_in_all; |
//ssa |
input [PV-1 : 0] ssa_ovc_released_all; |
input [PV-1 : 0] ssa_ovc_allocated_all; |
input [PV-1 : 0] ssa_decreased_credit_in_ss_ovc_all; |
|
|
reg [PV-1 : 0] ovc_status; |
reg [Bw-1 : 0] credit_counter [PV-1 : 0]; |
reg [Bw-1 : 0] credit_counter_next [PV-1 : 0]; |
reg [PV-1 : 0] full_all,nearly_full_all,full_all_next,nearly_full_all_next; |
|
wire [PV-1 : 0] assigned_ovc_is_full_all; |
wire [VP_1-1 : 0] credit_decreased [P-1 : 0]; |
wire [P_1-1 : 0] credit_decreased_gen [PV-1 : 0]; |
wire [PV-1 : 0] non_ss_credit_decreased_all; |
wire [PV-1 : 0] credit_increased_all; |
wire [VP_1-1 : 0] ovc_released [P-1 : 0]; |
wire [P_1-1 : 0] ovc_released_gen [PV-1 : 0]; |
wire [PV-1 : 0] non_ss_ovc_released_all; |
wire [VP_1-1 : 0] credit_in_perport [P-1 : 0]; |
wire [VP_1-1 : 0] full_perport [P-1 : 0]; |
wire [VP_1-1 : 0] nearly_full_perport [P-1 : 0]; |
|
|
//ssa |
|
wire [PV-1 : 0] credit_decreased_all; |
wire [PV-1 : 0] ovc_released_all; |
wire [PV-1 : 0] ovc_allocated_all; |
|
106,37 → 107,37
assign credit_decreased_all = non_ss_credit_decreased_all | ssa_decreased_credit_in_ss_ovc_all; |
assign ovc_released_all = non_ss_ovc_released_all | ssa_ovc_released_all; |
assign ovc_allocated_all = non_ss_ovc_allocated_all | ssa_ovc_allocated_all; |
|
|
integer k; |
genvar i,j; |
generate |
if(VC_REALLOCATION_TYPE=="ATOMIC") begin :atomic |
reg [PV-1 : 0] empty_all,empty_all_next; |
|
always @(posedge clk or posedge reset) begin |
if(reset) begin |
empty_all <= {PV{1'b0}}; |
end else begin |
empty_all <= empty_all_next; |
end |
end//always |
|
|
always @(*) begin |
for(k=0; k<PV; k=k+1'b1) begin |
empty_all_next[k] = (credit_counter_next[k] == Bint); |
end // for |
end//always |
|
// in atomic architecture an OVC is available if its not allocated and its empty |
assign ovc_avalable_all = ~ovc_status & empty_all; |
|
end else begin :nonatomic //NONATOMIC |
if(ROUTE_TYPE == "FULL_ADAPTIVE") begin :full_adpt |
|
|
|
integer k; |
genvar i,j; |
generate |
if(VC_REALLOCATION_TYPE=="ATOMIC") begin :atomic |
reg [PV-1 : 0] empty_all,empty_all_next; |
|
always @(posedge clk or posedge reset) begin |
if(reset) begin |
empty_all <= {PV{1'b0}}; |
end else begin |
empty_all <= empty_all_next; |
end |
end//always |
|
|
always @(*) begin |
for(k=0; k<PV; k=k+1'b1) begin |
empty_all_next[k] = (credit_counter_next[k] == Bint); |
end // for |
end//always |
|
// in atomic architecture an OVC is available if its not allocated and its empty |
assign ovc_avalable_all = ~ovc_status & empty_all; |
|
end else begin :nonatomic //NONATOMIC |
if(ROUTE_TYPE == "FULL_ADAPTIVE") begin :full_adpt |
|
reg [PV-1 : 0] full_adaptive_ovc_mask,full_adaptive_ovc_mask_next; |
|
|
|
|
|
159,128 → 160,128
end // for |
end//always |
|
|
always @(posedge clk or posedge reset) begin |
if(reset) begin |
|
always @(posedge clk or posedge reset) begin |
if(reset) begin |
full_adaptive_ovc_mask <= {PV{1'b0}}; |
end else begin |
full_adaptive_ovc_mask <= full_adaptive_ovc_mask_next; |
end |
end else begin |
full_adaptive_ovc_mask <= full_adaptive_ovc_mask_next; |
end |
end//always |
|
assign ovc_avalable_all = ~ovc_status & full_adaptive_ovc_mask; |
|
end else begin : par_adpt//par adaptive |
assign ovc_avalable_all = ~(ovc_status | nearly_full_all); |
end |
end //NONATOMIC |
endgenerate |
|
|
assign credit_increased_all = credit_in_all; |
assign assigned_ovc_not_full_all = ~ assigned_ovc_is_full_all; |
|
|
|
generate |
for(i=0;i<P;i=i+1 ) begin :port_lp |
|
inport_module #( |
.V (V), // vc_num_per_port |
.P (P) // router port num |
)the_inport_module |
( |
.flit_is_tail (flit_is_tail_all [(i+1)*V-1 :i*V]), |
.assigned_ovc_num (assigned_ovc_num_all [(i+1)*VV-1 :i*VV]), |
.ovc_is_assigned (ovc_is_assigned_all [(i+1)*V-1 :i*V]), |
.granted_dest_port (nonspec_granted_dest_port_all [(i+1)*P_1-1 :i*P_1]), |
.first_arbiter_granted_ivc (nonspec_first_arbiter_granted_ivc_all [(i+1)*V-1 :i*V]), |
.credit_decreased (credit_decreased [i]), |
.ovc_released (ovc_released [i]) |
|
); |
|
assign ovc_avalable_all = ~ovc_status & full_adaptive_ovc_mask; |
|
end else begin : par_adpt//par adaptive |
assign ovc_avalable_all = ~(ovc_status | nearly_full_all); |
end |
end //NONATOMIC |
endgenerate |
|
|
assign credit_increased_all = credit_in_all; |
assign assigned_ovc_not_full_all = ~ assigned_ovc_is_full_all; |
|
|
|
generate |
for(i=0;i<P;i=i+1 ) begin :port_lp |
|
inport_module #( |
.V (V), // vc_num_per_port |
.P (P) // router port num |
)the_inport_module |
( |
.flit_is_tail (flit_is_tail_all [(i+1)*V-1 :i*V]), |
.assigned_ovc_num (assigned_ovc_num_all [(i+1)*VV-1 :i*VV]), |
.ovc_is_assigned (ovc_is_assigned_all [(i+1)*V-1 :i*V]), |
.granted_dest_port (nonspec_granted_dest_port_all [(i+1)*P_1-1 :i*P_1]), |
.first_arbiter_granted_ivc (nonspec_first_arbiter_granted_ivc_all [(i+1)*V-1 :i*V]), |
.credit_decreased (credit_decreased [i]), |
.ovc_released (ovc_released [i]) |
|
); |
|
end//for |
|
|
|
for(i=0;i< PV;i=i+1) begin :total_vc_loop2 |
for(j=0;j<P; j=j+1)begin: assign_loop2 |
if((i/V)<j )begin: jj |
assign ovc_released_gen [i][j-1] = ovc_released[j][i]; |
assign credit_decreased_gen[i][j-1] = credit_decreased [j][i]; |
end else if((i/V)>j) begin: hh |
assign ovc_released_gen [i][j] = ovc_released[j][i-V]; |
assign credit_decreased_gen[i][j] = credit_decreased[j][i-V]; |
end |
end//j |
assign non_ss_ovc_released_all [i] = |ovc_released_gen[i]; |
assign non_ss_credit_decreased_all [i] = (|credit_decreased_gen[i])|non_ss_ovc_allocated_all[i]; |
end//i |
|
|
end//for |
|
|
|
for(i=0;i< PV;i=i+1) begin :total_vc_loop2 |
for(j=0;j<P; j=j+1)begin: assign_loop2 |
if((i/V)<j )begin: jj |
assign ovc_released_gen [i][j-1] = ovc_released[j][i]; |
assign credit_decreased_gen[i][j-1] = credit_decreased [j][i]; |
end else if((i/V)>j) begin: hh |
assign ovc_released_gen [i][j] = ovc_released[j][i-V]; |
assign credit_decreased_gen[i][j] = credit_decreased[j][i-V]; |
end |
end//j |
assign non_ss_ovc_released_all [i] = |ovc_released_gen[i]; |
assign non_ss_credit_decreased_all [i] = (|credit_decreased_gen[i])|non_ss_ovc_allocated_all[i]; |
end//i |
|
|
|
|
|
//remove source port from the list |
for(i=0;i< P;i=i+1) begin :port_loop |
if(i==0) begin :i0 |
assign credit_in_perport [i]=credit_in_all [PV-1 : V]; |
assign full_perport [i]=full_all [PV-1 : V]; |
assign nearly_full_perport [i]=nearly_full_all [PV-1 : V]; |
end else if(i==(P-1)) begin :ip_1 |
assign credit_in_perport [i]=credit_in_all [PV-V-1 : 0]; |
assign full_perport [i]=full_all [PV-V-1 : 0]; |
assign nearly_full_perport [i]=nearly_full_all [PV-V-1 : 0]; |
end else begin : els |
assign credit_in_perport [i]={credit_in_all [PV-1 : (i+1)*V],credit_in_all [(i*V)-1 : 0]}; |
assign full_perport [i]={full_all [PV-1 : (i+1)*V],full_all [(i*V)-1 : 0]}; |
assign nearly_full_perport [i]={nearly_full_all [PV-1 : (i+1)*V],nearly_full_all[(i*V)-1 : 0]}; |
end |
end//for |
|
|
|
for(i=0;i< PV;i=i+1) begin :PV_loop2 |
sw_mask_gen #( |
.V (V), // vc_num_per_port |
.P (P) // router port num |
|
)sw_mask |
( |
.assigned_ovc_num (assigned_ovc_num_all[(i+1)*V-1 :i*V]), |
.dest_port (dest_port_all [(i+1)*P_1-1 :i*P_1]), |
.full (full_perport [i/V]), |
.credit_increased (credit_in_perport [i/V]), |
.nearly_full (nearly_full_perport [i/V]), |
.ivc_getting_sw_grant (ivc_num_getting_sw_grant[i]), |
.assigned_ovc_is_full (assigned_ovc_is_full_all[i]), |
.clk (clk), |
.reset (reset) |
); |
end//for |
|
for(i=0; i<PV; i=i+1) begin :reg_blk |
always @(posedge clk or posedge reset) begin |
if(reset) begin |
credit_counter[i] <= Bint; |
ovc_status[i] <= 1'b0; |
full_all[i] <= 1'b0; |
nearly_full_all[i]<= 1'b0; |
end else begin |
credit_counter[i] <= credit_counter_next[i]; |
full_all[i] <= full_all_next[i]; |
nearly_full_all[i]<= nearly_full_all_next[i]; |
if(ovc_released_all[i]) ovc_status[i]<=1'b0; |
if(ovc_allocated_all[i]) ovc_status[i]<=1'b1; |
end |
end |
end//for |
|
|
|
endgenerate |
|
|
|
//remove source port from the list |
for(i=0;i< P;i=i+1) begin :port_loop |
if(i==0) begin :i0 |
assign credit_in_perport [i]=credit_in_all [PV-1 : V]; |
assign full_perport [i]=full_all [PV-1 : V]; |
assign nearly_full_perport [i]=nearly_full_all [PV-1 : V]; |
end else if(i==(P-1)) begin :ip_1 |
assign credit_in_perport [i]=credit_in_all [PV-V-1 : 0]; |
assign full_perport [i]=full_all [PV-V-1 : 0]; |
assign nearly_full_perport [i]=nearly_full_all [PV-V-1 : 0]; |
end else begin : els |
assign credit_in_perport [i]={credit_in_all [PV-1 : (i+1)*V],credit_in_all [(i*V)-1 : 0]}; |
assign full_perport [i]={full_all [PV-1 : (i+1)*V],full_all [(i*V)-1 : 0]}; |
assign nearly_full_perport [i]={nearly_full_all [PV-1 : (i+1)*V],nearly_full_all[(i*V)-1 : 0]}; |
end |
end//for |
|
|
|
for(i=0;i< PV;i=i+1) begin :PV_loop2 |
sw_mask_gen #( |
.V (V), // vc_num_per_port |
.P (P) // router port num |
|
)sw_mask |
( |
.assigned_ovc_num (assigned_ovc_num_all[(i+1)*V-1 :i*V]), |
.dest_port (dest_port_all [(i+1)*P_1-1 :i*P_1]), |
.full (full_perport [i/V]), |
.credit_increased (credit_in_perport [i/V]), |
.nearly_full (nearly_full_perport [i/V]), |
.ivc_getting_sw_grant (ivc_num_getting_sw_grant[i]), |
.assigned_ovc_is_full (assigned_ovc_is_full_all[i]), |
.clk (clk), |
.reset (reset) |
); |
end//for |
|
for(i=0; i<PV; i=i+1) begin :reg_blk |
always @(posedge clk or posedge reset) begin |
if(reset) begin |
credit_counter[i] <= Bint; |
ovc_status[i] <= 1'b0; |
full_all[i] <= 1'b0; |
nearly_full_all[i]<= 1'b0; |
end else begin |
credit_counter[i] <= credit_counter_next[i]; |
full_all[i] <= full_all_next[i]; |
nearly_full_all[i]<= nearly_full_all_next[i]; |
if(ovc_released_all[i]) ovc_status[i]<=1'b0; |
if(ovc_allocated_all[i]) ovc_status[i]<=1'b1; |
end |
end |
end//for |
|
|
|
endgenerate |
|
|
port_pre_sel_gen #( |
.P(P), |
304,99 → 305,99
.clk(clk) |
|
); |
|
|
|
|
|
always @(*) begin |
for(k=0; k<PV; k=k+1'b1) begin |
credit_counter_next[k] = credit_counter[k]; |
if(credit_increased_all[k] & ~credit_decreased_all[k]) begin |
credit_counter_next[k] = credit_counter[k]+1'b1; |
end else if (~credit_increased_all[k] & credit_decreased_all[k])begin |
credit_counter_next[k] = credit_counter[k]-1'b1; |
end |
end |
end |
|
always @(*) begin |
for(k=0; k<PV; k=k+1'b1) begin |
full_all_next[k] = credit_counter_next[k] == {Bw{1'b0}}; |
nearly_full_all_next[k] = credit_counter_next[k] <= 1; |
end |
end |
|
|
always @(*) begin |
for(k=0; k<PV; k=k+1'b1) begin |
credit_counter_next[k] = credit_counter[k]; |
if(credit_increased_all[k] & ~credit_decreased_all[k]) begin |
credit_counter_next[k] = credit_counter[k]+1'b1; |
end else if (~credit_increased_all[k] & credit_decreased_all[k])begin |
credit_counter_next[k] = credit_counter[k]-1'b1; |
end |
end |
end |
|
always @(*) begin |
for(k=0; k<PV; k=k+1'b1) begin |
full_all_next[k] = credit_counter_next[k] == {Bw{1'b0}}; |
nearly_full_all_next[k] = credit_counter_next[k] <= 1; |
end |
end |
|
|
|
|
//synthesis translate_off |
//synopsys translate_off |
//synthesis translate_off |
//synopsys translate_off |
generate |
if(DEBUG_EN) begin: debug |
always @(posedge clk or posedge reset ) begin |
if(reset )begin |
always @(posedge clk or posedge reset ) begin |
if(reset )begin |
|
end else begin |
for(k=0; k<PV; k=k+1'b1) begin |
if(credit_counter[k]== Bint && credit_increased_all[k]) |
$display("%t: ERROR: unexpected credit recived for empty ovc[%d]: %m",$time,k); |
if(credit_counter[k]== {Bw{1'b0}} && credit_decreased_all[k]) |
$display("%t: ERROR: Attempt to send flit to full ovc[%d]: %m",$time,k); |
if(ovc_released_all[k] && ovc_allocated_all[k]) |
$display("%t: ERROR: simultaneous allocation and release for an OVC[%d]: %m",$time,k); |
if(ovc_released_all[k] && ovc_status[k]==1'b0) |
$display("%t: ERROR: Attempt to release an unallocated OVC[%d]: %m",$time,k); |
if(ovc_allocated_all[k] && ovc_status[k]==1'b1) |
$display("%t: ERROR: Attempt to allocate an allocated OVC[%d]: %m",$time,k); |
end//for |
end |
end//always |
|
localparam NUM_WIDTH = log2(PV+1); |
wire [NUM_WIDTH-1 : 0] num1,num2; |
parallel_counter #( |
.IN_WIDTH(PV) |
)cnt1 |
( |
.in (ovc_status), |
.out (num1) |
); |
end else begin |
for(k=0; k<PV; k=k+1'b1) begin |
if(credit_counter[k]== Bint && credit_increased_all[k]) |
$display("%t: ERROR: unexpected credit recived for empty ovc[%d]: %m",$time,k); |
if(credit_counter[k]== {Bw{1'b0}} && credit_decreased_all[k]) |
$display("%t: ERROR: Attempt to send flit to full ovc[%d]: %m",$time,k); |
if(ovc_released_all[k] && ovc_allocated_all[k]) |
$display("%t: ERROR: simultaneous allocation and release for an OVC[%d]: %m",$time,k); |
if(ovc_released_all[k] && ovc_status[k]==1'b0) |
$display("%t: ERROR: Attempt to release an unallocated OVC[%d]: %m",$time,k); |
if(ovc_allocated_all[k] && ovc_status[k]==1'b1) |
$display("%t: ERROR: Attempt to allocate an allocated OVC[%d]: %m",$time,k); |
end//for |
end |
end//always |
|
localparam NUM_WIDTH = log2(PV+1); |
wire [NUM_WIDTH-1 : 0] num1,num2; |
parallel_counter #( |
.IN_WIDTH(PV) |
)cnt1 |
( |
.in (ovc_status), |
.out (num1) |
); |
|
parallel_counter #( |
.IN_WIDTH(PV) |
)cnt2 |
( |
.in (ovc_is_assigned_all), |
.out (num2) |
); |
|
always @(posedge clk) begin |
if(num1 != num2 ) $display("%t: ERROR: number of assigned IVC mismatch the number of occupied OVC: %m",$time); |
end |
|
|
|
parallel_counter #( |
.IN_WIDTH(PV) |
)cnt2 |
( |
.in (ovc_is_assigned_all), |
.out (num2) |
); |
|
always @(posedge clk) begin |
if(num1 != num2 ) $display("%t: ERROR: number of assigned IVC mismatch the number of occupied OVC: %m",$time); |
end |
|
|
|
|
check_ovc #( |
.V(V) , // vc_num_per_port |
.P(P) // router port num |
|
)test |
( |
.ovc_status(ovc_status), |
.assigned_ovc_num_all(assigned_ovc_num_all), |
.ovc_is_assigned_all(ovc_is_assigned_all), |
.dest_port_all(dest_port_all), |
.clk(clk), |
.reset(reset) |
); |
check_ovc #( |
.V(V) , // vc_num_per_port |
.P(P) // router port num |
|
)test |
( |
.ovc_status(ovc_status), |
.assigned_ovc_num_all(assigned_ovc_num_all), |
.ovc_is_assigned_all(ovc_is_assigned_all), |
.dest_port_all(dest_port_all), |
.clk(clk), |
.reset(reset) |
); |
|
end// DEBUG |
endgenerate |
//synthesis translate_on |
//synopsys translate_on |
|
|
//synthesis translate_on |
//synopsys translate_on |
|
|
endmodule |
|
|
404,197 → 405,197
|
/************************************ |
|
inport_module |
|
inport_module |
|
|
*************************************/ |
module inport_module #( |
parameter V = 4, // vc_num_per_port |
parameter P = 5 // router port num |
parameter V = 4, // vc_num_per_port |
parameter P = 5 // router port num |
)( |
flit_is_tail, |
assigned_ovc_num, |
ovc_is_assigned, |
granted_dest_port, |
first_arbiter_granted_ivc, |
credit_decreased, |
ovc_released |
|
); |
|
localparam VV = V * V, |
P_1 = P-1 , |
VP_1 = V * P_1; |
|
|
input [V-1 : 0] flit_is_tail; |
input [VV-1 : 0] assigned_ovc_num; |
input [V-1 : 0] ovc_is_assigned; |
input [P_1-1 : 0] granted_dest_port; |
input [V-1 : 0] first_arbiter_granted_ivc; |
output [VP_1-1 : 0] credit_decreased; |
output [VP_1-1 : 0] ovc_released; |
|
|
|
wire [V-1 : 0] muxout1; |
wire muxout2; |
|
wire [VV-1 : 0] assigned_ovc_num_masked; |
genvar i; |
generate |
for (i=0;i<V;i=i+1)begin: mask_lp |
assign assigned_ovc_num_masked[(i+1)*V-1 : i*V] = ovc_is_assigned[i]? assigned_ovc_num [(i+1)*V-1 : i*V] : {V{1'b0}}; |
end |
endgenerate |
|
|
|
|
// assigned ovc mux |
one_hot_mux #( |
.IN_WIDTH (VV), |
.SEL_WIDTH (V) |
)assigned_ovc_mux |
( |
.mux_in (assigned_ovc_num_masked), |
.mux_out (muxout1), |
.sel (first_arbiter_granted_ivc) |
); |
|
// tail mux |
one_hot_mux #( |
.IN_WIDTH (V), |
.SEL_WIDTH (V) |
)tail_mux |
( |
.mux_in (flit_is_tail), |
.mux_out (muxout2), |
.sel (first_arbiter_granted_ivc) |
); |
|
|
one_hot_demux #( |
.IN_WIDTH (V), |
.SEL_WIDTH (P_1) |
|
) demux |
( |
.demux_sel (granted_dest_port),//selectore |
.demux_in (muxout1),//repeated |
.demux_out (credit_decreased) |
); |
|
assign ovc_released = (muxout2)? credit_decreased : {VP_1{1'b0}}; |
|
|
flit_is_tail, |
assigned_ovc_num, |
ovc_is_assigned, |
granted_dest_port, |
first_arbiter_granted_ivc, |
credit_decreased, |
ovc_released |
|
); |
|
localparam VV = V * V, |
P_1 = P-1 , |
VP_1 = V * P_1; |
|
|
input [V-1 : 0] flit_is_tail; |
input [VV-1 : 0] assigned_ovc_num; |
input [V-1 : 0] ovc_is_assigned; |
input [P_1-1 : 0] granted_dest_port; |
input [V-1 : 0] first_arbiter_granted_ivc; |
output [VP_1-1 : 0] credit_decreased; |
output [VP_1-1 : 0] ovc_released; |
|
|
|
wire [V-1 : 0] muxout1; |
wire muxout2; |
|
wire [VV-1 : 0] assigned_ovc_num_masked; |
genvar i; |
generate |
for (i=0;i<V;i=i+1)begin: mask_lp |
assign assigned_ovc_num_masked[(i+1)*V-1 : i*V] = ovc_is_assigned[i]? assigned_ovc_num [(i+1)*V-1 : i*V] : {V{1'b0}}; |
end |
endgenerate |
|
|
|
|
// assigned ovc mux |
one_hot_mux #( |
.IN_WIDTH (VV), |
.SEL_WIDTH (V) |
)assigned_ovc_mux |
( |
.mux_in (assigned_ovc_num_masked), |
.mux_out (muxout1), |
.sel (first_arbiter_granted_ivc) |
); |
|
// tail mux |
one_hot_mux #( |
.IN_WIDTH (V), |
.SEL_WIDTH (V) |
)tail_mux |
( |
.mux_in (flit_is_tail), |
.mux_out (muxout2), |
.sel (first_arbiter_granted_ivc) |
); |
|
|
one_hot_demux #( |
.IN_WIDTH (V), |
.SEL_WIDTH (P_1) |
|
) demux |
( |
.demux_sel (granted_dest_port),//selectore |
.demux_in (muxout1),//repeated |
.demux_out (credit_decreased) |
); |
|
assign ovc_released = (muxout2)? credit_decreased : {VP_1{1'b0}}; |
|
|
endmodule |
|
|
/********************************** |
|
sw_mask_gen |
sw_mask_gen |
|
*********************************/ |
|
module sw_mask_gen #( |
parameter V = 4, // vc_num_per_port |
parameter P = 5 // router port num |
|
parameter V = 4, // vc_num_per_port |
parameter P = 5 // router port num |
|
)( |
assigned_ovc_num, |
dest_port, |
full, |
credit_increased, |
nearly_full, |
ivc_getting_sw_grant, |
assigned_ovc_is_full, |
clk,reset |
assigned_ovc_num, |
dest_port, |
full, |
credit_increased, |
nearly_full, |
ivc_getting_sw_grant, |
assigned_ovc_is_full, |
clk,reset |
); |
localparam P_1 = P-1 , |
VP_1 = V * P_1; |
|
input [V-1 : 0] assigned_ovc_num; |
input [P_1-1 : 0] dest_port; |
input [VP_1-1 : 0] full; |
input [VP_1-1 : 0] credit_increased; |
input [VP_1-1 : 0] nearly_full; |
input ivc_getting_sw_grant; |
output assigned_ovc_is_full; |
input clk,reset; |
localparam P_1 = P-1 , |
VP_1 = V * P_1; |
|
input [V-1 : 0] assigned_ovc_num; |
input [P_1-1 : 0] dest_port; |
input [VP_1-1 : 0] full; |
input [VP_1-1 : 0] credit_increased; |
input [VP_1-1 : 0] nearly_full; |
input ivc_getting_sw_grant; |
output assigned_ovc_is_full; |
input clk,reset; |
|
|
wire [VP_1-1 : 0] full_muxin1,nearly_full_muxin1; |
wire [V-1 : 0] full_muxout1,nearly_full_muxout1; |
wire full_muxout2,nearly_full_muxout2; |
reg full_reg1,full_reg1_next; |
reg full_reg2,full_reg2_next; |
|
|
assign full_muxin1 = full & (~credit_increased); |
assign nearly_full_muxin1 = nearly_full & (~credit_increased); |
|
|
// destport mux |
one_hot_mux #( |
.IN_WIDTH (VP_1), |
.SEL_WIDTH (P_1) |
)full_mux1 |
( |
.mux_in (full_muxin1), |
.mux_out (full_muxout1), |
.sel (dest_port) |
); |
|
one_hot_mux #( |
.IN_WIDTH (VP_1), |
.SEL_WIDTH (P_1) |
)nearly_full_mux1 |
( |
.mux_in (nearly_full_muxin1), |
.mux_out (nearly_full_muxout1), |
.sel (dest_port) |
); |
|
// assigned ovc mux |
one_hot_mux #( |
.IN_WIDTH (V), |
.SEL_WIDTH (V) |
)full_mux2 |
( |
.mux_in (full_muxout1), |
.mux_out (full_muxout2), |
.sel (assigned_ovc_num) |
); |
|
|
one_hot_mux #( |
.IN_WIDTH (V), |
.SEL_WIDTH (V) |
)nearlfull_mux2 |
( |
.mux_in (nearly_full_muxout1), |
.mux_out (nearly_full_muxout2), |
.sel (assigned_ovc_num) |
); |
|
always @(*) begin |
full_reg1_next = full_muxout2; |
full_reg2_next = nearly_full_muxout2 & ivc_getting_sw_grant; |
end |
|
always @(posedge clk or posedge reset) begin |
if(reset) begin |
full_reg1 <= 1'b0; |
full_reg2 <= 1'b0; |
end else begin |
full_reg1 <= full_reg1_next; |
full_reg2 <= full_reg2_next; |
end |
end//always |
|
assign assigned_ovc_is_full = full_reg1 | full_reg2; |
|
wire [VP_1-1 : 0] full_muxin1,nearly_full_muxin1; |
wire [V-1 : 0] full_muxout1,nearly_full_muxout1; |
wire full_muxout2,nearly_full_muxout2; |
reg full_reg1,full_reg1_next; |
reg full_reg2,full_reg2_next; |
|
|
assign full_muxin1 = full & (~credit_increased); |
assign nearly_full_muxin1 = nearly_full & (~credit_increased); |
|
|
// destport mux |
one_hot_mux #( |
.IN_WIDTH (VP_1), |
.SEL_WIDTH (P_1) |
)full_mux1 |
( |
.mux_in (full_muxin1), |
.mux_out (full_muxout1), |
.sel (dest_port) |
); |
|
one_hot_mux #( |
.IN_WIDTH (VP_1), |
.SEL_WIDTH (P_1) |
)nearly_full_mux1 |
( |
.mux_in (nearly_full_muxin1), |
.mux_out (nearly_full_muxout1), |
.sel (dest_port) |
); |
|
// assigned ovc mux |
one_hot_mux #( |
.IN_WIDTH (V), |
.SEL_WIDTH (V) |
)full_mux2 |
( |
.mux_in (full_muxout1), |
.mux_out (full_muxout2), |
.sel (assigned_ovc_num) |
); |
|
|
one_hot_mux #( |
.IN_WIDTH (V), |
.SEL_WIDTH (V) |
)nearlfull_mux2 |
( |
.mux_in (nearly_full_muxout1), |
.mux_out (nearly_full_muxout2), |
.sel (assigned_ovc_num) |
); |
|
always @(*) begin |
full_reg1_next = full_muxout2; |
full_reg2_next = nearly_full_muxout2 & ivc_getting_sw_grant; |
end |
|
always @(posedge clk or posedge reset) begin |
if(reset) begin |
full_reg1 <= 1'b0; |
full_reg2 <= 1'b0; |
end else begin |
full_reg1 <= full_reg1_next; |
full_reg2 <= full_reg2_next; |
end |
end//always |
|
assign assigned_ovc_is_full = full_reg1 | full_reg2; |
|
endmodule |
|
|
601,75 → 602,75
//synthesis translate_off |
//synopsys translate_off |
module check_ovc #( |
parameter V = 4, // vc_num_per_port |
parameter P = 5 // router port num |
|
parameter V = 4, // vc_num_per_port |
parameter P = 5 // router port num |
|
)( |
ovc_status, |
assigned_ovc_num_all, |
ovc_is_assigned_all, |
dest_port_all, |
clk, |
reset |
ovc_status, |
assigned_ovc_num_all, |
ovc_is_assigned_all, |
dest_port_all, |
clk, |
reset |
); |
|
localparam PV = V * P, |
PVV = PV * V, |
P_1 = P-1 , |
PVP_1 = PV * P_1; |
localparam PV = V * P, |
PVV = PV * V, |
P_1 = P-1 , |
PVP_1 = PV * P_1; |
|
|
input [PV-1 : 0] ovc_status; |
input [PVV-1 : 0] assigned_ovc_num_all; |
input [PV-1 : 0] ovc_is_assigned_all; |
input [PVP_1-1 : 0] dest_port_all; |
input clk,reset; |
|
wire [V-1 : 0] assigned_ovc_num [PV-1 : 0]; |
wire [P_1-1 : 0] destport_sel [PV-1 : 0]; |
wire [P-1 : 0] destport_num [PV-1 : 0]; |
|
wire [PV-1 : 0] ovc_num [PV-1 : 0]; |
genvar i; |
generate |
for(i=0; i<PV;i=i+1) begin :lp_pv |
assign assigned_ovc_num [i]= (ovc_is_assigned_all[i])? assigned_ovc_num_all[(i+1)*V-1 : i*V]: 0; |
assign destport_sel [i]= dest_port_all[(i+1)*P_1-1 : i*P_1]; |
|
add_sw_loc_one_hot #( |
.P(P), |
input [PV-1 : 0] ovc_status; |
input [PVV-1 : 0] assigned_ovc_num_all; |
input [PV-1 : 0] ovc_is_assigned_all; |
input [PVP_1-1 : 0] dest_port_all; |
input clk,reset; |
|
wire [V-1 : 0] assigned_ovc_num [PV-1 : 0]; |
wire [P_1-1 : 0] destport_sel [PV-1 : 0]; |
wire [P-1 : 0] destport_num [PV-1 : 0]; |
|
wire [PV-1 : 0] ovc_num [PV-1 : 0]; |
genvar i; |
generate |
for(i=0; i<PV;i=i+1) begin :lp_pv |
assign assigned_ovc_num [i]= (ovc_is_assigned_all[i])? assigned_ovc_num_all[(i+1)*V-1 : i*V]: 0; |
assign destport_sel [i]= dest_port_all[(i+1)*P_1-1 : i*P_1]; |
|
add_sw_loc_one_hot #( |
.P(P), |
.SW_LOC(i/V) |
) |
add_sw_loc |
( |
.destport_in(destport_sel[i]), |
.destport_out(destport_num[i]) |
); |
|
|
|
|
|
one_hot_demux #( |
.IN_WIDTH (V), |
.SEL_WIDTH (P) |
|
) demux |
( |
.demux_sel (destport_num[i]),//selectore |
.demux_in (assigned_ovc_num[i]),//repeated |
.demux_out (ovc_num[i]) |
); |
always @(posedge clk)begin |
if(ovc_status >0 && ovc_num[i] >0 && (ovc_num[i] & ovc_status)==0) $display ("%t :Error: OVC status%d missmatch:%b & %b, %m ",$time,i,ovc_num[i] , ovc_status); |
end |
|
|
end//for |
endgenerate |
|
|
|
) |
add_sw_loc |
( |
.destport_in(destport_sel[i]), |
.destport_out(destport_num[i]) |
); |
|
|
|
|
|
one_hot_demux #( |
.IN_WIDTH (V), |
.SEL_WIDTH (P) |
|
) demux |
( |
.demux_sel (destport_num[i]),//selectore |
.demux_in (assigned_ovc_num[i]),//repeated |
.demux_out (ovc_num[i]) |
); |
always @(posedge clk)begin |
if(ovc_status >0 && ovc_num[i] >0 && (ovc_num[i] & ovc_status)==0) $display ("%t :Error: OVC status%d missmatch:%b & %b, %m ",$time,i,ovc_num[i] , ovc_status); |
end |
|
|
end//for |
endgenerate |
|
|
|
|
endmodule |
//synopsys translate_on |
/src_noc/crossbar.v
1,87 → 1,89
`timescale 1ns/1ps |
`timescale 1ns/1ps |
|
module crossbar #( |
parameter V = 4, // vc_num_per_port |
parameter P = 5, // router port num |
parameter Fpay = 32, |
parameter MUX_TYPE="BINARY", //"ONE_HOT" or "BINARY" |
parameter ADD_PIPREG_AFTER_CROSSBAR=0, |
parameter SSA_EN="YES" // "YES" , "NO" |
parameter V = 4, // vc_num_per_port |
parameter P = 5, // router port num |
parameter Fpay = 32, |
parameter MUX_TYPE="BINARY", //"ONE_HOT" or "BINARY" |
parameter ADD_PIPREG_AFTER_CROSSBAR=0, |
parameter SSA_EN="YES" // "YES" , "NO" |
) |
( |
granted_dest_port_all, |
flit_in_all, |
flit_out_all, |
flit_out_we_all, |
ssa_flit_wr_all, |
clk, |
reset |
granted_dest_port_all, |
flit_in_all, |
flit_out_all, |
flit_out_we_all, |
ssa_flit_wr_all, |
clk, |
reset |
|
); |
|
function integer log2; |
input integer number; begin |
log2=0; |
while(2**log2<number) begin |
log2=log2+1; |
end |
end |
endfunction // log2 |
|
localparam PV = V * P, |
VV = V * V, |
PP = P * P, |
PVV = PV * V, |
P_1 = P-1 , |
VP_1 = V * P_1, |
PP_1 = P_1 * P, |
PVP_1 = PV * P_1; |
); |
|
|
localparam Fw = 2+V+Fpay, //flit width; |
PFw = P*Fw, |
P_1Fw = P_1 * Fw, |
P_1w = log2(P_1); |
|
|
input [PP_1-1 : 0] granted_dest_port_all; |
input [PFw-1 : 0] flit_in_all; |
output reg [PFw-1 : 0] flit_out_all; |
output reg [P-1 : 0] flit_out_we_all; |
input [P-1 : 0] ssa_flit_wr_all; |
input reset,clk; |
|
|
|
wire [PFw-1 : 0] flit_out_all_internal; |
wire [P-1 : 0] flit_out_we_all_internal,flit_we_mux_out; |
wire [P_1-1 : 0] granted_dest_port [P-1 : 0]; |
wire [P_1Fw-1 : 0] mux_in [P-1 : 0]; |
wire [P_1-1 : 0] mux_sel_pre [P-1 : 0]; |
wire [P_1-1 : 0] mux_sel [P-1 : 0]; |
wire [P_1w-1 : 0] mux_sel_bin [P-1 : 0]; |
wire [PP-1 : 0] flit_out_we_gen; |
|
genvar i,j; |
generate |
function integer log2; |
input integer number; begin |
log2=(number <=1) ? 1: 0; |
while(2**log2<number) begin |
log2=log2+1; |
end |
end |
endfunction // log2 |
|
localparam PV = V * P, |
VV = V * V, |
PP = P * P, |
PVV = PV * V, |
P_1 = P-1 , |
VP_1 = V * P_1, |
PP_1 = P_1 * P, |
PVP_1 = PV * P_1; |
|
localparam Fw = 2+V+Fpay, //flit width; |
PFw = P*Fw, |
P_1Fw = P_1 * Fw, |
P_1w = log2(P_1); |
|
|
input [PP_1-1 : 0] granted_dest_port_all; |
input [PFw-1 : 0] flit_in_all; |
output reg [PFw-1 : 0] flit_out_all; |
output reg [P-1 : 0] flit_out_we_all; |
input [P-1 : 0] ssa_flit_wr_all; |
input reset,clk; |
|
|
|
wire [PFw-1 : 0] flit_out_all_internal; |
wire [P-1 : 0] flit_out_we_all_internal,flit_we_mux_out; |
wire [P_1-1 : 0] granted_dest_port [P-1 : 0]; |
wire [P_1Fw-1 : 0] mux_in [P-1 : 0]; |
wire [P_1-1 : 0] mux_sel_pre [P-1 : 0]; |
wire [P_1-1 : 0] mux_sel [P-1 : 0]; |
wire [P_1w-1 : 0] mux_sel_bin [P-1 : 0]; |
wire [PP-1 : 0] flit_out_we_gen; |
|
genvar i,j; |
generate |
for(i=0;i<P;i=i+1)begin : port_loop |
assign granted_dest_port[i] = granted_dest_port_all[(i+1)*P_1-1 : i*P_1]; |
for(j=0;j<P;j=j+1)begin : port_loop2 //remove sender port flit from flit list |
if(i>j) begin :if1 |
assign mux_in[i][(j+1)*Fw-1 : j*Fw]= flit_in_all[(j+1)*Fw-1 : j*Fw]; |
assign mux_sel_pre[i][j] = granted_dest_port[j][i-1]; |
end |
else if(i<j) begin :if2 |
assign mux_in[i][j*Fw-1 : (j-1)*Fw]= flit_in_all[(j+1)*Fw-1 : j*Fw]; |
assign mux_sel_pre[i][j-1] = granted_dest_port[j][i]; |
end |
assign granted_dest_port[i] = granted_dest_port_all[(i+1)*P_1-1 : i*P_1]; |
for(j=0;j<P;j=j+1)begin : port_loop2 //remove sender port flit from flit list |
if(i>j) begin :if1 |
assign mux_in[i][(j+1)*Fw-1 : j*Fw]= flit_in_all[(j+1)*Fw-1 : j*Fw]; |
assign mux_sel_pre[i][j] = granted_dest_port[j][i-1]; |
end |
else if(i<j) begin :if2 |
assign mux_in[i][j*Fw-1 : (j-1)*Fw]= flit_in_all[(j+1)*Fw-1 : j*Fw]; |
assign mux_sel_pre[i][j-1] = granted_dest_port[j][i]; |
end |
end//for j |
|
|
|
|
if (SSA_EN =="YES")begin :predict //If no output is granted replace the output port with SS port |
|
|
|
|
if (SSA_EN =="YES")begin :predict //If no output is granted replace the output port with SS port |
add_ss_port #( |
.SW_LOC(i) |
.SW_LOC(i), |
.P(P) |
) |
ss_port |
( |
94,89 → 96,89
assign mux_sel[i]= mux_sel_pre[i]; |
|
end |
|
|
|
|
|
|
|
|
|
|
if (MUX_TYPE == "ONE_HOT") begin : one_hot_gen |
one_hot_mux #( |
.IN_WIDTH (P_1Fw), |
|
|
|
|
|
|
|
|
|
|
if (MUX_TYPE == "ONE_HOT") begin : one_hot_gen |
one_hot_mux #( |
.IN_WIDTH (P_1Fw), |
.SEL_WIDTH (P_1) |
) |
cross_mux |
( |
) |
cross_mux |
( |
.mux_in (mux_in [i]), |
.mux_out (flit_out_all_internal[(i+1)*Fw-1 : i*Fw]), |
.sel (mux_sel[i]) |
|
); |
end else begin : binary |
|
one_hot_to_bin #( |
.ONE_HOT_WIDTH (P_1), |
.BIN_WIDTH (P_1w) |
) |
conv |
( |
.one_hot_code (mux_sel[i]), |
.bin_code (mux_sel_bin[i]) |
|
); |
|
|
binary_mux #( |
.IN_WIDTH (P_1Fw), |
.OUT_WIDTH (Fw) |
) |
cross_mux |
( |
.mux_in (mux_in [i]), |
.mux_out (flit_out_all_internal[(i+1)*Fw-1 : i*Fw]), |
.sel (mux_sel_bin[i]) |
|
); |
end//binary |
|
|
|
add_sw_loc_one_hot #( |
.P(P), |
.SW_LOC(i) |
) |
add_sw_loc |
( |
.destport_in(granted_dest_port_all[(i+1)*P_1-1 : i*P_1]), |
.destport_out(flit_out_we_gen [(i+1)*P-1 : i*P]) |
); |
|
|
|
|
|
|
end//for i |
endgenerate |
|
custom_or #( |
.IN_NUM (P), |
.OUT_WIDTH (P) |
)wide_or |
( |
.or_in (flit_out_we_gen), |
.or_out (flit_we_mux_out) |
); |
|
assign flit_out_we_all_internal = flit_we_mux_out | ssa_flit_wr_all; |
.mux_out (flit_out_all_internal[(i+1)*Fw-1 : i*Fw]), |
.sel (mux_sel[i]) |
|
); |
end else begin : binary |
|
one_hot_to_bin #( |
.ONE_HOT_WIDTH (P_1), |
.BIN_WIDTH (P_1w) |
) |
conv |
( |
.one_hot_code (mux_sel[i]), |
.bin_code (mux_sel_bin[i]) |
|
); |
|
|
binary_mux #( |
.IN_WIDTH (P_1Fw), |
.OUT_WIDTH (Fw) |
) |
cross_mux |
( |
.mux_in (mux_in [i]), |
.mux_out (flit_out_all_internal[(i+1)*Fw-1 : i*Fw]), |
.sel (mux_sel_bin[i]) |
|
); |
end//binary |
|
|
|
add_sw_loc_one_hot #( |
.P(P), |
.SW_LOC(i) |
) |
add_sw_loc |
( |
.destport_in(granted_dest_port_all[(i+1)*P_1-1 : i*P_1]), |
.destport_out(flit_out_we_gen [(i+1)*P-1 : i*P]) |
); |
|
|
|
|
|
|
end//for i |
endgenerate |
|
custom_or #( |
.IN_NUM (P), |
.OUT_WIDTH (P) |
)wide_or |
( |
.or_in (flit_out_we_gen), |
.or_out (flit_we_mux_out) |
); |
|
assign flit_out_we_all_internal = flit_we_mux_out | ssa_flit_wr_all; |
generate |
if( ADD_PIPREG_AFTER_CROSSBAR == 1)begin :pip_reg1 |
always @(posedge clk or posedge reset)begin |
if(reset)begin |
if( ADD_PIPREG_AFTER_CROSSBAR == 1)begin :pip_reg1 |
always @(posedge clk or posedge reset)begin |
if(reset)begin |
flit_out_all <= {PFw{1'b0}}; |
flit_out_we_all <= {P{1'b0}}; |
end else begin |
184,17 → 186,17
flit_out_we_all <= flit_out_we_all_internal; |
|
end |
end |
end else begin :no_pip_reg1 |
always @(*)begin |
end |
end else begin :no_pip_reg1 |
always @(*)begin |
flit_out_all = flit_out_all_internal; |
flit_out_we_all = flit_out_we_all_internal; |
end |
end |
|
endgenerate |
|
|
|
|
end |
|
endgenerate |
|
|
|
|
endmodule |
/src_noc/flit_buffer.v
21,12 → 21,13
ssa_rd |
); |
|
|
function integer log2; |
input integer number; begin |
log2=0; |
log2=(number <=1) ? 1: 0; |
while(2**log2<number) begin |
log2=log2+1; |
end |
end |
end |
endfunction // log2 |
|
460,12 → 461,13
rd_data |
); |
|
|
function integer log2; |
input integer number; begin |
log2=0; |
log2=(number <=1) ? 1: 0; |
while(2**log2<number) begin |
log2=log2+1; |
end |
end |
end |
endfunction // log2 |
|
557,14 → 559,15
|
); |
|
|
function integer log2; |
input integer number; begin |
log2=0; |
log2=(number <=1) ? 1: 0; |
while(2**log2<number) begin |
log2=log2+1; |
end |
end |
end |
endfunction // log2 |
endfunction // log2 |
|
|
|
778,14 → 781,15
|
|
|
|
function integer log2; |
input integer number; begin |
log2=0; |
log2=(number <=1) ? 1: 0; |
while(2**log2<number) begin |
log2=log2+1; |
end |
end |
end |
endfunction // log2 |
endfunction // log2 |
|
|
|
977,12 → 981,13
clk |
); |
|
|
function integer log2; |
input integer number; begin |
log2=0; |
log2=(number <=1) ? 1: 0; |
while(2**log2<number) begin |
log2=log2+1; |
end |
end |
end |
endfunction // log2 |
|
/src_noc/inout_ports.v
1,164 → 1,165
`timescale 1ns/1ps |
`timescale 1ns/1ps |
|
module inout_ports #( |
parameter V = 4, // vc_num_per_port |
parameter P = 5, // router port num |
parameter B = 4, // buffer space :flit per VC |
parameter NX = 4, // number of node in x axis |
parameter NY = 4, // number of node in y axis |
parameter C = 4, // number of flit class |
parameter Fpay = 32, //payload width |
parameter VC_REALLOCATION_TYPE= "NONATOMIC", |
parameter COMBINATION_TYPE= "BASELINE",// "BASELINE", "COMB_SPEC1", "COMB_SPEC2", "COMB_NONSPEC" |
parameter TOPOLOGY= "MESH",//"MESH","TORUS" |
parameter ROUTE_NAME="XY",// "XY", "TRANC_XY" |
parameter ROUTE_TYPE="DETERMINISTIC",// "DETERMINISTIC", "FULL_ADAPTIVE", "PAR_ADAPTIVE" |
parameter CONGESTION_INDEX = 2,//"CREDIT","VC" |
parameter DEBUG_EN = 1, |
parameter AVC_ATOMIC_EN = 1, |
parameter ROUTE_SUBFUNC = "XY", |
parameter CONGw = 2, |
parameter CVw=(C==0)? V : C * V, |
parameter [CVw-1: 0] CLASS_SETTING = {CVw{1'b1}}, // shows how each class can use VCs |
parameter [V-1 : 0] ESCAP_VC_MASK = 4'b1000, // mask scape vc, valid only for full adaptive |
parameter SSA_EN="YES", // "YES" , "NO" |
parameter X = 0, // router x address |
parameter V = 4, // vc_num_per_port |
parameter P = 5, // router port num |
parameter B = 4, // buffer space :flit per VC |
parameter NX = 4, // number of node in x axis |
parameter NY = 4, // number of node in y axis |
parameter C = 4, // number of flit class |
parameter Fpay = 32, //payload width |
parameter VC_REALLOCATION_TYPE= "NONATOMIC", |
parameter COMBINATION_TYPE= "BASELINE",// "BASELINE", "COMB_SPEC1", "COMB_SPEC2", "COMB_NONSPEC" |
parameter TOPOLOGY= "MESH",//"MESH","TORUS" |
parameter ROUTE_NAME="XY",// "XY", "TRANC_XY" |
parameter ROUTE_TYPE="DETERMINISTIC",// "DETERMINISTIC", "FULL_ADAPTIVE", "PAR_ADAPTIVE" |
parameter CONGESTION_INDEX = 2,//"CREDIT","VC" |
parameter DEBUG_EN = 1, |
parameter AVC_ATOMIC_EN = 1, |
parameter ROUTE_SUBFUNC = "XY", |
parameter CONGw = 2, |
parameter CVw=(C==0)? V : C * V, |
parameter [CVw-1: 0] CLASS_SETTING = {CVw{1'b1}}, // shows how each class can use VCs |
parameter [V-1 : 0] ESCAP_VC_MASK = 4'b1000, // mask scape vc, valid only for full adaptive |
parameter SSA_EN="YES", // "YES" , "NO" |
parameter X = 0, // router x address |
parameter Y = 0 // router y address |
) |
( |
current_x, |
current_y, |
// to/from neighboring router |
flit_in_all, |
flit_in_we_all, |
credit_out_all, |
credit_in_all, |
congestion_in_all, |
congestion_out_all, |
|
// from vc/sw allocator |
ovc_allocated_all, |
granted_ovc_num_all, |
ivc_num_getting_sw_grant, |
ivc_num_getting_ovc_grant, |
spec_ovc_num_all, |
nonspec_first_arbiter_granted_ivc_all, |
spec_first_arbiter_granted_ivc_all, |
nonspec_granted_dest_port_all, |
spec_granted_dest_port_all, |
granted_dest_port_all, |
any_ivc_sw_request_granted_all, |
any_ovc_granted_in_outport_all, |
|
// to vc/sw allocator |
dest_port_all, |
ovc_is_assigned_all, |
ivc_request_all, |
assigned_ovc_not_full_all, |
masked_ovc_request_all, |
lk_destination_all, |
|
|
// to crossbar |
flit_out_all, |
ssa_flit_wr_all, |
clk,reset |
|
current_x, |
current_y, |
// to/from neighboring router |
flit_in_all, |
flit_in_we_all, |
credit_out_all, |
credit_in_all, |
congestion_in_all, |
congestion_out_all, |
|
// from vc/sw allocator |
ovc_allocated_all, |
granted_ovc_num_all, |
ivc_num_getting_sw_grant, |
ivc_num_getting_ovc_grant, |
spec_ovc_num_all, |
nonspec_first_arbiter_granted_ivc_all, |
spec_first_arbiter_granted_ivc_all, |
nonspec_granted_dest_port_all, |
spec_granted_dest_port_all, |
granted_dest_port_all, |
any_ivc_sw_request_granted_all, |
any_ovc_granted_in_outport_all, |
|
// to vc/sw allocator |
dest_port_all, |
ovc_is_assigned_all, |
ivc_request_all, |
assigned_ovc_not_full_all, |
masked_ovc_request_all, |
lk_destination_all, |
|
|
// to crossbar |
flit_out_all, |
ssa_flit_wr_all, |
clk,reset |
|
); |
|
function integer log2; |
input integer number; begin |
log2=0; |
while(2**log2<number) begin |
log2=log2+1; |
end |
end |
endfunction // log2 |
|
function integer log2; |
input integer number; begin |
log2=(number <=1) ? 1: 0; |
while(2**log2<number) begin |
log2=log2+1; |
end |
end |
endfunction // log2 |
|
|
localparam PV = V * P, |
PVV = PV * V, |
P_1 = P-1 , |
PP_1 = P_1 * P, |
PVP_1 = PV * P_1, |
Fw = 2+V+Fpay,//flit width |
PFw = P * Fw, |
Xw = log2(NX), |
Yw = log2(NY), |
PVV = PV * V, |
P_1 = P-1 , |
PP_1 = P_1 * P, |
PVP_1 = PV * P_1, |
Fw = 2+V+Fpay,//flit width |
PFw = P * Fw, |
Xw = log2(NX), |
Yw = log2(NY), |
CONG_ALw = CONGw*P; // congestion width per router |
|
|
input [Xw-1 : 0] current_x; |
input [Yw-1 : 0] current_y; |
|
input [PFw-1 : 0] flit_in_all; |
input [P-1 : 0] flit_in_we_all; |
output reg[PV-1 : 0] credit_out_all; |
input [PV-1 : 0] credit_in_all; |
input [PV-1 : 0] ovc_allocated_all; |
input [PVV-1 : 0] granted_ovc_num_all; |
input [PV-1 : 0] ivc_num_getting_sw_grant; |
input [PV-1 : 0] ivc_num_getting_ovc_grant; |
input [PVV-1 : 0] spec_ovc_num_all; |
input [PV-1 : 0] nonspec_first_arbiter_granted_ivc_all; |
input [PV-1 : 0] spec_first_arbiter_granted_ivc_all; |
input [PP_1-1 : 0] nonspec_granted_dest_port_all; |
input [PP_1-1 : 0] spec_granted_dest_port_all; |
input [PP_1-1 : 0] granted_dest_port_all; |
input [P-1 : 0] any_ivc_sw_request_granted_all; |
input [P-1 : 0] any_ovc_granted_in_outport_all; |
output [PVP_1-1 : 0] lk_destination_all; |
input [CONG_ALw-1 : 0] congestion_in_all; |
output [CONG_ALw-1 : 0] congestion_out_all; |
|
|
|
// to vc/sw allocator |
output [PVP_1-1 : 0] dest_port_all; |
output [PV-1 : 0] ovc_is_assigned_all; |
output [PV-1 : 0] ivc_request_all; |
output [PV-1 : 0] assigned_ovc_not_full_all; |
output [PVV-1 : 0] masked_ovc_request_all; |
input [Xw-1 : 0] current_x; |
input [Yw-1 : 0] current_y; |
|
input [PFw-1 : 0] flit_in_all; |
input [P-1 : 0] flit_in_we_all; |
output reg[PV-1 : 0] credit_out_all; |
input [PV-1 : 0] credit_in_all; |
input [PV-1 : 0] ovc_allocated_all; |
input [PVV-1 : 0] granted_ovc_num_all; |
input [PV-1 : 0] ivc_num_getting_sw_grant; |
input [PV-1 : 0] ivc_num_getting_ovc_grant; |
input [PVV-1 : 0] spec_ovc_num_all; |
input [PV-1 : 0] nonspec_first_arbiter_granted_ivc_all; |
input [PV-1 : 0] spec_first_arbiter_granted_ivc_all; |
input [PP_1-1 : 0] nonspec_granted_dest_port_all; |
input [PP_1-1 : 0] spec_granted_dest_port_all; |
input [PP_1-1 : 0] granted_dest_port_all; |
input [P-1 : 0] any_ivc_sw_request_granted_all; |
input [P-1 : 0] any_ovc_granted_in_outport_all; |
output [PVP_1-1 : 0] lk_destination_all; |
input [CONG_ALw-1 : 0] congestion_in_all; |
output [CONG_ALw-1 : 0] congestion_out_all; |
|
|
|
// to vc/sw allocator |
output [PVP_1-1 : 0] dest_port_all; |
output [PV-1 : 0] ovc_is_assigned_all; |
output [PV-1 : 0] ivc_request_all; |
output [PV-1 : 0] assigned_ovc_not_full_all; |
output [PVV-1 : 0] masked_ovc_request_all; |
|
|
|
|
|
// to crossbar |
output [PFw-1 : 0] flit_out_all; |
output [P-1 : 0] ssa_flit_wr_all; |
|
|
|
|
// to crossbar |
output [PFw-1 : 0] flit_out_all; |
output [P-1 : 0] ssa_flit_wr_all; |
|
input clk,reset; |
input clk,reset; |
|
|
wire [PVV-1 : 0] candidate_ovc_all; |
wire [PVP_1-1 : 0] dest_port_coded_all; |
wire [PVV-1 : 0] candidate_ovc_all; |
wire [PVP_1-1 : 0] dest_port_coded_all; |
|
wire [P_1-1 : 0] port_pre_sel; |
wire [PV-1 : 0] reset_ivc_all; |
wire [PV-1 : 0] flit_is_tail_all; |
reg [PV-1 : 0] ovc_is_assigned_all,ovc_is_assigned_all_next; |
wire [PV-1 : 0] port_pre_sel_ld_all; |
reg [PVV-1 : 0] assigned_ovc_num_all,assigned_ovc_num_all_next; |
wire [PV-1 : 0] x_diff_is_one_all; |
wire [PV-1 : 0] sel; |
wire [PV-1 : 0] ovc_avalable_all; |
|
wire [2*PV-1 : 0] destport_ab_clear_all; |
wire [P_1-1 : 0] port_pre_sel; |
wire [PV-1 : 0] reset_ivc_all; |
wire [PV-1 : 0] flit_is_tail_all; |
reg [PV-1 : 0] ovc_is_assigned_all,ovc_is_assigned_all_next; |
wire [PV-1 : 0] port_pre_sel_ld_all; |
reg [PVV-1 : 0] assigned_ovc_num_all,assigned_ovc_num_all_next; |
wire [PV-1 : 0] x_diff_is_one_all; |
wire [PV-1 : 0] sel; |
wire [PV-1 : 0] ovc_avalable_all; |
|
wire [2*PV-1 : 0] destport_ab_clear_all; |
|
// ssa |
|
|
|
wire [PV-1 : 0] ssa_ovc_allocated_all; |
wire [PV-1 : 0] ssa_ovc_released_all; |
wire [PVV-1 : 0] ssa_granted_ovc_num_all; |
wire [PV-1 : 0] ssa_ivc_num_getting_sw_grant_all; |
wire [PV-1 : 0] ssa_ivc_num_getting_ovc_grant_all; |
wire [PV-1 : 0] ssa_ivc_reset_all; |
wire [PV-1 : 0] ssa_decreased_credit_in_ss_ovc_all; |
wire [PV-1 : 0] ssa_ovc_allocated_all; |
wire [PV-1 : 0] ssa_ovc_released_all; |
wire [PVV-1 : 0] ssa_granted_ovc_num_all; |
wire [PV-1 : 0] ssa_ivc_num_getting_sw_grant_all; |
wire [PV-1 : 0] ssa_ivc_num_getting_ovc_grant_all; |
wire [PV-1 : 0] ssa_ivc_reset_all; |
wire [PV-1 : 0] ssa_decreased_credit_in_ss_ovc_all; |
|
|
|
generate |
if( SSA_EN =="YES" ) begin : predict |
|
172,8 → 173,8
.NY(NY), // number of node in y axis |
.X(X), // router x address |
.Y(Y), // router y address |
.DEBUG_EN(DEBUG_EN), |
.ESCAP_VC_MASK(ESCAP_VC_MASK) |
.DEBUG_EN(DEBUG_EN), |
.ESCAP_VC_MASK(ESCAP_VC_MASK) |
|
) |
the_ssa |
190,57 → 191,59
.ovc_is_assigned_all(ovc_is_assigned_all), |
.clk(clk), |
.reset(reset), |
|
|
.ovc_allocated_all(ssa_ovc_allocated_all), |
.ovc_released_all(ssa_ovc_released_all), |
.granted_ovc_num_all(ssa_granted_ovc_num_all), |
.ivc_num_getting_sw_grant_all(ssa_ivc_num_getting_sw_grant_all), |
.ivc_num_getting_ovc_grant_all(ssa_ivc_num_getting_ovc_grant_all), |
.ivc_reset_all(ssa_ivc_reset_all), |
.decreased_credit_in_ss_ovc_all(ssa_decreased_credit_in_ss_ovc_all), |
.ssa_flit_wr_all(ssa_flit_wr_all) |
.granted_ovc_num_all(ssa_granted_ovc_num_all), |
.ivc_num_getting_sw_grant_all(ssa_ivc_num_getting_sw_grant_all), |
.ivc_num_getting_ovc_grant_all(ssa_ivc_num_getting_ovc_grant_all), |
.ivc_reset_all(ssa_ivc_reset_all), |
.decreased_credit_in_ss_ovc_all(ssa_decreased_credit_in_ss_ovc_all), |
.ssa_flit_wr_all(ssa_flit_wr_all) |
|
|
); |
|
end else begin :non_predict |
assign ssa_ovc_allocated_all= {PV{1'b0}}; |
assign ssa_ovc_released_all= {PV{1'b0}}; |
assign ssa_granted_ovc_num_all= {PVV{1'b0}}; |
assign ssa_ivc_num_getting_sw_grant_all= {PV{1'b0}}; |
assign ssa_ivc_num_getting_ovc_grant_all= {PV{1'b0}}; |
assign ssa_ivc_reset_all= {PV{1'b0}}; |
assign ssa_flit_wr_all= {P{1'b0}}; |
assign ssa_decreased_credit_in_ss_ovc_all = {PV{1'b0}}; |
assign ssa_ovc_allocated_all= {PV{1'b0}}; |
assign ssa_ovc_released_all= {PV{1'b0}}; |
assign ssa_granted_ovc_num_all= {PVV{1'b0}}; |
assign ssa_ivc_num_getting_sw_grant_all= {PV{1'b0}}; |
assign ssa_ivc_num_getting_ovc_grant_all= {PV{1'b0}}; |
assign ssa_ivc_reset_all= {PV{1'b0}}; |
assign ssa_flit_wr_all= {P{1'b0}}; |
assign ssa_decreased_credit_in_ss_ovc_all = {PV{1'b0}}; |
|
end |
endgenerate |
|
wire [PVV-1 : 0] granted_ovc_num_all_or_ssa; |
wire [PV-1 : 0] ivc_num_getting_sw_grant_all_or_ssa; |
|
wire [PVV-1 : 0] granted_ovc_num_all_or_ssa; |
wire [PV-1 : 0] ivc_num_getting_sw_grant_all_or_ssa; |
|
|
|
assign granted_ovc_num_all_or_ssa = granted_ovc_num_all | ssa_granted_ovc_num_all; |
assign ivc_num_getting_sw_grant_all_or_ssa = ivc_num_getting_sw_grant | ssa_ivc_num_getting_sw_grant_all; |
assign reset_ivc_all = (flit_is_tail_all & ivc_num_getting_sw_grant) | ssa_ivc_reset_all; |
assign granted_ovc_num_all_or_ssa = granted_ovc_num_all | ssa_granted_ovc_num_all; |
assign ivc_num_getting_sw_grant_all_or_ssa = ivc_num_getting_sw_grant | ssa_ivc_num_getting_sw_grant_all; |
assign reset_ivc_all = (flit_is_tail_all & ivc_num_getting_sw_grant) | ssa_ivc_reset_all; |
|
|
|
|
|
//synthesis translate_off |
//synopsys translate_off |
if(DEBUG_EN)begin :dbg2 // The SSA must not have conflict with the main VC/Sw allocator |
localparam VV = V*V; |
genvar g; |
for(g=0; g< P; g=g+1 ) begin: p_loop |
always @ (posedge clk) begin |
if( (|granted_ovc_num_all[(g+1)*VV-1 : g*VV]) & (|ssa_granted_ovc_num_all[(g+1)*VV-1 : g*VV])) $display("%t: ERROR: VSA/SSA conflict: granted_ovc_num %m",$time); |
if( (|ivc_num_getting_sw_grant [(g+1)*V-1 : g*V]) & (|ssa_ivc_num_getting_sw_grant_all[(g+1)*V-1 : g*V]) ) $display("%t: ERROR: VSA/SSA conflict: ivc_num_getting_sw_grant %m",$time); |
if((|(flit_is_tail_all[(g+1)*V-1 : g*V] & ivc_num_getting_sw_grant[(g+1)*V-1 : g*V])) & (|ssa_ivc_reset_all[(g+1)*V-1 : g*V])) $display("%t: ERROR: VSA/SSA conflict: reset_ivc_all %m",$time); |
end//always |
end |
end //dbg |
generate |
if(DEBUG_EN)begin :dbg2 // The SSA must not have conflict with the main VC/Sw allocator |
localparam VV = V*V; |
genvar g; |
for(g=0; g< P; g=g+1 ) begin: p_loop |
always @ (posedge clk) begin |
if( (|granted_ovc_num_all[(g+1)*VV-1 : g*VV]) & (|ssa_granted_ovc_num_all[(g+1)*VV-1 : g*VV])) $display("%t: ERROR: VSA/SSA conflict: granted_ovc_num %m",$time); |
if( (|ivc_num_getting_sw_grant [(g+1)*V-1 : g*V]) & (|ssa_ivc_num_getting_sw_grant_all[(g+1)*V-1 : g*V]) ) $display("%t: ERROR: VSA/SSA conflict: ivc_num_getting_sw_grant %m",$time); |
if((|(flit_is_tail_all[(g+1)*V-1 : g*V] & ivc_num_getting_sw_grant[(g+1)*V-1 : g*V])) & (|ssa_ivc_reset_all[(g+1)*V-1 : g*V])) $display("%t: ERROR: VSA/SSA conflict: reset_ivc_all %m",$time); |
end//always |
end |
end //dbg |
endgenerate |
//synopsys translate_on |
//synthesis translate_on |
|
253,49 → 256,49
|
genvar k; |
generate |
for(k=0; k< PV; k=k+1 ) begin: PV_loop |
always @ (*) begin |
//default values |
ovc_is_assigned_all_next[k] = ovc_is_assigned_all[k]; |
assigned_ovc_num_all_next[(k+1)*V-1 : k*V] = assigned_ovc_num_all[(k+1)*V-1 : k*V] ; |
if(reset_ivc_all[k]) begin |
ovc_is_assigned_all_next[k] = 1'b0; |
//assigned_ovc_num_all_next[(k+1)*V-1 : k*V] = {V{1'b0}}; |
end |
else if(ivc_num_getting_ovc_grant[k] | ssa_ivc_num_getting_ovc_grant_all[k]) begin |
ovc_is_assigned_all_next[k] = 1'b1; |
assigned_ovc_num_all_next[(k+1)*V-1 : k*V] = granted_ovc_num_all_or_ssa[(k+1)*V-1 : k*V]; |
end |
end//always |
//synthesis translate_off |
//synopsys translate_off |
if(DEBUG_EN)begin :dbg |
always @ (posedge clk) begin |
if((ivc_num_getting_ovc_grant[k] | ssa_ivc_num_getting_ovc_grant_all[k]) && granted_ovc_num_all_or_ssa[(k+1)*V-1 : k*V]== {V{1'b0}}) begin |
$display("%t: ERROR: granted OVC num is NULL: %m",$time); |
|
end |
end//always |
end |
//synopsys translate_on |
//synthesis translate_on |
|
|
end//for |
for(k=0; k< PV; k=k+1 ) begin: PV_loop |
always @ (*) begin |
//default values |
ovc_is_assigned_all_next[k] = ovc_is_assigned_all[k]; |
assigned_ovc_num_all_next[(k+1)*V-1 : k*V] = assigned_ovc_num_all[(k+1)*V-1 : k*V] ; |
if(reset_ivc_all[k]) begin |
ovc_is_assigned_all_next[k] = 1'b0; |
//assigned_ovc_num_all_next[(k+1)*V-1 : k*V] = {V{1'b0}}; |
end |
else if(ivc_num_getting_ovc_grant[k] | ssa_ivc_num_getting_ovc_grant_all[k]) begin |
ovc_is_assigned_all_next[k] = 1'b1; |
assigned_ovc_num_all_next[(k+1)*V-1 : k*V] = granted_ovc_num_all_or_ssa[(k+1)*V-1 : k*V]; |
end |
end//always |
//synthesis translate_off |
//synopsys translate_off |
if(DEBUG_EN)begin :dbg |
always @ (posedge clk) begin |
if((ivc_num_getting_ovc_grant[k] | ssa_ivc_num_getting_ovc_grant_all[k]) && granted_ovc_num_all_or_ssa[(k+1)*V-1 : k*V]== {V{1'b0}}) begin |
$display("%t: ERROR: granted OVC num is NULL: %m",$time); |
|
end |
end//always |
end |
//synopsys translate_on |
//synthesis translate_on |
|
|
end//for |
endgenerate |
|
|
|
always @ (posedge clk or posedge reset) begin |
if (reset) begin |
ovc_is_assigned_all <= {PV{1'b0}}; |
assigned_ovc_num_all <= {PVV{1'b0}}; |
credit_out_all <= {PV{1'b0}}; |
end else begin |
ovc_is_assigned_all <= ovc_is_assigned_all_next; |
assigned_ovc_num_all <= assigned_ovc_num_all_next; |
credit_out_all <= ivc_num_getting_sw_grant_all_or_ssa; |
end |
if (reset) begin |
ovc_is_assigned_all <= {PV{1'b0}}; |
assigned_ovc_num_all <= {PVV{1'b0}}; |
credit_out_all <= {PV{1'b0}}; |
end else begin |
ovc_is_assigned_all <= ovc_is_assigned_all_next; |
assigned_ovc_num_all <= assigned_ovc_num_all_next; |
credit_out_all <= ivc_num_getting_sw_grant_all_or_ssa; |
end |
end |
|
|
302,8 → 305,8
|
|
generate |
//synthesis translate_off |
//synopsys translate_off |
//synthesis translate_off |
//synopsys translate_off |
if(DEBUG_EN)begin :dbg |
integer kk; |
always @(posedge clk ) begin |
312,86 → 315,86
end |
//synopsys translate_on |
//synthesis translate_on |
|
|
if( COMBINATION_TYPE== "BASELINE") begin : canonical |
|
canonical_credit_counter #( |
.V (V), |
.P (P), |
.B (B), |
.VC_REALLOCATION_TYPE (VC_REALLOCATION_TYPE), |
.ROUTE_TYPE (ROUTE_TYPE), |
.CONGESTION_INDEX (CONGESTION_INDEX), |
.ESCAP_VC_MASK (ESCAP_VC_MASK), |
.CONGw (CONGw), |
.AVC_ATOMIC_EN (AVC_ATOMIC_EN), |
.DEBUG_EN (DEBUG_EN) |
|
canonical_credit_counter #( |
.V (V), |
.P (P), |
.B (B), |
.VC_REALLOCATION_TYPE (VC_REALLOCATION_TYPE), |
.ROUTE_TYPE (ROUTE_TYPE), |
.CONGESTION_INDEX (CONGESTION_INDEX), |
.ESCAP_VC_MASK (ESCAP_VC_MASK), |
.CONGw (CONGw), |
.AVC_ATOMIC_EN (AVC_ATOMIC_EN), |
.DEBUG_EN (DEBUG_EN) |
|
) |
the_credit_counter |
( |
.non_ss_ovc_allocated_all (ovc_allocated_all), |
.flit_is_tail_all (flit_is_tail_all), |
.assigned_ovc_num_all (assigned_ovc_num_all), |
.spec_ovc_num_all (spec_ovc_num_all), |
.dest_port_all (dest_port_all), |
.nonspec_granted_dest_port_all (nonspec_granted_dest_port_all), |
.spec_granted_dest_port_all (spec_granted_dest_port_all), |
.credit_in_all (credit_in_all), |
.nonspec_first_arbiter_granted_ivc_all (nonspec_first_arbiter_granted_ivc_all), |
.spec_first_arbiter_granted_ivc_all (spec_first_arbiter_granted_ivc_all), |
.ivc_num_getting_sw_grant (ivc_num_getting_sw_grant_all_or_ssa ), |
.ovc_avalable_all (ovc_avalable_all), |
.assigned_ovc_not_full_all (assigned_ovc_not_full_all), |
.port_pre_sel (port_pre_sel),//only valid for adaptive routing |
.congestion_in_all (congestion_in_all),//only valid for adaptive routing |
.ssa_ovc_released_all (ssa_ovc_released_all), |
.ssa_ovc_allocated_all (ssa_ovc_allocated_all), |
.ssa_decreased_credit_in_ss_ovc_all (ssa_decreased_credit_in_ss_ovc_all), |
.reset (reset), |
.clk (clk) |
); |
|
end //canonical |
else begin : noncanonical |
|
credit_counter #( |
.V (V), |
.P (P), |
.B (B), |
.VC_REALLOCATION_TYPE (VC_REALLOCATION_TYPE), |
.ROUTE_TYPE (ROUTE_TYPE), |
.CONGESTION_INDEX (CONGESTION_INDEX), |
.ESCAP_VC_MASK (ESCAP_VC_MASK), |
.AVC_ATOMIC_EN (AVC_ATOMIC_EN), |
.CONGw (CONGw), |
.DEBUG_EN (DEBUG_EN) |
) |
the_credit_counter |
( |
.non_ss_ovc_allocated_all (ovc_allocated_all), |
.flit_is_tail_all (flit_is_tail_all), |
.assigned_ovc_num_all (assigned_ovc_num_all), |
.ovc_is_assigned_all (ovc_is_assigned_all), |
.dest_port_all (dest_port_all), |
.nonspec_granted_dest_port_all (nonspec_granted_dest_port_all), |
.credit_in_all (credit_in_all), |
.nonspec_first_arbiter_granted_ivc_all (nonspec_first_arbiter_granted_ivc_all), |
.ivc_num_getting_sw_grant (ivc_num_getting_sw_grant_all_or_ssa ), |
.ovc_avalable_all (ovc_avalable_all), |
.assigned_ovc_not_full_all (assigned_ovc_not_full_all), |
.port_pre_sel (port_pre_sel),//only valid for adaptive routing |
.congestion_in_all (congestion_in_all),//only valid for adaptive routing |
.ssa_ovc_released_all (ssa_ovc_released_all), |
) |
the_credit_counter |
( |
.non_ss_ovc_allocated_all (ovc_allocated_all), |
.flit_is_tail_all (flit_is_tail_all), |
.assigned_ovc_num_all (assigned_ovc_num_all), |
.spec_ovc_num_all (spec_ovc_num_all), |
.dest_port_all (dest_port_all), |
.nonspec_granted_dest_port_all (nonspec_granted_dest_port_all), |
.spec_granted_dest_port_all (spec_granted_dest_port_all), |
.credit_in_all (credit_in_all), |
.nonspec_first_arbiter_granted_ivc_all (nonspec_first_arbiter_granted_ivc_all), |
.spec_first_arbiter_granted_ivc_all (spec_first_arbiter_granted_ivc_all), |
.ivc_num_getting_sw_grant (ivc_num_getting_sw_grant_all_or_ssa ), |
.ovc_avalable_all (ovc_avalable_all), |
.assigned_ovc_not_full_all (assigned_ovc_not_full_all), |
.port_pre_sel (port_pre_sel),//only valid for adaptive routing |
.congestion_in_all (congestion_in_all),//only valid for adaptive routing |
.ssa_ovc_released_all (ssa_ovc_released_all), |
.ssa_ovc_allocated_all (ssa_ovc_allocated_all), |
.ssa_decreased_credit_in_ss_ovc_all (ssa_decreased_credit_in_ss_ovc_all), |
.reset (reset), |
.clk (clk) |
); |
|
end //canonical |
else begin : noncanonical |
|
credit_counter #( |
.V (V), |
.P (P), |
.B (B), |
.VC_REALLOCATION_TYPE (VC_REALLOCATION_TYPE), |
.ROUTE_TYPE (ROUTE_TYPE), |
.CONGESTION_INDEX (CONGESTION_INDEX), |
.ESCAP_VC_MASK (ESCAP_VC_MASK), |
.AVC_ATOMIC_EN (AVC_ATOMIC_EN), |
.CONGw (CONGw), |
.DEBUG_EN (DEBUG_EN) |
) |
the_credit_counter |
( |
.non_ss_ovc_allocated_all (ovc_allocated_all), |
.flit_is_tail_all (flit_is_tail_all), |
.assigned_ovc_num_all (assigned_ovc_num_all), |
.ovc_is_assigned_all (ovc_is_assigned_all), |
.dest_port_all (dest_port_all), |
.nonspec_granted_dest_port_all (nonspec_granted_dest_port_all), |
.credit_in_all (credit_in_all), |
.nonspec_first_arbiter_granted_ivc_all (nonspec_first_arbiter_granted_ivc_all), |
.ivc_num_getting_sw_grant (ivc_num_getting_sw_grant_all_or_ssa ), |
.ovc_avalable_all (ovc_avalable_all), |
.assigned_ovc_not_full_all (assigned_ovc_not_full_all), |
.port_pre_sel (port_pre_sel),//only valid for adaptive routing |
.congestion_in_all (congestion_in_all),//only valid for adaptive routing |
.ssa_ovc_released_all (ssa_ovc_released_all), |
.ssa_ovc_allocated_all (ssa_ovc_allocated_all), |
.ssa_decreased_credit_in_ss_ovc_all (ssa_decreased_credit_in_ss_ovc_all), |
.reset (reset), |
.clk (clk) |
); |
|
end//noncanonical |
|
// masking unavailable candidate OVC |
.reset (reset), |
.clk (clk) |
); |
|
end//noncanonical |
|
// masking unavailable candidate OVC |
if(ROUTE_TYPE == "DETERMINISTIC") begin: deterministic_req |
|
vc_alloc_request_gen_determinstic #( |
407,7 → 410,7
.masked_ovc_request_all (masked_ovc_request_all), |
.candidate_ovc_all (candidate_ovc_all) |
); |
assign sel={PV{1'bx}}; |
assign sel={PV{1'bx}}; |
assign destport_ab_clear_all={2*PV{1'b0}}; |
|
end else begin: adaptive |
480,8 → 483,8
|
|
|
|
endgenerate |
|
endgenerate |
|
|
congestion_out_gen #( |
508,50 → 511,50
|
input_ports |
#( |
.V(V), |
.P(P), |
.B(B), |
.NX(NX), |
.NY(NY), |
.C(C), |
.Fpay(Fpay), |
.VC_REALLOCATION_TYPE(VC_REALLOCATION_TYPE), |
.TOPOLOGY(TOPOLOGY), |
.ROUTE_NAME(ROUTE_NAME), |
.ROUTE_TYPE(ROUTE_TYPE), |
.DEBUG_EN(DEBUG_EN), |
.AVC_ATOMIC_EN(AVC_ATOMIC_EN), |
.COMBINATION_TYPE(COMBINATION_TYPE), |
.ROUTE_SUBFUNC(ROUTE_SUBFUNC), |
.CVw(CVw), |
.V(V), |
.P(P), |
.B(B), |
.NX(NX), |
.NY(NY), |
.C(C), |
.Fpay(Fpay), |
.VC_REALLOCATION_TYPE(VC_REALLOCATION_TYPE), |
.TOPOLOGY(TOPOLOGY), |
.ROUTE_NAME(ROUTE_NAME), |
.ROUTE_TYPE(ROUTE_TYPE), |
.DEBUG_EN(DEBUG_EN), |
.AVC_ATOMIC_EN(AVC_ATOMIC_EN), |
.COMBINATION_TYPE(COMBINATION_TYPE), |
.ROUTE_SUBFUNC(ROUTE_SUBFUNC), |
.CVw(CVw), |
.CLASS_SETTING(CLASS_SETTING), |
.ESCAP_VC_MASK(ESCAP_VC_MASK), |
.SSA_EN(SSA_EN) |
|
|
) |
the_input_queue |
( |
.current_x (current_x), |
.current_y (current_y), |
.ivc_num_getting_sw_grant (ivc_num_getting_sw_grant_all_or_ssa ), |
.any_ivc_sw_request_granted_all (any_ivc_sw_request_granted_all), |
.flit_in_all (flit_in_all), |
.flit_in_we_all (flit_in_we_all), |
.reset_ivc_all (reset_ivc_all), |
.flit_is_tail_all (flit_is_tail_all), |
.ivc_request_all (ivc_request_all), |
.dest_port_all (dest_port_coded_all), |
.candidate_ovcs_all (candidate_ovc_all), |
.flit_out_all (flit_out_all), |
.assigned_ovc_num_all (assigned_ovc_num_all), |
.sel (sel), |
.lk_destination_all (lk_destination_all), |
.x_diff_is_one_all (x_diff_is_one_all), |
.nonspec_first_arbiter_granted_ivc_all(nonspec_first_arbiter_granted_ivc_all), |
.ssa_ivc_num_getting_sw_grant_all (ssa_ivc_num_getting_sw_grant_all), |
.destport_ab_clear_all (destport_ab_clear_all), |
.reset (reset), |
.clk (clk) |
.current_x (current_x), |
.current_y (current_y), |
.ivc_num_getting_sw_grant (ivc_num_getting_sw_grant_all_or_ssa ), |
.any_ivc_sw_request_granted_all (any_ivc_sw_request_granted_all), |
.flit_in_all (flit_in_all), |
.flit_in_we_all (flit_in_we_all), |
.reset_ivc_all (reset_ivc_all), |
.flit_is_tail_all (flit_is_tail_all), |
.ivc_request_all (ivc_request_all), |
.dest_port_all (dest_port_coded_all), |
.candidate_ovcs_all (candidate_ovc_all), |
.flit_out_all (flit_out_all), |
.assigned_ovc_num_all (assigned_ovc_num_all), |
.sel (sel), |
.lk_destination_all (lk_destination_all), |
.x_diff_is_one_all (x_diff_is_one_all), |
.nonspec_first_arbiter_granted_ivc_all(nonspec_first_arbiter_granted_ivc_all), |
.ssa_ivc_num_getting_sw_grant_all (ssa_ivc_num_getting_sw_grant_all), |
.destport_ab_clear_all (destport_ab_clear_all), |
.reset (reset), |
.clk (clk) |
); |
|
|
558,7 → 561,7
|
|
|
|
|
|
endmodule |
|
590,14 → 593,15
input reset |
); |
|
|
function integer log2; |
input integer number; begin |
log2=0; |
log2=(number <=1) ? 1: 0; |
while(2**log2<number) begin |
log2=log2+1; |
end |
end |
end |
endfunction // log2 |
endfunction // log2 |
|
localparam BUFF_WIDTH = log2(B); |
localparam DEPTH_WIDTH = BUFF_WIDTH+1; |
/src_noc/input_ports.v
1,21 → 1,21
`timescale 1ns/1ps |
`timescale 1ns/1ps |
|
module input_ports |
#( |
parameter V = 4, // vc_num_per_port |
parameter P = 5, // router port num |
parameter B = 4, // buffer space :flit per VC |
parameter NX= 4, // number of node in x axis |
parameter NY= 4, // number of node in y axis |
parameter C = 4, // number of flit class |
parameter Fpay = 32, |
parameter COMBINATION_TYPE= "BASELINE",// "BASELINE", "COMB_SPEC1", "COMB_SPEC2", "COMB_NONSPEC" |
parameter VC_REALLOCATION_TYPE = "ATOMIC", |
parameter TOPOLOGY = "MESH",//"MESH","TORUS" |
parameter ROUTE_NAME="XY",// "XY", "TRANC_XY" |
parameter V = 4, // vc_num_per_port |
parameter P = 5, // router port num |
parameter B = 4, // buffer space :flit per VC |
parameter NX= 4, // number of node in x axis |
parameter NY= 4, // number of node in y axis |
parameter C = 4, // number of flit class |
parameter Fpay = 32, |
parameter COMBINATION_TYPE= "BASELINE",// "BASELINE", "COMB_SPEC1", "COMB_SPEC2", "COMB_NONSPEC" |
parameter VC_REALLOCATION_TYPE = "ATOMIC", |
parameter TOPOLOGY = "MESH",//"MESH","TORUS" |
parameter ROUTE_NAME="XY",// "XY", "TRANC_XY" |
parameter ROUTE_TYPE="DETERMINISTIC",// "DETERMINISTIC", "FULL_ADAPTIVE", "PAR_ADAPTIVE" |
parameter DEBUG_EN = 1, |
parameter ROUTE_SUBFUNC= "XY", |
parameter DEBUG_EN = 1, |
parameter ROUTE_SUBFUNC= "XY", |
parameter AVC_ATOMIC_EN= 0, |
parameter CVw=(C==0)? V : C * V, |
parameter [CVw-1: 0] CLASS_SETTING = {CVw{1'b1}}, // shows how each class can use VCs |
22,95 → 22,95
parameter [V-1 : 0] ESCAP_VC_MASK = 4'b1000, // mask scape vc, valid only for full adaptive |
parameter SSA_EN="YES" // "YES" , "NO" |
|
|
|
)( |
current_x, |
current_y, |
ivc_num_getting_sw_grant,// for non spec ivc_num_getting_first_sw_grant, |
any_ivc_sw_request_granted_all, |
flit_in_all, |
flit_in_we_all, |
reset_ivc_all, |
flit_is_tail_all, |
ivc_request_all, |
dest_port_all, |
candidate_ovcs_all, |
flit_out_all, |
assigned_ovc_num_all, |
lk_destination_all, |
sel, |
x_diff_is_one_all, |
nonspec_first_arbiter_granted_ivc_all, |
ssa_ivc_num_getting_sw_grant_all, |
destport_ab_clear_all, |
reset, |
clk |
current_x, |
current_y, |
ivc_num_getting_sw_grant,// for non spec ivc_num_getting_first_sw_grant, |
any_ivc_sw_request_granted_all, |
flit_in_all, |
flit_in_we_all, |
reset_ivc_all, |
flit_is_tail_all, |
ivc_request_all, |
dest_port_all, |
candidate_ovcs_all, |
flit_out_all, |
assigned_ovc_num_all, |
lk_destination_all, |
sel, |
x_diff_is_one_all, |
nonspec_first_arbiter_granted_ivc_all, |
ssa_ivc_num_getting_sw_grant_all, |
destport_ab_clear_all, |
reset, |
clk |
); |
|
|
|
function integer log2; |
input integer number; begin |
log2=0; |
while(2**log2<number) begin |
log2=log2+1; |
end |
end |
endfunction // log2 |
|
localparam PV = V * P, |
VV = V * V, |
PVV = PV * V, |
P_1 = P-1 , |
|
function integer log2; |
input integer number; begin |
log2=(number <=1) ? 1: 0; |
while(2**log2<number) begin |
log2=log2+1; |
end |
end |
endfunction // log2 |
localparam PV = V * P, |
VV = V * V, |
PVV = PV * V, |
P_1 = P-1 , |
VP_1 = V * P_1, |
PVP_1 = PV * P_1; |
PVP_1 = PV * P_1; |
|
localparam Xw = log2(NX), // number of node in x axis |
Yw = log2(NY), // number of node in y axis |
Fw = 2+V+Fpay, //flit width; |
PFw = P*Fw; |
localparam Xw = log2(NX), // number of node in x axis |
Yw = log2(NY), // number of node in y axis |
Fw = 2+V+Fpay, //flit width; |
PFw = P*Fw; |
|
|
input [Xw-1 : 0] current_x; |
input [Yw-1 : 0] current_y; |
input [PV-1 : 0] ivc_num_getting_sw_grant; |
input [P-1 : 0] any_ivc_sw_request_granted_all; |
input [PFw-1 : 0] flit_in_all; |
input [P-1 : 0] flit_in_we_all; |
input [PV-1 : 0] reset_ivc_all; |
output [PV-1 : 0] flit_is_tail_all; |
output [PV-1 : 0] ivc_request_all; |
output [PVP_1-1 : 0] dest_port_all; |
output [PVV-1 : 0] candidate_ovcs_all; |
output [PFw-1 : 0] flit_out_all; |
input [PVV-1 : 0] assigned_ovc_num_all; |
input [PV-1 : 0] sel; |
output [PV-1 : 0] x_diff_is_one_all; |
input reset,clk; |
output [PVP_1-1 : 0] lk_destination_all; |
input [PV-1 : 0] nonspec_first_arbiter_granted_ivc_all; |
input [PV-1 : 0] ssa_ivc_num_getting_sw_grant_all; |
input [2*PV-1 : 0] destport_ab_clear_all; |
input [Xw-1 : 0] current_x; |
input [Yw-1 : 0] current_y; |
input [PV-1 : 0] ivc_num_getting_sw_grant; |
input [P-1 : 0] any_ivc_sw_request_granted_all; |
input [PFw-1 : 0] flit_in_all; |
input [P-1 : 0] flit_in_we_all; |
input [PV-1 : 0] reset_ivc_all; |
output [PV-1 : 0] flit_is_tail_all; |
output [PV-1 : 0] ivc_request_all; |
output [PVP_1-1 : 0] dest_port_all; |
output [PVV-1 : 0] candidate_ovcs_all; |
output [PFw-1 : 0] flit_out_all; |
input [PVV-1 : 0] assigned_ovc_num_all; |
input [PV-1 : 0] sel; |
output [PV-1 : 0] x_diff_is_one_all; |
input reset,clk; |
output [PVP_1-1 : 0] lk_destination_all; |
input [PV-1 : 0] nonspec_first_arbiter_granted_ivc_all; |
input [PV-1 : 0] ssa_ivc_num_getting_sw_grant_all; |
input [2*PV-1 : 0] destport_ab_clear_all; |
|
genvar i; |
generate |
for(i=0;i<P;i=i+1)begin : port_loop |
|
|
input_queue_per_port |
for(i=0;i<P;i=i+1)begin : port_loop |
|
|
input_queue_per_port |
#( |
.V(V), |
.P(P), |
.B(B), |
.NX(NX), |
.NY(NY), |
.C(C), |
.Fpay(Fpay), |
.SW_LOC(i), |
.VC_REALLOCATION_TYPE(VC_REALLOCATION_TYPE), |
.COMBINATION_TYPE(COMBINATION_TYPE), |
.TOPOLOGY(TOPOLOGY), |
.ROUTE_NAME(ROUTE_NAME), |
.V(V), |
.P(P), |
.B(B), |
.NX(NX), |
.NY(NY), |
.C(C), |
.Fpay(Fpay), |
.SW_LOC(i), |
.VC_REALLOCATION_TYPE(VC_REALLOCATION_TYPE), |
.COMBINATION_TYPE(COMBINATION_TYPE), |
.TOPOLOGY(TOPOLOGY), |
.ROUTE_NAME(ROUTE_NAME), |
.ROUTE_TYPE(ROUTE_TYPE), |
.DEBUG_EN(DEBUG_EN), |
.ROUTE_SUBFUNC(ROUTE_SUBFUNC), |
119,39 → 119,39
.CLASS_SETTING(CLASS_SETTING), |
.ESCAP_VC_MASK(ESCAP_VC_MASK), |
.SSA_EN(SSA_EN) |
|
|
) |
the_input_queue_per_port |
( |
.current_x(current_x), |
.current_y(current_y), |
.ivc_num_getting_sw_grant(ivc_num_getting_sw_grant [(i+1)*V-1 : i*V]),// for non spec ivc_num_getting_first_sw_grant, |
.any_ivc_sw_request_granted(any_ivc_sw_request_granted_all [i]), |
.flit_in(flit_in_all[(i+1)*Fw-1 : i*Fw]), |
.current_x(current_x), |
.current_y(current_y), |
.ivc_num_getting_sw_grant(ivc_num_getting_sw_grant [(i+1)*V-1 : i*V]),// for non spec ivc_num_getting_first_sw_grant, |
.any_ivc_sw_request_granted(any_ivc_sw_request_granted_all [i]), |
.flit_in(flit_in_all[(i+1)*Fw-1 : i*Fw]), |
.flit_in_we(flit_in_we_all[i]), |
.reset_ivc(reset_ivc_all [(i+1)*V-1 : i*V]), |
.flit_is_tail(flit_is_tail_all [(i+1)*V-1 : i*V]), |
.ivc_request(ivc_request_all [(i+1)*V-1 : i*V]), |
.dest_port(dest_port_all [(i+1)*VP_1-1 : i*VP_1]), |
.candidate_ovcs(candidate_ovcs_all [(i+1)* VV -1 : i*VV]), |
.flit_out(flit_out_all [(i+1)*Fw-1 : i*Fw]), |
.assigned_ovc_num(assigned_ovc_num_all [(i+1)*VV-1 : i*VV]), |
.sel(sel [(i+1)*V-1 : i*V]), |
.x_diff_is_one(x_diff_is_one_all[(i+1)*V-1 : i*V]), |
.nonspec_first_arbiter_granted_ivc(nonspec_first_arbiter_granted_ivc_all[(i+1)*V-1 : i*V]), |
.reset(reset), |
.clk(clk), |
.lk_destination(lk_destination_all[(i+1)*VP_1-1 : i*VP_1]), |
.ssa_ivc_num_getting_sw_grant(ssa_ivc_num_getting_sw_grant_all[(i+1)*V-1 : i*V]), |
.destport_ab_clear(destport_ab_clear_all[(i+1)*2*V-1 : i*2*V]) |
); |
|
end//for |
|
.reset_ivc(reset_ivc_all [(i+1)*V-1 : i*V]), |
.flit_is_tail(flit_is_tail_all [(i+1)*V-1 : i*V]), |
.ivc_request(ivc_request_all [(i+1)*V-1 : i*V]), |
.dest_port(dest_port_all [(i+1)*VP_1-1 : i*VP_1]), |
.candidate_ovcs(candidate_ovcs_all [(i+1)* VV -1 : i*VV]), |
.flit_out(flit_out_all [(i+1)*Fw-1 : i*Fw]), |
.assigned_ovc_num(assigned_ovc_num_all [(i+1)*VV-1 : i*VV]), |
.sel(sel [(i+1)*V-1 : i*V]), |
.x_diff_is_one(x_diff_is_one_all[(i+1)*V-1 : i*V]), |
.nonspec_first_arbiter_granted_ivc(nonspec_first_arbiter_granted_ivc_all[(i+1)*V-1 : i*V]), |
.reset(reset), |
.clk(clk), |
.lk_destination(lk_destination_all[(i+1)*VP_1-1 : i*VP_1]), |
.ssa_ivc_num_getting_sw_grant(ssa_ivc_num_getting_sw_grant_all[(i+1)*V-1 : i*V]), |
.destport_ab_clear(destport_ab_clear_all[(i+1)*2*V-1 : i*2*V]) |
); |
|
end//for |
|
|
|
|
|
|
|
|
endgenerate |
|
|
164,7 → 164,7
|
/************************** |
|
input_queue_per_port |
input_queue_per_port |
|
**************************/ |
|
172,61 → 172,62
|
module input_queue_per_port |
#( |
parameter V = 4, // vc_num_per_port |
parameter P = 5, // router port num |
parameter B = 4, // buffer space :flit per VC |
parameter NX = 4, // number of node in x axis |
parameter NY = 4, // number of node in y axis |
parameter C = 4, // number of flit class |
parameter Fpay = 32, |
parameter SW_LOC = 0, |
parameter VC_REALLOCATION_TYPE = "ATOMIC", |
parameter COMBINATION_TYPE= "BASELINE",// "BASELINE", "COMB_SPEC1", "COMB_SPEC2", "COMB_NONSPEC" |
parameter TOPOLOGY = "MESH",//"MESH","TORUS" |
parameter ROUTE_NAME="XY",// "XY", "TRANC_XY" |
parameter ROUTE_TYPE="DETERMINISTIC",// "DETERMINISTIC", "FULL_ADAPTIVE", "PAR_ADAPTIVE" |
parameter DEBUG_EN =1, |
parameter ROUTE_SUBFUNC= "XY", |
parameter AVC_ATOMIC_EN= 0, |
parameter CVw=(C==0)? V : C * V, |
parameter [CVw-1: 0] CLASS_SETTING = {CVw{1'b1}}, // shows how each class can use VCs |
parameter [V-1 : 0] ESCAP_VC_MASK = 4'b1000, // mask scape vc, valid only for full adaptive |
parameter SSA_EN="YES" // "YES" , "NO" |
parameter V = 4, // vc_num_per_port |
parameter P = 5, // router port num |
parameter B = 4, // buffer space :flit per VC |
parameter NX = 4, // number of node in x axis |
parameter NY = 4, // number of node in y axis |
parameter C = 4, // number of flit class |
parameter Fpay = 32, |
parameter SW_LOC = 0, |
parameter VC_REALLOCATION_TYPE = "ATOMIC", |
parameter COMBINATION_TYPE= "BASELINE",// "BASELINE", "COMB_SPEC1", "COMB_SPEC2", "COMB_NONSPEC" |
parameter TOPOLOGY = "MESH",//"MESH","TORUS" |
parameter ROUTE_NAME="XY",// "XY", "TRANC_XY" |
parameter ROUTE_TYPE="DETERMINISTIC",// "DETERMINISTIC", "FULL_ADAPTIVE", "PAR_ADAPTIVE" |
parameter DEBUG_EN =1, |
parameter ROUTE_SUBFUNC= "XY", |
parameter AVC_ATOMIC_EN= 0, |
parameter CVw=(C==0)? V : C * V, |
parameter [CVw-1: 0] CLASS_SETTING = {CVw{1'b1}}, // shows how each class can use VCs |
parameter [V-1 : 0] ESCAP_VC_MASK = 4'b1000, // mask scape vc, valid only for full adaptive |
parameter SSA_EN="YES" // "YES" , "NO" |
|
)( |
current_x, |
current_y, |
ivc_num_getting_sw_grant,// for non spec ivc_num_getting_first_sw_grant, |
any_ivc_sw_request_granted, |
flit_in, |
flit_in_we, |
reset_ivc, |
flit_is_tail, |
ivc_request, |
dest_port, |
candidate_ovcs, |
flit_out, |
assigned_ovc_num, |
sel, |
reset, |
clk, |
x_diff_is_one, |
lk_destination, |
nonspec_first_arbiter_granted_ivc, |
destport_ab_clear, |
ssa_ivc_num_getting_sw_grant |
|
|
current_x, |
current_y, |
ivc_num_getting_sw_grant,// for non spec ivc_num_getting_first_sw_grant, |
any_ivc_sw_request_granted, |
flit_in, |
flit_in_we, |
reset_ivc, |
flit_is_tail, |
ivc_request, |
dest_port, |
candidate_ovcs, |
flit_out, |
assigned_ovc_num, |
sel, |
reset, |
clk, |
x_diff_is_one, |
lk_destination, |
nonspec_first_arbiter_granted_ivc, |
destport_ab_clear, |
ssa_ivc_num_getting_sw_grant |
|
|
); |
|
function integer log2; |
input integer number; begin |
log2=0; |
while(2**log2<number) begin |
log2=log2+1; |
end |
end |
endfunction // log2 |
|
function integer log2; |
input integer number; begin |
log2=(number <=1) ? 1: 0; |
while(2**log2<number) begin |
log2=log2+1; |
end |
end |
endfunction // log2 |
|
localparam CLASS_HDR_WIDTH =8, |
ROUTING_HDR_WIDTH =8, |
235,96 → 236,96
|
|
|
localparam VV = V * V, |
P_1 = P-1 , |
VP_1 = V * P_1; |
localparam VV = V * V, |
P_1 = P-1 , |
VP_1 = V * P_1; |
|
localparam Xw = log2(NX), // number of node in x axis |
Yw = log2(NY), // number of node in y axis |
Cw = (C>1)? log2(C): 1, |
Fw = 2+V+Fpay; //flit width; |
localparam Xw = log2(NX), // number of node in x axis |
Yw = log2(NY), // number of node in y axis |
Cw = (C>1)? log2(C): 1, |
Fw = 2+V+Fpay; //flit width; |
|
|
|
localparam HDR_FLG =1, |
TAIL_FLG =0, |
MAX_PCK = (VC_REALLOCATION_TYPE== "ATOMIC")? 1 : (B/2)+(B%2);// min packet size is two hence the max packet number in buffer is (B/2) |
|
localparam HDR_FLG =1, |
TAIL_FLG =0, |
MAX_PCK = (VC_REALLOCATION_TYPE== "ATOMIC")? 1 : (B/2)+(B%2);// min packet size is two hence the max packet number in buffer is (B/2) |
|
|
|
|
|
input [Xw-1 : 0] current_x; |
input [Yw-1 : 0] current_y; |
input [Yw-1 : 0] current_y; |
input [V-1 : 0] ivc_num_getting_sw_grant; |
input any_ivc_sw_request_granted; |
input [Fw-1 : 0] flit_in; |
input flit_in_we; |
input [V-1 : 0] reset_ivc; |
output [V-1 : 0] flit_is_tail; |
output [V-1 : 0] ivc_request; |
output [VP_1-1 : 0] dest_port; |
output [VV-1 : 0] candidate_ovcs; |
output [Fw-1 : 0] flit_out; |
input [VV-1 : 0] assigned_ovc_num; |
input flit_in_we; |
input [V-1 : 0] reset_ivc; |
output [V-1 : 0] flit_is_tail; |
output [V-1 : 0] ivc_request; |
output [VP_1-1 : 0] dest_port; |
output [VV-1 : 0] candidate_ovcs; |
output [Fw-1 : 0] flit_out; |
input [VV-1 : 0] assigned_ovc_num; |
input [V-1 : 0] sel; |
input reset,clk; |
input reset,clk; |
output [VP_1-1 : 0] lk_destination; |
output [V-1 : 0] x_diff_is_one; |
input [V-1 : 0] nonspec_first_arbiter_granted_ivc; |
input [V-1 : 0] ssa_ivc_num_getting_sw_grant; |
input [2*V-1 : 0] destport_ab_clear; |
input [V-1 : 0] ssa_ivc_num_getting_sw_grant; |
input [2*V-1 : 0] destport_ab_clear; |
|
|
|
wire [Cw-1 : 0] class_in; |
wire [P_1-1 : 0] destport_in; |
wire [Xw-1 : 0] x_dst_in; |
wire [Yw-1 : 0] y_dst_in; |
wire [Cw-1 : 0] class_in; |
wire [P_1-1 : 0] destport_in; |
wire [Xw-1 : 0] x_dst_in; |
wire [Yw-1 : 0] y_dst_in; |
wire [Xw-1 : 0] x_src_in; |
wire [Yw-1 : 0] y_src_in; |
wire [V-1 : 0] vc_num_in; |
wire [V-1 : 0] hdr_flit_wr,flit_wr; |
reg [V-1 : 0] hdr_flit_wr_delayed; |
wire [V-1 : 0] class_rd_fifo,dst_rd_fifo; |
reg [V-1 : 0] lk_dst_rd_fifo; |
wire [P_1-1 : 0] lk_destination_in; |
wire [V-1 : 0] vc_num_in; |
wire [V-1 : 0] hdr_flit_wr,flit_wr; |
reg [V-1 : 0] hdr_flit_wr_delayed; |
wire [V-1 : 0] class_rd_fifo,dst_rd_fifo; |
reg [V-1 : 0] lk_dst_rd_fifo; |
wire [P_1-1 : 0] lk_destination_in; |
|
|
|
wire [Fw-1 : 0] buffer_out; |
wire [Fw-1 : 0] buffer_out; |
wire [1 : 0] flg_hdr_in; |
wire [V-1 : 0] ivc_not_empty; |
wire [Cw-1 : 0] class_out [V-1 : 0]; |
wire [V-1 : 0] ivc_not_empty; |
wire [Cw-1 : 0] class_out [V-1 : 0]; |
|
|
//extract header flit info |
|
extract_header_flit_info #( |
.CLASS_HDR_WIDTH(CLASS_HDR_WIDTH), |
.ROUTING_HDR_WIDTH(ROUTING_HDR_WIDTH), |
.DST_ADR_HDR_WIDTH(DST_ADR_HDR_WIDTH), |
.SRC_ADR_HDR_WIDTH(SRC_ADR_HDR_WIDTH), |
.TOPOLOGY(TOPOLOGY), |
.V(V), |
.P(P), |
.NX(NX), |
.NY(NY), |
.C(C), |
.Fpay(Fpay) |
.CLASS_HDR_WIDTH(CLASS_HDR_WIDTH), |
.ROUTING_HDR_WIDTH(ROUTING_HDR_WIDTH), |
.DST_ADR_HDR_WIDTH(DST_ADR_HDR_WIDTH), |
.SRC_ADR_HDR_WIDTH(SRC_ADR_HDR_WIDTH), |
.TOPOLOGY(TOPOLOGY), |
.V(V), |
.P(P), |
.NX(NX), |
.NY(NY), |
.C(C), |
.Fpay(Fpay) |
) |
header_extractor |
( |
.flit_in(flit_in), |
.flit_in_we(flit_in_we), |
.class_in(class_in), |
.destport_in(destport_in), |
.x_dst_in(x_dst_in), |
.y_dst_in(y_dst_in), |
.x_src_in(x_src_in ), |
.y_src_in(y_src_in ), |
.vc_num_in(vc_num_in), |
.hdr_flit_wr(hdr_flit_wr), |
.flg_hdr_in(flg_hdr_in) |
.flit_in(flit_in), |
.flit_in_we(flit_in_we), |
.class_in(class_in), |
.destport_in(destport_in), |
.x_dst_in(x_dst_in), |
.y_dst_in(y_dst_in), |
.x_src_in(x_src_in ), |
.y_src_in(y_src_in ), |
.vc_num_in(vc_num_in), |
.hdr_flit_wr(hdr_flit_wr), |
.flg_hdr_in(flg_hdr_in) |
); |
|
|
331,98 → 332,98
|
// genrate write enable for lk_routing result with one clock cycle latency after reciveing the flit |
always @(posedge clk or posedge reset) begin |
if(reset) begin |
hdr_flit_wr_delayed <= {V{1'b0}}; |
//lk_dst_rd_fifo <= {V{1'b0}}; |
end else begin |
hdr_flit_wr_delayed <= hdr_flit_wr; |
// lk_dst_rd_fifo <= dst_rd_fifo; |
end |
if(reset) begin |
hdr_flit_wr_delayed <= {V{1'b0}}; |
//lk_dst_rd_fifo <= {V{1'b0}}; |
end else begin |
hdr_flit_wr_delayed <= hdr_flit_wr; |
// lk_dst_rd_fifo <= dst_rd_fifo; |
end |
end |
|
|
genvar i; |
generate |
for (i=0;i<V; i=i+1) begin: V_loop |
|
class_ovc_table #( |
.CVw(CVw), |
for (i=0;i<V; i=i+1) begin: V_loop |
|
class_ovc_table #( |
.CVw(CVw), |
.CLASS_SETTING(CLASS_SETTING), |
.C(C), |
.V(V) |
)class_table |
( |
.class_in (class_out[i]), |
.candidate_ovcs (candidate_ovcs [(i+1)*V-1 : i*V]) |
); |
|
|
//tail fifo |
fwft_fifo #( |
.DATA_WIDTH(1), |
.MAX_DEPTH (B), |
.IGNORE_SAME_LOC_RD_WR_WARNING(SSA_EN) |
) |
tail_fifo |
( |
.din (flg_hdr_in [TAIL_FLG]), |
.wr_en (flit_wr [i]), // Write enable |
.rd_en (ivc_num_getting_sw_grant[i]), // Read the next word |
.dout (flit_is_tail[i]), // Data out |
.full (), |
.nearly_full (), |
.recieve_more_than_0 (), |
.recieve_more_than_1 (), |
.reset (reset), |
.clk (clk) |
|
); |
|
//class_fifo |
if(C>1)begin :cb1 |
fwft_fifo #( |
.DATA_WIDTH(Cw), |
.MAX_DEPTH (MAX_PCK) |
) |
class_fifo |
( |
.din (class_in), |
.wr_en (hdr_flit_wr[i]), // Write enable |
.rd_en (class_rd_fifo[i]), // Read the next word |
.dout (class_out[i]), // Data out |
.full (), |
.nearly_full (), |
.recieve_more_than_0 (), |
.recieve_more_than_1 (), |
.reset (reset), |
.clk (clk) |
|
); |
end else begin :c_num_1 |
.C(C), |
.V(V) |
)class_table |
( |
.class_in (class_out[i]), |
.candidate_ovcs (candidate_ovcs [(i+1)*V-1 : i*V]) |
); |
|
|
//tail fifo |
fwft_fifo #( |
.DATA_WIDTH(1), |
.MAX_DEPTH (B), |
.IGNORE_SAME_LOC_RD_WR_WARNING(SSA_EN) |
) |
tail_fifo |
( |
.din (flg_hdr_in [TAIL_FLG]), |
.wr_en (flit_wr [i]), // Write enable |
.rd_en (ivc_num_getting_sw_grant[i]), // Read the next word |
.dout (flit_is_tail[i]), // Data out |
.full (), |
.nearly_full (), |
.recieve_more_than_0 (), |
.recieve_more_than_1 (), |
.reset (reset), |
.clk (clk) |
|
); |
|
//class_fifo |
if(C>1)begin :cb1 |
fwft_fifo #( |
.DATA_WIDTH(Cw), |
.MAX_DEPTH (MAX_PCK) |
) |
class_fifo |
( |
.din (class_in), |
.wr_en (hdr_flit_wr[i]), // Write enable |
.rd_en (class_rd_fifo[i]), // Read the next word |
.dout (class_out[i]), // Data out |
.full (), |
.nearly_full (), |
.recieve_more_than_0 (), |
.recieve_more_than_1 (), |
.reset (reset), |
.clk (clk) |
|
); |
end else begin :c_num_1 |
assign class_out[i] = 1'b0; |
end |
//lk_dst_fifo |
//lk_dst_fifo |
|
fwft_fifo #( |
.DATA_WIDTH(P_1), |
.MAX_DEPTH (MAX_PCK) |
) |
lk_dest_fifo |
( |
.din (lk_destination_in), |
.wr_en (hdr_flit_wr_delayed [i]), // Write enable |
.rd_en (lk_dst_rd_fifo [i]), // Read the next word |
.dout (lk_destination [(i+1)*P_1-1 : i*P_1]), // Data out |
.full (), |
.nearly_full (), |
.recieve_more_than_0 (), |
.recieve_more_than_1 (), |
.reset (reset), |
.clk (clk) |
|
); |
|
if( ROUTE_TYPE=="DETERMINISTIC") begin : dtrmn_dest |
fwft_fifo #( |
.DATA_WIDTH(P_1), |
.MAX_DEPTH (MAX_PCK) |
) |
lk_dest_fifo |
( |
.din (lk_destination_in), |
.wr_en (hdr_flit_wr_delayed [i]), // Write enable |
.rd_en (lk_dst_rd_fifo [i]), // Read the next word |
.dout (lk_destination [(i+1)*P_1-1 : i*P_1]), // Data out |
.full (), |
.nearly_full (), |
.recieve_more_than_0 (), |
.recieve_more_than_1 (), |
.reset (reset), |
.clk (clk) |
|
); |
|
if( ROUTE_TYPE=="DETERMINISTIC") begin : dtrmn_dest |
//destport_fifo |
fwft_fifo #( |
.DATA_WIDTH(P_1), |
441,11 → 442,11
.reset (reset), |
.clk (clk) |
|
); |
end else begin : adptv_dest |
|
|
|
); |
end else begin : adptv_dest |
|
|
|
fwft_fifo_with_output_clear #( |
.DATA_WIDTH(P_1), |
.MAX_DEPTH (MAX_PCK) |
465,17 → 466,17
.clear ({2'b00,destport_ab_clear[((i+1)*2)-1 : i*2]}) // dest_port_in ={x,y,a,b} |
|
); |
|
|
end |
|
|
if( ROUTE_TYPE=="FULL_ADAPTIVE" && ROUTE_SUBFUNC=="ODD_EVEN") begin :odd |
|
|
end |
|
|
if( ROUTE_TYPE=="FULL_ADAPTIVE" && ROUTE_SUBFUNC=="ODD_EVEN") begin :odd |
wire x_diff_is_one_in; |
assign x_diff_is_one_in =(current_x==(NX-1'b1))? 1'b0 : (x_dst_in == (current_x + 1'b1)); |
|
|
fwft_fifo #( |
|
|
fwft_fifo #( |
.DATA_WIDTH(1), |
.MAX_DEPTH (MAX_PCK) |
) |
493,31 → 494,31
.clk (clk) |
|
); |
|
|
end else begin : no_odd |
|
assign x_diff_is_one={V{1'bX}}; |
|
end |
|
end//for i |
|
assign flit_wr = (flit_in_we )? vc_num_in : {V{1'b0}}; |
|
always @(posedge clk or posedge reset) begin |
if(reset) begin |
lk_dst_rd_fifo <= {V{1'b0}}; |
end else begin |
lk_dst_rd_fifo <= dst_rd_fifo; |
end |
end//always |
|
|
assign dst_rd_fifo = reset_ivc; |
assign class_rd_fifo = reset_ivc; |
assign ivc_request = ivc_not_empty; |
|
|
|
end else begin : no_odd |
|
assign x_diff_is_one={V{1'bX}}; |
|
end |
|
end//for i |
|
assign flit_wr = (flit_in_we )? vc_num_in : {V{1'b0}}; |
|
always @(posedge clk or posedge reset) begin |
if(reset) begin |
lk_dst_rd_fifo <= {V{1'b0}}; |
end else begin |
lk_dst_rd_fifo <= dst_rd_fifo; |
end |
end//always |
|
|
assign dst_rd_fifo = reset_ivc; |
assign class_rd_fifo = reset_ivc; |
assign ivc_request = ivc_not_empty; |
|
|
|
|
578,59 → 579,59
|
|
|
|
|
endgenerate |
|
|
endgenerate |
|
|
|
|
look_ahead_routing #( |
.P (P), |
.NX (NX), |
.NY (NY), |
.SW_LOC (SW_LOC), |
.TOPOLOGY (TOPOLOGY), |
.ROUTE_NAME(ROUTE_NAME), |
.ROUTE_TYPE(ROUTE_TYPE) |
)lk_routing |
( |
.current_x (current_x), |
.current_y (current_y), |
.dest_x (x_dst_in), |
.dest_y (y_dst_in), |
.destport (destport_in), |
.lkdestport (lk_destination_in), |
.reset (reset), |
.clk (clk) |
); |
look_ahead_routing #( |
.P (P), |
.NX (NX), |
.NY (NY), |
.SW_LOC (SW_LOC), |
.TOPOLOGY (TOPOLOGY), |
.ROUTE_NAME(ROUTE_NAME), |
.ROUTE_TYPE(ROUTE_TYPE) |
)lk_routing |
( |
.current_x (current_x), |
.current_y (current_y), |
.dest_x (x_dst_in), |
.dest_y (y_dst_in), |
.destport (destport_in), |
.lkdestport (lk_destination_in), |
.reset (reset), |
.clk (clk) |
); |
|
|
|
|
|
flit_update #( |
.V(V), |
.P(P), |
.Fpay(Fpay), |
.DST_ADR_HDR_WIDTH(DST_ADR_HDR_WIDTH), |
flit_update #( |
.V(V), |
.P(P), |
.Fpay(Fpay), |
.DST_ADR_HDR_WIDTH(DST_ADR_HDR_WIDTH), |
.SRC_ADR_HDR_WIDTH(SRC_ADR_HDR_WIDTH), |
.ROUTE_TYPE(ROUTE_TYPE), |
.SSA_EN(SSA_EN) |
.ROUTE_TYPE(ROUTE_TYPE), |
.SSA_EN(SSA_EN) |
|
) |
the_flit_update |
( |
.flit_in (buffer_out), |
.flit_out (flit_out), |
.vc_num_in (ivc_num_getting_sw_grant), |
.lk_dest_all_in (lk_destination), |
.assigned_ovc_num (assigned_ovc_num), |
.any_ivc_sw_request_granted(any_ivc_sw_request_granted), |
.lk_dest_not_registered(lk_destination_in), |
.sel (sel), |
.reset (reset), |
.clk (clk) |
); |
) |
the_flit_update |
( |
.flit_in (buffer_out), |
.flit_out (flit_out), |
.vc_num_in (ivc_num_getting_sw_grant), |
.lk_dest_all_in (lk_destination), |
.assigned_ovc_num (assigned_ovc_num), |
.any_ivc_sw_request_granted(any_ivc_sw_request_granted), |
.lk_dest_not_registered(lk_destination_in), |
.sel (sel), |
.reset (reset), |
.clk (clk) |
); |
|
//synthesis translate_off |
//synopsys translate_off |
638,25 → 639,25
generate |
if(DEBUG_EN) begin :dbg |
|
wire [V-1 : 0] vc_num_hdr_wr, vc_num_tail_wr,vc_num_bdy_wr ; |
reg [V-1 : 0] hdr_passed, hdr_passed_next; |
|
assign vc_num_hdr_wr = (flg_hdr_in[HDR_FLG] && flit_in_we)? vc_num_in : 0; |
assign vc_num_tail_wr = (flg_hdr_in[TAIL_FLG]&& flit_in_we)? vc_num_in : 0; |
assign vc_num_bdy_wr = (flg_hdr_in == 2'b00 && flit_in_we)? vc_num_in : 0; |
always @(*)begin |
hdr_passed_next = (hdr_passed | vc_num_hdr_wr) & ~vc_num_tail_wr; |
end |
|
always @ (posedge clk or posedge reset) begin |
if(reset) hdr_passed <= 0; |
else begin |
hdr_passed <= hdr_passed_next; |
if (( hdr_passed & vc_num_hdr_wr)>0 ) $display("%t :Error: a header flit received in an active IVC %m",$time); |
if ((~hdr_passed & vc_num_tail_wr)>0 ) $display("%t :Error: a tail flit received in an inactive IVC %m",$time); |
if ((~hdr_passed & vc_num_bdy_wr )>0) $display("%t :Error: a body flit received in an inactive IVC %m",$time); |
end |
end |
wire [V-1 : 0] vc_num_hdr_wr, vc_num_tail_wr,vc_num_bdy_wr ; |
reg [V-1 : 0] hdr_passed, hdr_passed_next; |
|
assign vc_num_hdr_wr = (flg_hdr_in[HDR_FLG] && flit_in_we)? vc_num_in : 0; |
assign vc_num_tail_wr = (flg_hdr_in[TAIL_FLG]&& flit_in_we)? vc_num_in : 0; |
assign vc_num_bdy_wr = (flg_hdr_in == 2'b00 && flit_in_we)? vc_num_in : 0; |
always @(*)begin |
hdr_passed_next = (hdr_passed | vc_num_hdr_wr) & ~vc_num_tail_wr; |
end |
|
always @ (posedge clk or posedge reset) begin |
if(reset) hdr_passed <= 0; |
else begin |
hdr_passed <= hdr_passed_next; |
if (( hdr_passed & vc_num_hdr_wr)>0 ) $display("%t :Error: a header flit received in an active IVC %m",$time); |
if ((~hdr_passed & vc_num_tail_wr)>0 ) $display("%t :Error: a tail flit received in an inactive IVC %m",$time); |
if ((~hdr_passed & vc_num_bdy_wr )>0) $display("%t :Error: a body flit received in an inactive IVC %m",$time); |
end |
end |
|
localparam LOCAL = 0, |
// EAST = 1, |
738,8 → 739,8
|
|
/*********************************** |
|
flit_update |
|
flit_update |
|
**********************************/ |
module flit_update #( |
749,7 → 750,7
parameter DST_ADR_HDR_WIDTH =8, |
parameter SRC_ADR_HDR_WIDTH =8, |
parameter ROUTE_TYPE = "DETERMINISTIC", |
parameter SSA_EN ="YES" |
parameter SSA_EN ="YES" |
)( |
flit_in , |
flit_out, |
777,8 → 778,8
input reset,clk; |
input [VV-1 : 0] assigned_ovc_num; |
input [V-1 : 0] sel; |
input any_ivc_sw_request_granted; |
input [P_1-1 : 0] lk_dest_not_registered; |
input any_ivc_sw_request_granted; |
input [P_1-1 : 0] lk_dest_not_registered; |
|
generate |
if(ROUTE_TYPE == "DETERMINISTIC") begin :dtrmn |
793,14 → 794,14
the_flit_update |
( |
.flit_in(flit_in), |
.flit_out(flit_out), |
.vc_num_in(vc_num_in), |
.lk_dest_all_in(lk_dest_all_in), |
.assigned_ovc_num(assigned_ovc_num), |
.flit_out(flit_out), |
.vc_num_in(vc_num_in), |
.lk_dest_all_in(lk_dest_all_in), |
.assigned_ovc_num(assigned_ovc_num), |
.any_ivc_sw_request_granted(any_ivc_sw_request_granted), |
.lk_dest_not_registered(lk_dest_not_registered), |
.reset(reset), |
.clk(clk) |
.reset(reset), |
.clk(clk) |
); |
|
|
835,108 → 836,108
|
|
module flit_update_dtrmn #( |
parameter V = 4, |
parameter P = 5, |
parameter Fpay = 32, |
parameter DST_ADR_HDR_WIDTH =8, |
parameter V = 4, |
parameter P = 5, |
parameter Fpay = 32, |
parameter DST_ADR_HDR_WIDTH =8, |
parameter SRC_ADR_HDR_WIDTH =8, |
parameter SSA_EN ="YES" |
parameter SSA_EN ="YES" |
|
|
)( |
flit_in , |
flit_out, |
vc_num_in, |
lk_dest_all_in, |
assigned_ovc_num, |
any_ivc_sw_request_granted, |
lk_dest_not_registered, |
reset, |
clk |
flit_in , |
flit_out, |
vc_num_in, |
lk_dest_all_in, |
assigned_ovc_num, |
any_ivc_sw_request_granted, |
lk_dest_not_registered, |
reset, |
clk |
); |
|
localparam Fw = 2+V+Fpay, |
P_1 = P-1, |
VP_1 = V * P_1, |
VV = V * V; |
|
localparam DEST_LOC_LSB = SRC_ADR_HDR_WIDTH+DST_ADR_HDR_WIDTH, |
DEST_LOC_HSB = DEST_LOC_LSB+P_1-1; |
|
localparam Fw = 2+V+Fpay, |
P_1 = P-1, |
VP_1 = V * P_1, |
VV = V * V; |
|
localparam DEST_LOC_LSB = SRC_ADR_HDR_WIDTH+DST_ADR_HDR_WIDTH, |
DEST_LOC_HSB = DEST_LOC_LSB+P_1-1; |
|
|
input [Fw-1 : 0] flit_in; |
output reg [Fw-1 : 0] flit_out; |
input [V-1 : 0] vc_num_in; |
input [VP_1-1 : 0] lk_dest_all_in; |
input reset,clk; |
input [VV-1 : 0] assigned_ovc_num; |
input any_ivc_sw_request_granted; |
input [P_1-1 : 0] lk_dest_not_registered; |
|
wire hdr_flag; |
reg [V-1 : 0] vc_num_delayed; |
wire [V-1 : 0] ovc_num; |
//reg [VV-1 : 0] assigned_ovc_num_delayed; |
wire [P_1-1 : 0] lk_mux_out; |
wire [P_1-1 : 0] lk_dest; |
|
always @(posedge clk or posedge reset) begin |
if(reset) begin |
vc_num_delayed <= {V{1'b0}}; |
//assigned_ovc_num_delayed <= {VV{1'b0}}; |
end else begin |
vc_num_delayed<= vc_num_in; |
//assigned_ovc_num_delayed <=assigned_ovc_num; |
end |
end |
|
assign hdr_flag = flit_in[Fw-1]; |
|
one_hot_mux #( |
.IN_WIDTH (VP_1), |
.SEL_WIDTH (V) |
) |
lkdest_mux |
( |
.mux_in (lk_dest_all_in), |
.mux_out (lk_mux_out), |
.sel (vc_num_delayed) |
); |
|
one_hot_mux #( |
.IN_WIDTH (VV), |
.SEL_WIDTH (V) |
) |
ovc_num_mux |
( |
.mux_in (assigned_ovc_num), |
.mux_out (ovc_num), |
.sel (vc_num_delayed) |
); |
input [Fw-1 : 0] flit_in; |
output reg [Fw-1 : 0] flit_out; |
input [V-1 : 0] vc_num_in; |
input [VP_1-1 : 0] lk_dest_all_in; |
input reset,clk; |
input [VV-1 : 0] assigned_ovc_num; |
input any_ivc_sw_request_granted; |
input [P_1-1 : 0] lk_dest_not_registered; |
|
wire hdr_flag; |
reg [V-1 : 0] vc_num_delayed; |
wire [V-1 : 0] ovc_num; |
//reg [VV-1 : 0] assigned_ovc_num_delayed; |
wire [P_1-1 : 0] lk_mux_out; |
wire [P_1-1 : 0] lk_dest; |
|
always @(posedge clk or posedge reset) begin |
if(reset) begin |
vc_num_delayed <= {V{1'b0}}; |
//assigned_ovc_num_delayed <= {VV{1'b0}}; |
end else begin |
vc_num_delayed<= vc_num_in; |
//assigned_ovc_num_delayed <=assigned_ovc_num; |
end |
end |
|
assign hdr_flag = flit_in[Fw-1]; |
|
one_hot_mux #( |
.IN_WIDTH (VP_1), |
.SEL_WIDTH (V) |
) |
lkdest_mux |
( |
.mux_in (lk_dest_all_in), |
.mux_out (lk_mux_out), |
.sel (vc_num_delayed) |
); |
|
one_hot_mux #( |
.IN_WIDTH (VV), |
.SEL_WIDTH (V) |
) |
ovc_num_mux |
( |
.mux_in (assigned_ovc_num), |
.mux_out (ovc_num), |
.sel (vc_num_delayed) |
); |
|
generate |
if( SSA_EN == "YES" ) begin : predict // bypass the lk fifo when no ivc is granted |
reg ivc_any_delayed; |
always @(posedge clk or posedge reset) begin |
if(reset) begin |
ivc_any_delayed <= 1'b0; |
end else begin |
ivc_any_delayed <= any_ivc_sw_request_granted; |
end |
end |
|
assign lk_dest = (ivc_any_delayed == 1'b0)? lk_dest_not_registered : lk_mux_out; |
generate |
if( SSA_EN == "YES" ) begin : predict // bypass the lk fifo when no ivc is granted |
reg ivc_any_delayed; |
always @(posedge clk or posedge reset) begin |
if(reset) begin |
ivc_any_delayed <= 1'b0; |
end else begin |
ivc_any_delayed <= any_ivc_sw_request_granted; |
end |
end |
|
assign lk_dest = (ivc_any_delayed == 1'b0)? lk_dest_not_registered : lk_mux_out; |
|
end else begin : no_predict |
assign lk_dest =lk_mux_out; |
end |
endgenerate |
end else begin : no_predict |
assign lk_dest =lk_mux_out; |
end |
endgenerate |
|
|
always @(*)begin |
flit_out = {flit_in[Fw-1 : Fw-2],ovc_num,flit_in[Fpay-1 :0]}; |
if(hdr_flag) flit_out[DEST_LOC_HSB : DEST_LOC_LSB]= lk_dest; |
end |
|
always @(*)begin |
flit_out = {flit_in[Fw-1 : Fw-2],ovc_num,flit_in[Fpay-1 :0]}; |
if(hdr_flag) flit_out[DEST_LOC_HSB : DEST_LOC_LSB]= lk_dest; |
end |
endmodule |
|
|
947,7 → 948,7
parameter Fpay = 32, |
parameter DST_ADR_HDR_WIDTH = 8, |
parameter SRC_ADR_HDR_WIDTH = 8, |
parameter SSA_EN ="YES" |
parameter SSA_EN ="YES" |
)( |
flit_in , |
flit_out, |
977,8 → 978,8
input reset,clk; |
input [VV-1 : 0] assigned_ovc_num; |
input [V-1 : 0] sel; |
input any_ivc_sw_request_granted; |
input [P_1-1 : 0] lk_dest_not_registered; |
input any_ivc_sw_request_granted; |
input [P_1-1 : 0] lk_dest_not_registered; |
|
wire hdr_flag; |
reg [V-1 : 0] vc_num_delayed; |
1012,23 → 1013,23
); |
|
|
generate |
if( SSA_EN == "YES" ) begin : predict // bypass the lk fifo when no ivc is granted |
reg ivc_any_delayed; |
always @(posedge clk or posedge reset) begin |
if(reset) begin |
ivc_any_delayed <= 1'b0; |
end else begin |
ivc_any_delayed <= any_ivc_sw_request_granted; |
end |
end |
|
assign lk_dest = (ivc_any_delayed == 1'b0)? lk_dest_not_registered : lk_mux_out; |
generate |
if( SSA_EN == "YES" ) begin : predict // bypass the lk fifo when no ivc is granted |
reg ivc_any_delayed; |
always @(posedge clk or posedge reset) begin |
if(reset) begin |
ivc_any_delayed <= 1'b0; |
end else begin |
ivc_any_delayed <= any_ivc_sw_request_granted; |
end |
end |
|
assign lk_dest = (ivc_any_delayed == 1'b0)? lk_dest_not_registered : lk_mux_out; |
|
end else begin : no_predict |
assign lk_dest =lk_mux_out; |
end |
endgenerate |
end else begin : no_predict |
assign lk_dest =lk_mux_out; |
end |
endgenerate |
|
|
|
1101,34 → 1102,35
hdr_flit_wr, |
flg_hdr_in |
); |
// minimum flit size is 32 width |
// for flit size >= 32 bits |
/* header flit format |
31--------------24 23--------16 15--------8 7-----0 |
message_class_data routing_info destination_address source_address |
*/ |
|
function integer log2; |
input integer number; begin |
log2=0; |
log2=(number <=1) ? 1: 0; |
while(2**log2<number) begin |
log2=log2+1; |
end |
end |
end |
endfunction // log2 |
|
localparam ADDR_DIMENTION = (TOPOLOGY == "MESH" || TOPOLOGY == "TORUS") ? 2 : 1, // "RING" and FULLY_CONNECT |
ALL_DATA_HDR_WIDTH = CLASS_HDR_WIDTH+ROUTING_HDR_WIDTH+DST_ADR_HDR_WIDTH+SRC_ADR_HDR_WIDTH, |
HDR_FLG = 1, |
P_1 = P-1 , |
ALL_DATA_HDR_WIDTH = CLASS_HDR_WIDTH+ROUTING_HDR_WIDTH+DST_ADR_HDR_WIDTH+SRC_ADR_HDR_WIDTH, |
HDR_FLG = 1, |
P_1 = P-1 , |
Fw = 2+V+Fpay,//flit width |
Xw = log2(NX), |
Yw = log2(NY), |
Cw = (C>1)? log2(C): 1; |
|
|
|
input [Fw-1 : 0] flit_in; |
|
|
input [Fw-1 : 0] flit_in; |
input flit_in_we; |
output [Cw-1 : 0] class_in; |
output [Cw-1 : 0] class_in; |
output [P_1-1 : 0] destport_in; |
output [Xw-1 : 0] x_dst_in; |
output [Yw-1 : 0] y_dst_in; |
1137,19 → 1139,19
//output [Yw-1 : 0] Z_dst_in; |
output [V-1 : 0] vc_num_in; |
output [V-1 : 0] hdr_flit_wr; |
output [1 : 0] flg_hdr_in; |
|
|
|
output [1 : 0] flg_hdr_in; |
|
|
|
wire [CLASS_HDR_WIDTH-1 : 0] class_hdr; |
wire [ROUTING_HDR_WIDTH-1 : 0] routing_hdr; |
wire [DST_ADR_HDR_WIDTH-1 : 0] dst_adr_hdr; |
wire [SRC_ADR_HDR_WIDTH-1 : 0] src_adr_hdr; |
|
|
|
assign {class_hdr,routing_hdr,dst_adr_hdr,src_adr_hdr}= flit_in [ALL_DATA_HDR_WIDTH-1 :0]; |
|
|
|
|
assign {class_hdr,routing_hdr,dst_adr_hdr,src_adr_hdr}= flit_in [ALL_DATA_HDR_WIDTH-1 :0]; |
|
|
//x_dst_hdr, y_dst_hdr, x_src_hdr, y_src_hdr |
generate |
1166,14 → 1168,14
end |
endgenerate |
|
|
|
assign vc_num_in = flit_in [Fpay+V-1 : Fpay]; |
assign flg_hdr_in= flit_in [Fw-1 : Fw-2]; |
assign class_in = class_hdr [Cw-1 : 0]; |
|
assign destport_in= routing_hdr [P_1-1 : 0]; |
assign hdr_flit_wr= (flit_in_we & flg_hdr_in[HDR_FLG] )? vc_num_in : {V{1'b0}}; |
|
|
assign vc_num_in = flit_in [Fpay+V-1 : Fpay]; |
assign flg_hdr_in= flit_in [Fw-1 : Fw-2]; |
assign class_in = class_hdr [Cw-1 : 0]; |
|
assign destport_in= routing_hdr [P_1-1 : 0]; |
assign hdr_flit_wr= (flit_in_we & flg_hdr_in[HDR_FLG] )? vc_num_in : {V{1'b0}}; |
|
endmodule |
|
/src_noc/main_comp.v
213,14 → 213,15
|
); |
|
|
function integer log2; |
input integer number; begin |
log2=0; |
log2=(number <=1) ? 1: 0; |
while(2**log2<number) begin |
log2=log2+1; |
end |
end |
end |
endfunction // log2 |
endfunction // log2 |
|
localparam MUX_IN_WIDTH = BIN_WIDTH* ONE_HOT_WIDTH; |
|
274,12 → 275,13
|
); |
|
|
function integer log2; |
input integer number; begin |
log2=0; |
log2=(number <=1) ? 1: 0; |
while(2**log2<number) begin |
log2=log2+1; |
end |
end |
end |
endfunction // log2 |
|
324,14 → 326,15
output [OUT_WIDTH-1 : 0] out |
|
); |
|
function integer log2; |
input integer number; begin |
log2=0; |
log2=(number <=1) ? 1: 0; |
while(2**log2<number) begin |
log2=log2+1; |
end |
end |
end |
endfunction // log2 |
endfunction // log2 |
|
|
wire [IN_WIDTH-2 : 0] addrin2; |
375,14 → 378,15
output result |
|
); |
|
function integer log2; |
input integer number; begin |
log2=0; |
log2=(number <=1) ? 1: 0; |
while(2**log2<number) begin |
log2=log2+1; |
end |
end |
end |
endfunction // log2 |
endfunction // log2 |
|
|
|
458,14 → 462,15
); |
|
|
|
function integer log2; |
input integer number; begin |
log2=0; |
log2=(number <=1) ? 1: 0; |
while(2**log2<number) begin |
log2=log2+1; |
end |
end |
end |
endfunction // log2 |
endfunction // log2 |
|
localparam OUT_WIDTH = log2(IN_WIDTH+1); |
localparam PCIw = (IN_WIDTH < 8 )? 7 : |
/src_noc/noc.v
24,10 → 24,10
parameter ROUTE_SUBFUNC ="XY", |
parameter AVC_ATOMIC_EN=1, |
parameter ADD_PIPREG_AFTER_CROSSBAR=0, |
parameter CVw=(C==0)? V : C * V, |
parameter [CVw-1: 0] CLASS_SETTING = {CVw{1'b1}}, // shows how each class can use VCs |
parameter [V-1 : 0] ESCAP_VC_MASK = 4'b1000, // mask scape vc, valid only for full adaptive |
parameter SSA_EN="YES" // "YES" , "NO" |
parameter CVw=(C==0)? V : C * V, |
parameter [CVw-1: 0] CLASS_SETTING = {CVw{1'b1}}, // shows how each class can use VCs |
parameter [V-1 : 0] ESCAP_VC_MASK = 4'b1000, // mask scape vc, valid only for full adaptive |
parameter SSA_EN="YES" // "YES" , "NO" |
|
)( |
reset, |
53,14 → 53,14
|
localparam P= (TOPOLOGY=="RING")? 3 : 5; |
|
function integer log2; |
input integer number; begin |
log2=0; |
while(2**log2<number) begin |
log2=log2+1; |
end |
end |
endfunction // log2 |
function integer log2; |
input integer number; begin |
log2=(number <=1) ? 1: 0; |
while(2**log2<number) begin |
log2=log2+1; |
end |
end |
endfunction // log2 |
|
localparam PV = V * P, |
P_1 = P-1 , |
171,6 → 171,18
assign router_congestion_in_all [`SELECT_WIRE(x,0,1,CONGw)] = router_congestion_out_all [`SELECT_WIRE(0,0,2,CONGw)]; |
end |
|
if(x>0)begin :not_first_x |
assign router_flit_in_all [`SELECT_WIRE(x,0,2,Fw)] = router_flit_out_all [`SELECT_WIRE((x-1),0,1,Fw)]; |
assign router_credit_in_all [`SELECT_WIRE(x,0,2,V)] = router_credit_out_all [`SELECT_WIRE((x-1),0,1,V)] ; |
assign router_flit_in_we_all [x][2] = router_flit_out_we_all [`CORE_NUM((x-1),0)][1]; |
assign router_congestion_in_all[`SELECT_WIRE(x,0,2,CONGw)] = router_congestion_out_all [`SELECT_WIRE((x-1),0,1,CONGw)]; |
end else begin :first_x |
assign router_flit_in_all [`SELECT_WIRE(x,0,2,Fw)] = router_flit_out_all [`SELECT_WIRE((NX-1),0,1,Fw)] ; |
assign router_credit_in_all [`SELECT_WIRE(x,0,2,V)] = router_credit_out_all [`SELECT_WIRE((NX-1),0,1,V)] ; |
assign router_flit_in_we_all [x][2] = router_flit_out_we_all [`CORE_NUM((NX-1),0)][1]; |
assign router_congestion_in_all [`SELECT_WIRE(x,0,2,CONGw)] = router_congestion_out_all [`SELECT_WIRE((NX-1),0,1,CONGw)]; |
end |
|
// local port connection |
assign router_flit_in_all [`SELECT_WIRE(x,0,0,Fw)] = ni_flit_out [x]; |
assign router_credit_in_all [`SELECT_WIRE(x,0,0,V)] = ni_credit_out [x]; |
/src_noc/route_mesh.v
1,97 → 1,98
`timescale 1ns/1ps |
`timescale 1ns/1ps |
|
/******************************************** |
Deterministic |
Deterministic |
*********************************************/ |
|
|
/***************************************************** |
xy_mesh_routing |
/***************************************************** |
xy_mesh_routing |
|
*****************************************************/ |
*****************************************************/ |
|
|
|
module xy_mesh_routing #( |
parameter NX = 4, |
parameter NY = 3, |
parameter OUT_BIN = 1 // 1: destination port is in binary format 0: onehot |
parameter NX = 4, |
parameter NY = 3, |
parameter OUT_BIN = 1 // 1: destination port is in binary format 0: onehot |
) |
( |
current_x, // current router x address |
current_y, // current router y address |
dest_x, // destination x address |
dest_y, // destination y address |
destport // router output port |
|
current_x, // current router x address |
current_y, // current router y address |
dest_x, // destination x address |
dest_y, // destination y address |
destport // router output port |
|
); |
|
function integer log2; |
input integer number; begin |
log2=0; |
while(2**log2<number) begin |
log2=log2+1; |
end |
end |
endfunction // log2 |
|
|
localparam P = 5; // router port number is always 5 in a mesh topology |
|
localparam Xw = log2(NX), |
Yw = log2(NY), |
Pw = log2(P), |
DSTw = (OUT_BIN)? Pw : P; |
function integer log2; |
input integer number; begin |
log2=(number <=1) ? 1: 0; |
while(2**log2<number) begin |
log2=log2+1; |
end |
end |
endfunction // log2 |
|
|
|
input [Xw-1 :0] current_x; |
input [Yw-1 :0] current_y; |
input [Xw-1 :0] dest_x; |
input [Yw-1 :0] dest_y; |
output [DSTw-1 :0] destport; |
localparam P = 5; // router port number is always 5 in a mesh topology |
|
localparam Xw = log2(NX), |
Yw = log2(NY), |
Pw = log2(P), |
DSTw = (OUT_BIN)? Pw : P; |
|
|
|
|
|
input [Xw-1 :0] current_x; |
input [Yw-1 :0] current_y; |
input [Xw-1 :0] dest_x; |
input [Yw-1 :0] dest_y; |
output [DSTw-1 :0] destport; |
|
localparam LOCAL = (OUT_BIN==1)? 0 : 1 ,//5'b00001 |
EAST = (OUT_BIN==1)? 1 : 2 ,//5'b00010 |
NORTH = (OUT_BIN==1)? 2 : 4 ,//5'b00100 |
WEST = (OUT_BIN==1)? 3 : 8 ,//5'b01000 |
SOUTH = (OUT_BIN==1)? 4 : 16 ;//5'b10000 |
|
|
reg [DSTw-1 :0] destport_next; |
|
|
|
assign destport= destport_next; |
|
always@(*)begin |
destport_next = LOCAL [DSTw-1 :0]; |
if (dest_x > current_x) destport_next = EAST [DSTw-1 :0]; |
else if (dest_x < current_x) destport_next = WEST [DSTw-1 :0]; |
else begin |
if (dest_y > current_y) destport_next = SOUTH [DSTw-1:0]; |
else if (dest_y < current_y) destport_next = NORTH [DSTw-1 :0]; |
end |
end |
|
|
|
|
|
localparam LOCAL = (OUT_BIN==1)? 0 : 1 ,//5'b00001 |
EAST = (OUT_BIN==1)? 1 : 2 ,//5'b00010 |
NORTH = (OUT_BIN==1)? 2 : 4 ,//5'b00100 |
WEST = (OUT_BIN==1)? 3 : 8 ,//5'b01000 |
SOUTH = (OUT_BIN==1)? 4 : 16 ;//5'b10000 |
|
|
reg [DSTw-1 :0] destport_next; |
|
|
|
assign destport= destport_next; |
|
always@(*)begin |
destport_next = LOCAL [DSTw-1 :0]; |
if (dest_x > current_x) destport_next = EAST [DSTw-1 :0]; |
else if (dest_x < current_x) destport_next = WEST [DSTw-1 :0]; |
else begin |
if (dest_y > current_y) destport_next = SOUTH [DSTw-1:0]; |
else if (dest_y < current_y) destport_next = NORTH [DSTw-1 :0]; |
end |
end |
|
|
endmodule |
|
/******************************************** |
Partial adaptive |
The west-first routing algorithm does not allow turns from north to west or from south to west. |
Partial adaptive |
The west-first routing algorithm does not allow turns from north to west or from south to west. |
The north last routing algorithm does not allow turns from north to east or from north to west. |
The negetive fist routing algorithm does net allow turns from north to west or from east to south. |
|
|
|
*********************************************/ |
|
/************************************ |
|
west-first |
|
west-first |
|
*************************************/ |
module west_first_routing #( |
parameter NX = 4, |
106,14 → 107,15
|
); |
|
|
function integer log2; |
input integer number; begin |
log2=0; |
log2=(number <=1) ? 1: 0; |
while(2**log2<number) begin |
log2=log2+1; |
end |
end |
end |
endfunction // log2 |
endfunction // log2 |
|
localparam P = 5, |
P_1 = P-1, |
215,14 → 217,15
|
); |
|
|
function integer log2; |
input integer number; begin |
log2=0; |
log2=(number <=1) ? 1: 0; |
while(2**log2<number) begin |
log2=log2+1; |
end |
end |
end |
endfunction // log2 |
endfunction // log2 |
|
localparam P = 5, |
P_1 = P-1, |
245,8 → 248,8
wire x_plus,x_min,y_plus,y_min,same_x,same_y; |
|
mesh_dir #( |
.NX(NX), |
.NY(NY) |
.NX(NX), |
.NY(NY) |
) |
dir( |
.current_x(current_x), |
253,13 → 256,13
.current_y(current_y), |
.dest_x(dest_x), |
.dest_y(dest_y), |
.x_plus(x_plus), |
.x_min(x_min), |
.y_plus(y_plus), |
.y_min(y_min), |
.same_x(same_x), |
.same_y(same_y) |
|
.x_plus(x_plus), |
.x_min(x_min), |
.y_plus(y_plus), |
.y_min(y_min), |
.same_x(same_x), |
.same_y(same_y) |
|
); |
|
reg [4 : 0] possible_out_port; |
334,14 → 337,15
|
); |
|
|
function integer log2; |
input integer number; begin |
log2=0; |
log2=(number <=1) ? 1: 0; |
while(2**log2<number) begin |
log2=log2+1; |
end |
end |
end |
endfunction // log2 |
endfunction // log2 |
|
localparam P = 5, |
P_1 = P-1, |
440,122 → 444,123
|
|
module odd_even_routing #( |
parameter NX = 4, |
parameter NY = 4, |
parameter LOCATED_IN_NI = 1 // 1: the router locaed inside ni |
// 0: the routing module located inside router |
) |
( |
current_x, // current router x address |
current_y, // current router y address |
dest_x, // destination x address |
dest_y, // destination y address |
destport // router output port |
|
); |
parameter NX = 4, |
parameter NY = 4, |
parameter LOCATED_IN_NI = 1 // 1: the router locaed inside ni |
// 0: the routing module located inside router |
) |
( |
current_x, // current router x address |
current_y, // current router y address |
dest_x, // destination x address |
dest_y, // destination y address |
destport // router output port |
|
); |
|
|
|
function integer log2; |
input integer number; begin |
log2=0; |
while(2**log2<number) begin |
log2=log2+1; |
end |
end |
endfunction // log2 |
|
localparam P = 5, |
P_1 = P-1, |
Xw = log2(NX), |
Yw = log2(NY); |
|
|
|
function integer log2; |
input integer number; begin |
log2=(number <=1) ? 1: 0; |
while(2**log2<number) begin |
log2=log2+1; |
end |
end |
endfunction // log2 |
|
localparam P = 5, |
P_1 = P-1, |
Xw = log2(NX), |
Yw = log2(NY); |
|
input [Xw-1 :0] current_x; |
input [Yw-1 :0] current_y; |
input [Xw-1 :0] dest_x; |
input [Yw-1 :0] dest_y; |
output [P_1-1 :0] destport; |
|
|
|
localparam LOCAL = 3'd0; |
localparam EAST = 3'd1; |
localparam NORTH = 3'd2; |
localparam WEST = 3'd3; |
localparam SOUTH = 3'd4; |
|
wire signed [Xw :0] xc;//current |
wire signed [Xw :0] xd;//destination |
wire signed [Yw :0] yc;//current |
wire signed [Yw :0] yd;//destination |
wire signed [Xw :0] xdiff; |
wire signed [Yw :0] ydiff; |
|
|
assign xc ={1'b0, current_x [Xw-1 :0]}; |
assign yc ={1'b0, current_y [Yw-1 :0]}; |
assign xd ={1'b0, dest_x}; |
assign yd ={1'b0, dest_y}; |
assign xdiff = xd-xc; |
assign ydiff = yd-yc; |
|
reg [P-1 : 0] possible_out_port; |
|
|
|
always @(*)begin |
possible_out_port = 5'd0; |
if (xdiff == 0 && ydiff == 0) begin |
possible_out_port [LOCAL]=1'b1; |
end |
else if(xdiff ==0) begin //currently in the same column as destination |
if( ydiff<0) begin |
possible_out_port [NORTH]=1'b1; |
end else begin |
possible_out_port [SOUTH]=1'b1; |
end |
end |
else if(ydiff == 0) begin //currently in the same row as destination |
if( xdiff<0) begin |
possible_out_port [WEST]=1'b1; |
end else begin |
possible_out_port [EAST]=1'b1; |
end |
end |
else begin |
if(xdiff>0)begin //east_bound |
if(ydiff == 0) begin |
possible_out_port [EAST]=1'b1; |
end |
else begin |
if(current_x[0] || (LOCATED_IN_NI == 1)) begin |
if( ydiff<0) begin |
possible_out_port [NORTH]=1'b1; |
end else begin |
possible_out_port [SOUTH]=1'b1; |
end |
end |
if(dest_x[0] || xdiff!=1) begin // //odd destination column or >= 2 columns to destination |
possible_out_port [EAST]=1'b1; |
end |
end |
end |
else begin // west_bound |
possible_out_port [WEST] = 1'b1; |
if(current_x[0]== 1'b0) begin //even column |
if( ydiff<0) begin |
possible_out_port [NORTH]=1'b1; |
end else begin |
possible_out_port [SOUTH]=1'b1; |
end |
end |
end |
end |
end |
|
|
|
// code the destination port |
input [Xw-1 :0] current_x; |
input [Yw-1 :0] current_y; |
input [Xw-1 :0] dest_x; |
input [Yw-1 :0] dest_y; |
output [P_1-1 :0] destport; |
|
|
|
localparam LOCAL = 3'd0; |
localparam EAST = 3'd1; |
localparam NORTH = 3'd2; |
localparam WEST = 3'd3; |
localparam SOUTH = 3'd4; |
|
wire signed [Xw :0] xc;//current |
wire signed [Xw :0] xd;//destination |
wire signed [Yw :0] yc;//current |
wire signed [Yw :0] yd;//destination |
wire signed [Xw :0] xdiff; |
wire signed [Yw :0] ydiff; |
|
|
assign xc ={1'b0, current_x [Xw-1 :0]}; |
assign yc ={1'b0, current_y [Yw-1 :0]}; |
assign xd ={1'b0, dest_x}; |
assign yd ={1'b0, dest_y}; |
assign xdiff = xd-xc; |
assign ydiff = yd-yc; |
|
reg [P-1 : 0] possible_out_port; |
|
|
|
always @(*)begin |
possible_out_port = 5'd0; |
if (xdiff == 0 && ydiff == 0) begin |
possible_out_port [LOCAL]=1'b1; |
end |
else if(xdiff ==0) begin //currently in the same column as destination |
if( ydiff<0) begin |
possible_out_port [NORTH]=1'b1; |
end else begin |
possible_out_port [SOUTH]=1'b1; |
end |
end |
else if(ydiff == 0) begin //currently in the same row as destination |
if( xdiff<0) begin |
possible_out_port [WEST]=1'b1; |
end else begin |
possible_out_port [EAST]=1'b1; |
end |
end |
else begin |
if(xdiff>0)begin //east_bound |
if(ydiff == 0) begin |
possible_out_port [EAST]=1'b1; |
end |
else begin |
if(current_x[0] || (LOCATED_IN_NI == 1)) begin |
if( ydiff<0) begin |
possible_out_port [NORTH]=1'b1; |
end else begin |
possible_out_port [SOUTH]=1'b1; |
end |
end |
if(dest_x[0] || xdiff!=1) begin // //odd destination column or >= 2 columns to destination |
possible_out_port [EAST]=1'b1; |
end |
end |
end |
else begin // west_bound |
possible_out_port [WEST] = 1'b1; |
if(current_x[0]== 1'b0) begin //even column |
if( ydiff<0) begin |
possible_out_port [NORTH]=1'b1; |
end else begin |
possible_out_port [SOUTH]=1'b1; |
end |
end |
end |
end |
end |
|
|
|
// code the destination port |
wire x,y,a,b; |
assign x = (xdiff > 0); |
assign y = (ydiff < 0); |
563,63 → 568,64
assign b = possible_out_port[NORTH]| possible_out_port[SOUTH]; |
assign destport = {x,y,a,b}; |
|
|
|
|
|
|
|
endmodule |
|
|
/*********************************** |
fully adaptive |
fully adaptive |
|
***********************************/ |
|
|
/************************************ |
|
|
/************************************ |
|
Duato’s Fully Adaptive |
Duato’s Fully Adaptive |
The packet which can travel in both x & y dimention can not use the reserved VC in y axies |
*************************************/ |
|
|
|
*************************************/ |
|
|
|
module duato_mesh_routing #( |
parameter NX = 4, |
parameter NY = 4 |
) |
( |
current_x, // current router x address |
current_y, // current router y address |
dest_x, // destination x address |
dest_y, // destination y address |
destport // router output port |
|
); |
parameter NX = 4, |
parameter NY = 4 |
) |
( |
current_x, // current router x address |
current_y, // current router y address |
dest_x, // destination x address |
dest_y, // destination y address |
destport // router output port |
|
); |
|
|
|
function integer log2; |
input integer number; begin |
log2=0; |
while(2**log2<number) begin |
log2=log2+1; |
end |
end |
endfunction // log2 |
|
|
localparam P = 5, |
P_1 = P-1, |
Xw = log2(NX), |
Yw = log2(NY); |
|
|
|
function integer log2; |
input integer number; begin |
log2=(number <=1) ? 1: 0; |
while(2**log2<number) begin |
log2=log2+1; |
end |
end |
endfunction // log2 |
|
|
localparam P = 5, |
P_1 = P-1, |
Xw = log2(NX), |
Yw = log2(NY); |
|
input [Xw-1 :0] current_x; |
input [Yw-1 :0] current_y; |
input [Xw-1 :0] dest_x; |
input [Yw-1 :0] dest_y; |
output [P_1-1 :0] destport; |
input [Xw-1 :0] current_x; |
input [Yw-1 :0] current_y; |
input [Xw-1 :0] dest_x; |
input [Yw-1 :0] dest_y; |
output [P_1-1 :0] destport; |
|
|
|
|
localparam LOCAL= 3'd0, |
EAST = 3'd1, |
NORTH= 3'd2, |
646,11 → 652,11
.same_y(same_y) |
|
); |
|
|
reg [P-1 : 0] possible_out_port; |
|
always @(*)begin |
|
|
reg [P-1 : 0] possible_out_port; |
|
always @(*)begin |
possible_out_port = 5'd0; |
if(same_x && same_y) begin |
possible_out_port [LOCAL]=1'b1; |
685,7 → 691,7
end |
end |
|
|
|
// code the destination port |
wire x,y,a,b; |
assign x = x_plus; |
693,15 → 699,15
assign a = possible_out_port[EAST] | possible_out_port[WEST]; |
assign b = possible_out_port[NORTH]| possible_out_port[SOUTH]; |
assign destport = {x,y,a,b}; |
|
|
|
|
|
|
endmodule |
|
|
|
|
|
|
|
|
module mesh_dir #( |
parameter NX = 4, |
parameter NY = 4 |
718,14 → 724,15
same_y |
); |
|
|
function integer log2; |
input integer number; begin |
log2=0; |
log2=(number <=1) ? 1: 0; |
while(2**log2<number) begin |
log2=log2+1; |
end |
end |
end |
endfunction // log2 |
endfunction // log2 |
|
localparam Xw = log2(NX), |
Yw = log2(NY); |
/src_noc/route_torus.v
2,37 → 2,37
|
|
/******************************************** |
Deterministic |
Deterministic |
*********************************************/ |
|
/******************************************** |
TRANC |
*********************************************/ |
/******************************************** |
TRANC |
*********************************************/ |
module tranc_xy_routing #( |
parameter NX = 4, |
parameter NY = 4, |
parameter OUT_BIN = 0 // 1: destination port is in binary format 0: onehot |
|
parameter NX = 4, |
parameter NY = 4, |
parameter OUT_BIN = 0 // 1: destination port is in binary format 0: onehot |
|
) |
( |
current_x, |
current_y, |
dest_x, |
dest_y, |
destport |
|
current_x, |
current_y, |
dest_x, |
dest_y, |
destport |
|
); |
|
|
function integer log2; |
input integer number; begin |
log2=0; |
log2=(number <=1) ? 1: 0; |
while(2**log2<number) begin |
log2=log2+1; |
end |
end |
end |
endfunction // log2 |
|
|
|
localparam P = 5, |
Xw = log2(NX), |
Yw = log2(NY), |
39,13 → 39,13
Pw = log2(P), |
DSTw = (OUT_BIN)? Pw : P; |
|
|
|
input [Xw-1 : 0] current_x; |
input [Yw-1 : 0] current_y; |
input [Xw-1 : 0] dest_x; |
input [Yw-1 : 0] dest_y; |
output [DSTw -1 : 0] destport; |
|
|
localparam LOCAL = (OUT_BIN)? 3'd0 : 5'b00001, |
EAST = (OUT_BIN)? 3'd1 : 5'b00010, |
NORTH = (OUT_BIN)? 3'd2 : 5'b00100, |
52,54 → 52,54
WEST = (OUT_BIN)? 3'd3 : 5'b01000, |
SOUTH = (OUT_BIN)? 3'd4 : 5'b10000; |
|
reg [DSTw-1 :0] destport_next; |
wire tranc_x_plus,tranc_y_plus,tranc_x_min,tranc_y_min; |
wire same_x,same_y; |
|
|
tranc_dir #( |
.NX(NX), |
.NY(NY) |
) |
tranc_dir( |
.tranc_x_plus(tranc_x_plus), |
.tranc_x_min(tranc_x_min), |
.tranc_y_plus(tranc_y_plus), |
.tranc_y_min(tranc_y_min), |
.same_x(same_x), |
.same_y(same_y), |
.current_x(current_x), |
.current_y(current_y), |
.dest_x(dest_x), |
.dest_y(dest_y) |
|
); |
|
always@(*)begin |
if (same_x & same_y) destport_next= LOCAL; |
else begin |
if (tranc_x_plus) destport_next= EAST; |
else if (tranc_x_min) destport_next= WEST; |
else if (tranc_y_plus) destport_next= SOUTH; |
else destport_next= NORTH; |
end |
end |
reg [DSTw-1 :0] destport_next; |
wire tranc_x_plus,tranc_y_plus,tranc_x_min,tranc_y_min; |
wire same_x,same_y; |
|
|
tranc_dir #( |
.NX(NX), |
.NY(NY) |
) |
tranc_dir( |
.tranc_x_plus(tranc_x_plus), |
.tranc_x_min(tranc_x_min), |
.tranc_y_plus(tranc_y_plus), |
.tranc_y_min(tranc_y_min), |
.same_x(same_x), |
.same_y(same_y), |
.current_x(current_x), |
.current_y(current_y), |
.dest_x(dest_x), |
.dest_y(dest_y) |
|
); |
|
always@(*)begin |
if (same_x & same_y) destport_next= LOCAL; |
else begin |
if (tranc_x_plus) destport_next= EAST; |
else if (tranc_x_min) destport_next= WEST; |
else if (tranc_y_plus) destport_next= SOUTH; |
else destport_next= NORTH; |
end |
end |
|
assign destport= destport_next; |
|
endmodule |
assign destport= destport_next; |
|
endmodule |
|
/******************************************** |
Partial adaptive |
Partial adaptive |
*********************************************/ |
|
/******************************************** |
TRANC West-First |
*********************************************/ |
/******************************************** |
TRANC West-First |
*********************************************/ |
|
|
module tranc_west_first_routing #( |
parameter NX = 4, |
|
module tranc_west_first_routing #( |
parameter NX = 4, |
parameter NY = 4 |
) |
( |
114,14 → 114,15
|
|
|
|
function integer log2; |
input integer number; begin |
log2=0; |
log2=(number <=1) ? 1: 0; |
while(2**log2<number) begin |
log2=log2+1; |
end |
end |
end |
endfunction // log2 |
endfunction // log2 |
|
|
localparam P = 5, |
142,8 → 143,8
localparam NORTH= 3'd2; |
localparam WEST = 3'd3; |
localparam SOUTH= 3'd4; |
|
wire tranc_x_plus,tranc_y_plus,tranc_x_min,tranc_y_min; |
|
wire tranc_x_plus,tranc_y_plus,tranc_x_min,tranc_y_min; |
wire same_x,same_y; |
|
|
164,37 → 165,37
.dest_y(dest_y) |
|
); |
|
reg [P-1 : 0] possible_out_port; |
|
always @(*)begin |
possible_out_port = 5'd0; |
if(same_x && same_y) begin |
possible_out_port [LOCAL]=1'b1; |
end |
else if (tranc_x_min) begin |
possible_out_port [WEST] = 1'b1; |
end |
else if (tranc_x_plus && tranc_y_min) begin |
possible_out_port [EAST]=1'b1; |
possible_out_port [NORTH]=1'b1; |
end |
else if(tranc_x_plus && tranc_y_plus) begin |
possible_out_port [EAST]=1'b1; |
possible_out_port [SOUTH]=1'b1; |
end |
else if( tranc_x_plus && same_y) begin |
possible_out_port [EAST]=1'b1; |
end |
else if(same_x && tranc_y_min) begin |
possible_out_port [NORTH]=1'b1; |
end |
else if(same_x && tranc_y_plus) begin |
possible_out_port [SOUTH]=1'b1; |
end |
end |
|
// code the destination port |
|
reg [P-1 : 0] possible_out_port; |
|
always @(*)begin |
possible_out_port = 5'd0; |
if(same_x && same_y) begin |
possible_out_port [LOCAL]=1'b1; |
end |
else if (tranc_x_min) begin |
possible_out_port [WEST] = 1'b1; |
end |
else if (tranc_x_plus && tranc_y_min) begin |
possible_out_port [EAST]=1'b1; |
possible_out_port [NORTH]=1'b1; |
end |
else if(tranc_x_plus && tranc_y_plus) begin |
possible_out_port [EAST]=1'b1; |
possible_out_port [SOUTH]=1'b1; |
end |
else if( tranc_x_plus && same_y) begin |
possible_out_port [EAST]=1'b1; |
end |
else if(same_x && tranc_y_min) begin |
possible_out_port [NORTH]=1'b1; |
end |
else if(same_x && tranc_y_plus) begin |
possible_out_port [SOUTH]=1'b1; |
end |
end |
|
// code the destination port |
wire x,y,a,b; |
assign x = tranc_x_plus; |
assign y = tranc_y_plus; |
201,13 → 202,13
assign a = possible_out_port[EAST] | possible_out_port[WEST]; |
assign b = possible_out_port[NORTH]| possible_out_port[SOUTH]; |
assign destport = {x,y,a,b}; |
|
|
endmodule |
|
|
|
/******************************************** |
|
|
endmodule |
|
|
|
/******************************************** |
TRANC North-Last |
*********************************************/ |
|
228,14 → 229,16
|
|
|
|
|
function integer log2; |
input integer number; begin |
log2=0; |
log2=(number <=1) ? 1: 0; |
while(2**log2<number) begin |
log2=log2+1; |
end |
end |
end |
endfunction // log2 |
endfunction // log2 |
|
|
localparam P = 5, |
329,8 → 332,8
|
|
endmodule |
|
|
|
|
|
|
/******************************************** |
354,14 → 357,15
|
|
|
|
function integer log2; |
input integer number; begin |
log2=0; |
log2=(number <=1) ? 1: 0; |
while(2**log2<number) begin |
log2=log2+1; |
end |
end |
end |
endfunction // log2 |
endfunction // log2 |
|
|
localparam P = 5, |
459,20 → 463,20
|
|
/*********************************** |
fully adaptive |
fully adaptive |
|
***********************************/ |
|
/************************************ |
/************************************ |
|
Duato’s Fully Adaptive |
Duato’s Fully Adaptive |
|
*************************************/ |
|
|
|
module tranc_duato_routing #( |
parameter NX = 4, |
*************************************/ |
|
|
|
module tranc_duato_routing #( |
parameter NX = 4, |
parameter NY = 4 |
) |
( |
487,14 → 491,15
|
|
|
|
function integer log2; |
input integer number; begin |
log2=0; |
log2=(number <=1) ? 1: 0; |
while(2**log2<number) begin |
log2=log2+1; |
end |
end |
end |
endfunction // log2 |
endfunction // log2 |
|
|
localparam P = 5, |
515,9 → 520,9
localparam NORTH= 3'd2; |
localparam WEST = 3'd3; |
localparam SOUTH= 3'd4; |
|
|
wire tranc_x_plus,tranc_y_plus,tranc_x_min,tranc_y_min; |
|
|
wire tranc_x_plus,tranc_y_plus,tranc_x_min,tranc_y_min; |
wire same_x,same_y; |
|
|
538,48 → 543,48
.dest_y(dest_y) |
|
); |
|
|
reg [P-1 : 0] possible_out_port; |
|
|
always @(*)begin |
possible_out_port = 5'd0; |
if(same_x && same_y) begin |
possible_out_port [LOCAL]=1'b1; |
end |
else if (tranc_x_min && tranc_y_min) begin |
possible_out_port [WEST]= 1'b1; |
possible_out_port [NORTH]= 1'b1; |
end |
else if (tranc_x_min && tranc_y_plus) begin |
possible_out_port [WEST]= 1'b1; |
possible_out_port [SOUTH]= 1'b1; |
end |
else if (tranc_x_min && same_y) begin |
possible_out_port [WEST]= 1'b1; |
end |
else if (tranc_x_plus && tranc_y_min) begin |
possible_out_port [EAST]= 1'b1; |
possible_out_port [NORTH]= 1'b1; |
|
end |
else if (tranc_x_plus && tranc_y_plus) begin |
possible_out_port [EAST]= 1'b1; |
possible_out_port [SOUTH]= 1'b1; |
end |
else if (tranc_x_plus && same_y) begin |
possible_out_port [EAST]= 1'b1; |
end |
else if (same_x && tranc_y_min) begin |
possible_out_port [NORTH]= 1'b1; |
end |
else if (same_x && tranc_y_plus) begin |
possible_out_port [SOUTH]= 1'b1; |
end |
end |
|
// code the destination port |
|
|
reg [P-1 : 0] possible_out_port; |
|
|
always @(*)begin |
possible_out_port = 5'd0; |
if(same_x && same_y) begin |
possible_out_port [LOCAL]=1'b1; |
end |
else if (tranc_x_min && tranc_y_min) begin |
possible_out_port [WEST]= 1'b1; |
possible_out_port [NORTH]= 1'b1; |
end |
else if (tranc_x_min && tranc_y_plus) begin |
possible_out_port [WEST]= 1'b1; |
possible_out_port [SOUTH]= 1'b1; |
end |
else if (tranc_x_min && same_y) begin |
possible_out_port [WEST]= 1'b1; |
end |
else if (tranc_x_plus && tranc_y_min) begin |
possible_out_port [EAST]= 1'b1; |
possible_out_port [NORTH]= 1'b1; |
|
end |
else if (tranc_x_plus && tranc_y_plus) begin |
possible_out_port [EAST]= 1'b1; |
possible_out_port [SOUTH]= 1'b1; |
end |
else if (tranc_x_plus && same_y) begin |
possible_out_port [EAST]= 1'b1; |
end |
else if (same_x && tranc_y_min) begin |
possible_out_port [NORTH]= 1'b1; |
end |
else if (same_x && tranc_y_plus) begin |
possible_out_port [SOUTH]= 1'b1; |
end |
end |
|
// code the destination port |
wire x,y,a,b; |
assign x = tranc_x_plus; |
assign y = tranc_y_plus; |
586,18 → 591,18
assign a = possible_out_port[EAST] | possible_out_port[WEST]; |
assign b = possible_out_port[NORTH]| possible_out_port[SOUTH]; |
assign destport = {x,y,a,b}; |
|
|
endmodule |
|
|
|
/**************************************** |
|
tranc_dir |
|
|
****************************************/ |
|
|
endmodule |
|
|
|
/**************************************** |
|
tranc_dir |
|
|
****************************************/ |
|
module tranc_dir #( |
parameter NX = 4, |
616,14 → 621,15
); |
|
|
|
function integer log2; |
input integer number; begin |
log2=0; |
log2=(number <=1) ? 1: 0; |
while(2**log2<number) begin |
log2=log2+1; |
end |
end |
end |
endfunction // log2 |
endfunction // log2 |
|
|
localparam Xw = log2(NX), |
657,8 → 663,8
assign yd ={{(SIGNED_Y_WIDTH-Yw){1'b0}}, dest_y}; |
assign xdiff = xd-xc; |
assign ydiff = yd-yc; |
|
always@ (*)begin |
|
always@ (*)begin |
tranc_x_plus =1'b0; |
tranc_x_min =1'b0; |
tranc_y_plus =1'b0; |
/src_noc/router.v
1,23 → 1,23
`timescale 1ns/1ps |
`timescale 1ns/1ps |
|
|
|
module router # ( |
parameter V = 4, // vc_num_per_port |
parameter P = 5, // router port num |
parameter B = 4, // buffer space :flit per VC |
parameter NX = 8, // number of node in x axis |
parameter NY = 8, // number of node in y axis |
parameter C = 2, // number of flit class |
parameter Fpay = 32, |
parameter TOPOLOGY= "MESH", |
parameter MUX_TYPE= "ONE_HOT", //"ONE_HOT" or "BINARY" |
parameter VC_REALLOCATION_TYPE = "NONATOMIC",// "ATOMIC" , "NONATOMIC" |
parameter COMBINATION_TYPE= "COMB_SPEC1",// "BASELINE", "COMB_SPEC1", "COMB_SPEC2", "COMB_NONSPEC" |
parameter FIRST_ARBITER_EXT_P_EN = 0, |
parameter ROUTE_TYPE = "FULL_ADAPTIVE",// "DETERMINISTIC", "FULL_ADAPTIVE", "PAR_ADAPTIVE" |
parameter ROUTE_NAME = "DUATO", |
parameter CONGESTION_INDEX = 7, |
parameter V = 4, // vc_num_per_port |
parameter P = 5, // router port num |
parameter B = 4, // buffer space :flit per VC |
parameter NX = 8, // number of node in x axis |
parameter NY = 8, // number of node in y axis |
parameter C = 2, // number of flit class |
parameter Fpay = 32, |
parameter TOPOLOGY= "MESH", |
parameter MUX_TYPE= "ONE_HOT", //"ONE_HOT" or "BINARY" |
parameter VC_REALLOCATION_TYPE = "NONATOMIC",// "ATOMIC" , "NONATOMIC" |
parameter COMBINATION_TYPE= "COMB_SPEC1",// "BASELINE", "COMB_SPEC1", "COMB_SPEC2", "COMB_NONSPEC" |
parameter FIRST_ARBITER_EXT_P_EN = 0, |
parameter ROUTE_TYPE = "FULL_ADAPTIVE",// "DETERMINISTIC", "FULL_ADAPTIVE", "PAR_ADAPTIVE" |
parameter ROUTE_NAME = "DUATO", |
parameter CONGESTION_INDEX = 7, |
parameter DEBUG_EN=0, |
parameter ROUTE_SUBFUNC= "XY", |
parameter AVC_ATOMIC_EN= 0, |
30,110 → 30,110
parameter X = 0, // router x address |
parameter Y = 0 // router y address |
)( |
current_x, |
current_y, |
flit_in_all, |
flit_in_we_all, |
credit_out_all, |
congestion_in_all, |
|
flit_out_all, |
flit_out_we_all, |
credit_in_all, |
congestion_out_all, |
|
clk,reset |
current_x, |
current_y, |
flit_in_all, |
flit_in_we_all, |
credit_out_all, |
congestion_in_all, |
|
flit_out_all, |
flit_out_we_all, |
credit_in_all, |
congestion_out_all, |
|
clk,reset |
|
); |
|
function integer log2; |
input integer number; begin |
log2=0; |
while(2**log2<number) begin |
log2=log2+1; |
end |
end |
endfunction // log2 |
function integer log2; |
input integer number; begin |
log2=(number <=1) ? 1: 0; |
while(2**log2<number) begin |
log2=log2+1; |
end |
end |
endfunction // log2 |
|
|
|
|
|
localparam PV = V * P, |
PVV = PV * V, |
P_1 = P-1 , |
PP_1 = P_1 * P, |
PVP_1 = PV * P_1; |
localparam PV = V * P, |
PVV = PV * V, |
P_1 = P-1 , |
PP_1 = P_1 * P, |
PVP_1 = PV * P_1; |
|
localparam Fw = 2+V+Fpay, //flit width; |
PFw = P*Fw, |
localparam Fw = 2+V+Fpay, //flit width; |
PFw = P*Fw, |
Xw = log2(NX), |
Yw = log2(NY), |
CONG_ALw= CONGw* P; // congestion width per router |
|
|
|
input [Xw-1 : 0] current_x; |
input [Yw-1 : 0] current_y; |
|
input [PFw-1 : 0] flit_in_all; |
input [P-1 : 0] flit_in_we_all; |
output [PV-1 : 0] credit_out_all; |
input [CONG_ALw-1 : 0] congestion_in_all; |
|
output [PFw-1 : 0] flit_out_all; |
output [P-1 : 0] flit_out_we_all; |
input [PV-1 : 0] credit_in_all; |
output [CONG_ALw-1 : 0] congestion_out_all; |
|
input clk,reset; |
|
input [Xw-1 : 0] current_x; |
input [Yw-1 : 0] current_y; |
|
input [PFw-1 : 0] flit_in_all; |
input [P-1 : 0] flit_in_we_all; |
output [PV-1 : 0] credit_out_all; |
input [CONG_ALw-1 : 0] congestion_in_all; |
|
output [PFw-1 : 0] flit_out_all; |
output [P-1 : 0] flit_out_we_all; |
input [PV-1 : 0] credit_in_all; |
output [CONG_ALw-1 : 0] congestion_out_all; |
|
input clk,reset; |
|
|
//internal wires |
wire [PV-1 : 0] ovc_allocated_all; |
wire [PVV-1 : 0] granted_ovc_num_all; |
wire [PV-1 : 0] ivc_num_getting_sw_grant; |
wire [PV-1 : 0] ivc_num_getting_ovc_grant; |
wire [PVV-1 : 0] spec_ovc_num_all; |
wire [PV-1 : 0] nonspec_first_arbiter_granted_ivc_all; |
wire [PV-1 : 0] spec_first_arbiter_granted_ivc_all; |
wire [PP_1-1 : 0] nonspec_granted_dest_port_all; |
wire [PP_1-1 : 0] spec_granted_dest_port_all; |
wire [PP_1-1 : 0] granted_dest_port_all; |
wire [P-1 : 0] any_ivc_sw_request_granted_all; |
wire [P-1 : 0] any_ovc_granted_in_outport_all; |
|
// to vc/sw allocator |
wire [PVP_1-1 : 0] dest_port_all; |
wire [PV-1 : 0] ovc_is_assigned_all; |
wire [PV-1 : 0] ivc_request_all; |
wire [PV-1 : 0] assigned_ovc_not_full_all; |
wire [PVV-1 : 0] masked_ovc_request_all; |
wire [PVP_1-1 : 0] lk_destination_all; |
//internal wires |
wire [PV-1 : 0] ovc_allocated_all; |
wire [PVV-1 : 0] granted_ovc_num_all; |
wire [PV-1 : 0] ivc_num_getting_sw_grant; |
wire [PV-1 : 0] ivc_num_getting_ovc_grant; |
wire [PVV-1 : 0] spec_ovc_num_all; |
wire [PV-1 : 0] nonspec_first_arbiter_granted_ivc_all; |
wire [PV-1 : 0] spec_first_arbiter_granted_ivc_all; |
wire [PP_1-1 : 0] nonspec_granted_dest_port_all; |
wire [PP_1-1 : 0] spec_granted_dest_port_all; |
wire [PP_1-1 : 0] granted_dest_port_all; |
wire [P-1 : 0] any_ivc_sw_request_granted_all; |
wire [P-1 : 0] any_ovc_granted_in_outport_all; |
|
// to vc/sw allocator |
wire [PVP_1-1 : 0] dest_port_all; |
wire [PV-1 : 0] ovc_is_assigned_all; |
wire [PV-1 : 0] ivc_request_all; |
wire [PV-1 : 0] assigned_ovc_not_full_all; |
wire [PVV-1 : 0] masked_ovc_request_all; |
wire [PVP_1-1 : 0] lk_destination_all; |
|
|
|
|
// to the crossbar |
wire [PFw-1 : 0] iport_flit_out_all; |
wire [P-1 : 0] ssa_flit_wr_all; |
|
|
// to the crossbar |
wire [PFw-1 : 0] iport_flit_out_all; |
wire [P-1 : 0] ssa_flit_wr_all; |
|
reg [PP_1-1 : 0] granted_dest_port_all_delayed; |
|
|
inout_ports |
reg [PP_1-1 : 0] granted_dest_port_all_delayed; |
|
|
inout_ports |
#( |
.V(V), |
.P(P), |
.B(B), |
.NX(NX), |
.NY(NY), |
.C(C), |
.Fpay(Fpay), |
.VC_REALLOCATION_TYPE(VC_REALLOCATION_TYPE), |
.COMBINATION_TYPE(COMBINATION_TYPE), |
.TOPOLOGY(TOPOLOGY), |
.ROUTE_TYPE(ROUTE_TYPE), |
.ROUTE_NAME(ROUTE_NAME), |
.V(V), |
.P(P), |
.B(B), |
.NX(NX), |
.NY(NY), |
.C(C), |
.Fpay(Fpay), |
.VC_REALLOCATION_TYPE(VC_REALLOCATION_TYPE), |
.COMBINATION_TYPE(COMBINATION_TYPE), |
.TOPOLOGY(TOPOLOGY), |
.ROUTE_TYPE(ROUTE_TYPE), |
.ROUTE_NAME(ROUTE_NAME), |
.CONGESTION_INDEX(CONGESTION_INDEX), |
.DEBUG_EN(DEBUG_EN), |
.ROUTE_SUBFUNC(ROUTE_SUBFUNC), |
144,161 → 144,163
.ESCAP_VC_MASK(ESCAP_VC_MASK), |
.SSA_EN(SSA_EN), |
.X(X), |
.Y(Y) |
.Y(Y) |
) |
the_inout_ports |
( |
.current_x(current_x), |
.current_y(current_y), |
.flit_in_all(flit_in_all), |
.flit_in_we_all(flit_in_we_all), |
.credit_out_all(credit_out_all), |
.credit_in_all(credit_in_all), |
.masked_ovc_request_all(masked_ovc_request_all), |
.ovc_allocated_all(ovc_allocated_all), |
.granted_ovc_num_all(granted_ovc_num_all), |
.ivc_num_getting_sw_grant(ivc_num_getting_sw_grant), |
.ivc_num_getting_ovc_grant(ivc_num_getting_ovc_grant), |
.spec_ovc_num_all(spec_ovc_num_all), |
.nonspec_first_arbiter_granted_ivc_all(nonspec_first_arbiter_granted_ivc_all), |
.spec_first_arbiter_granted_ivc_all(spec_first_arbiter_granted_ivc_all), |
.nonspec_granted_dest_port_all(nonspec_granted_dest_port_all), |
.spec_granted_dest_port_all(spec_granted_dest_port_all), |
.granted_dest_port_all(granted_dest_port_all), |
.any_ivc_sw_request_granted_all(any_ivc_sw_request_granted_all), |
.any_ovc_granted_in_outport_all(any_ovc_granted_in_outport_all), |
.dest_port_all(dest_port_all), |
.ovc_is_assigned_all(ovc_is_assigned_all), |
.ivc_request_all(ivc_request_all), |
.assigned_ovc_not_full_all(assigned_ovc_not_full_all), |
.flit_out_all(iport_flit_out_all), |
.congestion_in_all(congestion_in_all), |
.congestion_out_all(congestion_out_all), |
.lk_destination_all(lk_destination_all), |
.current_x(current_x), |
.current_y(current_y), |
.flit_in_all(flit_in_all), |
.flit_in_we_all(flit_in_we_all), |
.credit_out_all(credit_out_all), |
.credit_in_all(credit_in_all), |
.masked_ovc_request_all(masked_ovc_request_all), |
.ovc_allocated_all(ovc_allocated_all), |
.granted_ovc_num_all(granted_ovc_num_all), |
.ivc_num_getting_sw_grant(ivc_num_getting_sw_grant), |
.ivc_num_getting_ovc_grant(ivc_num_getting_ovc_grant), |
.spec_ovc_num_all(spec_ovc_num_all), |
.nonspec_first_arbiter_granted_ivc_all(nonspec_first_arbiter_granted_ivc_all), |
.spec_first_arbiter_granted_ivc_all(spec_first_arbiter_granted_ivc_all), |
.nonspec_granted_dest_port_all(nonspec_granted_dest_port_all), |
.spec_granted_dest_port_all(spec_granted_dest_port_all), |
.granted_dest_port_all(granted_dest_port_all), |
.any_ivc_sw_request_granted_all(any_ivc_sw_request_granted_all), |
.any_ovc_granted_in_outport_all(any_ovc_granted_in_outport_all), |
.dest_port_all(dest_port_all), |
.ovc_is_assigned_all(ovc_is_assigned_all), |
.ivc_request_all(ivc_request_all), |
.assigned_ovc_not_full_all(assigned_ovc_not_full_all), |
.flit_out_all(iport_flit_out_all), |
.congestion_in_all(congestion_in_all), |
.congestion_out_all(congestion_out_all), |
.lk_destination_all(lk_destination_all), |
.ssa_flit_wr_all(ssa_flit_wr_all), |
.clk(clk), |
.reset(reset) |
.clk(clk), |
.reset(reset) |
); |
|
|
combined_vc_sw_alloc #( |
.V(V), //VC number per port |
.P(P), //port number |
.COMBINATION_TYPE(COMBINATION_TYPE), |
.FIRST_ARBITER_EXT_P_EN (FIRST_ARBITER_EXT_P_EN), |
.ROUTE_TYPE(ROUTE_TYPE), |
.ESCAP_VC_MASK(ESCAP_VC_MASK), |
.DEBUG_EN(DEBUG_EN) |
.V(V), //VC number per port |
.P(P), //port number |
.COMBINATION_TYPE(COMBINATION_TYPE), |
.FIRST_ARBITER_EXT_P_EN (FIRST_ARBITER_EXT_P_EN), |
.ROUTE_TYPE(ROUTE_TYPE), |
.ESCAP_VC_MASK(ESCAP_VC_MASK), |
.DEBUG_EN(DEBUG_EN) |
) |
the_combined_vc_sw_alloc |
( |
.dest_port_all(dest_port_all), |
.masked_ovc_request_all(masked_ovc_request_all), |
.ovc_is_assigned_all(ovc_is_assigned_all), |
.ivc_request_all(ivc_request_all), |
.assigned_ovc_not_full_all(assigned_ovc_not_full_all), |
.ovc_allocated_all(ovc_allocated_all), |
.granted_ovc_num_all(granted_ovc_num_all), |
.ivc_num_getting_ovc_grant(ivc_num_getting_ovc_grant), |
.ivc_num_getting_sw_grant(ivc_num_getting_sw_grant), |
.spec_first_arbiter_granted_ivc_all(spec_first_arbiter_granted_ivc_all), |
.nonspec_first_arbiter_granted_ivc_all(nonspec_first_arbiter_granted_ivc_all), |
.nonspec_granted_dest_port_all(nonspec_granted_dest_port_all), |
.spec_granted_dest_port_all(spec_granted_dest_port_all), |
.granted_dest_port_all(granted_dest_port_all), |
.any_ivc_sw_request_granted_all(any_ivc_sw_request_granted_all), |
.any_ovc_granted_in_outport_all(any_ovc_granted_in_outport_all), |
.spec_ovc_num_all(spec_ovc_num_all), |
.lk_destination_all(lk_destination_all), |
.clk(clk), |
.reset(reset) |
); |
|
.dest_port_all(dest_port_all), |
.masked_ovc_request_all(masked_ovc_request_all), |
.ovc_is_assigned_all(ovc_is_assigned_all), |
.ivc_request_all(ivc_request_all), |
.assigned_ovc_not_full_all(assigned_ovc_not_full_all), |
.ovc_allocated_all(ovc_allocated_all), |
.granted_ovc_num_all(granted_ovc_num_all), |
.ivc_num_getting_ovc_grant(ivc_num_getting_ovc_grant), |
.ivc_num_getting_sw_grant(ivc_num_getting_sw_grant), |
.spec_first_arbiter_granted_ivc_all(spec_first_arbiter_granted_ivc_all), |
.nonspec_first_arbiter_granted_ivc_all(nonspec_first_arbiter_granted_ivc_all), |
.nonspec_granted_dest_port_all(nonspec_granted_dest_port_all), |
.spec_granted_dest_port_all(spec_granted_dest_port_all), |
.granted_dest_port_all(granted_dest_port_all), |
.any_ivc_sw_request_granted_all(any_ivc_sw_request_granted_all), |
.any_ovc_granted_in_outport_all(any_ovc_granted_in_outport_all), |
.spec_ovc_num_all(spec_ovc_num_all), |
.lk_destination_all(lk_destination_all), |
.clk(clk), |
.reset(reset) |
); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
always @( posedge clk or posedge reset)begin |
if(reset) begin |
granted_dest_port_all_delayed<= {PP_1{1'b0}}; |
|
end else begin |
granted_dest_port_all_delayed<= granted_dest_port_all; |
|
end |
end//always |
|
|
crossbar #( |
.V (V), // vc_num_per_port |
.P (P), // router port num |
.Fpay (Fpay), |
.MUX_TYPE (MUX_TYPE), |
.ADD_PIPREG_AFTER_CROSSBAR (ADD_PIPREG_AFTER_CROSSBAR), |
.SSA_EN (SSA_EN) |
|
always @( posedge clk or posedge reset)begin |
if(reset) begin |
granted_dest_port_all_delayed<= {PP_1{1'b0}}; |
|
end else begin |
granted_dest_port_all_delayed<= granted_dest_port_all; |
|
end |
end//always |
|
|
crossbar #( |
.V (V), // vc_num_per_port |
.P (P), // router port num |
.Fpay (Fpay), |
.MUX_TYPE (MUX_TYPE), |
.ADD_PIPREG_AFTER_CROSSBAR (ADD_PIPREG_AFTER_CROSSBAR), |
.SSA_EN (SSA_EN) |
) |
the_crossbar |
( |
.granted_dest_port_all (granted_dest_port_all_delayed), |
.flit_in_all (iport_flit_out_all), |
.flit_out_all (flit_out_all), |
.flit_out_we_all (flit_out_we_all), |
.ssa_flit_wr_all (ssa_flit_wr_all), |
.clk (clk), |
.reset (reset) |
|
); |
the_crossbar |
( |
.granted_dest_port_all (granted_dest_port_all_delayed), |
.flit_in_all (iport_flit_out_all), |
.flit_out_all (flit_out_all), |
.flit_out_we_all (flit_out_we_all), |
.ssa_flit_wr_all (ssa_flit_wr_all), |
.clk (clk), |
.reset (reset) |
|
); |
|
|
|
//synthesis translate_off |
//synopsys translate_off |
localparam EAST = 1, |
|
|
//synthesis translate_off |
//synopsys translate_off |
localparam EAST = 1, |
NORTH = 2, |
WEST = 3, |
SOUTH = 4; |
|
generate |
if(DEBUG_EN)begin :dbg |
always @(posedge clk) begin |
if(TOPOLOGY == "MESH")begin |
if(current_x == {Xw{1'b0}} && flit_out_we_all[WEST]) $display ( "%t\t Error: a packet is going to the WEST in a router located in first column in mesh topology %m",$time ); |
if(current_x == NX-1 && flit_out_we_all[EAST]) $display ( "%t\t Error: a packet is going to the EAST in a router located in last column in mesh topology %m",$time ); |
if(current_y == {Yw{1'b0}} && flit_out_we_all[NORTH])$display ( "%t\t Error: a packet is going to the NORTH in a router located in first row in mesh topology %m",$time ); |
if(current_y == NY-1 && flit_out_we_all[SOUTH])$display ( "%t\t Error: a packet is going to the SOUTH in a router located in last row in mesh topology %b %m",$time,flit_out_all[(SOUTH+1)*Fw-1 : SOUTH*Fw] ); |
generate |
if(DEBUG_EN)begin :dbg |
if(TOPOLOGY == "MESH")begin |
always @(posedge clk) begin |
|
if(current_x == {Xw{1'b0}} && flit_out_we_all[WEST]) $display ( "%t\t Error: a packet is going to the WEST in a router located in first column in mesh topology %m",$time ); |
if(current_x == NX-1 && flit_out_we_all[EAST]) $display ( "%t\t Error: a packet is going to the EAST in a router located in last column in mesh topology %m",$time ); |
if(current_y == {Yw{1'b0}} && flit_out_we_all[NORTH])$display ( "%t\t Error: a packet is going to the NORTH in a router located in first row in mesh topology %m",$time ); |
if(current_y == NY-1 && flit_out_we_all[SOUTH])$display ( "%t\t Error: a packet is going to the SOUTH in a router located in last row in mesh topology %b %m",$time,flit_out_all[(SOUTH+1)*Fw-1 : SOUTH*Fw] ); |
|
|
end//always |
end////MESH |
end// DEBUG |
endgenerate |
|
|
|
/* |
// for testing the route path |
reg tt; |
always @(posedge clk) begin |
if(reset) tt<=0; |
else begin |
if(flit_in_we_all>0 && tt==0)begin |
$display("%t : x=%d,Y=%d",$time,current_x,current_y); |
tt<=1; |
end |
end//always |
end// DEBUG |
endgenerate |
|
|
|
/* |
// for testing the route path |
reg tt; |
always @(posedge clk) begin |
if(reset) tt<=0; |
else begin |
if(flit_in_we_all>0 && tt==0)begin |
$display("%t : x=%d,Y=%d",$time,current_x,current_y); |
tt<=1; |
end |
end |
end |
*/ |
/* |
reg [10 : 0] counter; |
reg [31 : 0] flit_counter; |
|
always @(posedge clk or posedge reset) begin |
end |
end |
*/ |
/* |
reg [10 : 0] counter; |
reg [31 : 0] flit_counter; |
|
always @(posedge clk or posedge reset) begin |
if(reset) begin |
flit_counter <=0; |
counter <= 0; |
/src_noc/routing.v
1,4 → 1,4
`timescale 1ns/1ps |
`timescale 1ns/1ps |
/************************************ |
|
look_ahead_routing |
24,14 → 24,15
reset, |
clk |
); |
|
function integer log2; |
input integer number; begin |
log2=0; |
log2=(number <=1) ? 1: 0; |
while(2**log2<number) begin |
log2=log2+1; |
end |
end |
end |
endfunction // log2 |
endfunction // log2 |
|
localparam P_1 = P-1, |
Xw = log2(NX), // number of node in x axis |
54,20 → 55,20
generate |
if(ROUTE_TYPE=="DETERMINISTIC") begin :dtrmst |
deterministic_look_ahead_routing #( |
.P(P), |
.NX(NX), |
.NY(NY), |
.SW_LOC(SW_LOC), |
.TOPOLOGY(TOPOLOGY), |
.ROUTE_NAME(ROUTE_NAME) |
.P(P), |
.NX(NX), |
.NY(NY), |
.SW_LOC(SW_LOC), |
.TOPOLOGY(TOPOLOGY), |
.ROUTE_NAME(ROUTE_NAME) |
) |
deterministic_look_ahead( |
.current_x(current_x), |
.current_y(current_y), |
.dest_x(destx_delayed), |
.dest_y(desty_delayed), |
.destport(destport_delayed), |
.lkdestport(lkdestport) |
.current_x(current_x), |
.current_y(current_y), |
.dest_x(destx_delayed), |
.dest_y(desty_delayed), |
.destport(destport_delayed), |
.lkdestport(lkdestport) |
); |
|
end else begin :adapt |
77,7 → 78,7
.NY(NY), |
.TOPOLOGY(TOPOLOGY), |
.ROUTE_NAME(ROUTE_NAME), |
.ROUTE_TYPE(ROUTE_TYPE) |
.ROUTE_TYPE(ROUTE_TYPE) |
) |
adaptive_look_ahead |
( |
137,13 → 138,14
|
); |
|
|
function integer log2; |
input integer number; begin |
log2=0; |
while(2**log2<number) begin |
input integer number; begin |
log2=(number <=1) ? 1: 0; |
while(2**log2<number) begin |
log2=log2+1; |
end |
end |
end |
end |
endfunction // log2 |
|
|
165,65 → 167,67
wire [Yw-1 : 0] next_y; |
|
add_sw_loc_one_hot #( |
.P(P), |
.SW_LOC(SW_LOC) |
.P(P), |
.SW_LOC(SW_LOC) |
) add_sw_loc |
( |
.destport_in(destport), |
.destport_out(destport_one_hot) |
( |
.destport_in(destport), |
.destport_out(destport_one_hot) |
); |
|
next_router_addr_predictor #( |
.P(P), |
.NX(NX), |
.NY(NY) |
.P(P), |
.TOPOLOGY(TOPOLOGY), |
.NX(NX), |
.NY(NY) |
) |
addr_predictor |
( |
.destport(destport_one_hot), |
.current_x(current_x), |
.current_y(current_y), |
.next_x(next_x), |
.next_y(next_y) |
.destport(destport_one_hot), |
.current_x(current_x), |
.current_y(current_y), |
.next_x(next_x), |
.next_y(next_y) |
); |
|
|
next_router_inport_predictor #( |
.P(5) |
.TOPOLOGY(TOPOLOGY), |
.P(P) |
) |
inport_predictor |
( |
.destport(destport_one_hot), |
.receive_port(receive_port) |
.destport(destport_one_hot), |
.receive_port(receive_port) |
); |
|
|
conventional_routing #( |
.TOPOLOGY(TOPOLOGY), |
.ROUTE_NAME(ROUTE_NAME), |
.ROUTE_TYPE("DETERMINISTIC"), |
.P(P), |
.NX(NX), |
.NY(NY), |
.LOCATED_IN_NI(0) |
.TOPOLOGY(TOPOLOGY), |
.ROUTE_NAME(ROUTE_NAME), |
.ROUTE_TYPE("DETERMINISTIC"), |
.P(P), |
.NX(NX), |
.NY(NY), |
.LOCATED_IN_NI(0) |
) |
conv_routing |
( |
.current_x(next_x), |
.current_y(next_y), |
.dest_x(dest_x), |
.dest_y(dest_y), |
.destport(lkdestport_one_hot) |
|
.current_x(next_x), |
.current_y(next_y), |
.dest_x(dest_x), |
.dest_y(dest_y), |
.destport(lkdestport_one_hot) |
|
); |
|
remove_receive_port_one_hot #( |
.P(P) |
.P(P) |
) |
remove_receive_port_one_hot( |
.destport_in(lkdestport_one_hot), |
.receiver_port(receive_port), |
.destport_out(lkdestport) |
.destport_in(lkdestport_one_hot), |
.receiver_port(receive_port), |
.destport_out(lkdestport) |
); |
|
|
259,13 → 263,14
|
); |
|
|
function integer log2; |
input integer number; begin |
log2=0; |
while(2**log2<number) begin |
input integer number; begin |
log2=(number <=1) ? 1: 0; |
while(2**log2<number) begin |
log2=log2+1; |
end |
end |
end |
end |
endfunction // log2 |
|
|
312,6 → 317,7
|
next_router_addr_predictor #( |
.P(P), |
.TOPOLOGY(TOPOLOGY), |
.NX(NX), |
.NY(NY) |
) |
327,6 → 333,7
|
next_router_addr_predictor #( |
.P(P), |
.TOPOLOGY(TOPOLOGY), |
.NX(NX), |
.NY(NY) |
) |
344,7 → 351,7
ni_conventional_routing #( |
.TOPOLOGY(TOPOLOGY), |
.ROUTE_NAME(ROUTE_NAME), |
.ROUTE_TYPE(ROUTE_TYPE), |
.ROUTE_TYPE(ROUTE_TYPE), |
.P(P), |
.NX(NX), |
.NY(NY), |
362,7 → 369,7
ni_conventional_routing #( |
.TOPOLOGY(TOPOLOGY), |
.ROUTE_NAME(ROUTE_NAME), |
.ROUTE_TYPE(ROUTE_TYPE), |
.ROUTE_TYPE(ROUTE_TYPE), |
.P(P), |
.NX(NX), |
.NY(NY), |
395,6 → 402,7
|
module next_router_addr_predictor #( |
parameter P = 5, |
parameter TOPOLOGY ="MESH", |
parameter NX = 4,//toutal number of router in x direction |
parameter NY = 4//toutal number of router in y direction |
) |
409,20 → 417,23
|
function integer log2; |
input integer number; begin |
log2=0; |
log2=(number <=1) ? 1: 0; |
while(2**log2<number) begin |
log2=log2+1; |
end |
end |
end |
endfunction // log2 |
|
localparam Xw = log2(NX), |
Yw = log2(NY); |
|
// mesh torus |
localparam EAST = 3'd1, |
NORTH = 3'd2, |
WEST = 3'd3, |
SOUTH = 3'd4; |
SOUTH = 3'd4; |
//ring line |
localparam FORWARD = 2'd1, |
BACKWARD= 2'd2; |
|
localparam [Xw-1 : 0] LAST_X_ADDR =(NX[Xw-1 : 0]-1'b1); |
localparam [Yw-1 : 0] LAST_Y_ADDR =(NY[Yw-1 : 0]-1'b1); |
432,29 → 443,59
input [Yw-1 : 0] current_y; |
output reg [Xw-1 : 0] next_x; |
output reg [Yw-1 : 0] next_y; |
|
|
always @(*) begin |
//default values |
next_x= current_x; |
next_y= current_y; |
if(destport[EAST]) begin |
next_x= (current_x==LAST_X_ADDR ) ? {Xw{1'b0}} : current_x+1'b1; |
next_y= current_y; |
end |
else if(destport[NORTH]) begin |
|
generate |
if(TOPOLOGY=="MESH" || TOPOLOGY == "TORUS") begin : mesh |
always @(*) begin |
//default values |
next_x= current_x; |
next_y= (current_y==0)? LAST_Y_ADDR : current_y-1'b1; |
end |
else if(destport[WEST]) begin |
next_x= (current_x==0) ? LAST_X_ADDR : current_x-1'b1; |
next_y= current_y; |
end |
else if(destport[SOUTH]) begin |
next_y= current_y; |
if(destport[EAST]) begin |
next_x= (current_x==LAST_X_ADDR ) ? {Xw{1'b0}} : current_x+1'b1; |
next_y= current_y; |
end |
else if(destport[NORTH]) begin |
next_x= current_x; |
next_y= (current_y==0)? LAST_Y_ADDR : current_y-1'b1; |
end |
else if(destport[WEST]) begin |
next_x= (current_x==0) ? LAST_X_ADDR : current_x-1'b1; |
next_y= current_y; |
end |
else if(destport[SOUTH]) begin |
next_x= current_x; |
next_y= (current_y== LAST_Y_ADDR ) ? {Yw{1'b0}}: current_y+1'b1; |
end |
end//always |
|
end else if(TOPOLOGY=="RING" || TOPOLOGY == "LINE") begin : ring |
|
always @(*) begin |
//default values |
next_x= current_x; |
next_y= (current_y== LAST_Y_ADDR ) ? {Yw{1'b0}}: current_y+1'b1; |
end |
end//always |
next_y= 1'b0; |
if(destport[FORWARD]) begin |
next_x= (current_x==LAST_X_ADDR ) ? {Xw{1'b0}} : current_x+1'b1; |
|
end |
else if(destport[BACKWARD]) begin |
next_x= (current_x=={Xw{1'b0}} ) ? LAST_X_ADDR : current_x-1'b1; |
|
end |
|
end//always |
|
|
end |
//synthesis translate_off |
//synopsys translate_off |
else begin : wrong_topology initial $display("Error: next router inport is not predicted for %s topology",TOPOLOGY); end |
//synopsys translate_on |
//synthesis translate_on |
|
|
|
endgenerate |
endmodule |
|
/******************************************************* |
465,12 → 506,16
********************************************************/ |
|
module next_router_inport_predictor #( |
parameter P = 5 |
parameter TOPOLOGY ="MESH", |
parameter P =5 |
)( |
destport, |
receive_port |
|
); |
|
|
|
input [P-1 : 0] destport; |
output [P-1 : 0] receive_port; |
|
479,12 → 524,30
NORTH = 3'd2, |
WEST = 3'd3, |
SOUTH = 3'd4; |
|
assign receive_port[LOCAL] = destport[LOCAL]; |
assign receive_port[WEST] = destport[EAST]; |
assign receive_port[EAST] = destport[WEST]; |
assign receive_port[NORTH] = destport[SOUTH]; |
assign receive_port[SOUTH] = destport[NORTH]; |
generate |
if(TOPOLOGY=="MESH" || TOPOLOGY == "TORUS") begin : mesh |
|
assign receive_port[LOCAL] = destport[LOCAL]; |
assign receive_port[WEST] = destport[EAST]; |
assign receive_port[EAST] = destport[WEST]; |
assign receive_port[NORTH] = destport[SOUTH]; |
assign receive_port[SOUTH] = destport[NORTH]; |
|
end else if(TOPOLOGY=="RING" || TOPOLOGY == "LINE") begin : ring |
assign receive_port[LOCAL] = destport[LOCAL]; |
assign receive_port[1] = destport[2]; |
assign receive_port[2] = destport[1]; |
end |
//synthesis translate_off |
//synopsys translate_off |
else begin : wrong_topology initial $display("Error: next router inport is not predicted for %s topology",TOPOLOGY); end |
//synopsys translate_on |
//synthesis translate_on |
|
|
|
|
endgenerate |
|
endmodule |
|
546,12 → 609,13
); |
|
|
|
function integer log2; |
input integer number; begin |
log2=0; |
log2=(number <=1) ? 1: 0; |
while(2**log2<number) begin |
log2=log2+1; |
end |
end |
end |
endfunction // log2 |
|
568,12 → 632,12
|
|
one_hot_to_bin #( |
.ONE_HOT_WIDTH(P), |
.BIN_WIDTH(Pw) |
.ONE_HOT_WIDTH(P), |
.BIN_WIDTH(Pw) |
) |
convert1( |
.one_hot_code(receiver_port), |
.bin_code(receiver_port_bin) |
.one_hot_code(receiver_port), |
.bin_code(receiver_port_bin) |
); |
|
one_hot_to_bin #( |
591,12 → 655,12
assign destport_out_bin=temp[P_1w-1 :0]; |
|
bin_to_one_hot #( |
.BIN_WIDTH(P_1w), |
.ONE_HOT_WIDTH(P_1) |
.BIN_WIDTH(P_1w), |
.ONE_HOT_WIDTH(P_1) |
) |
convert3( |
.bin_code(destport_out_bin), |
.one_hot_code(destport_out) |
.bin_code(destport_out_bin), |
.one_hot_code(destport_out) |
); |
|
|
666,14 → 730,15
|
); |
|
|
function integer log2; |
input integer number; begin |
log2=0; |
log2=(number <=1) ? 1: 0; |
while(2**log2<number) begin |
log2=log2+1; |
end |
end |
end |
endfunction // log2 |
endfunction // log2 |
|
localparam P_1 = P-1, |
Xw = log2(NX), |
794,9 → 859,9
); |
end //DUATO |
//synthesis translate_off |
//synopsys translate_off |
//synopsys translate_off |
else begin : not_supported initial $display ("Error: %s is an unsupported routing algorithm for %s topology \n",ROUTE_NAME,TOPOLOGY); end |
//synopsys translate_on |
//synopsys translate_on |
//synthesis translate_on |
end else if (TOPOLOGY == "TORUS" ) begin :torus |
if(ROUTE_NAME == "TRANC_XY") begin : tranc_routing_blk |
881,17 → 946,18
); |
end //TRANC_DUATO |
//synthesis translate_off |
//synopsys translate_off |
//synopsys translate_off |
else begin : not_supported2 initial $display("Error: %s is an unsupported routing algorithm for %s topology",ROUTE_NAME,TOPOLOGY); end |
//synopsys translate_on |
//synopsys translate_on |
//synthesis translate_on |
end //TORUS |
/* |
|
else if (TOPOLOGY == "RING" ) begin :ring |
if(ROUTE_NAME == "TRANC_XY") begin : tranc_ring_blk |
tranc_ring_routing #( |
.NX(NX), |
.OUT_BIN(0) |
|
|
) |
tranc_ring |
( |
899,14 → 965,14
.dest_x(dest_x), |
.destport(destport) |
); |
|
|
end // "TRANC" |
else begin : not_supported2 initial $display("Error: %s is an unsupported routing algorithm for %s topology",ROUTE_NAME,TOPOLOGY); end |
end //"RING" |
*/ |
|
//synthesis translate_off |
//synopsys translate_off |
//synopsys translate_off |
else begin : wrong_topology initial $display("Error: %s is an unsupported topology",TOPOLOGY); end |
//synopsys translate_on |
//synopsys translate_on |
//synthesis translate_on |
|
endgenerate |
942,14 → 1008,15
|
); |
|
|
function integer log2; |
input integer number; begin |
log2=0; |
log2=(number <=1) ? 1: 0; |
while(2**log2<number) begin |
log2=log2+1; |
end |
end |
end |
endfunction // log2 |
endfunction // log2 |
|
localparam P_1 = P-1, |
Xw = log2(NX), |
968,28 → 1035,28
wire [DSTw-1 :0] destport_one_hot; |
|
conventional_routing #( |
.TOPOLOGY(TOPOLOGY), |
.ROUTE_NAME(ROUTE_NAME), |
.ROUTE_TYPE(ROUTE_TYPE), |
.P(P), |
.NX(NX), |
.NY(NY), |
.LOCATED_IN_NI(LOCATED_IN_NI) |
.TOPOLOGY(TOPOLOGY), |
.ROUTE_NAME(ROUTE_NAME), |
.ROUTE_TYPE(ROUTE_TYPE), |
.P(P), |
.NX(NX), |
.NY(NY), |
.LOCATED_IN_NI(LOCATED_IN_NI) |
) |
conventional |
( |
.current_x(current_x), |
.current_y(current_y), |
.dest_x(dest_x), |
.dest_y(dest_y), |
.destport(destport_one_hot) |
|
.current_x(current_x), |
.current_y(current_y), |
.dest_x(dest_x), |
.dest_y(dest_y), |
.destport(destport_one_hot) |
|
); |
|
generate |
if(ROUTE_TYPE == "DETERMINISTIC") begin: dtrmn |
//remove local port number |
assign destport = destport_one_hot[P-1 : 1]; |
//remove local port number |
assign destport = destport_one_hot[P-1 : 1]; |
|
end else begin: adptv |
|
1020,12 → 1087,13
|
); |
|
|
function integer log2; |
input integer number; begin |
log2=0; |
log2=(number <=1) ? 1: 0; |
while(2**log2<number) begin |
log2=log2+1; |
end |
end |
end |
endfunction // log2 |
|
1083,7 → 1151,6
end//always |
|
assign same_x = (xdiff == 0); |
|
|
|
|
/src_noc/ss_allocator.v
64,7 → 64,7
PFw = P * Fw, |
VV = V * V; |
|
|
//p=5 |
localparam LOCAL = 3'd0, |
EAST = 3'd1, |
NORTH = 3'd2, |
72,7 → 72,8
SOUTH = 3'd4, |
DISABLED = 3'b111; |
|
|
|
|
|
|
|
113,13 → 114,20
|
generate |
for (i=0; i<PV; i=i+1) begin : vc_loop |
localparam SS_PORT = ((i/V)== EAST)? WEST: |
localparam SS_PORT_P5 = ((i/V)== EAST)? WEST: |
((i/V)== WEST)? EAST: |
((i/V)== SOUTH)? NORTH: |
((i/V)== NORTH)? SOUTH: |
DISABLED; |
|
localparam SS_PORT_P3 = ((i/V)== 1)? 3'd2: |
((i/V)== 2)? 3'd1: |
DISABLED; |
|
localparam SS_PORT = (P==5) ? SS_PORT_P5: |
(P==3) ? SS_PORT_P3: DISABLED; |
|
|
|
|
if (SS_PORT== DISABLED)begin : no_prefrable |
|
188,11 → 196,20
|
|
for(i=0;i<P;i=i+1)begin: port_lp |
localparam SS_P = (i== EAST)? WEST: |
localparam SS_P5 = (i== EAST)? WEST: |
(i== WEST)? EAST: |
(i== SOUTH)? NORTH: |
(i== NORTH)? SOUTH: |
LOCAL; |
|
|
localparam SS_P3 = (i== 1)? 2: |
(i== 2)? 1: |
LOCAL; |
|
localparam SS_P = (P==5) ? SS_P5 : |
(P==3) ? SS_P3 : i; |
|
|
|
always @(posedge clk or posedge reset)begin |
514,13 → 531,13
|
|
module add_ss_port #( |
parameter SW_LOC=1 |
parameter SW_LOC=1, |
parameter P=5 |
)( |
destport_in, |
destport_out |
); |
localparam P=5, |
P_1= P-1; |
localparam P_1= P-1; |
|
localparam LOCAL = 3'd0, |
EAST = 3'd1, |
527,11 → 544,22
NORTH = 3'd2, |
WEST = 3'd3, |
SOUTH = 3'd4; |
|
localparam SS_PORT = (SW_LOC== EAST )? WEST-3'd1 : // the sender port must be removed from destination port code |
|
|
|
localparam SS_PORT_P5 = (SW_LOC== EAST )? WEST-3'd1 : // the sender port must be removed from destination port code |
(SW_LOC== NORTH )? SOUTH-3'd1: // the sender port must be removed from destination port code |
(SW_LOC== WEST )? EAST : |
NORTH ; |
|
localparam SS_PORT_P3 = 2'd1; |
|
|
localparam SS_PORT = (P==5) ? SS_PORT_P5: SS_PORT_P3; |
|
|
|
|
|
input [P_1-1 : 0] destport_in; |
output reg [P_1-1 : 0] destport_out; |
/src_noc/traffic_gen.v
22,8 → 22,12
parameter MAX_PCK_NUM = 10000, |
parameter MAX_SIM_CLKs = 100000, |
parameter MAX_PCK_SIZ = 10, // max packet size |
parameter TIMSTMP_FIFO_NUM=16 |
|
parameter TIMSTMP_FIFO_NUM=16, |
//header flit filds' width |
parameter CLASS_HDR_WIDTH =8, |
parameter ROUTING_HDR_WIDTH =8, |
parameter DST_ADR_HDR_WIDTH =8, |
parameter SRC_ADR_HDR_WIDTH =8 |
) |
( |
//input |
60,14 → 64,15
clk |
); |
|
|
function integer log2; |
input integer number; begin |
log2=0; |
log2=(number <=1) ? 1: 0; |
while(2**log2<number) begin |
log2=log2+1; |
end |
end |
end |
endfunction // log2 |
endfunction // log2 |
|
localparam P= (TOPOLOGY=="RING")? 3 : 5; |
localparam ROUTE_TYPE = (ROUTE_NAME == "XY" || ROUTE_NAME == "TRANC_XY" )? "DETERMINISTIC" : |
96,11 → 101,7
PCK_SIZw = log2(MAX_PCK_SIZ+1); |
|
|
localparam CLASS_IN_HDR_WIDTH =8, |
DEST_IN_HDR_WIDTH =8, |
X_Y_IN_HDR_WIDTH =4; |
|
|
|
input reset, clk; |
input [RATIOw-1 :0] ratio; |
input start; |
137,31 → 138,30
|
|
wire [P_1-1 : 0] destport; |
wire [DEST_IN_HDR_WIDTH-1 : 0] wr_destport_hdr; |
wire [V-1 : 0] ovc_wr_in; |
wire [V-1 : 0] full_vc,empty_vc; |
reg [V-1 : 0] wr_vc,wr_vc_next; |
wire [V-1 : 0] cand_vc; |
wire [X_Y_IN_HDR_WIDTH-1 : 0] wr_des_x_addr,wr_des_y_addr; |
wire [X_Y_IN_HDR_WIDTH-1 : 0] wr_src_x_addr,wr_src_y_addr; |
wire [CLASS_IN_HDR_WIDTH-1 : 0] wr_class_hdr; |
|
|
wire [CLK_CNTw-1 : 0] wr_timestamp,pck_timestamp; |
wire hdr_flit,tail_flit; |
reg [PCK_SIZw-1 : 0] flit_counter; |
reg flit_cnt_rst,flit_cnt_inc; |
wire [1 : 0] rd_hdr_flg; |
wire [CLASS_IN_HDR_WIDTH-1 : 0] rd_class_hdr; |
wire [DEST_IN_HDR_WIDTH-1 : 0] rd_destport_hdr; |
wire [X_Y_IN_HDR_WIDTH-1 : 0] rd_des_x_addr, rd_des_y_addr,rd_src_x_addr,rd_src_y_addr; |
reg [CLK_CNTw-1 : 0] rsv_counter,last_pck_time; |
wire [Cw-1 : 0] rd_class_hdr; |
// wire [P_1-1 : 0] rd_destport_hdr; |
wire [Xw-1 : 0] rd_des_x_addr, rd_src_x_addr; |
wire [Yw-1 : 0] rd_des_y_addr, rd_src_y_addr; |
reg [CLK_CNTw-1 : 0] rsv_counter; |
reg [CLK_CNTw-1 : 0] clk_counter; |
wire [Vw-1 : 0] rd_vc_bin,wr_vc_bin; |
wire [Vw-1 : 0] rd_vc_bin;//,wr_vc_bin; |
reg [CLK_CNTw-1 : 0] rsv_time_stamp[V-1:0]; |
wire [V-1 : 0] rd_vc; |
wire wr_vc_is_full,wr_vc_avb,wr_vc_is_empty; |
reg [V-1 : 0] credit_out_next; |
reg [X_Y_IN_HDR_WIDTH-1 : 0] rsv_pck_src_x [V-1:0]; |
reg [X_Y_IN_HDR_WIDTH-1 : 0] rsv_pck_src_y [V-1:0]; |
reg [Xw-1 : 0] rsv_pck_src_x [V-1:0]; |
reg [Yw-1 : 0] rsv_pck_src_y [V-1:0]; |
reg [Cw-1 : 0] rsv_pck_class_in [V-1:0]; |
|
|
239,17 → 239,59
.valid_dst(valid_dst), |
.destport(destport) |
); |
|
// for flit size >= 32 bits |
/* header flit format |
31--------------24 23--------16 15--------8 7-----0 |
message_class_data routing_info destination_address source_address |
*/ |
localparam ADDR_DIMENTION = (TOPOLOGY == "MESH" || TOPOLOGY == "TORUS") ? 2 : /* ("RING" and FULLY_CONNECT)?*/ 1; |
|
reg [CLASS_HDR_WIDTH-1 : 0] wr_class_hdr; |
reg [ROUTING_HDR_WIDTH-1 : 0] wr_routing_hdr; |
reg [DST_ADR_HDR_WIDTH-1 : 0] wr_dst_adr_hdr; |
reg [SRC_ADR_HDR_WIDTH-1 : 0] wr_src_adr_hdr; |
|
|
assign wr_timestamp =pck_timestamp; |
|
always @(*) begin |
wr_class_hdr= {CLASS_HDR_WIDTH{1'b0}}; |
wr_class_hdr[Cw-1 : 0] = pck_class_in; |
wr_routing_hdr ={ROUTING_HDR_WIDTH{1'b0}}; |
wr_routing_hdr[P_1-1 : 0] = destport; |
end |
|
generate |
if (ADDR_DIMENTION==1) begin :one_dimen |
|
always @(*) begin |
wr_src_adr_hdr= {SRC_ADR_HDR_WIDTH{1'b0}}; |
wr_dst_adr_hdr= {DST_ADR_HDR_WIDTH{1'b0}}; |
wr_src_adr_hdr [Xw-1 :0]= current_x; |
wr_dst_adr_hdr [Xw-1 :0]= dest_x; |
end |
|
end else begin :two_dimen |
|
always @(*) begin |
wr_src_adr_hdr= {SRC_ADR_HDR_WIDTH{1'b0}}; |
wr_dst_adr_hdr= {DST_ADR_HDR_WIDTH{1'b0}}; |
|
wr_src_adr_hdr[Yw-1 : 0] = current_y; |
wr_src_adr_hdr[(SRC_ADR_HDR_WIDTH/2)+Xw-1 : (SRC_ADR_HDR_WIDTH/2)] = current_x; |
|
wr_dst_adr_hdr[Yw-1 : 0]= dest_y; |
wr_dst_adr_hdr[(SRC_ADR_HDR_WIDTH/2)+Xw-1 : (SRC_ADR_HDR_WIDTH/2)]= dest_x; |
end |
|
end |
endgenerate |
|
|
|
|
|
assign wr_class_hdr ={{(CLASS_IN_HDR_WIDTH-Cw){1'b0}},pck_class_in}; |
assign wr_destport_hdr ={{(DEST_IN_HDR_WIDTH-P_1){1'b0}},destport}; |
assign wr_des_x_addr ={{(X_Y_IN_HDR_WIDTH-Xw){1'b0}}, dest_x}; |
assign wr_des_y_addr ={{(X_Y_IN_HDR_WIDTH-Yw){1'b0}}, dest_y}; |
assign wr_src_x_addr ={{(X_Y_IN_HDR_WIDTH-Yw){1'b0}}, current_x}; |
assign wr_src_y_addr ={{(X_Y_IN_HDR_WIDTH-Yw){1'b0}}, current_y}; |
assign wr_timestamp =pck_timestamp; |
|
|
|
|
258,29 → 300,66
assign update = flit_in_wr & flit_in[Fw-2]; |
assign hdr_flit = (flit_counter == 0); |
assign tail_flit = (flit_counter == pck_size-1'b1); |
assign time_stamp_h2h = rsv_time_stamp[rd_vc_bin] - flit_in[CLK_CNTw-1 : 0]; |
assign time_stamp_h2h = rsv_time_stamp[rd_vc_bin] - flit_in[CLK_CNTw-1 : 0]; |
assign time_stamp_h2t = clk_counter - flit_in[CLK_CNTw-1 : 0]; |
|
wire [Fpay-1 : 0] flit_out_pyload; |
wire [1 : 0] flit_out_hdr; |
wire [Fpay-1 : 0] flit_out_pyload; |
wire [1 : 0] flit_out_hdr; |
|
assign flit_out_pyload = (hdr_flit) ? {wr_class_hdr,wr_destport_hdr,wr_des_x_addr,wr_des_y_addr,wr_src_x_addr,wr_src_y_addr}: |
(tail_flit) ? wr_timestamp: |
{pck_number,flit_counter}; |
assign flit_out_hdr = (hdr_flit) ? 2'b10: |
(tail_flit) ? 2'b01: |
2'b00; |
assign flit_out_pyload = (hdr_flit) ? {wr_class_hdr,wr_routing_hdr,wr_dst_adr_hdr,wr_src_adr_hdr}: |
(tail_flit) ? wr_timestamp: |
{pck_number,flit_counter}; |
|
assign flit_out_hdr = (hdr_flit) ? 2'b10: |
(tail_flit) ? 2'b01: |
2'b00; |
|
assign flit_out = {flit_out_hdr, wr_vc, flit_out_pyload }; |
|
|
|
assign {rd_hdr_flg,rd_vc,rd_class_hdr,rd_destport_hdr,rd_des_x_addr,rd_des_y_addr,rd_src_x_addr,rd_src_y_addr} = flit_in; |
|
|
|
|
//extract header flit info |
|
extract_header_flit_info #( |
.CLASS_HDR_WIDTH(CLASS_HDR_WIDTH), |
.ROUTING_HDR_WIDTH(ROUTING_HDR_WIDTH), |
.DST_ADR_HDR_WIDTH(DST_ADR_HDR_WIDTH), |
.SRC_ADR_HDR_WIDTH(SRC_ADR_HDR_WIDTH), |
.TOPOLOGY(TOPOLOGY), |
.V(V), |
.P(P), |
.NX(NX), |
.NY(NY), |
.C(C), |
.Fpay(Fpay) |
) |
header_extractor |
( |
.flit_in(flit_in), |
.flit_in_we(flit_in_wr), |
.class_in(rd_class_hdr), |
.destport_in(),//(rd_destport_hdr), |
.x_dst_in(rd_des_x_addr), |
.y_dst_in(rd_des_y_addr), |
.x_src_in(rd_src_x_addr), |
.y_src_in(rd_src_y_addr), |
.vc_num_in(rd_vc), |
.hdr_flit_wr( ), |
.flg_hdr_in(rd_hdr_flg) |
); |
|
|
|
|
|
wire [Xw-1 : 0] src_x; |
wire [Yw-1 : 0] src_y; |
assign src_x = rsv_pck_src_x[rd_vc_bin][Xw-1 : 0]; |
assign src_y = rsv_pck_src_y[rd_vc_bin][Yw-1 : 0]; |
assign src_x = rsv_pck_src_x[rd_vc_bin]; |
assign src_y = rsv_pck_src_y[rd_vc_bin]; |
assign pck_class_out = rsv_pck_class_in[rd_vc_bin]; |
|
|
293,8 → 372,8
the_distance_gen |
( |
.src_x(src_x), |
.dest_x(current_x), |
.src_y(src_y), |
.dest_x(current_x), |
.dest_y(current_y), |
.distance(distance) |
); |
302,7 → 381,7
generate |
if(V==1) begin : v1 |
assign rd_vc_bin=1'b0; |
assign wr_vc_bin=1'b0; |
// assign wr_vc_bin=1'b0; |
end else begin :vother |
|
one_hot_to_bin #( .ONE_HOT_WIDTH (V)) conv1 |
310,12 → 389,13
.one_hot_code (rd_vc), |
.bin_code (rd_vc_bin) |
); |
|
/* |
one_hot_to_bin #( .ONE_HOT_WIDTH (V)) conv2 |
( |
.one_hot_code (wr_vc), |
.bin_code (wr_vc_bin) |
); |
*/ |
end |
endgenerate |
|
432,7 → 512,7
if (flit_in[Fw-1])begin |
rsv_pck_src_x[rd_vc_bin] <= rd_src_x_addr; |
rsv_pck_src_y[rd_vc_bin] <= rd_src_y_addr; |
rsv_pck_class_in[rd_vc_bin] <= rd_class_hdr[Cw-1 : 0]; |
rsv_pck_class_in[rd_vc_bin] <= rd_class_hdr; |
rsv_time_stamp[rd_vc_bin] <= clk_counter; |
rsv_counter <= rsv_counter+1'b1; |
|
446,7 → 526,7
|
// synthesis translate_off |
if(report) begin |
$display ("%t,\t toptal of %d pcks have been recived in core (%d,%d)", last_pck_time,rsv_counter,current_x,current_y); |
$display ("%t,\t toptal of %d pcks have been recived in core (%d,%d)",$time ,rsv_counter,current_x,current_y); |
end |
// synthesis translate_on |
|
460,8 → 540,8
|
// synthesis translate_off |
always @(posedge clk) begin |
if(flit_out_wr && hdr_flit && wr_des_x_addr[Xw-1 : 0] == current_x && wr_des_y_addr[Yw-1 : 0] == current_y) $display("%t: Error: The source and destination address of injected packet is the same in router(%d,%d) ",$time, wr_des_x_addr ,wr_des_y_addr); |
if(flit_in_wr && rd_hdr_flg[1] && rd_des_x_addr [Xw-1 : 0] != current_x && rd_des_y_addr [Yw-1 : 0] != current_y ) $display("%t: Error: packet with des(%d,%d) has been recieved in wrong router (%d,%d). ",$time,rd_des_x_addr, rd_des_y_addr, current_x , current_y); |
if(flit_out_wr && hdr_flit && dest_x == current_x && dest_y == current_y) $display("%t: Error: The source and destination address of injected packet is the same in router(%d,%d) ",$time, dest_x ,dest_y); |
if(flit_in_wr && rd_hdr_flg[1] && (rd_des_x_addr != current_x || rd_des_y_addr != current_y )) $display("%t: Error: packet with des(%d,%d) has been recieved in wrong router (%d,%d). ",$time,rd_des_x_addr, rd_des_y_addr, current_x , current_y); |
end |
// synthesis translate_on |
|
541,17 → 621,17
|
); |
|
|
function integer log2; |
input integer number; begin |
log2=0; |
log2=(number <=1) ? 1: 0; |
while(2**log2<number) begin |
log2=log2+1; |
end |
end |
end |
endfunction // log2 |
endfunction // log2 |
|
|
|
localparam PCK_SIZw= log2(MAX_PCK_SIZ); |
localparam CNTw = log2(100); |
localparam STATE_INIT= MAX_PCK_SIZ*100; |
681,15 → 761,15
|
); |
|
function integer log2; |
|
function integer log2; |
input integer number; begin |
log2=0; |
log2=(number <=1) ? 1: 0; |
while(2**log2<number) begin |
log2=log2+1; |
end |
end |
end |
endfunction // log2 |
|
endfunction // log2 |
|
|
localparam P_1 = P-1, |
799,12 → 879,14
distance |
|
); |
|
|
function integer log2; |
input integer number; begin |
log2=0; |
log2=(number <=1) ? 1: 0; |
while(2**log2<number) begin |
log2=log2+1; |
end |
end |
end |
endfunction // log2 |
|
831,7 → 913,7
|
|
|
end else begin //torus |
end else begin //torus ring |
|
wire tranc_x_plus,tranc_x_min,tranc_y_plus,tranc_y_min,same_x,same_y; |
|
/src_verilator/noc_connection.sv
40,14 → 40,15
); |
|
|
function integer log2; |
input integer number; begin |
log2=0; |
while(2**log2<number) begin |
log2=log2+1; |
end |
end |
endfunction // log2 |
|
function integer log2; |
input integer number; begin |
log2=(number <=1) ? 1: 0; |
while(2**log2<number) begin |
log2=log2+1; |
end |
end |
endfunction // log2 |
|
function integer CORE_NUM; |
input integer x,y; |
/src_verilator/router_verilator.v
19,15 → 19,16
|
|
|
function integer log2; |
input integer number; begin |
log2=0; |
while(2**log2<number) begin |
log2=log2+1; |
end |
end |
endfunction // log2 |
|
function integer log2; |
input integer number; begin |
log2=(number <=1) ? 1: 0; |
while(2**log2<number) begin |
log2=log2+1; |
end |
end |
endfunction // log2 |
|
function integer CORE_NUM; |
input integer x,y; |
begin |
/src_verilator/simulator.cpp
0,0 → 1,831
#include <stdlib.h> |
#include <stdio.h> |
#include <unistd.h> |
#include <string.h> |
|
|
|
|
#include <ctype.h> |
#include <stdint.h> |
|
#include <inttypes.h> |
|
|
#include <verilated.h> // Defines common routines |
#include "Vrouter.h" // From Verilating "router.v" |
#include "Vnoc.h" |
#include "Vtraffic.h" |
|
|
|
|
#include "parameter.h" |
//#include "traffic_tabel.h" |
|
|
#define NC (NX*NY) |
#define RATIO_INIT 2 |
|
unsigned char FIXED_SRC_DST_PAIR; |
|
unsigned char Xw=0,Yw=0; |
|
|
|
|
//Vrouter *router; |
Vrouter *router[NC]; // Instantiation of module |
Vnoc *noc; |
Vtraffic *traffic[NC]; |
|
unsigned long int main_time = 0; // Current simulation time |
unsigned int saved_time = 0; |
|
|
unsigned int total_pck_num=0; |
unsigned int sum_clk_h2h,sum_clk_h2t; |
|
double sum_clk_per_hop; |
const int CC=(C==0)? 1 : C; |
|
unsigned int total_pck_num_per_class[CC]={0}; |
unsigned int sum_clk_h2h_per_class[CC]={0}; |
unsigned int sum_clk_h2t_per_class[CC]={0}; |
double sum_clk_per_hop_per_class[CC]={0}; |
unsigned int clk_counter; |
unsigned int count_en; |
unsigned int total_router; |
|
|
|
|
|
|
char all_done=0; |
|
unsigned int flit_counter =0; |
|
char ratio=RATIO_INIT; |
double first_avg_latency_flit,current_avg_latency_flit; |
|
double sc_time_stamp (); |
int pow2( int ); |
|
|
|
int reset,clk; |
|
#if (STND_DEV_EN) |
#include <math.h> |
double sum_clk_pow2=0; |
double sum_clk_pow2_per_class[C]={0}; |
double standard_dev( double , unsigned int, double); |
#endif |
|
void update_noc_statistic ( |
unsigned int, |
unsigned int, |
unsigned int, |
unsigned int |
); |
|
|
void pck_dst_gen ( |
unsigned int, |
unsigned int, |
unsigned int, |
unsigned int*, |
unsigned int* |
); |
|
unsigned char pck_class_in_gen( |
unsigned int |
|
); |
|
|
|
|
void print_statistic (char *); |
void print_parameter(); |
|
|
void reset_all_register(); |
|
|
|
char * TRAFFIC; |
|
int PACKET_SIZE; |
int MAX_PCK_NUM; |
int MAX_SIM_CLKs; |
int inject_ratios[100]; |
int C0_p=100, C1_p=0, C2_p=0, C3_p=0; |
|
|
int HOTSPOT_PERCENTAGE; |
int HOTSPOT_NUM; |
int HOTSPOT_CORE_1, HOTSPOT_CORE_2, HOTSPOT_CORE_3, HOTSPOT_CORE_4,HOTSPOT_CORE_5; |
|
void usage(){ |
printf(" ./simulator -t [Traffic Pattern] -s [PACKET_SIZE] -n [MAX_PCK_NUM] c [MAX_SIM_CLKs] -i [INJECTION_RATIO] -p [class traffic ratios %] -h[HOTSPOT info] \n"); |
printf(" Traffic Pattern: \"HOTSPOT\" \"RANDOM\" \"TORNADO\" \"BIT_REVERSE\" \"BIT_COMPLEMENT\" \"TRANSPOSE1\" \"TRANSPOSE2\"\n"); |
printf(" PACKET_SIZE: packet size in flit\n "); |
printf(" MAX_PCK_NUM: total number of sent packets. Simulation will stop when total of sent packet by all nodes reach this number\n"); |
printf(" MAX_SIM_CLKs: simulation clock limit. Simulation will stop when simulation clock number reach this value \n"); |
printf(" INJECTION_RATIO: packet injection ratios"); |
printf(" class traffic ratios %: The percentage of traffic injected for each class. represented in string whit each clas ratio is seprated by coma. \"n0,n1,n2..\" \n"); |
printf(" HOTSPOT info: represented in a string with following format: \"HOTSPOT_PERCENTAGE,HOTSOPT_NUM,HOTSPOT_CORE_1,HOTSPOT_CORE_2,HOTSPOT_CORE_3,HOTSPOT_CORE_4,HOTSPOT_CORE_5\" \n"); |
} |
|
|
int parse_string ( char * str, int * array) |
{ |
int i=0; |
char *pt; |
pt = strtok (str,","); |
while (pt != NULL) { |
int a = atoi(pt); |
array[i]=a; |
i++; |
pt = strtok (NULL, ","); |
} |
return i; |
} |
|
void processArgs (int argc, char **argv ) |
{ |
char c; |
int p; |
int array[10]; |
|
/* don't want getopt to moan - I can do that just fine thanks! */ |
opterr = 0; |
if (argc < 2) usage(); |
while ((c = getopt (argc, argv, "t:s:n:c:i:p:h:")) != -1) |
{ |
switch (c) |
{ |
|
case 't': |
TRAFFIC=optarg; |
break; |
case 's': |
PACKET_SIZE=atoi(optarg); |
break; |
case 'n': |
MAX_PCK_NUM=atoi(optarg); |
break; |
case 'c': |
MAX_SIM_CLKs=atoi(optarg); |
break; |
case 'i': |
ratio=atoi(optarg); |
break; |
case 'p': |
p= parse_string (optarg, array); |
C0_p=array[0]; |
C1_p=array[1]; |
C2_p=array[2]; |
C3_p=array[3]; |
break; |
case 'h': |
p= parse_string (optarg, array); |
HOTSPOT_PERCENTAGE=array[0]; |
HOTSPOT_NUM=array[1]; |
HOTSPOT_CORE_1=array[2]; |
HOTSPOT_CORE_2=array[3]; |
HOTSPOT_CORE_3=array[4]; |
HOTSPOT_CORE_4=array[5]; |
HOTSPOT_CORE_5=array[6]; |
|
break; |
|
|
|
case '?': |
if (isprint (optopt)) |
fprintf (stderr, "Unknown option `-%c'.\n", optopt); |
else |
fprintf (stderr, |
"Unknown option character `\\x%x'.\n", |
optopt); |
default: |
usage(); |
exit(1); |
} |
} |
} |
|
|
int main(int argc, char** argv) { |
char change_injection_ratio=0,inject_done; |
int i,j,x,y;//,report_delay_counter=0; |
char file_name[100]; |
char deafult_out[] = {"result"}; |
char * out_file_name; |
unsigned int dest_x, dest_y; |
int flit_out_all_size = sizeof(router[0]->flit_out_all)/sizeof(router[0]->flit_out_all[0]); |
while((0x1<<Xw) < NX)Xw++; //log2 |
while((0x1<<Yw) < NY)Yw++; |
|
|
processArgs ( argc, argv ); |
|
|
FIXED_SRC_DST_PAIR = strcmp (TRAFFIC,"RANDOM") & strcmp(TRAFFIC,"HOTSPOT") & strcmp(TRAFFIC,"random") & strcmp(TRAFFIC,"hot spot"); |
|
|
|
|
|
|
Verilated::commandArgs(argc, argv); // Remember args |
|
for(i=0;i<NC;i++) router[i] = new Vrouter; // Create instance |
noc = new Vnoc; |
for(i=0;i<NC;i++) traffic[i] = new Vtraffic; |
|
|
/******************** |
* initialize input |
*********************/ |
|
reset=1; |
reset_all_register(); |
noc->start_i=0; |
|
for(x=0;x<NX;x++)for(y=0;y<NY;y++){ |
i=(y*NX)+x; |
router[i]->current_x = x; |
router[i]->current_y = y; |
traffic[i]->current_x = x; |
traffic[i]->current_y = y; |
traffic[i]->start=0; |
traffic[i]->pck_size_in=PACKET_SIZE; |
traffic[i]->ratio=ratio; |
traffic[i]->pck_class_in= pck_class_in_gen( i); |
pck_dst_gen ( x,y,i, &dest_x, &dest_y); |
traffic[i]->dest_x= dest_x; |
traffic[i]->dest_y=dest_y; |
|
} |
|
|
|
|
main_time=0; |
print_parameter(); |
printf("\n\n\n Flit injection ratio per router is =%d \n",ratio); |
//printf("\n\n\n delay= %u clk",router->delay); |
while (!Verilated::gotFinish()) { |
|
if (main_time-saved_time >= 10 ) { |
reset = 0; |
} |
|
if(main_time == saved_time+21){ count_en=1; noc->start_i=1;}//for(i=0;i<NC;i++) traffic[i]->start=1;} |
if(main_time == saved_time+26) noc->start_i=0;// for(i=0;i<NC;i++) traffic[i]->start=0; |
|
|
|
|
if ((main_time % 4) == 0) { |
clk = 1; // Toggle clock |
if(count_en) clk_counter++; |
inject_done= ((total_pck_num >= MAX_PCK_NUM) || (clk_counter>= MAX_SIM_CLKs)); |
//if(inject_done) printf("clk_counter=========%d\n",clk_counter); |
for(x=0;x<NX;x++)for(y=0;y<NY;y++) |
{ |
i=(y*NX)+x; |
// a packet has been received |
if(traffic[i]->update & ~reset){ |
update_noc_statistic ( |
traffic[i]->time_stamp_h2h, |
traffic[i]->time_stamp_h2t, |
traffic[i]->distance, |
traffic[i]->pck_class_out |
) ; |
} |
// the header flit has been sent out |
if(traffic[i]->hdr_flit_sent ){ |
traffic[i]->pck_class_in= pck_class_in_gen( i); |
if(!FIXED_SRC_DST_PAIR){ |
pck_dst_gen ( x,y,i, &dest_x, &dest_y); |
traffic[i]->dest_x= dest_x; |
traffic[i]->dest_y=dest_y; |
} |
} |
|
if(traffic[i]->flit_out_wr==1) flit_counter++; |
|
}//for |
if(inject_done) { |
for(x=0;x<NX;x++)for(y=0;y<NY;y++) if(traffic[(y*NX)+x]->pck_number>0) total_router = total_router +1; |
|
printf(" simulation clock cycles:%d\n",clk_counter); |
printf(" total received flits:%d\n",flit_counter); |
print_statistic(out_file_name); |
change_injection_ratio = 1; |
for(i=0;i<NC;i++) { |
router[i]->final(); |
traffic[i]->final(); |
} |
noc->final(); |
|
|
return 0; |
} |
|
|
|
}//if |
else |
{ |
|
clk = 0; |
noc->ni_flit_in_wr =0; |
|
for(x=0;x<NX;x++)for(y=0;y<NY;y++){ |
i=(y*NX)+x; |
|
|
router[i]->flit_in_we_all = noc->router_flit_out_we_all[i]; |
router[i]->credit_in_all = noc->router_credit_out_all[i]; |
router[i]->congestion_in_all = noc->router_congestion_out_all[i]; |
for(j=0;j<flit_out_all_size;j++)router[i]->flit_in_all[j] = noc->router_flit_out_all[i][j]; |
|
|
noc->router_flit_in_we_all[i] = router[i]->flit_out_we_all ; |
noc->router_credit_in_all[i] = router[i]->credit_out_all; |
noc->router_congestion_in_all[i]= router[i]->congestion_out_all; |
for(j=0;j<flit_out_all_size;j++) noc->router_flit_in_all[i][j] = router[i]->flit_out_all[j] ; |
|
traffic[i]->flit_in = noc->ni_flit_out [i]; |
traffic[i]->credit_in= noc->ni_credit_out[i]; |
|
|
noc->ni_credit_in[i] = traffic[i]->credit_out; |
noc->ni_flit_in [i] = traffic[i]->flit_out; |
|
if(traffic[i]->flit_out_wr) noc->ni_flit_in_wr = noc->ni_flit_in_wr | ((vluint64_t)1<<i); |
|
traffic[i]->flit_in_wr= ((noc->ni_flit_out_wr >> i) & 0x01); |
|
|
}//for |
|
|
}//else |
//if(main_time > 20 && main_time < 30 ) traffic->start=1; else traffic->start=0; |
//if(main_time == saved_time+25) router[0]->flit_in_we_all=0; |
//if((main_time % 250)==0) printf("router->all_done =%u\n",router->all_done); |
|
|
noc-> clk = clk; |
noc-> reset = reset; |
|
|
for(i=0;i<NC;i++) { |
traffic[i]->start= ((noc->start_o >>i)& 0x01); |
traffic[i]->reset= reset; |
traffic[i]->clk = clk; |
router[i]->reset= reset; |
router[i]->clk= clk ; |
|
} |
|
|
noc->eval(); |
|
|
for(i=0;i<NC;i++) { |
router[i]->eval(); |
traffic[i]->eval(); |
|
} |
|
|
|
|
//router[0]->eval(); // Evaluate model |
//printf("clk=%x\n",router->clk ); |
|
main_time++; |
//getchar(); |
|
|
} |
for(i=0;i<NC;i++) { |
router[i]->final(); |
traffic[i]->final(); |
} // Done simulating |
noc->final(); |
|
} |
|
|
|
|
|
|
|
|
double sc_time_stamp () { // Called by $time in Verilog |
return main_time; |
} |
|
int pow2( int num){ |
int pw; |
pw= (0x1 << num); |
return pw; |
} |
|
|
|
/********************************** |
* |
* update_noc_statistic |
* |
* |
*********************************/ |
|
|
|
void update_noc_statistic ( |
unsigned int clk_num_h2h, |
unsigned int clk_num_h2t, |
unsigned int distance, |
unsigned int class_num |
) |
{ |
|
|
total_pck_num+=1; |
//if((total_pck_num & 0Xffff )==0 ) printf("total_pck_num=%d\n",total_pck_num); |
sum_clk_h2h+=clk_num_h2h; |
sum_clk_h2t+=clk_num_h2t; |
#if (STND_DEV_EN) |
sum_clk_pow2+=(double)clk_num_h2h * (double) clk_num_h2h; |
sum_clk_pow2_per_class[class_num]+=(double)clk_num_h2h * (double) clk_num_h2h; |
#endif |
|
sum_clk_per_hop+= ((double)clk_num_h2h/(double)distance); |
total_pck_num_per_class[class_num]+=1; |
sum_clk_h2h_per_class[class_num]+=clk_num_h2h ; |
sum_clk_h2t_per_class[class_num]+=clk_num_h2t ; |
sum_clk_per_hop_per_class[class_num]+= ((double)clk_num_h2h/(double)distance); |
|
|
|
|
} |
|
/************************* |
* |
* update |
* |
* |
************************/ |
|
|
|
|
|
|
|
|
|
|
|
void print_statistic (char * out_file_name){ |
double avg_latency_per_hop, avg_latency_flit, avg_latency_pck, avg_throughput,min_avg_latency_per_class; |
int i; |
#if (STND_DEV_EN) |
double std_dev; |
#endif |
char file_name[100]; |
avg_throughput= ((double)(total_pck_num*PACKET_SIZE*100)/total_router )/clk_counter; |
printf(" Total active routers: %d \n",total_router); |
printf(" Avg throughput is: %f (flits/clk/node %%)\n", avg_throughput); |
avg_latency_flit = (double)sum_clk_h2h/total_pck_num; |
avg_latency_pck = (double)sum_clk_h2t/total_pck_num; |
if(ratio==RATIO_INIT) first_avg_latency_flit=avg_latency_flit; |
#if (STND_DEV_EN) |
std_dev= standard_dev( sum_clk_pow2,total_pck_num, avg_latency_flit); |
// sprintf(file_name,"%s_std.txt",out_file_name); |
//update_file( file_name,avg_throughput,std_dev); |
|
#endif |
avg_latency_per_hop = (double)sum_clk_per_hop/total_pck_num; |
printf ("\nall : \n"); |
// sprintf(file_name,"%s_all.txt",out_file_name); |
//update_file(file_name ,ratio,avg_latency ); |
if(strcmp (AVG_LATENCY_METRIC,"HEAD_2_TAIL")==0){ |
printf(" Total number of packet = %d \n average latency per hop = %f \n average latency = %f\n",total_pck_num,avg_latency_per_hop,avg_latency_pck); |
// update_file(file_name ,avg_throughput,avg_latency_pck); |
|
}else{ |
printf(" Total number of packet = %d \n average latency per hop = %f \n average latency = %f\n",total_pck_num,avg_latency_per_hop,avg_latency_flit); |
// update_file(file_name ,avg_throughput,avg_latency_flit); |
|
} |
//fwrite(fp,"%d,%f,%f,%f,",total_pck_num,avg_latency_per_hop,avg_latency,max_latency_per_hop); |
min_avg_latency_per_class=1000000; |
for(i=0;i<C;i++){ |
avg_throughput = (total_pck_num_per_class[i]>0)? ((double)(total_pck_num_per_class[i]*PACKET_SIZE*100)/total_router )/clk_counter:0; |
avg_latency_flit = (total_pck_num_per_class[i]>0)? (double)sum_clk_h2h_per_class[i]/total_pck_num_per_class[i]:0; |
avg_latency_pck = (total_pck_num_per_class[i]>0)? (double)sum_clk_h2t_per_class[i]/total_pck_num_per_class[i]:0; |
avg_latency_per_hop = (total_pck_num_per_class[i]>0)? (double)sum_clk_per_hop_per_class[i]/total_pck_num_per_class[i]:0; |
if(strcmp (AVG_LATENCY_METRIC,"HEAD_2_TAIL")==0){ |
printf ("\nclass : %d \n",i); |
printf (" Total number of packet = %d \n avg_throughput = %f \n average latency per hop = %f \n average latency = %f\n",total_pck_num_per_class[i],avg_throughput,avg_latency_per_hop,avg_latency_pck); |
//sprintf(file_name,"%s_c%u.txt",out_file_name,i); |
// update_file( file_name,avg_throughput,avg_latency_pck ); |
}else{ |
|
printf ("\nclass : %d \n",i); |
printf (" Total number of packet = %d \n avg_throughput = %f \n average latency per hop = %f \n average latency = %f\n",total_pck_num_per_class[i],avg_throughput,avg_latency_per_hop,avg_latency_flit); |
// sprintf(file_name,"%s_c%u.txt",out_file_name,i); |
// update_file( file_name,avg_throughput,avg_latency_flit ); |
|
|
|
|
} |
if(min_avg_latency_per_class > avg_latency_flit) min_avg_latency_per_class=avg_latency_flit; |
|
#if (STND_DEV_EN) |
std_dev= (total_pck_num_per_class[i]>0)? standard_dev( sum_clk_pow2_per_class[i],total_pck_num_per_class[i], avg_latency_flit):0; |
// sprintf(file_name,"%s_std%u.txt",out_file_name,i); |
// update_file( file_name,avg_throughput,std_dev); |
|
#endif |
|
|
}//for |
current_avg_latency_flit=min_avg_latency_per_class; |
|
|
|
|
} |
|
void print_parameter (){ |
|
printf ("Router parameters: \n"); |
printf ("\tTopology: %s\n",TOPOLOGY); |
printf ("\tRouting algorithm: %s\n",ROUTE_NAME); |
printf ("\tVC_per port: %d\n", V); |
printf ("\tBuffer_width: %d\n", B); |
printf ("\tRouter num in row: %d \n",NX); |
printf ("\tRouter num in column: %d \n",NY); |
printf ("\tNumber of Class: %d\n", C); |
printf ("\tFlit data width: %d \n", Fpay); |
printf ("\tVC reallocation mechanism: %s \n", VC_REALLOCATION_TYPE); |
printf ("\tVC/sw combination mechanism: %s \n", COMBINATION_TYPE); |
printf ("\troute-subfunction: %s \n", ROUTE_SUBFUNC ); |
printf ("\tAVC_ATOMIC_EN:%d \n", AVC_ATOMIC_EN); |
printf ("\tCongestion Index:%d \n",CONGESTION_INDEX); |
printf ("\tADD_PIPREG_AFTER_CROSSBAR:%d\n",ADD_PIPREG_AFTER_CROSSBAR); |
|
|
|
#if(DEBUG_EN) |
printf ("\tDebuging is enabled\n"); |
#else |
printf ("\tDebuging is disabled\n"); |
#endif |
|
printf ("Simulation parameters\n"); |
if(strcmp (AVG_LATENCY_METRIC,"HEAD_2_TAIL")==0)printf ("\tOutput is the average latency on sending the packet head until receiving tail\n"); |
else printf ("\tOutput is the average latency on sending the packet head until receiving the head\n"); |
printf ("\tTraffic pattern:%s\n",TRAFFIC); |
if(C>0) printf ("\ttraffic percentage of class 0 is : %d\n", C0_p); |
if(C>1) printf ("\ttraffic percentage of class 1 is : %d\n", C1_p); |
if(C>2) printf ("\ttraffic percentage of class 2 is : %d\n", C2_p); |
if(C>3) printf ("\ttraffic percentage of class 3 is : %d\n", C3_p); |
if((strcmp (TRAFFIC,"HOTSPOT")==0)|| (strcmp (TRAFFIC,"hot spot")==0)){ |
printf ("\tHot spot percentage: %u\n", HOTSPOT_PERCENTAGE); |
printf ("\tNumber of hot spot cores: %d\n", HOTSPOT_NUM); |
|
} |
//printf ("\tTotal packets sent by one router: %u\n", TOTAL_PKT_PER_ROUTER); |
printf ("\t Simulation timeout =%d\n", MAX_SIM_CLKs); |
printf ("\t Simulation ends on total packet num of =%d\n", MAX_PCK_NUM); |
printf ("\tPacket size: %u flits\n",PACKET_SIZE); |
printf ("\t SSA_EN enabled:%s \n",SSA_EN); |
} |
|
|
/************************ |
* |
* reset system |
* |
* |
* *******************/ |
|
void reset_all_register (void){ |
int i; |
|
|
|
total_router=0; |
total_pck_num=0; |
sum_clk_h2h=0; |
sum_clk_h2t=0; |
#if (STND_DEV_EN) |
sum_clk_pow2=0; |
#endif |
|
sum_clk_per_hop=0; |
count_en=0; |
clk_counter=0; |
|
for(i=0;i<C;i++) |
{ |
total_pck_num_per_class[i]=0; |
sum_clk_h2h_per_class[i]=0; |
sum_clk_h2t_per_class[i]=0; |
sum_clk_per_hop_per_class[i]=0; |
#if (STND_DEV_EN) |
sum_clk_pow2_per_class[i]=0; |
#endif |
|
} //for |
flit_counter=0; |
} |
|
|
|
|
/*********************** |
* |
* standard_dev |
* |
* ******************/ |
|
#if (STND_DEV_EN) |
|
|
double standard_dev( double sum_pow2, unsigned int total_num, double average){ |
double std_dev; |
|
std_dev = sum_pow2/(double)total_num; |
std_dev -= (average*average); |
std_dev = sqrt(std_dev); |
|
return std_dev; |
|
} |
|
#endif |
|
|
|
/********************** |
* |
* pck_class_in_gen |
* |
* *****************/ |
|
unsigned char pck_class_in_gen( |
unsigned int core_num |
|
) { |
|
unsigned char pck_class_in; |
unsigned char rnd=rand()%100; |
|
pck_class_in= ( rnd < C0_p )? 0: |
( rnd < (C0_p+C1_p) )? 1: |
( rnd < (C0_p+C1_p+C2_p))?2:3; |
|
|
|
return pck_class_in; |
} |
|
/********************************** |
|
pck_dst_gen |
|
*********************************/ |
|
void pck_dst_gen ( |
unsigned int current_x, |
unsigned int current_y, |
unsigned int core_num, |
unsigned int *dest_x, |
unsigned int *dest_y |
){ |
|
|
unsigned int rnd=0; |
unsigned int rnd100=0; |
int i; |
|
|
if((strcmp (TRAFFIC,"RANDOM")==0) || (strcmp (TRAFFIC,"random")==0)){ |
|
do{ |
rnd=rand()%NC; |
}while (rnd==core_num); // get a random IP core, make sure its not same as sender core |
|
(*dest_y) = (rnd / NX ); |
(*dest_x) = (rnd % NX ); |
|
|
} |
else if ((strcmp(TRAFFIC,"HOTSPOT")==0) || (strcmp (TRAFFIC,"hot spot")==0)){ |
|
do{ |
rnd=rand()%NC; |
}while (rnd==core_num); // get a random IP core, make sure its not same as sender core |
|
rnd100=rand()%100; |
|
if (rnd100 < HOTSPOT_PERCENTAGE && core_num !=HOTSPOT_CORE_1 ) rnd = HOTSPOT_CORE_1; |
else if((HOTSPOT_NUM > 1) && (rnd100 >= 20 ) && (rnd100 < (20+HOTSPOT_PERCENTAGE)) && core_num!=HOTSPOT_CORE_2 ) rnd = HOTSPOT_CORE_2; |
else if((HOTSPOT_NUM > 2) && (rnd100 >= 40) && (rnd100 < (40+HOTSPOT_PERCENTAGE)) && core_num!=HOTSPOT_CORE_3 ) rnd = HOTSPOT_CORE_3; |
else if((HOTSPOT_NUM > 3) && (rnd100 >= 60) && (rnd100 < (60+HOTSPOT_PERCENTAGE)) && core_num!=HOTSPOT_CORE_4 ) rnd = HOTSPOT_CORE_4; |
else if((HOTSPOT_NUM > 4) && (rnd100 >= 80) && (rnd100 < (80+HOTSPOT_PERCENTAGE)) && core_num!=HOTSPOT_CORE_5 ) rnd = HOTSPOT_CORE_5; |
|
|
|
(*dest_y) = (rnd / NX ); |
(*dest_x) = (rnd % NX ); |
|
|
} else if(( strcmp(TRAFFIC ,"TRANSPOSE1")==0)|| (strcmp (TRAFFIC,"transposed 1")==0)){ |
|
(*dest_x) = NX-current_y-1; |
(*dest_y) = NY-current_x-1; |
|
|
|
} else if(( strcmp(TRAFFIC ,"TRANSPOSE2")==0)|| (strcmp (TRAFFIC,"transposed 2")==0)){ |
(*dest_x) = current_y; |
(*dest_y) = current_x; |
|
|
} else if(( strcmp(TRAFFIC ,"BIT_REVERSE")==0)|| (strcmp (TRAFFIC,"bit reverse")==0)){ |
unsigned int joint_addr= (current_x<<Xw)+current_y; |
unsigned int reverse_addr=0; |
unsigned int pos=0; |
for(i=0; i<(Xw+Yw); i++){//reverse the address |
pos= (((Xw+Yw)-1)-i); |
reverse_addr|= ((joint_addr >> pos) & 0x01) << i; |
// reverse_addr[i] = joint_addr [((Xw+Yw)-1)-i]; |
} |
(*dest_x) = reverse_addr>>Yw; |
(*dest_y) = reverse_addr&(0xFF>> (8-Yw)); |
|
|
|
|
} else if(( strcmp(TRAFFIC ,"BIT_COMPLEMENT") ==0)|| (strcmp (TRAFFIC,"bit complement")==0)){ |
|
(*dest_x) = (~current_x) &(0xFF>> (8-Xw)); |
(*dest_y) = (~current_y) &(0xFF>> (8-Yw)); |
|
|
} else if(( strcmp(TRAFFIC ,"TORNADO") == 0)|| (strcmp (TRAFFIC,"tornado")==0)){ |
//[(x+(k/2-1)) mod k, (y+(k/2-1)) mod k], |
(*dest_x) = ((current_x + ((NX/2)-1))%NX); |
(*dest_y) = ((current_y + ((NY/2)-1))%NY); |
|
|
} else if( strcmp(TRAFFIC ,"CUSTOM") == 0){ |
//[(x+(k/2-1)) mod k, (y+(k/2-1)) mod k], |
if(current_x ==0 && current_y == 0 ){ |
(*dest_x) = NX-1; |
(*dest_y) = NY-1; |
}else{// make it unvalid |
(*dest_x) = current_x; |
(*dest_y) = current_y; |
|
} |
|
} |
|
else printf ("traffic %s is an unsupported traffic pattern\n",TRAFFIC); |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
src_verilator/simulator.cpp
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: src_verilator/traffic_gen_verilator.v
===================================================================
--- src_verilator/traffic_gen_verilator.v (revision 31)
+++ src_verilator/traffic_gen_verilator.v (revision 32)
@@ -36,14 +36,15 @@
clk
);
+
function integer log2;
input integer number; begin
- log2=0;
+ log2=(number <=1) ? 1: 0;
while(2**log2
© copyright 1999-2024
OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.