#!/usr/bin/perl -w
|
#!/usr/bin/perl -w
|
|
|
#this file contains NoC topology related sub-functions
|
#this file contains NoC topology related sub-functions
|
|
|
use constant::boolean;
|
use constant::boolean;
|
use strict;
|
use strict;
|
use warnings;
|
use warnings;
|
|
|
use FindBin;
|
use FindBin;
|
use lib $FindBin::Bin;
|
use lib $FindBin::Bin;
|
|
|
sub get_topology_info {
|
sub get_topology_info {
|
my ($self) =@_;
|
my ($self) =@_;
|
my $topology=$self->object_get_attribute('noc_param','TOPOLOGY');
|
my $topology=$self->object_get_attribute('noc_param','TOPOLOGY');
|
my $T1=$self->object_get_attribute('noc_param','T1');
|
my $T1=$self->object_get_attribute('noc_param','T1');
|
my $T2=$self->object_get_attribute('noc_param','T2');
|
my $T2=$self->object_get_attribute('noc_param','T2');
|
my $T3=$self->object_get_attribute('noc_param','T3');
|
my $T3=$self->object_get_attribute('noc_param','T3');
|
my $V = $self->object_get_attribute('noc_param','V');
|
my $V = $self->object_get_attribute('noc_param','V');
|
my $Fpay = $self->object_get_attribute('noc_param','Fpay');
|
my $Fpay = $self->object_get_attribute('noc_param','Fpay');
|
|
|
return get_topology_info_sub($topology, $T1, $T2, $T3,$V, $Fpay);
|
return get_topology_info_sub($topology, $T1, $T2, $T3,$V, $Fpay);
|
}
|
}
|
|
|
|
|
sub get_topology_info_from_parameters {
|
sub get_topology_info_from_parameters {
|
my ($ref) =@_;
|
my ($ref) =@_;
|
my %noc_info;
|
my %noc_info;
|
my %param= %$ref if(defined $ref );
|
my %param= %$ref if(defined $ref );
|
my $topology=$param{'TOPOLOGY'};
|
my $topology=$param{'TOPOLOGY'};
|
my $T1 =$param{'T1'};
|
my $T1 =$param{'T1'};
|
my $T2 =$param{'T2'};
|
my $T2 =$param{'T2'};
|
my $T3 =$param{'T3'};
|
my $T3 =$param{'T3'};
|
my $V =$param{'V'};
|
my $V =$param{'V'};
|
my $Fpay=$param{'Fpay'};
|
my $Fpay=$param{'Fpay'};
|
return get_topology_info_sub($topology, $T1, $T2, $T3,$V, $Fpay);
|
return get_topology_info_sub($topology, $T1, $T2, $T3,$V, $Fpay);
|
}
|
}
|
|
|
|
|
|
|
sub get_topology_info_sub {
|
sub get_topology_info_sub {
|
|
|
my ($topology, $T1, $T2, $T3,$V, $Fpay)=@_;
|
my ($topology, $T1, $T2, $T3,$V, $Fpay)=@_;
|
|
|
my $NE; # number of end points
|
my $NE; # number of end points
|
my $NR; # number of routers
|
my $NR; # number of routers
|
my $RAw; # routers address width
|
my $RAw; # routers address width
|
my $EAw; # Endpoints address width
|
my $EAw; # Endpoints address width
|
|
|
|
|
my $Fw = 2+$V+$Fpay;
|
my $Fw = 2+$V+$Fpay;
|
if($topology eq '"TREE"') {
|
if($topology eq '"TREE"') {
|
my $K = $T1;
|
my $K = $T1;
|
my $L = $T2;
|
my $L = $T2;
|
$NE = powi( $K,$L );
|
$NE = powi( $K,$L );
|
$NR = sum_powi ( $K,$L );
|
$NR = sum_powi ( $K,$L );
|
my $Kw=log2($K);
|
my $Kw=log2($K);
|
my $LKw=$L*$Kw;
|
my $LKw=$L*$Kw;
|
my $Lw=log2($L);
|
my $Lw=log2($L);
|
$RAw=$LKw + $Lw;
|
$RAw=$LKw + $Lw;
|
$EAw = $LKw;
|
$EAw = $LKw;
|
|
|
}elsif($topology eq '"FATTREE"') {
|
}elsif($topology eq '"FATTREE"') {
|
my $K = $T1;
|
my $K = $T1;
|
my $L = $T2;
|
my $L = $T2;
|
$NE = powi( $K,$L );
|
$NE = powi( $K,$L );
|
$NR = $L * powi( $K , $L - 1 );
|
$NR = $L * powi( $K , $L - 1 );
|
my $Kw=log2($K);
|
my $Kw=log2($K);
|
my $LKw=$L*$Kw;
|
my $LKw=$L*$Kw;
|
my $Lw=log2($L);
|
my $Lw=log2($L);
|
$RAw=$LKw + $Lw;
|
$RAw=$LKw + $Lw;
|
$EAw = $LKw;
|
$EAw = $LKw;
|
|
|
}elsif ($topology eq '"RING"' || $topology eq '"LINE"'){
|
}elsif ($topology eq '"RING"' || $topology eq '"LINE"'){
|
my $NX=$T1;
|
my $NX=$T1;
|
my $NY=1;
|
my $NY=1;
|
my $NL=$T3;
|
my $NL=$T3;
|
$NE = $NX*$NY*$NL;
|
$NE = $NX*$NY*$NL;
|
$NR = $NX*$NY;
|
$NR = $NX*$NY;
|
my $Xw=log2($NX);
|
my $Xw=log2($NX);
|
my $Yw=log2($NY);
|
my $Yw=log2($NY);
|
my $Lw=log2($NL);
|
my $Lw=log2($NL);
|
$RAw = $Xw;
|
$RAw = $Xw;
|
$EAw = ($NL==1) ? $RAw : $RAw + $Lw;
|
$EAw = ($NL==1) ? $RAw : $RAw + $Lw;
|
|
|
}elsif ($topology eq '"MESH"' || $topology eq '"TORUS"' ) {
|
}elsif ($topology eq '"MESH"' || $topology eq '"TORUS"' ) {
|
my $NX=$T1;
|
my $NX=$T1;
|
my $NY=$T2;
|
my $NY=$T2;
|
my $NL=$T3;
|
my $NL=$T3;
|
$NE = $NX*$NY*$NL;
|
$NE = $NX*$NY*$NL;
|
$NR = $NX*$NY;
|
$NR = $NX*$NY;
|
my $Xw=log2($NX);
|
my $Xw=log2($NX);
|
my $Yw=log2($NY);
|
my $Yw=log2($NY);
|
my $Lw=log2($NL);
|
my $Lw=log2($NL);
|
$RAw = $Xw + $Yw;
|
$RAw = $Xw + $Yw;
|
$EAw = ($NL==1) ? $RAw : $RAw + $Lw;
|
$EAw = ($NL==1) ? $RAw : $RAw + $Lw;
|
}elsif ($topology eq '"FMESH"'){
|
}elsif ($topology eq '"FMESH"'){
|
my $NX=$T1;
|
my $NX=$T1;
|
my $NY=$T2;
|
my $NY=$T2;
|
my $NL=$T3;
|
my $NL=$T3;
|
$NE = $NX*$NY*$NL + 2*($NX + $NY);
|
$NE = $NX*$NY*$NL + 2*($NX + $NY);
|
$NR = $NX*$NY;
|
$NR = $NX*$NY;
|
my $Xw=log2($NX);
|
my $Xw=log2($NX);
|
my $Yw=log2($NY);
|
my $Yw=log2($NY);
|
my $Lw=log2($NL);
|
my $Lw=log2($NL);
|
$RAw = $Xw + $Yw;
|
$RAw = $Xw + $Yw;
|
$EAw = $RAw + log2(4+$NL);
|
$EAw = $RAw + log2(4+$NL);
|
|
|
}elsif ($topology eq '"STAR"' ) {
|
}elsif ($topology eq '"STAR"' ) {
|
$NE= $T1;
|
$NE= $T1;
|
$NR= 1;
|
$NR= 1;
|
$RAw=log2($NR);
|
$RAw=log2($NR);
|
$EAw=log2($NE);
|
$EAw=log2($NE);
|
|
|
}else{ #custom
|
}else{ #custom
|
$NE= $T1;
|
$NE= $T1;
|
$NR= $T2;
|
$NR= $T2;
|
$RAw=log2($NR);
|
$RAw=log2($NR);
|
$EAw=log2($NE);
|
$EAw=log2($NE);
|
}
|
}
|
return ($NE, $NR, $RAw, $EAw, $Fw);
|
return ($NE, $NR, $RAw, $EAw, $Fw);
|
}
|
}
|
|
|
|
|
sub fattree_addrencode {
|
sub fattree_addrencode {
|
my ( $pos, $k, $l)=@_;
|
my ( $pos, $k, $l)=@_;
|
my $pow; my $ tmp;
|
my $pow; my $ tmp;
|
my $addrencode=0;
|
my $addrencode=0;
|
my $kw=log2($k);
|
my $kw=log2($k);
|
$pow=1;
|
$pow=1;
|
for (my $i = 0; $i <$l; $i=$i+1 ) {
|
for (my $i = 0; $i <$l; $i=$i+1 ) {
|
$tmp=int($pos/$pow);
|
$tmp=int($pos/$pow);
|
$tmp=$tmp % $k;
|
$tmp=$tmp % $k;
|
$tmp=$tmp<<($i)*$kw;
|
$tmp=$tmp << ($i)*$kw;
|
$addrencode=$addrencode | $tmp;
|
$addrencode=$addrencode | $tmp;
|
$pow=$pow * $k;
|
$pow=$pow * $k;
|
}
|
}
|
return $addrencode;
|
return $addrencode;
|
}
|
}
|
|
|
sub fattree_addrdecode{
|
sub fattree_addrdecode{
|
my ($addrencode, $k, $l)=@_;
|
my ($addrencode, $k, $l)=@_;
|
my $kw=0;
|
my $kw=0;
|
my $mask=0;
|
my $mask=0;
|
my $pow; my $tmp;
|
my $pow; my $tmp;
|
my $pos=0;
|
my $pos=0;
|
while((0x1<<$kw) < $k){
|
while((0x1 << $kw) < $k){
|
$kw++;
|
$kw++;
|
$mask<<=1;
|
$mask<<=1;
|
$mask|=0x1;
|
$mask|=0x1;
|
}
|
}
|
$pow=1;
|
$pow=1;
|
for (my $i = 0; $i <$l; $i=$i+1 ) {
|
for (my $i = 0; $i <$l; $i=$i+1 ) {
|
$tmp = $addrencode & $mask;
|
$tmp = $addrencode & $mask;
|
#printf("tmp1=%u\n",tmp);
|
#printf("tmp1=%u\n",tmp);
|
$tmp=($tmp*$pow);
|
$tmp=($tmp*$pow);
|
$pos= $pos + $tmp;
|
$pos= $pos + $tmp;
|
$pow=$pow * $k;
|
$pow=$pow * $k;
|
$addrencode>>=$kw;
|
$addrencode>>=$kw;
|
}
|
}
|
return $pos;
|
return $pos;
|
}
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
sub get_connected_router_id_to_endp{
|
sub get_connected_router_id_to_endp{
|
my ($self,$endp_id)=@_;
|
my ($self,$endp_id)=@_;
|
my $topology=$self->object_get_attribute('noc_param','TOPOLOGY');
|
my $topology=$self->object_get_attribute('noc_param','TOPOLOGY');
|
my $T1=$self->object_get_attribute('noc_param','T1');
|
my $T1=$self->object_get_attribute('noc_param','T1');
|
my $T2=$self->object_get_attribute('noc_param','T2');
|
my $T2=$self->object_get_attribute('noc_param','T2');
|
my $T3=$self->object_get_attribute('noc_param','T3');
|
my $T3=$self->object_get_attribute('noc_param','T3');
|
if($topology eq '"FATTREE"' || $topology eq '"TREE"') {
|
if($topology eq '"FATTREE"' || $topology eq '"TREE"') {
|
return int($endp_id/$T1);
|
return int($endp_id/$T1);
|
}elsif ($topology eq '"RING"' || $topology eq '"LINE"' || $topology eq '"MESH"' || $topology eq '"TORUS"'){
|
}elsif ($topology eq '"RING"' || $topology eq '"LINE"' || $topology eq '"MESH"' || $topology eq '"TORUS"'){
|
return int($endp_id/$T3);
|
return int($endp_id/$T3);
|
}elsif ($topology eq '"STAR"' ) {
|
}elsif ($topology eq '"STAR"' ) {
|
return 0;#there is only one routerin star topology
|
return 0;#there is only one routerin star topology
|
}elsif ($topology eq '"FMESH"'){
|
}elsif ($topology eq '"FMESH"'){
|
my $tmp = $T1*$T2*$T3;
|
my $tmp = $T1*$T2*$T3;
|
return int($endp_id/$T3) if($endp_id<$tmp);
|
return int($endp_id/$T3) if($endp_id<$tmp);
|
return $endp_id-$tmp if($endp_id<$tmp+$T1);
|
return $endp_id-$tmp if($endp_id<$tmp+$T1);
|
return ($endp_id-$tmp-$T1)+ $T1*($T2-1) if($endp_id<$tmp+2*$T1);
|
return ($endp_id-$tmp-$T1)+ $T1*($T2-1) if($endp_id<$tmp+2*$T1);
|
return ($endp_id-$tmp-2*$T1)*$T1 if($endp_id<$tmp+2*$T1+$T2);
|
return ($endp_id-$tmp-2*$T1)*$T1 if($endp_id<$tmp+2*$T1+$T2);
|
return ($endp_id-$tmp-2*$T1-$T2+1)*$T1-1;
|
return ($endp_id-$tmp-2*$T1-$T2+1)*$T1-1;
|
|
|
}else{#custom
|
}else{#custom
|
my @er_addr = $self->object_get_attribute('noc_connection','er_addr');
|
my @er_addr = $self->object_get_attribute('noc_connection','er_addr');
|
return $er_addr[$endp_id];
|
return $er_addr[$endp_id];
|
}
|
}
|
}
|
}
|
|
|
|
|
sub fmesh_addrencode{
|
sub fmesh_addrencode{
|
my($id,$T1,$T2,$T3)=@_;
|
my($id,$T1,$T2,$T3)=@_;
|
my ($y, $x, $l,$p, $diff,$mul);
|
my ($y, $x, $l,$p, $diff,$mul);
|
$mul = $T1*$T2*$T3;
|
$mul = $T1*$T2*$T3;
|
|
|
my $LOCAL = 0;
|
my $LOCAL = 0;
|
my $EAST = 1;
|
my $EAST = 1;
|
my $NORTH = 2;
|
my $NORTH = 2;
|
my $WEST = 3;
|
my $WEST = 3;
|
my $SOUTH = 4;
|
my $SOUTH = 4;
|
|
|
if($id < $mul) {
|
if($id < $mul) {
|
$y = (($id/$T3) / $T1 );
|
$y = (($id/$T3) / $T1 );
|
$x = (($id/$T3) % $T1 );
|
$x = (($id/$T3) % $T1 );
|
$l = ( $id %$T3);
|
$l = ( $id %$T3);
|
$p = ($l==0)? $LOCAL : 4+$l;
|
$p = ($l==0)? $LOCAL : 4+$l;
|
}else{
|
}else{
|
$diff = $id - $mul ;
|
$diff = $id - $mul ;
|
if( $diff < $T1){ #top mesh edge
|
if( $diff < $T1){ #top mesh edge
|
$y = 0;
|
$y = 0;
|
$x = $diff;
|
$x = $diff;
|
$p = $NORTH;
|
$p = $NORTH;
|
}
|
}
|
elsif ( $diff < 2* $T1) { #bottom mesh edge
|
elsif ( $diff < 2* $T1) { #bottom mesh edge
|
$y = $T2-1;
|
$y = $T2-1;
|
$x = $diff-$T1;
|
$x = $diff-$T1;
|
$p = $SOUTH;
|
$p = $SOUTH;
|
}
|
}
|
elsif ( $diff < (2* $T1)+$T2 ) { #left mesh edge
|
elsif ( $diff < (2* $T1)+$T2 ) { #left mesh edge
|
$y = $diff - (2* $T1);
|
$y = $diff - (2* $T1);
|
$x = 0;
|
$x = 0;
|
$p = $WEST;
|
$p = $WEST;
|
}
|
}
|
else { #right mesh edge
|
else { #right mesh edge
|
$y = $diff - (2* $T1) -$T2;
|
$y = $diff - (2* $T1) -$T2;
|
$x = $T1-1;
|
$x = $T1-1;
|
$p = $EAST;
|
$p = $EAST;
|
}
|
}
|
}
|
}
|
my $NXw=log2($T1);
|
my $NXw=log2($T1);
|
my $NYw=log2($T2);
|
my $NYw=log2($T2);
|
my $addrencode=0;
|
my $addrencode=0;
|
$addrencode = ($p<<($NXw+$NYw)| ($y << $NXw) | $x);
|
$addrencode = ($p << ($NXw+$NYw)| ($y << $NXw) | $x);
|
return $addrencode;
|
return $addrencode;
|
}
|
}
|
|
|
sub fmesh_endp_addr_decoder {
|
sub fmesh_endp_addr_decoder {
|
my ($code, $T1, $T2, $T3)=@_;
|
my ($code, $T1, $T2, $T3)=@_;
|
my ($x, $y, $p) =mesh_tori_addr_sep ($code, $T1, $T2, $T3);
|
my ($x, $y, $p) =mesh_tori_addr_sep ($code, $T1, $T2, $T3);
|
my $LOCAL = 0;
|
my $LOCAL = 0;
|
my $EAST = 1;
|
my $EAST = 1;
|
my $NORTH = 2;
|
my $NORTH = 2;
|
my $WEST = 3;
|
my $WEST = 3;
|
my $SOUTH = 4;
|
my $SOUTH = 4;
|
return (($y*$T1)+$x)*$T3 if($p== $LOCAL);
|
return (($y*$T1)+$x)*$T3 if($p== $LOCAL);
|
return (($y*$T1)+$x)*$T3+($p-$SOUTH) if($p > $SOUTH);
|
return (($y*$T1)+$x)*$T3+($p-$SOUTH) if($p > $SOUTH);
|
return (($T1*$T2*$T3) + $x) if($p== $NORTH);
|
return (($T1*$T2*$T3) + $x) if($p== $NORTH);
|
return (($T1*$T2*$T3) + $T1 + $x) if($p== $SOUTH);
|
return (($T1*$T2*$T3) + $T1 + $x) if($p== $SOUTH);
|
return (($T1*$T2*$T3) + 2*$T1 + $y) if($p== $WEST );
|
return (($T1*$T2*$T3) + 2*$T1 + $y) if($p== $WEST );
|
return (($T1*$T2*$T3) + 2*$T1 + $T2 + $y) if($p== $EAST );
|
return (($T1*$T2*$T3) + 2*$T1 + $T2 + $y) if($p== $EAST );
|
return 0; #should not reach here
|
return 0; #should not reach here
|
}
|
}
|
|
|
|
|
|
|
|
|
|
|
sub get_router_num {
|
sub get_router_num {
|
my ($self,$x, $y)=@_;
|
my ($self,$x, $y)=@_;
|
my $topology=$self->object_get_attribute('noc_param','TOPOLOGY');
|
my $topology=$self->object_get_attribute('noc_param','TOPOLOGY');
|
my $T1=$self->object_get_attribute('noc_param','T1');
|
my $T1=$self->object_get_attribute('noc_param','T1');
|
my $T2=$self->object_get_attribute('noc_param','T2');
|
my $T2=$self->object_get_attribute('noc_param','T2');
|
if($topology eq '"FATTREE"') {
|
if($topology eq '"FATTREE"') {
|
return fattree_addrdecode($x, $T1, $T2);
|
return fattree_addrdecode($x, $T1, $T2);
|
}elsif ($topology eq '"RING"' || $topology eq '"LINE"' || $topology eq '"FMESH"' || $topology eq '"MESH"' || $topology eq '"TORUS"'){
|
}elsif ($topology eq '"RING"' || $topology eq '"LINE"' || $topology eq '"FMESH"' || $topology eq '"MESH"' || $topology eq '"TORUS"'){
|
return ($y*$T1)+$x;
|
return ($y*$T1)+$x;
|
}else{#custom
|
}else{#custom
|
#It is not used for custom & STAR topology
|
#It is not used for custom & STAR topology
|
}
|
}
|
}
|
}
|
|
|
sub router_addr_encoder{
|
sub router_addr_encoder{
|
my ($self, $id)=@_;
|
my ($self, $id)=@_;
|
my $topology=$self->object_get_attribute('noc_param','TOPOLOGY');
|
my $topology=$self->object_get_attribute('noc_param','TOPOLOGY');
|
my $T1=$self->object_get_attribute('noc_param','T1');
|
my $T1=$self->object_get_attribute('noc_param','T1');
|
my $T2=$self->object_get_attribute('noc_param','T2');
|
my $T2=$self->object_get_attribute('noc_param','T2');
|
my $T3=$self->object_get_attribute('noc_param','T3');
|
my $T3=$self->object_get_attribute('noc_param','T3');
|
if($topology eq '"FATTREE"' || $topology eq '"TREE"') {
|
if($topology eq '"FATTREE"' || $topology eq '"TREE"') {
|
return fattree_addrencode($id, $T1, $T2);
|
return fattree_addrencode($id, $T1, $T2);
|
}elsif ($topology eq '"RING"' || $topology eq '"LINE"' || $topology eq '"MESH"' || $topology eq '"FESH"' || $topology eq '"TORUS"'){
|
}elsif ($topology eq '"RING"' || $topology eq '"LINE"' || $topology eq '"MESH"' || $topology eq '"FESH"' || $topology eq '"TORUS"'){
|
return mesh_tori_addrencode($id,$T1, $T2,1);
|
return mesh_tori_addrencode($id,$T1, $T2,1);
|
}else { #custom & STAR
|
}else { #custom & STAR
|
return $id;
|
return $id;
|
}
|
}
|
}
|
}
|
|
|
sub endp_addr_encoder{
|
sub endp_addr_encoder{
|
my ($self, $id)=@_;
|
my ($self, $id)=@_;
|
my $topology=$self->object_get_attribute('noc_param','TOPOLOGY');
|
my $topology=$self->object_get_attribute('noc_param','TOPOLOGY');
|
my $T1=$self->object_get_attribute('noc_param','T1');
|
my $T1=$self->object_get_attribute('noc_param','T1');
|
my $T2=$self->object_get_attribute('noc_param','T2');
|
my $T2=$self->object_get_attribute('noc_param','T2');
|
my $T3=$self->object_get_attribute('noc_param','T3');
|
my $T3=$self->object_get_attribute('noc_param','T3');
|
if($topology eq '"FATTREE"' || $topology eq '"TREE"') {
|
if($topology eq '"FATTREE"' || $topology eq '"TREE"') {
|
return fattree_addrencode($id, $T1, $T2);
|
return fattree_addrencode($id, $T1, $T2);
|
}elsif ($topology eq '"RING"' || $topology eq '"LINE"' || $topology eq '"MESH"' || $topology eq '"TORUS"'){
|
}elsif ($topology eq '"MESH"' || $topology eq '"TORUS"'){
|
return mesh_tori_addrencode($id,$T1, $T2,$T3);
|
return mesh_tori_addrencode($id,$T1, $T2,$T3);
|
|
}elsif ($topology eq '"RING"' || $topology eq '"LINE"'){
|
|
return ring_line_addrencode($id,$T1, $T3);
|
}elsif ($topology eq '"FMESH"' ){
|
}elsif ($topology eq '"FMESH"' ){
|
return fmesh_addrencode($id,$T1, $T2,$T3);
|
return fmesh_addrencode($id,$T1, $T2,$T3);
|
}else{#CUSTOM & STAR
|
}else{#CUSTOM & STAR
|
return $id;
|
return $id;
|
}
|
}
|
}
|
}
|
|
|
sub endp_addr_decoder {
|
sub endp_addr_decoder {
|
my ($self,$code)=@_;
|
my ($self,$code)=@_;
|
my $topology=$self->object_get_attribute('noc_param','TOPOLOGY');
|
my $topology=$self->object_get_attribute('noc_param','TOPOLOGY');
|
my $T1=$self->object_get_attribute('noc_param','T1');
|
my $T1=$self->object_get_attribute('noc_param','T1');
|
my $T2=$self->object_get_attribute('noc_param','T2');
|
my $T2=$self->object_get_attribute('noc_param','T2');
|
my $T3=$self->object_get_attribute('noc_param','T3');
|
my $T3=$self->object_get_attribute('noc_param','T3');
|
if($topology eq '"FATTREE"' || $topology eq '"TREE"') {
|
if($topology eq '"FATTREE"' || $topology eq '"TREE"') {
|
return fattree_addrdecode($code, $T1, $T2);
|
return fattree_addrdecode($code, $T1, $T2);
|
}
|
}
|
elsif ($topology eq '"RING"' || $topology eq '"LINE"' || $topology eq '"MESH"' || $topology eq '"TORUS"'){
|
elsif ($topology eq '"RING"' || $topology eq '"LINE"' || $topology eq '"MESH"' || $topology eq '"TORUS"'){
|
my ($x, $y, $l) = mesh_tori_addr_sep($code,$T1, $T2,$T3);
|
my ($x, $y, $l) = mesh_tori_addr_sep($code,$T1, $T2,$T3);
|
#print "my ($x, $y, $l) = mesh_tori_addr_sep($code,$T1, $T2,$T3);\n";
|
#print "my ($x, $y, $l) = mesh_tori_addr_sep($code,$T1, $T2,$T3);\n";
|
return (($y*$T1)+$x)*$T3+$l;
|
return (($y*$T1)+$x)*$T3+$l;
|
}elsif ($topology eq '"FMESH"' ){
|
}elsif ($topology eq '"FMESH"' ){
|
return fmesh_endp_addr_decoder($code,$T1, $T2,$T3);
|
return fmesh_endp_addr_decoder($code,$T1, $T2,$T3);
|
}else{#custom & STAR
|
}else{#custom & STAR
|
return $code;
|
return $code;
|
}
|
}
|
}
|
}
|
|
|
sub mask_gen{
|
sub mask_gen{
|
my $k=shift;
|
my $k=shift;
|
my $kw=0;
|
my $kw=0;
|
my $mask=0;
|
my $mask=0;
|
while((0x1<<$kw) < $k){
|
while((0x1 << $kw) < $k){
|
$kw++;
|
$kw++;
|
$mask<<=1;
|
$mask<<=1;
|
$mask|=0x1;
|
$mask|=0x1;
|
}
|
}
|
return $mask;
|
return $mask;
|
}
|
}
|
|
|
|
|
sub mesh_tori_addr_sep {
|
sub mesh_tori_addr_sep {
|
my ($code,$NX, $NY,$NL)=@_;
|
my ($code,$NX, $NY,$NL)=@_;
|
my ($x, $y, $l);
|
my ($x, $y, $l);
|
my $NXw=log2($NX);
|
my $NXw=log2($NX);
|
my $NYw=log2($NY);
|
my $NYw=log2($NY);
|
$x = $code & mask_gen($NX);
|
$x = $code & mask_gen($NX);
|
$code>>=$NXw;
|
$code>>=$NXw;
|
$y = $code & mask_gen($NY);
|
$y = $code & mask_gen($NY);
|
$code>>=$NYw;
|
$code>>=$NYw;
|
$l = $code;
|
$l = $code;
|
return ($x, $y, $l);
|
return ($x, $y, $l);
|
}
|
}
|
|
|
sub mesh_tori_addrencode{
|
sub mesh_tori_addrencode{
|
my ($id,$T1, $T2,$T3)=@_;
|
my ($id,$T1, $T2,$T3)=@_;
|
my ($x,$y,$l)=mesh_tori_addrencod_sep($id,$T1,$T2,$T3);
|
my ($x,$y,$l)=mesh_tori_addrencod_sep($id,$T1,$T2,$T3);
|
return mesh_tori_addr_join($x,$y,$l,$T1, $T2,$T3);
|
return mesh_tori_addr_join($x,$y,$l,$T1, $T2,$T3);
|
}
|
}
|
|
|
|
sub ring_line_addrencode {
|
|
my ($id,$T1, $T3)=@_;
|
|
my ($x,$y,$l)=mesh_tori_addrencod_sep($id,$T1,0,$T3);
|
|
return ring_line_addr_join($x,$y,$l,$T1, $T3);
|
|
}
|
|
|
sub mesh_tori_addrencod_sep{
|
sub mesh_tori_addrencod_sep{
|
my ($id,$T1,$T2,$T3)=@_;
|
my ($id,$T1,$T2,$T3)=@_;
|
my ($x,$y,$l);
|
my ($x,$y,$l);
|
$l=$id % $T3; # id%NL
|
$l=$id % $T3; # id%NL
|
my $R= int($id / $T3);
|
my $R= int($id / $T3);
|
$x= $R % $T1;# (id/NL)%NX
|
$x= $R % $T1;# (id/NL)%NX
|
$y=int($R / $T1);# (id/NL)/NX
|
$y=int($R / $T1);# (id/NL)/NX
|
return ($x,$y,$l);
|
return ($x,$y,$l);
|
}
|
}
|
|
|
sub mesh_tori_addr_join {
|
sub mesh_tori_addr_join {
|
my ($x, $y, $l,$T1, $T2,$T3)=@_;
|
my ($x, $y, $l,$T1, $T2,$T3)=@_;
|
my $NXw=log2($T1);
|
my $NXw=log2($T1);
|
my $NYw=log2($T2);
|
my $NYw=log2($T2);
|
my $addrencode=0;
|
my $addrencode=0;
|
$addrencode =($T3==1)? ($y << $NXw | $x) : ($l<<($NXw+$NYw)| ($y << $NXw) | $x);
|
$addrencode =($T3==1)? ($y << $NXw | $x) : ($l << ($NXw+$NYw)| ($y << $NXw) | $x);
|
return $addrencode;
|
return $addrencode;
|
}
|
}
|
|
|
|
sub ring_line_addr_join {
|
|
my ($x, $y, $l,$T1, $T3)=@_;
|
|
my $NXw=log2($T1);
|
|
my $addrencode=0;
|
|
$addrencode =($T3==1)? $x : ($l << $NXw) | $x;
|
|
return $addrencode;
|
|
}
|
|
|
|
|
|
|
sub mcast_partial_width {
|
sub mcast_partial_width {
|
my ($p,$NE)=@_;
|
my ($p,$NE)=@_;
|
my $m=0;
|
my $m=0;
|
$p=remove_not_hex($p);
|
$p=remove_not_hex($p);
|
my @arr=split (//, $p);
|
my @arr=split (//, $p);
|
foreach my $i (@arr) {
|
foreach my $i (@arr) {
|
my $n=hex($i);
|
my $n=hex($i);
|
$m++ if($n & 0x1);
|
$m++ if($n & 0x1);
|
$m++ if($n & 0x2);
|
$m++ if($n & 0x2);
|
$m++ if($n & 0x4);
|
$m++ if($n & 0x4);
|
$m++ if($n & 0x8);
|
$m++ if($n & 0x8);
|
}
|
}
|
return $m;
|
return $m;
|
}
|
}
|
|
|
|
|
|
|
sub get_noc_verilator_top_modules_info {
|
sub get_noc_verilator_top_modules_info {
|
my ($self) =@_;
|
my ($self) =@_;
|
|
|
my $topology=$self->object_get_attribute('noc_param','TOPOLOGY');
|
my $topology=$self->object_get_attribute('noc_param','TOPOLOGY');
|
my $T1=$self->object_get_attribute('noc_param','T1');
|
my $T1=$self->object_get_attribute('noc_param','T1');
|
my $T2=$self->object_get_attribute('noc_param','T2');
|
my $T2=$self->object_get_attribute('noc_param','T2');
|
my $T3=$self->object_get_attribute('noc_param','T3');
|
my $T3=$self->object_get_attribute('noc_param','T3');
|
my $cast = $self->object_get_attribute('noc_param','MCAST_ENDP_LIST');
|
my $cast = $self->object_get_attribute('noc_param','MCAST_ENDP_LIST');
|
my $CAST_TYPE= $self->object_get_attribute('noc_param','CAST_TYPE');
|
my $CAST_TYPE= $self->object_get_attribute('noc_param','CAST_TYPE');
|
my $DAw_OFFSETw = ($topology eq '"MESH"' || $topology eq '"TORUS"' || $topology eq '"FMESH"')? $T1 : 0;
|
my $DAw_OFFSETw = ($topology eq '"MESH"' || $topology eq '"TORUS"' || $topology eq '"FMESH"')? $T1 : 0;
|
|
|
|
|
my %tops;
|
my %tops;
|
my %nr_p; # number of routers have $p port num
|
my %nr_p; # number of routers have $p port num
|
my $router_p; #number of routers with different port number in topology
|
my $router_p; #number of routers with different port number in topology
|
|
|
my ($ne, $nr, $RAw, $EAw)=get_topology_info($self);
|
my ($ne, $nr, $RAw, $EAw)=get_topology_info($self);
|
|
|
my $MCAST_PRTLw= mcast_partial_width($cast,$ne);
|
my $MCAST_PRTLw= mcast_partial_width($cast,$ne);
|
my $MCASTw =
|
my $MCASTw =
|
($CAST_TYPE eq '"MULTICAST_FULL"') ? $ne :
|
($CAST_TYPE eq '"MULTICAST_FULL"') ? $ne :
|
($CAST_TYPE eq '"MULTICAST_PARTIAL"' && $EAw >= $MCAST_PRTLw) ? $EAw +1 :
|
($CAST_TYPE eq '"MULTICAST_PARTIAL"' && $EAw >= $MCAST_PRTLw) ? $EAw +1 :
|
($CAST_TYPE eq '"MULTICAST_PARTIAL"' && $EAw < $MCAST_PRTLw) ? $MCAST_PRTLw +1 :
|
($CAST_TYPE eq '"MULTICAST_PARTIAL"' && $EAw < $MCAST_PRTLw) ? $MCAST_PRTLw +1 :
|
$EAw +1; #broadcast
|
$EAw +1; #broadcast
|
|
|
my $DAw = ($CAST_TYPE eq '"UNICAST"') ? $EAw: $MCASTw + $DAw_OFFSETw;
|
my $DAw = ($CAST_TYPE eq '"UNICAST"') ? $EAw: $MCASTw + $DAw_OFFSETw;
|
|
|
print "$DAw=$DAw\n";
|
|
|
|
my $custom_include="";
|
my $custom_include="";
|
if($topology eq '"FATTREE"') {
|
if($topology eq '"FATTREE"') {
|
my $K = $T1;
|
my $K = $T1;
|
my $L = $T2;
|
my $L = $T2;
|
my $p2 = 2*$K;
|
my $p2 = 2*$K;
|
$router_p=2;
|
$router_p=2;
|
my $NRL= $ne/$K; #number of router in each layer
|
my $NRL= $ne/$K; #number of router in each layer
|
$nr_p{1}=$NRL;
|
$nr_p{1}=$NRL;
|
$nr_p{2}=$nr-$NRL;
|
$nr_p{2}=$nr-$NRL;
|
$nr_p{p1}=$K;
|
$nr_p{p1}=$K;
|
$nr_p{p2}=2*$K;
|
$nr_p{p2}=2*$K;
|
|
|
%tops = (
|
%tops = (
|
#"Vrouter1" => "router_top_v_p${K}.v",
|
#"Vrouter1" => "router_top_v_p${K}.v",
|
#"Vrouter2" => "router_top_v_p${p2}.v",
|
#"Vrouter2" => "router_top_v_p${p2}.v",
|
"Vrouter1" => "--top-module router_top_v -GP=${K} ",
|
"Vrouter1" => "--top-module router_top_v -GP=${K} ",
|
"Vrouter2" => "--top-module router_top_v -GP=${p2} ",
|
"Vrouter2" => "--top-module router_top_v -GP=${p2} ",
|
# "Vnoc" => " --top-module noc_connection ",
|
# "Vnoc" => " --top-module noc_connection ",
|
|
|
);
|
);
|
}elsif ($topology eq '"TREE"'){
|
}elsif ($topology eq '"TREE"'){
|
my $K = $T1;
|
my $K = $T1;
|
my $L = $T2;
|
my $L = $T2;
|
my $p2 = $K+1;
|
my $p2 = $K+1;
|
$router_p=2;# number of router with different port number
|
$router_p=2;# number of router with different port number
|
$nr_p{1}=1;
|
$nr_p{1}=1;
|
$nr_p{2}=$nr-1;
|
$nr_p{2}=$nr-1;
|
$nr_p{p1}=$K;
|
$nr_p{p1}=$K;
|
$nr_p{p2}=$K+1;
|
$nr_p{p2}=$K+1;
|
|
|
%tops = (
|
%tops = (
|
#"Vrouter1" => "router_top_v_p${K}.v",
|
#"Vrouter1" => "router_top_v_p${K}.v",
|
#"Vrouter2" => "router_top_v_p${p2}.v",
|
#"Vrouter2" => "router_top_v_p${p2}.v",
|
"Vrouter1" => "--top-module router_top_v -GP=${K} ",
|
"Vrouter1" => "--top-module router_top_v -GP=${K} ",
|
"Vrouter2" => "--top-module router_top_v -GP=${p2} ",
|
"Vrouter2" => "--top-module router_top_v -GP=${p2} ",
|
# "Vnoc" => " --top-module noc_connection ",
|
# "Vnoc" => " --top-module noc_connection ",
|
);
|
);
|
|
|
}elsif ($topology eq '"RING"' || $topology eq '"LINE"'){
|
}elsif ($topology eq '"RING"' || $topology eq '"LINE"'){
|
|
|
$router_p=1;
|
$router_p=1;
|
$nr_p{1}=$nr;
|
$nr_p{1}=$nr;
|
my $ports= 3+$T3-1;
|
my $ports= 3+$T3-1;
|
$nr_p{p1}=$ports;
|
$nr_p{p1}=$ports;
|
%tops = (
|
%tops = (
|
#"Vrouter1" => "router_top_v_p${ports}.v",
|
#"Vrouter1" => "router_top_v_p${ports}.v",
|
"Vrouter1" => "--top-module router_top_v -GP=${ports} ",
|
"Vrouter1" => "--top-module router_top_v -GP=${ports} ",
|
# "Vnoc" => " --top-module noc_connection ",
|
# "Vnoc" => " --top-module noc_connection ",
|
|
|
);
|
);
|
|
|
|
|
}elsif ($topology eq '"MESH"' || $topology eq '"TORUS"' || $topology eq '"FMESH"') {
|
}elsif ($topology eq '"MESH"' || $topology eq '"TORUS"' || $topology eq '"FMESH"') {
|
|
|
$router_p=1;
|
$router_p=1;
|
$nr_p{1}=$nr;
|
$nr_p{1}=$nr;
|
my $ports= 5+$T3-1;
|
my $ports= 5+$T3-1;
|
$nr_p{p1}=$ports;
|
$nr_p{p1}=$ports;
|
%tops = (
|
%tops = (
|
#"Vrouter1" => "router_top_v_p${ports}.v",
|
#"Vrouter1" => "router_top_v_p${ports}.v",
|
"Vrouter1" => "--top-module router_top_v -GP=${ports} ",
|
"Vrouter1" => "--top-module router_top_v -GP=${ports} ",
|
# "Vnoc" => " --top-module noc_connection",
|
# "Vnoc" => " --top-module noc_connection",
|
|
|
);
|
);
|
}elsif ($topology eq '"STAR"') {
|
}elsif ($topology eq '"STAR"') {
|
$router_p=1;# number of router with different port number
|
$router_p=1;# number of router with different port number
|
my $ports= $T1;
|
my $ports= $T1;
|
$nr_p{p1}=$ports;
|
$nr_p{p1}=$ports;
|
$nr_p{1}=1;
|
$nr_p{1}=1;
|
%tops = (
|
%tops = (
|
#"Vrouter1" => "router_top_v_p${ports}.v",
|
#"Vrouter1" => "router_top_v_p${ports}.v",
|
"Vrouter1" => "--top-module router_top_v -GP=${ports} ",
|
"Vrouter1" => "--top-module router_top_v -GP=${ports} ",
|
# "Vnoc" => " --top-module noc_connection",
|
# "Vnoc" => " --top-module noc_connection",
|
|
|
);
|
);
|
|
|
}else {#custom
|
}else {#custom
|
|
|
my $dir =get_project_dir()."/mpsoc/rtl/src_topolgy";
|
my $dir =get_project_dir()."/mpsoc/rtl/src_topolgy";
|
my $file="$dir/param.obj";
|
my $file="$dir/param.obj";
|
my %param;
|
my %param;
|
if(-f $file){
|
if(-f $file){
|
my ($pp,$r,$err) = regen_object($file );
|
my ($pp,$r,$err) = regen_object($file );
|
if ($r){
|
if ($r){
|
print "**Error: cannot open $file file: $err\n";
|
print "**Error: cannot open $file file: $err\n";
|
return;
|
return;
|
}
|
}
|
|
|
%param=%{$pp};
|
%param=%{$pp};
|
}else {
|
}else {
|
print "**Error: cannot find $file \n";
|
print "**Error: cannot find $file \n";
|
return;
|
return;
|
}
|
}
|
|
|
my $topology_name=$self->object_get_attribute('noc_param','CUSTOM_TOPOLOGY_NAME');
|
my $topology_name=$self->object_get_attribute('noc_param','CUSTOM_TOPOLOGY_NAME');
|
my $ref=$param{$topology_name}{'ROUTER_Ps'};
|
my $ref=$param{$topology_name}{'ROUTER_Ps'};
|
print $ref;
|
print $ref;
|
my %router_ps= %{$ref};
|
my %router_ps= %{$ref};
|
my $i=1;
|
my $i=1;
|
#%tops = ("Vnoc" => " --top-module noc_connection");
|
#%tops = ("Vnoc" => " --top-module noc_connection");
|
|
|
#should sort neumeric. The router with smaller port number should comes first
|
#should sort neumeric. The router with smaller port number should comes first
|
|
|
foreach my $p (sort { $a <=> $b } keys %router_ps){
|
foreach my $p (sort { $a <=> $b } keys %router_ps){
|
$nr_p{$i}=$router_ps{$p};
|
$nr_p{$i}=$router_ps{$p};
|
$nr_p{"p$i"}=$p;
|
$nr_p{"p$i"}=$p;
|
#$tops{"Vrouter$i"}= "router_top_v_p${p}.v",
|
#$tops{"Vrouter$i"}= "router_top_v_p${p}.v",
|
$tops{"Vrouter$i"}= "--top-module router_top_v -GP=${p} ",
|
$tops{"Vrouter$i"}= "--top-module router_top_v -GP=${p} ",
|
$i++;
|
$i++;
|
|
|
}
|
}
|
$router_p=$i-1;
|
$router_p=$i-1;
|
${topology_name} =~ s/\"+//g;
|
${topology_name} =~ s/\"+//g;
|
$custom_include="#define IS_${topology_name}_noc\n";
|
$custom_include="#define IS_${topology_name}_noc\n";
|
}#else
|
}#else
|
|
|
|
|
|
|
my $includ_h="\n";
|
my $includ_h="\n";
|
for (my $p=1; $p<=$router_p ; $p++){
|
for (my $p=1; $p<=$router_p ; $p++){
|
$includ_h=$includ_h."#include \"Vrouter$p.h\" \n";
|
$includ_h=$includ_h."#include \"Vrouter$p.h\" \n";
|
}
|
}
|
my $rns_num = $router_p+1;
|
my $rns_num = $router_p+1;
|
$includ_h.="int router_NRs[$rns_num];\n";
|
$includ_h.="int router_NRs[$rns_num];\n";
|
|
|
my $max_p=0;
|
my $max_p=0;
|
for (my $p=1; $p<=$router_p ; $p++){
|
for (my $p=1; $p<=$router_p ; $p++){
|
my $pnum= $nr_p{"p$p"};
|
my $pnum= $nr_p{"p$p"};
|
$includ_h=$includ_h."#define NR${p} $nr_p{$p}\n";
|
$includ_h=$includ_h."#define NR${p} $nr_p{$p}\n";
|
$includ_h=$includ_h."#define NR${p}_PNUM $pnum\n";
|
$includ_h=$includ_h."#define NR${p}_PNUM $pnum\n";
|
|
|
$includ_h=$includ_h."Vrouter${p} *router${p}[ $nr_p{$p} ]; // Instantiation of router with $pnum port number\n";
|
$includ_h=$includ_h."Vrouter${p} *router${p}[ $nr_p{$p} ]; // Instantiation of router with $pnum port number\n";
|
$max_p = $pnum if($max_p < $pnum);
|
$max_p = $pnum if($max_p < $pnum);
|
}
|
}
|
$includ_h.="#define MAX_P $max_p //The maximum number of ports available in a router in this topology\n";
|
$includ_h.="#define MAX_P $max_p //The maximum number of ports available in a router in this topology\n";
|
|
|
$includ_h.="#define DAw $DAw //The traffic generator's destination address width\n";
|
$includ_h.="#define DAw $DAw //The traffic generator's destination address width\n";
|
|
|
|
|
my $st1='';
|
my $st1='';
|
my $st2='';
|
my $st2='';
|
my $st3='';
|
my $st3='';
|
my $st4='';
|
my $st4='';
|
my $st5='';
|
my $st5='';
|
my $st6='';
|
my $st6='';
|
my $st7='';
|
my $st7='';
|
my $st8='';
|
my $st8='';
|
|
|
my $i=1;
|
my $i=1;
|
my $j=0;
|
my $j=0;
|
my $accum=0;
|
my $accum=0;
|
for (my $p=1; $p<=$router_p ; $p++){
|
for (my $p=1; $p<=$router_p ; $p++){
|
$includ_h=$includ_h."
|
$includ_h=$includ_h."
|
|
|
|
|
|
|
";
|
";
|
#if ROUTER_P_NUM >$j
|
#if ROUTER_P_NUM >$j
|
|
|
#endif
|
#endif
|
|
|
$st2=$st2."
|
$st2=$st2."
|
router_NRs[$p] =$nr_p{$p};
|
router_NRs[$p] =$nr_p{$p};
|
for(i=0;i<NR${i};i++) router${i}[i] = new Vrouter${i};
|
for(i=0;i<NR${i};i++) router${i}[i] = new Vrouter${i};
|
";
|
";
|
|
|
$st3=$st3."
|
$st3=$st3."
|
for(i=0;i<NR${i};i++){
|
for(i=0;i<NR${i};i++){
|
router${i}[i]->reset= reset;
|
router${i}[i]->reset= reset;
|
router${i}[i]->clk= clk ;
|
router${i}[i]->clk= clk ;
|
}
|
}
|
";
|
";
|
|
|
$st4=$st4."
|
$st4=$st4."
|
for(i=0;i<NR${i};i++) router${i}[i]->eval();
|
for(i=0;i<NR${i};i++) router${i}[i]->eval();
|
";
|
";
|
|
|
|
|
$st5=$st5."
|
$st5=$st5."
|
for(i=0;i<NR${i};i++) router${i}[i]->final();
|
for(i=0;i<NR${i};i++) router${i}[i]->final();
|
";
|
";
|
|
|
|
|
$st6=$st6."
|
$st6=$st6."
|
if (i<NR${i}){ router${i}[i]->eval(); return;}
|
if (i<NR${i}){ router${i}[i]->eval(); return;}
|
i-= NR${i};
|
i-= NR${i};
|
";
|
";
|
|
|
|
|
|
|
|
|
|
|
$st7.="
|
$st7.="
|
if (i<NR${i}){
|
if (i<NR${i}){
|
update_router_st(
|
update_router_st(
|
NR${i}_PNUM,
|
NR${i}_PNUM,
|
router${i}[i]->current_r_id,
|
router${i}[i]->current_r_id,
|
router${i}[i]->router_event
|
router${i}[i]->router_event,
|
|
sizeof(router${i}[i]->router_event[0])
|
);
|
);
|
return;
|
return;
|
}
|
}
|
i-= NR${i};
|
i-= NR${i};
|
";
|
";
|
|
|
$st8=$st8."
|
$st8=$st8."
|
if (i<NR${i}){
|
if (i<NR${i}){
|
router${i}[i]->reset= reset;
|
router${i}[i]->reset= reset;
|
router${i}[i]->clk= clk ;
|
router${i}[i]->clk= clk ;
|
return;
|
return;
|
}
|
}
|
i-= NR${i};
|
i-= NR${i};
|
";
|
";
|
|
|
|
|
|
|
$i++;
|
$i++;
|
$j++;
|
$j++;
|
$accum=$accum+$nr_p{$p};
|
$accum=$accum+$nr_p{$p};
|
|
|
}
|
}
|
|
|
|
|
$includ_h=$includ_h."
|
$includ_h=$includ_h."
|
|
|
|
|
void Vrouter_new(){
|
void Vrouter_new(){
|
int i=0;
|
int i=0;
|
$st2
|
$st2
|
}
|
}
|
|
|
$custom_include
|
$custom_include
|
|
|
void inline connect_routers_reset_clk(){
|
void inline connect_routers_reset_clk(){
|
int i;
|
int i;
|
$st3
|
$st3
|
}
|
}
|
|
|
|
|
void inline routers_eval(){
|
void inline routers_eval(){
|
int i=0;
|
int i=0;
|
$st4
|
$st4
|
}
|
}
|
|
|
void inline routers_final(){
|
void inline routers_final(){
|
int i;
|
int i;
|
$st5
|
$st5
|
}
|
}
|
|
|
void inline single_router_eval(int i){
|
void inline single_router_eval(int i){
|
$st6
|
$st6
|
}
|
}
|
|
|
#define SMART_NUM ((SMART_MAX==0)? 1 : SMART_MAX)
|
#define SMART_NUM ((SMART_MAX==0)? 1 : SMART_MAX)
|
#if SMART_NUM > 8
|
|
typedef unsigned int EVENT;
|
|
#else
|
|
typedef unsigned char EVENT;
|
|
#endif
|
|
|
|
extern void update_router_st (
|
extern void update_router_st (
|
unsigned int,
|
unsigned int,
|
unsigned int,
|
unsigned int,
|
EVENT *
|
void * ,
|
|
size_t
|
);
|
);
|
|
|
void single_router_st_update(int i){
|
void single_router_st_update(int i){
|
$st7
|
$st7
|
}
|
}
|
|
|
void inline single_router_reset_clk(int i){
|
void inline single_router_reset_clk(int i){
|
$st8
|
$st8
|
}
|
}
|
|
|
|
|
";
|
";
|
|
|
#$includ_h.=" void connect_all_nodes(){\n";
|
#$includ_h.=" void connect_all_nodes(){\n";
|
|
|
#my $dot_file=get_dot_file_text($self,'topology');
|
#my $dot_file=get_dot_file_text($self,'topology');
|
#print "$dot_file\n";
|
#print "$dot_file\n";
|
#my @lines =split ("\n",$dot_file);
|
#my @lines =split ("\n",$dot_file);
|
#foreach my $l (@lines) {
|
#foreach my $l (@lines) {
|
# if ( $l =~ m{#*\"\s*R(\d+)\"\s*:\s*\"[pP](\d+)\"\s*->\s*\"R(\d+)\"\s*:\s*\"[pP](\d+)\"} ) {
|
# if ( $l =~ m{#*\"\s*R(\d+)\"\s*:\s*\"[pP](\d+)\"\s*->\s*\"R(\d+)\"\s*:\s*\"[pP](\d+)\"} ) {
|
# my ($R1, $P1, $R2,$P2) = ($1, $2,$3,$4);
|
# my ($R1, $P1, $R2,$P2) = ($1, $2,$3,$4);
|
# $includ_h.=connect_sim_nodes ($self,$topology,$R1, $P1, $R2, $P2);
|
# $includ_h.=connect_sim_nodes ($self,$topology,$R1, $P1, $R2, $P2);
|
#
|
#
|
#
|
#
|
# }
|
# }
|
# if ( $l =~ m{#*\"\s*R(\d+)\"\s*:\s*\"[pP](\d+)\"\s*->\s*\"[Tt](\d+)\"} ) {
|
# if ( $l =~ m{#*\"\s*R(\d+)\"\s*:\s*\"[pP](\d+)\"\s*->\s*\"[Tt](\d+)\"} ) {
|
# my ($R1, $P1, $T) = ($1, $2,$3);
|
# my ($R1, $P1, $T) = ($1, $2,$3);
|
# $includ_h.=connect_sim_nodes($self,$topology,$R1, $P1, $T);
|
# $includ_h.=connect_sim_nodes($self,$topology,$R1, $P1, $T);
|
#
|
#
|
#
|
#
|
# }
|
# }
|
# if ( $l =~ m{#*\s*\"[Tt](\d+)\"\s*->\s*\"R(\d+)\"\s*:\s*\"[pP](\d+)\"} ) {
|
# if ( $l =~ m{#*\s*\"[Tt](\d+)\"\s*->\s*\"R(\d+)\"\s*:\s*\"[pP](\d+)\"} ) {
|
# my ($T, $R1, $P1) = ($1, $2,$3);
|
# my ($T, $R1, $P1) = ($1, $2,$3);
|
# $includ_h.=connect_sim_nodes($self,$topology,$R1, $P1, $T);
|
# $includ_h.=connect_sim_nodes($self,$topology,$R1, $P1, $T);
|
# }
|
# }
|
#}
|
#}
|
#$includ_h.="\n}\n";
|
#$includ_h.="\n}\n";
|
|
|
return ($nr,$ne,$router_p,\%tops,$includ_h);
|
return ($nr,$ne,$router_p,\%tops,$includ_h);
|
}
|
}
|
|
|
sub connect_sim_nodes{
|
sub connect_sim_nodes{
|
my ($self,$topology,$R1, $P1, $R2, $P2)=@_;
|
my ($self,$topology,$R1, $P1, $R2, $P2)=@_;
|
if(defined $P2){ #R2R
|
if(defined $P2){ #R2R
|
if($topology eq '"FATTREE"' || $topology eq '"TREE"'){
|
if($topology eq '"FATTREE"' || $topology eq '"TREE"'){
|
|
|
}else{
|
}else{
|
return connect_r2r(1,$R1, $P1,1, $R2, $P2);
|
return connect_r2r(1,$R1, $P1,1, $R2, $P2);
|
|
|
}
|
}
|
}else {
|
}else {
|
my $T=$R2;
|
my $T=$R2;
|
if($topology eq '"FATTREE"' || $topology eq '"TREE"'){
|
if($topology eq '"FATTREE"' || $topology eq '"TREE"'){
|
|
|
}else{
|
}else{
|
return connect_r2t(1,$R1, $P1, $T);
|
return connect_r2t(1,$R1, $P1, $T);
|
|
|
}
|
}
|
|
|
}
|
}
|
|
|
|
|
}
|
}
|
|
|
sub connect_r2r{
|
sub connect_r2r{
|
my ($vrouter1_num,$r1,$p1,$vrouter2_num,$r2,$p2)=@_;
|
my ($vrouter1_num,$r1,$p1,$vrouter2_num,$r2,$p2)=@_;
|
return "
|
return "
|
memcpy(&router${vrouter1_num}[$r1]->chan_in[$p1], router${vrouter2_num}[$r2]->chan_out[$p2] , sizeof( router${vrouter1_num}[$r1]->chan_in[$p1] ) );
|
memcpy(&router${vrouter1_num}[$r1]->chan_in[$p1], router${vrouter2_num}[$r2]->chan_out[$p2] , sizeof( router${vrouter1_num}[$r1]->chan_in[$p1] ) );
|
memcpy(&router${vrouter2_num}[$r2]->chan_in[$p2], router${vrouter1_num}[$r1]->chan_out[$p1] , sizeof( router${vrouter1_num}[$r1]->chan_in[$p1] ) );
|
memcpy(&router${vrouter2_num}[$r2]->chan_in[$p2], router${vrouter1_num}[$r1]->chan_out[$p1] , sizeof( router${vrouter1_num}[$r1]->chan_in[$p1] ) );
|
";
|
";
|
}
|
}
|
|
|
sub connect_r2t{
|
sub connect_r2t{
|
my ($vrouter1_num,$r1, $p1, $T)=@_;
|
my ($vrouter1_num,$r1, $p1, $T)=@_;
|
return "
|
return "
|
memcpy(&router${vrouter1_num}[$r1]->chan_in[$p1], traffic[$T]->chan_out , sizeof( traffic[$T]->chan_in ) );
|
memcpy(&router${vrouter1_num}[$r1]->chan_in[$p1], traffic[$T]->chan_out , sizeof( traffic[$T]->chan_in ) );
|
memcpy(&traffic[$T]->chan_in, router${vrouter1_num}[$r1]->chan_out[$p1] , sizeof( traffic[$T]->chan_in ) );
|
memcpy(&traffic[$T]->chan_in, router${vrouter1_num}[$r1]->chan_out[$p1] , sizeof( traffic[$T]->chan_in ) );
|
";
|
";
|
}
|
}
|
|
|
|
|
sub gen_tiles_physical_addrsses_header_file{
|
sub gen_tiles_physical_addrsses_header_file{
|
my ($self,$file)=@_;
|
my ($self,$file)=@_;
|
my $topology=$self->object_get_attribute('noc_param','TOPOLOGY');
|
my $topology=$self->object_get_attribute('noc_param','TOPOLOGY');
|
my $txt = "#ifndef PHY_ADDR_H
|
my $txt = "#ifndef PHY_ADDR_H
|
#define PHY_ADDR_H\n\n";
|
#define PHY_ADDR_H\n\n";
|
|
|
#add phy addresses
|
#add phy addresses
|
my ($NE, $NR, $RAw, $EAw,$Fw)=get_topology_info($self);
|
my ($NE, $NR, $RAw, $EAw,$Fw)=get_topology_info($self);
|
for (my $id=0; $id<$NE; $id++){
|
for (my $id=0; $id<$NE; $id++){
|
my $phy= endp_addr_encoder($self,$id);
|
my $phy= endp_addr_encoder($self,$id);
|
my $hex = sprintf("0x%x", $phy);
|
my $hex = sprintf("0x%x", $phy);
|
$txt=$txt."\t#define PHY_ADDR_ENDP_$id $hex\n";
|
$txt=$txt."\t#define PHY_ADDR_ENDP_$id $hex\n";
|
|
|
}
|
}
|
|
|
|
|
$txt=$txt."#endif\n";
|
$txt=$txt."#endif\n";
|
save_file($file,$txt);
|
save_file($file,$txt);
|
}
|
}
|
|
|
|
|
sub get_endpoints_mah_distance {
|
sub get_endpoints_mah_distance {
|
my ($self,$endp1,$endp2)=@_;
|
my ($self,$endp1,$endp2)=@_;
|
|
|
my $router1=get_connected_router_id_to_endp($self,$endp1);
|
my $router1=get_connected_router_id_to_endp($self,$endp1);
|
my $router2=get_connected_router_id_to_endp($self,$endp2);
|
my $router2=get_connected_router_id_to_endp($self,$endp2);
|
|
|
my $topology=$self->object_get_attribute('noc_param','TOPOLOGY');
|
my $topology=$self->object_get_attribute('noc_param','TOPOLOGY');
|
if($topology eq '"FATTREE"' || $topology eq '"TREE"') {
|
if($topology eq '"FATTREE"' || $topology eq '"TREE"') {
|
return fattree_mah_distance($self, $router1,$router2);
|
return fattree_mah_distance($self, $router1,$router2);
|
}elsif ($topology eq '"RING"' || $topology eq '"LINE"' || $topology eq '"MESH"' || $topology eq '"TORUS"' || $topology eq '"FMESH"' ){
|
}elsif ($topology eq '"RING"' || $topology eq '"LINE"' || $topology eq '"MESH"' || $topology eq '"TORUS"' || $topology eq '"FMESH"' ){
|
return mesh_tori_mah_distance($self, $router1,$router2);
|
return mesh_tori_mah_distance($self, $router1,$router2);
|
}elsif ($topology eq '"STAR"'){
|
}elsif ($topology eq '"STAR"'){
|
return 1;
|
return 1;
|
}else { #custom
|
}else { #custom
|
return undef;
|
return undef;
|
}
|
}
|
|
|
}
|
}
|
|
|
sub mesh_tori_mah_distance {
|
sub mesh_tori_mah_distance {
|
my ($self, $router1,$router2)=@_;
|
my ($self, $router1,$router2)=@_;
|
my $T1=$self->object_get_attribute('noc_param','T1');
|
my $T1=$self->object_get_attribute('noc_param','T1');
|
my $T2=$self->object_get_attribute('noc_param','T2');
|
my $T2=$self->object_get_attribute('noc_param','T2');
|
my ($x1,$y1,$l1) = mesh_tori_addrencod_sep ($router1,$T1,$T2,1);
|
my ($x1,$y1,$l1) = mesh_tori_addrencod_sep ($router1,$T1,$T2,1);
|
my ($x2,$y2,$l2) = mesh_tori_addrencod_sep ($router2,$T1,$T2,1);
|
my ($x2,$y2,$l2) = mesh_tori_addrencod_sep ($router2,$T1,$T2,1);
|
my $x_diff = ($x1 > $x2) ? ($x1 - $x2) : ($x2 - $x1);
|
my $x_diff = ($x1 > $x2) ? ($x1 - $x2) : ($x2 - $x1);
|
my $y_diff = ($y1 > $y2) ? ($y1 - $y2) : ($y2 - $y1);
|
my $y_diff = ($y1 > $y2) ? ($y1 - $y2) : ($y2 - $y1);
|
my $mah_distance = $x_diff + $y_diff;
|
my $mah_distance = $x_diff + $y_diff;
|
return $mah_distance;
|
return $mah_distance;
|
}
|
}
|
|
|
sub fattree_mah_distance {
|
sub fattree_mah_distance {
|
my ($self, $router1,$router2)=@_;
|
my ($self, $router1,$router2)=@_;
|
my $k =$self->object_get_attribute('noc_param','T1');
|
my $k =$self->object_get_attribute('noc_param','T1');
|
my $l =$self->object_get_attribute('noc_param','T2');
|
my $l =$self->object_get_attribute('noc_param','T2');
|
|
|
my $pow;
|
my $pow;
|
my $tmp1;
|
my $tmp1;
|
my $tmp2;
|
my $tmp2;
|
my $distance=0;
|
my $distance=0;
|
$pow=1;
|
$pow=1;
|
for (my $i = 0; $i <$l; $i=$i+1 ) {
|
for (my $i = 0; $i <$l; $i=$i+1 ) {
|
$tmp1=int($router1/$pow);
|
$tmp1=int($router1/$pow);
|
$tmp2=int($router2/$pow);
|
$tmp2=int($router2/$pow);
|
$tmp1=$tmp1 % $k;
|
$tmp1=$tmp1 % $k;
|
$tmp2=$tmp2 % $k;
|
$tmp2=$tmp2 % $k;
|
$pow=$pow * $k;
|
$pow=$pow * $k;
|
$distance= ($i+1)*2-1 if($tmp1!=$tmp2); # distance obtained based on the highest level index which differ
|
$distance= ($i+1)*2-1 if($tmp1!=$tmp2); # distance obtained based on the highest level index which differ
|
|
|
}
|
}
|
return $distance;
|
return $distance;
|
}
|
}
|
|
|
1
|
1
|
|
|