├── LICENSE ├── Makefile ├── Makefile.defs ├── NOC_package.cpp ├── NOC_package.h ├── NoC_WR.cpp ├── NoC_WR.h ├── README.md ├── RX_package.cpp ├── RX_package.h ├── SWok.cpp ├── SWok.h ├── fifo.cpp ├── fifo.h ├── indata5x5 ├── main.cpp ├── map.txt ├── receiver.cpp ├── receiver.h ├── transmitter.cpp ├── transmitter.h └── wrapper_mod.h /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 frobino 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | EXTRACFLAGS = 2 | EXTRA_LIBS = 3 | 4 | MODULE = run 5 | SRCS = $(wildcard *.cpp) 6 | 7 | OBJS = $(SRCS:.cpp=.o) 8 | 9 | include ./Makefile.defs 10 | 11 | CFLAGS = 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /Makefile.defs: -------------------------------------------------------------------------------- 1 | ## Variable that points to SystemC installation path, not needed for debianized package 2 | #SYSTEMC = -I /home/osso/Tools/systemc-2.2.0/include/ 3 | SYSTEMC = 4 | 5 | CC = g++ 6 | OPT = -O0 7 | DEBUG = -g 8 | 9 | INCDIR = -I. -I.. 10 | 11 | LIBDIR = -L. -L.. 12 | 13 | ## Build with maximum gcc warning level 14 | CFLAGS = -Wall -Wno-deprecated -Wno-return-type -Wno-char-subscripts -pthread $(DEBUG) $(OPT) $(EXTRACFLAGS) -std=gnu++0x $(SYSTEMC) 15 | #CFLAGS = -arch i386 -Wall -Wno-deprecated -Wno-return-type -Wno-char-subscripts $(DEBUG) $(OPT) $(EXTRACFLAGS) 16 | 17 | LIBS = -lstdc++ -lm $(EXTRA_LIBS) -lsystemc -L /home/osso/Tools/systemc-2.2.0/lib-linux/ 18 | 19 | EXE = $(MODULE).x 20 | 21 | .PHONY: clean 22 | 23 | #$(EXE): $(OBJS) $(SYSTEMC)/lib-$(TARGET_ARCH)/libsystemc.a 24 | $(EXE): $(OBJS) 25 | $(CC) $(CFLAGS) $(INCDIR) $(LIBDIR) -o $@ $(OBJS) $(LIBS) 2>&1 | c++filt 26 | 27 | ## based on http://www.paulandlesley.org/gmake/autodep.html 28 | %.o : %.cpp 29 | $(CC) $(CFLAGS) $(INCDIR) -c -MMD -o $@ $< 30 | @cp $*.d $*.P; \ 31 | sed -e 's/#.*//' -e 's/^[^:]*: *//' -e 's/ *\\$$//' \ 32 | -e '/^$$/ d' -e 's/$$/ :/' < $*.d >> $*.P; \ 33 | rm -f $*.d 34 | 35 | 36 | clean: 37 | -rm -f $(OBJS) *~ $(EXE) *.vcd *.wif *.isdb *.dmp *.P *.log 38 | 39 | -include $(SRCS:.cpp=.P) 40 | -------------------------------------------------------------------------------- /NOC_package.cpp: -------------------------------------------------------------------------------- 1 | /// \file NOC_package.cpp 2 | /// \brief File containing the description of the functions of the NoC package. 3 | /// 4 | /// See also NOC_package.h 5 | #include "NOC_package.h" 6 | 7 | //------------------------------------------------------------------------------------------------------------------------- 8 | 9 | /// Defined in NOC_package.h. 10 | /// 11 | /// It uses 2 steps to decide input priority. 12 | /// Step1: set priority between North and East inputs and between South and West inputs. 13 | /// Step2: set priority between the previous "winners" (highest priority of N vs E and highest priority of S vs W) and the "losers" (lowest priority of N vs E and lowest priority of S vs W). 14 | struct PriorityOrder sort_4input_priority(int No_HC,int Ea_HC,int So_HC,int We_HC) 15 | { 16 | struct PriorityOrder InputPriorityOrder; 17 | int NE_max_row,NE_min_row,SW_max_row,SW_min_row; 18 | int NE_max_prio,NE_min_prio,SW_max_prio,SW_min_prio; 19 | 20 | 21 | if (No_HC >= Ea_HC){ 22 | NE_max_row = North; //north input 23 | NE_min_row = East; //east input 24 | NE_max_prio = No_HC; 25 | NE_min_prio = Ea_HC; 26 | } 27 | else{ 28 | NE_max_row = East; //east input 29 | NE_min_row = North; //north input 30 | NE_max_prio = Ea_HC; 31 | NE_min_prio = No_HC; 32 | } 33 | 34 | if (So_HC >= We_HC){ 35 | SW_max_row = South; //south input 36 | SW_min_row = West; //west input 37 | SW_max_prio = So_HC; 38 | SW_min_prio = We_HC; 39 | } 40 | else{ 41 | SW_max_row = West; //west input 42 | SW_min_row = South; //south input 43 | SW_max_prio = We_HC; 44 | SW_min_prio = So_HC; 45 | } 46 | 47 | //second step 48 | if (NE_max_prio >= SW_max_prio){ //largest NE >= largest SW 49 | InputPriorityOrder.max_prio = NE_max_row; 50 | if (NE_min_prio >= SW_max_prio) //smallest NE >= largest SW 51 | InputPriorityOrder.hi_prio = NE_min_row; 52 | else 53 | InputPriorityOrder.hi_prio = SW_max_row; 54 | } 55 | else{ 56 | InputPriorityOrder.max_prio = SW_max_row; 57 | if (SW_min_prio > NE_max_prio) //smallest SW > largest NE 58 | InputPriorityOrder.hi_prio = SW_min_row; 59 | else 60 | InputPriorityOrder.hi_prio = NE_max_row; 61 | 62 | } 63 | 64 | if (NE_min_prio < SW_min_prio){ //smallest NE < smallest SW 65 | InputPriorityOrder.min_prio = NE_min_row; 66 | if (NE_max_prio < SW_min_prio) //largest NE < smallest SW 67 | InputPriorityOrder.lo_prio = NE_max_row; 68 | else 69 | InputPriorityOrder.lo_prio = SW_min_row; 70 | } 71 | else { 72 | InputPriorityOrder.min_prio = SW_min_row; 73 | if (SW_max_prio <= NE_min_prio) //largest SW < smallest NE 74 | InputPriorityOrder.lo_prio = SW_max_row; 75 | else 76 | InputPriorityOrder.lo_prio = NE_min_row; 77 | } 78 | 79 | 80 | return InputPriorityOrder; 81 | } 82 | 83 | //------------------------------------------------------------------------------------------------------------------------- 84 | 85 | /// Defined in NOC_package.h. 86 | /// 87 | /// It uses 2 steps to decide output priority. 88 | /// Step1: set priority between North and East outputs and between South and West outputs. 89 | /// Step2: set priority between the previous "winners" (highest priority of N vs E and highest priority of S vs W) and the "losers" (lowest priority of N vs E and lowest priority of S vs W). 90 | struct PriorityOrder sort_4output_priority(int NorthLoad,int EastLoad,int SouthLoad,int WestLoad) 91 | { 92 | struct PriorityOrder OutputPriorityOrder; 93 | int NE_max_row, NE_min_row, SW_max_row, SW_min_row; 94 | int NE_max_prio, NE_min_prio, SW_max_prio, SW_min_prio; 95 | 96 | //sort load in output priority order 97 | //first step 98 | if (NorthLoad >= EastLoad){ 99 | NE_max_row = North; //north input 100 | NE_min_row = East; //east input 101 | NE_max_prio = NorthLoad; 102 | NE_min_prio = EastLoad; 103 | } 104 | else{ 105 | NE_max_row = East; //east input 106 | NE_min_row = North; //north input 107 | NE_max_prio = EastLoad; 108 | NE_min_prio = NorthLoad; 109 | } 110 | 111 | if (SouthLoad >= WestLoad){ 112 | SW_max_row = South; //south input 113 | SW_min_row = West; //west input 114 | SW_max_prio = SouthLoad; 115 | SW_min_prio = WestLoad; 116 | } 117 | else{ 118 | SW_max_row = West; //west input 119 | SW_min_row = South; //south input 120 | SW_max_prio = WestLoad; 121 | SW_min_prio = SouthLoad; 122 | } 123 | 124 | //second step 125 | if (NE_max_prio >= SW_max_prio){ //largest NE >= largest SW 126 | OutputPriorityOrder.min_prio = NE_max_row; //highest load, so lowest priority! in fact later outputs are presented from 3(min load) to 0(max load) 127 | if (NE_min_prio >= SW_max_prio) //smallest NE >= largest SW 128 | OutputPriorityOrder.lo_prio = NE_min_row; 129 | else 130 | OutputPriorityOrder.lo_prio = SW_max_row; 131 | } 132 | else{ 133 | OutputPriorityOrder.min_prio = SW_max_row; 134 | if (SW_min_prio > NE_max_prio) //smallest SW > largest NE 135 | OutputPriorityOrder.lo_prio = SW_min_row; 136 | else 137 | OutputPriorityOrder.lo_prio = NE_max_row; 138 | } 139 | 140 | if (NE_min_prio < SW_min_prio){ //smallest NE < smallest SW 141 | OutputPriorityOrder.max_prio = NE_min_row; 142 | if (NE_max_prio < SW_min_prio) //largest NE < smallest SW 143 | OutputPriorityOrder.hi_prio = NE_max_row; 144 | else 145 | OutputPriorityOrder.hi_prio = SW_min_row; 146 | } 147 | else{ 148 | OutputPriorityOrder.max_prio = SW_min_row; 149 | if (SW_max_prio <= NE_min_prio) //largest SW < smallest NE 150 | OutputPriorityOrder.hi_prio = SW_max_row; 151 | else 152 | OutputPriorityOrder.hi_prio = NE_min_row; 153 | } 154 | 155 | 156 | 157 | return OutputPriorityOrder; 158 | } 159 | 160 | //------------------------------------------------------------------------------------------------------------------------- 161 | 162 | /// Defined in NOC_package.h. 163 | /// 164 | /// It analyzes the destination field of the packet and sets the favourite direction of the packet. 165 | sc_bv<4> get_aim(int dest_Row,int dest_Col) 166 | { 167 | sc_bv<4> direction; 168 | 169 | direction="0000"; 170 | 171 | if (dest_Row>0) //if the row of the destination is >0 the packet wants to go north 172 | direction[North]='1'; 173 | if (dest_Col>0) //if the column of the destination is >0 the packet wants to go east 174 | direction[East]='1'; 175 | if (dest_Row<0) //if the row of the destination is <0 the packet wants to go south 176 | direction[South]='1'; 177 | if (dest_Col<0) //if the column of the destination is <0 the packet wants to go west 178 | direction[West]='1'; 179 | 180 | return direction; 181 | } 182 | 183 | //------------------------------------------------------------------------------------------------------------------------- 184 | 185 | /// Defined in NOC_package.h. 186 | /// 187 | /// It decides on which output to send all the valid inputs received. 188 | /// Phase1: calculation on number of valid input (switchload). 189 | /// Phase2: get aiming direction. 190 | /// Phase3: try to send packets to resource. 191 | /// Phase4: fix an output for the highest priority input, ... ,fix an output for the lowest priority input. 192 | /// Phase5: considering how many valid inputs i had, i update the outputs with a new value or I leave the old one with the empty bit = false. 193 | int ctrl_box(struct Packet* Sample_in_N,struct Packet* Sample_in_S,struct Packet* Sample_in_W,struct Packet* Sample_in_E,struct Packet* Sample_in_R,struct PriorityOrder input_priority, struct PriorityOrder output_priority,sc_bit* Resource_ready,int row_sw,int col_sw,int m_row_noc,int m_col_noc) 194 | { 195 | int switchload=0; 196 | struct Packet Sample_in[5]; 197 | Sample_in[North]=*Sample_in_N; 198 | Sample_in[South]=*Sample_in_S; 199 | Sample_in[West]=*Sample_in_W; 200 | Sample_in[East]=*Sample_in_E; 201 | Sample_in[Resource]=*Sample_in_R; 202 | sc_bv<4> aimMatrix[4]; 203 | sc_bv<4> R_aim; 204 | sc_bv<5> switched; 205 | int selectvector[5]; 206 | switched="11111"; // 1=not yet assigned, 0=already assigned ->used to indicate which outputs are already been assigned to an input packet 207 | selectvector[0]=0; // example: on the north output I send the packet arriving from east: selectvector[Nord]=East (keep in mem the final results!) 208 | selectvector[1]=0; 209 | selectvector[2]=0; 210 | selectvector[3]=0; 211 | selectvector[4]=0; 212 | sc_bv<4> thread; 213 | 214 | 215 | 216 | //start calculation of swload 217 | if (Sample_in[North].empty==true) 218 | switchload++; 219 | if (Sample_in[South].empty==true) 220 | switchload++; 221 | if (Sample_in[West].empty==true) 222 | switchload++; 223 | if (Sample_in[East].empty==true) 224 | switchload++; 225 | //end calculation of swload 226 | 227 | 228 | //get aiming direction 229 | aimMatrix[North]=get_aim(Sample_in[North].dest_addr_R,Sample_in[North].dest_addr_C); 230 | aimMatrix[East]=get_aim(Sample_in[East].dest_addr_R,Sample_in[East].dest_addr_C); 231 | aimMatrix[South]=get_aim(Sample_in[South].dest_addr_R,Sample_in[South].dest_addr_C); 232 | aimMatrix[West]=get_aim(Sample_in[West].dest_addr_R,Sample_in[West].dest_addr_C); 233 | 234 | //try to send packet to resource 235 | if ((aimMatrix[input_priority.max_prio]=="0000") && (Sample_in[input_priority.max_prio].empty==true)) 236 | { 237 | selectvector[Resource]=input_priority.max_prio; 238 | Sample_in[input_priority.max_prio].empty=false; 239 | switched[Resource]='0'; 240 | } 241 | else if ((aimMatrix[input_priority.hi_prio]=="0000") && (Sample_in[input_priority.hi_prio].empty==true)) 242 | { 243 | selectvector[Resource]=input_priority.hi_prio; 244 | Sample_in[input_priority.hi_prio].empty=false; 245 | switched[Resource]='0'; 246 | } 247 | else if ((aimMatrix[input_priority.lo_prio]=="0000") && (Sample_in[input_priority.lo_prio].empty==true)) 248 | { 249 | selectvector[Resource]=input_priority.lo_prio; 250 | Sample_in[input_priority.lo_prio].empty=false; 251 | switched[Resource]='0'; 252 | } 253 | else if ((aimMatrix[input_priority.min_prio]=="0000") && (Sample_in[input_priority.min_prio].empty==true)) 254 | { 255 | selectvector[Resource]=input_priority.min_prio; 256 | Sample_in[input_priority.min_prio].empty=false; 257 | switched[Resource]='0'; 258 | } 259 | else 260 | { 261 | //selectvector[Resource]=0; not necessary 262 | switched[Resource]='1'; // finally, when I will see switched[Resource]=1, I'll know that on that output there are no more packets to send-> I'll put on that ouput the same value of before with empty bit set at 0! 263 | } 264 | 265 | 266 | //try to route the received packet with max priority 267 | thread=(aimMatrix[input_priority.max_prio])&(switched(3,0)); 268 | if (Sample_in[input_priority.max_prio].empty==true) //packet exists 269 | { 270 | if (thread=="0000") //desired aim not free, switch oA if free 271 | { 272 | if (switched[output_priority.max_prio]=='1') //if output with max priority is free... 273 | { 274 | selectvector[output_priority.max_prio]=input_priority.max_prio; //...I send on that output the packet with max priority and I indicate this event in the results vector... 275 | switched[output_priority.max_prio]='0';//...and I set as "busy/occupied" that output 276 | } 277 | else if (switched[output_priority.hi_prio]=='1') 278 | { 279 | selectvector[output_priority.hi_prio]=input_priority.max_prio; 280 | switched[output_priority.hi_prio]='0'; 281 | } 282 | else if (switched[output_priority.lo_prio]=='1') 283 | { 284 | selectvector[output_priority.lo_prio]=input_priority.max_prio; 285 | switched[output_priority.lo_prio]='0'; 286 | } 287 | else 288 | { 289 | selectvector[output_priority.min_prio]=input_priority.max_prio; 290 | switched[output_priority.min_prio]='0'; 291 | } 292 | 293 | } 294 | else // the desired aim is free, I have just to understand which is the right direction to route the packet 295 | { 296 | cout<<"th: "< 10 | #include 11 | 12 | //-------------------------------------------------------------------------------------- 13 | 14 | /// Struct used to store characteristics of the different subnets 15 | struct subnet 16 | { 17 | /// dimension of the subnet (total rows number) 18 | int dim_row; //subnet dimension in the network (4x3, 2x1, ...) 19 | /// dimension of the subnet (total cols number) 20 | int dim_col; //subnet dimension in the network (4x3, 2x1, ...) 21 | 22 | ///position of the top left switch of the subnet in the entire NoC (row coordinate) 23 | int pos_row; //subnet position in the network 24 | ///position of the top left switch of the subnet in the entire NoC (column coordinate) 25 | int pos_col; //subnet position in the network 26 | } ; 27 | 28 | //-------------------------------------------------------------------------------------- 29 | 30 | /// Struct of the packet: field for destination address (row,column), field for source address (row,column), empty bit, hop counter, payload 31 | struct Packet{ 32 | /// row of the destination address 33 | int dest_addr_R; 34 | /// col of the destination address 35 | int dest_addr_C; 36 | /// row of the source address 37 | int source_addr_R; 38 | /// col of the source address 39 | int source_addr_C; 40 | /// empty bit: true=valid pck, false=invalid; 41 | bool empty; //true=valid pck, false=invalid; 42 | /// hop counter field 43 | int HC; 44 | //sc_bv<96> payload; 45 | /// payload field 46 | int payload; 47 | 48 | /// describe the = operator 49 | inline Packet& operator = (const Packet& rhs) { 50 | 51 | dest_addr_R= rhs.dest_addr_R; 52 | dest_addr_C= rhs.dest_addr_C; 53 | source_addr_R= rhs.source_addr_R; 54 | source_addr_C= rhs.source_addr_C; 55 | empty= rhs.empty; 56 | HC= rhs.HC; 57 | payload= rhs.payload; 58 | 59 | return *this; 60 | } 61 | 62 | /// describe the == operator 63 | inline bool operator == (const Packet & rhs) const { 64 | return (rhs.dest_addr_R == dest_addr_R && 65 | rhs.dest_addr_C == dest_addr_C && 66 | rhs.source_addr_R == source_addr_R && 67 | rhs.source_addr_C == source_addr_C && 68 | rhs.empty == empty && 69 | rhs.HC == HC && 70 | rhs.payload == payload 71 | ); 72 | } 73 | 74 | 75 | /// describe the sc_trace operator (what to do in case of sc_trace) 76 | inline friend void sc_trace(sc_trace_file *tf, const Packet & v, 77 | const std::string & NAME ) { 78 | sc_trace(tf,v.dest_addr_R, NAME + ".dest_addr_R"); 79 | sc_trace(tf,v.dest_addr_C, NAME + ".dest_addr_C"); 80 | sc_trace(tf,v.source_addr_R, NAME + ".source_addr_R"); 81 | sc_trace(tf,v.source_addr_C, NAME + ".source_addr_C"); 82 | sc_trace(tf,v.empty, NAME + ".empty"); 83 | sc_trace(tf,v.HC, NAME + ".HC"); 84 | sc_trace(tf,v.payload, NAME + ".payload"); 85 | 86 | } 87 | 88 | /// describe the << operator (what to do in case of cout<< ) 89 | inline friend ostream& operator << ( ostream& os, Packet const & v ) { 90 | os << "(" << v.dest_addr_R << "," << std::boolalpha << v.dest_addr_C << "," << std::boolalpha << v.source_addr_R << "," << std::boolalpha << v.source_addr_C << "," << std::boolalpha << v.empty << "," << std::boolalpha << v.HC << "," << std::boolalpha << v.payload << ")"; 91 | return os; 92 | } 93 | 94 | }; 95 | 96 | //-------------------------------------------------------------------------------------- 97 | 98 | /// data structure to remember input packets/output priority 99 | struct PriorityOrder{ 100 | /// index of the I/O selected to be the one with maximum priority 101 | int max_prio; 102 | /// index of the I/O selected to be the one with high priority 103 | int hi_prio; 104 | /// index of the I/O selected to be the one with low priority 105 | int lo_prio; 106 | /// index of the I/O selected to be the one with minimum priority 107 | int min_prio; 108 | }; 109 | 110 | /// Function which decides the priorities of the input packets. Decision based on the hop counter field of every valid packet received. 111 | struct PriorityOrder sort_4input_priority(int No_HC,int Ea_HC,int So_HC,int We_HC); 112 | /// Function which decides the order in which outputs are proposed to the high priority input packets. Decision based on the load average of the closest switches. 113 | struct PriorityOrder sort_4output_priority(int NorthLoad,int EastLoad,int SouthLoad,int WestLoad); 114 | 115 | //-------------------------------------------------------------------------------------- 116 | 117 | /// Function which analyzes destination field of the input packet and resturns the preferred output in order 118 | sc_bv<4> get_aim(int dest_Row,int dest_Col); 119 | 120 | //-------------------------------------------------------------------------------------- 121 | 122 | /// The most important function of the switch. After analyzing input/output priority, etc... this function decides exactly how to send the input packets, moving them to the right outputs; 123 | int ctrl_box(struct Packet* Sample_in_N,struct Packet* Sample_in_S,struct Packet* Sample_in_W,struct Packet* Sample_in_E,struct Packet* Sample_in_R,struct PriorityOrder input_priority, struct PriorityOrder output_priority,sc_bit* Resource_ready,int row_sw,int col_sw,int m_row_noc,int m_col_noc); 124 | //-------------------------------------------------------------------------------------- 125 | 126 | /// Calculate the load average of the switch 127 | int loadaverager(int switchload,int average_vector[4],sc_bit rst_n); 128 | 129 | //-------------------------------------------------------------------------------------- 130 | 131 | /// Create the output file example.txt where there are all the movements of the packets in the NoC 132 | void printout(struct Packet* d_Nso,struct Packet* d_Sso,struct Packet* d_Wso,struct Packet* d_Eso,struct Packet* d_Rso,struct Packet* d_Ns,struct Packet* d_Ss,struct Packet* d_Ws,struct Packet* d_Es,struct Packet* d_Rs,int row,int col,ofstream* myfile); 133 | 134 | 135 | //-------------------------------------------------------------------------------------- 136 | 137 | /// constant used to refer to the Resource I/O 138 | const int Resource = 4; 139 | /// constant used to refer to the North I/O 140 | const int North = 3; 141 | /// constant used to refer to the East I/O 142 | const int East = 2; 143 | /// constant used to refer to the South I/O 144 | const int South = 1; 145 | /// constant used to refer to the West I/O 146 | const int West = 0; 147 | /// empty packet structure 148 | const struct Packet empty_NL_PDU={0,0,0,0,false,0,0}; 149 | 150 | 151 | //-------------------------------------------------------------------------------------- 152 | 153 | #endif 154 | 155 | -------------------------------------------------------------------------------- /NoC_WR.cpp: -------------------------------------------------------------------------------- 1 | /// \file NoC_WR.cpp 2 | /// \brief File containing the description of the processes of the NoC (TESTBENCH). 3 | /// 4 | /// See also NoC_WR.h 5 | #include "NoC_WR.h" 6 | 7 | /// read input files 8 | void NoC_WR::readin() 9 | { 10 | myfile3.open ("indata5x5"); 11 | //myfile3.open ("indata_muypacket"); 12 | char rubbish[10]; 13 | int d_addr_C,d_addr_R; 14 | bool eb; 15 | int payload; 16 | int i=0; 17 | int col,row; 18 | 19 | struct Packet Res; 20 | 21 | i=0; 22 | rst_n=(sc_bit)1; 23 | rst_n_bool=true; 24 | wait(10,SC_NS); 25 | rst_n=(sc_bit)0; 26 | rst_n_bool=false; 27 | wait(10,SC_NS); 28 | wait(10,SC_NS); 29 | rst_n=(sc_bit)1; 30 | rst_n_bool=true; 31 | wait(60,SC_NS); 32 | 33 | 34 | while (i<50) //maximum number of lines that can be read from the indata file 35 | { 36 | cout<<"ciao"<>rubbish; //cycle identifier 38 | for (row=1;row<=total_dim_row;row++) //col 39 | { 40 | myfile3>>rubbish; //row identifier 41 | for (col=1;col<=total_dim_col;col++) //col 42 | { 43 | myfile3>>eb; 44 | //cout << eb << endl; 45 | myfile3>>d_addr_R; 46 | //cout << d_addr_R << endl; 47 | myfile3>>d_addr_C; 48 | //cout << d_addr_C << endl; 49 | myfile3>>payload; 50 | //cout << payload << endl; 51 | 52 | Res=empty_NL_PDU; 53 | Res.dest_addr_R=d_addr_R; 54 | Res.dest_addr_C=d_addr_C; 55 | Res.empty=eb; 56 | Res.payload=payload; 57 | 58 | 59 | Resource_in_matrix[row-1][col-1]=Res; 60 | 61 | cout<<"Resource_in_matrix ["<** Resource_in_matrix; 26 | /// The matrix of signals which receives the packet from the switch to the resource 27 | sc_signal** Resource_out_matrix; 28 | /// The matrix of signals which connects the output of the fifo and the resource input of every switch 29 | sc_signal** fout; 30 | 31 | /// The matrix of signals which connects the switches in the vertical direction (north I with wrapper) 32 | sc_signal** North_in; 33 | /// The matrix of signals which connects the switches in the vertical direction (north O with wrapper) 34 | sc_signal** North_out; 35 | /// The matrix of signals which connects the switches in the horizontal direction (west I with wrapper) 36 | sc_signal** West_in; 37 | /// The matrix of signals which connects the switches in the horizontal direction (west O with wrapper) 38 | sc_signal** West_out; 39 | /// The matrix of signals which connects the switches in the horizontal direction (east I with wrapper) 40 | sc_signal** East_in; 41 | /// The matrix of signals which connects the switches in the horizontal direction (east O with wrapper) 42 | sc_signal** East_out; 43 | /// The matrix of signals which connects the switches in the vertical direction (south I with wrapper) 44 | sc_signal** South_in; 45 | /// The matrix of signals which connects the switches in the vertical direction (south O with wrapper) 46 | sc_signal** South_out; 47 | 48 | /// The matrix of signals used to connect the switches of the last column to itself (east out returns on east in) 49 | sc_signal** East_inout; 50 | /// The matrix of signals used to connect the switches of the last row to itself (south out returns on south in) 51 | sc_signal** South_inout; 52 | /// The matrix of signals used to connect the switches of the first row to itself (north out returns on north in) 53 | sc_signal** North_inout; 54 | /// The matrix of signals used to connect the switches of the first column to itself (west out returns on west in) 55 | sc_signal** West_inout; 56 | 57 | /// The matrix of signals used to connect the load average informations 58 | sc_signal** averageload;//it works as averageload and as avout 59 | /// The signal used to set to zero the averageload input of the switch at the limit of the region 60 | sc_signal averageload_at0; 61 | 62 | /// The matrix of signals used to connect the switch signals which indicates the request of new resource data between switch and fifo 63 | sc_signal** Resource_Ready_matrix; 64 | 65 | /// The signal for the asynchronous reset 66 | sc_signal rst_n; //>NO MATRIX< 67 | /// reset in bool format 68 | sc_signal rst_n_bool; 69 | 70 | /// Matrix of pointers to switch structures 71 | SWok*** s; 72 | 73 | /// Matrix of pointers to wrapper structures 74 | wrapper_mod*** wrapperNS; 75 | /// Matrix of pointers to wrapper structures 76 | wrapper_mod*** wrapperWE; 77 | 78 | /// Matrix of pointers to fifo structures 79 | fifo*** f; 80 | 81 | /// File which rapresent the inputs from the resource to the NoC 82 | ifstream myfile3; 83 | /// Function reading the input files and creating the necessary data structures 84 | void readin(); 85 | 86 | //----elements for map------- 87 | 88 | /// Matrix created from map.txt input file and used as a map 89 | int** the_map; 90 | /// Vector in which information about the subnets are stored 91 | subnet* subnets; 92 | /// Vector in which information about the clock of the subnets are stored 93 | int* clock_periods; 94 | /// Matrix of clocks for the subnets 95 | sc_clock** clocks; 96 | /// entire NoC rows number 97 | int total_dim_row; 98 | /// entire NoC columns number 99 | int total_dim_col; 100 | /// number of subnets in the NoC 101 | int number_subnets; 102 | /// counter 103 | int general_count; 104 | /// row counter 105 | int row_count; 106 | /// col counter 107 | int col_count; 108 | /// row counter 109 | int row; 110 | /// col counter 111 | int col; 112 | /// String necessary to remove unuseful string from the input files 113 | char rubbish[20]; 114 | /// String necessary to instantiate components in SystemC (they need a name) 115 | char tmp_str[20]; 116 | /// File which represents the inputs from the resource to the NoC 117 | ifstream mapfile; 118 | 119 | //------config wrappers-------- 120 | /// Variebles for configuring the wrappers 121 | int* Ns; 122 | /// Varieble for configuring the wrappers 123 | int N_left; 124 | /// Varieble for configuring the wrappers 125 | int N_right; 126 | 127 | /// constructor of the NoC 128 | SC_CTOR(NoC_WR) 129 | { 130 | //initialization 131 | averageload_at0=0; 132 | 133 | //read from file and create map 134 | mapfile.open ("map.txt"); 135 | 136 | mapfile>>rubbish;mapfile>>rubbish;mapfile>>rubbish; //total row dimensions(row,col): 137 | mapfile>>total_dim_row; 138 | mapfile>>total_dim_col; 139 | //create dinamically map-matrix 140 | the_map = new int*[total_dim_row]; 141 | for (general_count=0;general_count>rubbish;mapfile>>rubbish;mapfile>>rubbish; //number of subnets: 148 | mapfile>>number_subnets; 149 | //create dinamically info subnets structure 150 | subnets=new subnet[number_subnets]; 151 | clock_periods=new int[number_subnets]; 152 | Ns=new int[number_subnets]; 153 | 154 | clocks=new sc_clock*[number_subnets]; 155 | 156 | for (general_count=0;general_count>rubbish;mapfile>>rubbish;mapfile>>rubbish; //subnet n dimension(row,col): 159 | mapfile>>subnets[general_count].dim_row; 160 | mapfile>>subnets[general_count].dim_col; 161 | 162 | mapfile>>rubbish;mapfile>>rubbish;mapfile>>rubbish; //subnet n position(row,col): 163 | mapfile>>subnets[general_count].pos_row; 164 | mapfile>>subnets[general_count].pos_col; 165 | 166 | mapfile>>rubbish;mapfile>>rubbish;mapfile>>rubbish;mapfile>>rubbish; //subnet n clock period(SC_NS): 167 | mapfile>>clock_periods[general_count]; 168 | 169 | mapfile>>rubbish;mapfile>>rubbish;mapfile>>rubbish; //subnet n N: 170 | mapfile>>Ns[general_count]; 171 | 172 | sprintf(tmp_str,"clk%d",general_count); 173 | 174 | clocks[general_count]=new sc_clock(tmp_str,clock_periods[general_count],SC_NS); 175 | 176 | } 177 | 178 | mapfile.close(); 179 | 180 | for (general_count=0;general_count*[total_dim_row]; 194 | Resource_out_matrix = new sc_signal*[total_dim_row]; 195 | fout = new sc_signal*[total_dim_row]; 196 | North_in = new sc_signal*[total_dim_row]; 197 | North_out = new sc_signal*[total_dim_row]; 198 | West_in = new sc_signal*[total_dim_row]; 199 | West_out = new sc_signal*[total_dim_row]; 200 | East_in = new sc_signal*[total_dim_row]; 201 | East_out = new sc_signal*[total_dim_row]; 202 | South_in = new sc_signal*[total_dim_row]; 203 | South_out = new sc_signal*[total_dim_row]; 204 | East_inout = new sc_signal*[total_dim_row]; 205 | South_inout = new sc_signal*[total_dim_row]; 206 | North_inout = new sc_signal*[total_dim_row]; 207 | West_inout = new sc_signal*[total_dim_row]; 208 | 209 | averageload = new sc_signal*[total_dim_row]; 210 | 211 | Resource_Ready_matrix= new sc_signal*[total_dim_row]; 212 | 213 | s=new SWok**[total_dim_row]; 214 | f=new fifo**[total_dim_row]; 215 | wrapperNS=new wrapper_mod**[total_dim_row+1]; 216 | wrapperWE=new wrapper_mod**[total_dim_row]; 217 | 218 | for (row_count=0;row_count[total_dim_col]; 221 | Resource_out_matrix[row_count] = new sc_signal[total_dim_col]; 222 | fout[row_count] = new sc_signal[total_dim_col]; 223 | North_in[row_count] = new sc_signal[total_dim_col]; 224 | North_out[row_count] = new sc_signal[total_dim_col]; 225 | West_in[row_count] = new sc_signal[total_dim_col]; 226 | West_out[row_count] = new sc_signal[total_dim_col]; 227 | East_in[row_count] = new sc_signal[total_dim_col]; 228 | East_out[row_count] = new sc_signal[total_dim_col]; 229 | South_in[row_count] = new sc_signal[total_dim_col]; 230 | South_out[row_count] = new sc_signal[total_dim_col]; 231 | 232 | East_inout[row_count] = new sc_signal[total_dim_col]; 233 | South_inout[row_count] = new sc_signal[total_dim_col]; 234 | North_inout[row_count] = new sc_signal[total_dim_col]; 235 | West_inout[row_count] = new sc_signal[total_dim_col]; 236 | 237 | averageload[row_count] = new sc_signal[total_dim_col]; 238 | 239 | Resource_Ready_matrix[row_count]= new sc_signal[total_dim_col]; 240 | 241 | s[row_count]=new SWok*[total_dim_col]; 242 | f[row_count]=new fifo*[total_dim_col]; 243 | //wrapperNS[row_count]=new wrapper_mod*[total_dim_col]; 244 | wrapperWE[row_count]=new wrapper_mod*[total_dim_col+1]; 245 | 246 | } 247 | 248 | for (row_count=0;row_count<(total_dim_row+1);row_count++) 249 | { 250 | wrapperNS[row_count]=new wrapper_mod*[total_dim_col]; 251 | } 252 | 253 | 254 | //--------> switchmapping 255 | 256 | for (row=1;row<=total_dim_row;row++)// to NumberOfRows generate //row 257 | { 258 | for (col=1;col<=total_dim_col;col++) //col 259 | { 260 | sprintf(tmp_str,"s%d%d",row,col); 261 | s[row-1][col-1]=new SWok(tmp_str,total_dim_row,total_dim_col); 262 | 263 | 264 | s[row-1][col-1]->row_sw=row; 265 | s[row-1][col-1]->col_sw=col; 266 | //map input e output packets 267 | s[row-1][col-1]->d_N(North_in[row-1][col-1]); 268 | s[row-1][col-1]->d_No(North_out[row-1][col-1]); 269 | 270 | s[row-1][col-1]->d_W(West_in[row-1][col-1]); 271 | s[row-1][col-1]->d_Wo(West_out[row-1][col-1]); 272 | 273 | //s[row-1][col-1]->d_S(North_out[row+1-1][col-1]); 274 | //s[row-1][col-1]->d_So(North_in[row+1-1][col-1]); 275 | s[row-1][col-1]->d_S(South_in[row-1][col-1]); 276 | s[row-1][col-1]->d_So(South_out[row-1][col-1]); 277 | 278 | 279 | //s[row-1][col-1]->d_E(West_out[row-1][col+1-1]); 280 | //s[row-1][col-1]->d_Eo(West_in[row-1][col+1-1]); 281 | s[row-1][col-1]->d_E(East_in[row-1][col-1]); 282 | s[row-1][col-1]->d_Eo(East_out[row-1][col-1]); 283 | 284 | s[row-1][col-1]->d_R(fout[row-1][col-1]); 285 | s[row-1][col-1]->d_Ro(Resource_out_matrix[row-1][col-1]); 286 | 287 | s[row-1][col-1]->NorthLoad(averageload_at0); 288 | s[row-1][col-1]->SouthLoad(averageload_at0); 289 | s[row-1][col-1]->EastLoad(averageload_at0); 290 | s[row-1][col-1]->WestLoad(averageload_at0); 291 | 292 | //map output load 293 | s[row-1][col-1]->averageload(averageload[row-1][col-1]); 294 | 295 | //map output resource ready 296 | s[row-1][col-1]->d_Resource_ready(Resource_Ready_matrix[row-1][col-1]); 297 | s[row-1][col-1]->rst_n(rst_n); 298 | 299 | //map clk 300 | s[row-1][col-1]->clk(*clocks[(the_map[row-1][col-1])]); 301 | 302 | } 303 | } 304 | 305 | //--------> wrappperNS mapping 306 | 307 | for (row=1;row<=(total_dim_row+1);row++)// to NumberOfRows generate //row 308 | { 309 | for (col=1;col<=total_dim_col;col++) //col 310 | { 311 | if(row==1){ 312 | N_left=Ns[the_map[row-1][col-1]]; 313 | N_right=Ns[the_map[row-1][col-1]]; 314 | } 315 | else if(row==(total_dim_row+1)){ 316 | N_left=Ns[the_map[row-2][col-1]]; 317 | N_right=Ns[the_map[row-2][col-1]]; 318 | } 319 | else{ 320 | //--------I added this because it was exchanging Nright and Nleft 321 | 322 | //N_left=Ns[the_map[row-1][col-1]]; 323 | //N_right=Ns[the_map[row-2][col-1]]; 324 | N_right=Ns[the_map[row-1][col-1]]; 325 | N_left=Ns[the_map[row-2][col-1]]; 326 | } 327 | 328 | sprintf(tmp_str,"wNS%d%d",row,col); 329 | //wrapperNS[row-1][col-1]=new wrapper_mod(tmp_str); 330 | wrapperNS[row-1][col-1]=new wrapper_mod(tmp_str,N_left,N_right); 331 | 332 | wrapperNS[row-1][col-1]->rst_n(rst_n_bool); 333 | 334 | if(row==1){ 335 | wrapperNS[row-1][col-1]->R_dataout(North_inout[row-1][col-1]); 336 | wrapperNS[row-1][col-1]->R_datain(North_inout[row-1][col-1]);} 337 | else{ 338 | wrapperNS[row-1][col-1]->R_dataout(South_in[row-2][col-1]); 339 | wrapperNS[row-1][col-1]->R_datain(South_out[row-2][col-1]);} 340 | 341 | if(row==(total_dim_row+1)){ 342 | wrapperNS[row-1][col-1]->L_dataout(South_inout[row-2][col-1]); 343 | wrapperNS[row-1][col-1]->L_datain(South_inout[row-2][col-1]);} 344 | else{ 345 | wrapperNS[row-1][col-1]->L_dataout(North_in[row-1][col-1]); 346 | wrapperNS[row-1][col-1]->L_datain(North_out[row-1][col-1]);} 347 | //clks 348 | if(row==1){ 349 | wrapperNS[row-1][col-1]->clkL(*clocks[the_map[row-1][col-1]]); 350 | wrapperNS[row-1][col-1]->clkR(*clocks[the_map[row-1][col-1]]);} 351 | else if(row==(total_dim_row+1)){ 352 | wrapperNS[row-1][col-1]->clkL(*clocks[the_map[row-2][col-1]]); 353 | wrapperNS[row-1][col-1]->clkR(*clocks[the_map[row-2][col-1]]);} 354 | else{ 355 | wrapperNS[row-1][col-1]->clkL(*clocks[the_map[row-1][col-1]]); 356 | wrapperNS[row-1][col-1]->clkR(*clocks[the_map[row-2][col-1]]);} 357 | 358 | } 359 | } 360 | 361 | 362 | //--------> wrappperWE mapping 363 | 364 | for (row=1;row<=total_dim_row;row++)// to NumberOfRows generate //row 365 | { 366 | for (col=1;col<=(total_dim_col+1);col++) //col 367 | { 368 | if(col==1){ 369 | N_left=Ns[the_map[row-1][col-1]]; 370 | N_right=Ns[the_map[row-1][col-1]]; 371 | } 372 | else if(col==(total_dim_col+1)){ 373 | N_left=Ns[the_map[row-1][col-2]]; 374 | N_right=Ns[the_map[row-1][col-2]]; 375 | } 376 | else{ 377 | //--------I added this because it was exchanging Nright and Nleft 378 | 379 | //N_left=Ns[the_map[row-1][col-2]]; 380 | //N_right=Ns[the_map[row-1][col-1]]; 381 | N_right=Ns[the_map[row-1][col-2]]; 382 | N_left=Ns[the_map[row-1][col-1]]; 383 | } 384 | 385 | sprintf(tmp_str,"wWE%d%d",row,col); 386 | //wrapperWE[row-1][col-1]=new wrapper_mod(tmp_str); 387 | wrapperWE[row-1][col-1]=new wrapper_mod(tmp_str,N_left,N_right); 388 | 389 | wrapperWE[row-1][col-1]->rst_n(rst_n_bool); 390 | 391 | if(col==1){ 392 | wrapperWE[row-1][col-1]->L_dataout(West_inout[row-1][col-1]); 393 | wrapperWE[row-1][col-1]->L_datain(West_inout[row-1][col-1]);} 394 | else{ 395 | wrapperWE[row-1][col-1]->L_dataout(East_in[row-1][col-2]); 396 | wrapperWE[row-1][col-1]->L_datain(East_out[row-1][col-2]);} 397 | 398 | if(col==(total_dim_col+1)){ 399 | wrapperWE[row-1][col-1]->R_dataout(East_inout[row-1][col-2]); 400 | wrapperWE[row-1][col-1]->R_datain(East_inout[row-1][col-2]);} 401 | else{ 402 | wrapperWE[row-1][col-1]->R_dataout(West_in[row-1][col-1]); 403 | wrapperWE[row-1][col-1]->R_datain(West_out[row-1][col-1]);} 404 | //clks 405 | if(col==1){ 406 | wrapperWE[row-1][col-1]->clkL(*clocks[the_map[row-1][col-1]]); 407 | wrapperWE[row-1][col-1]->clkR(*clocks[the_map[row-1][col-1]]);} 408 | else if(col==(total_dim_col+1)){ 409 | wrapperWE[row-1][col-1]->clkL(*clocks[the_map[row-1][col-2]]); 410 | wrapperWE[row-1][col-1]->clkR(*clocks[the_map[row-1][col-2]]);} 411 | else{ 412 | wrapperWE[row-1][col-1]->clkL(*clocks[the_map[row-1][col-2]]); 413 | wrapperWE[row-1][col-1]->clkR(*clocks[the_map[row-1][col-1]]);} 414 | 415 | } 416 | } 417 | 418 | //--------> fifo mapping 419 | for (row=1;row<=total_dim_row;row++)// to NumberOfRows generate //row 420 | { 421 | for (col=1;col<=total_dim_col;col++) //col 422 | { 423 | sprintf(tmp_str,"f%d%d",row,col); 424 | f[row-1][col-1]=new fifo(tmp_str); 425 | f[row-1][col-1]->FIFO_in(Resource_in_matrix[row-1][col-1]); 426 | f[row-1][col-1]->rst_n(rst_n); 427 | f[row-1][col-1]->Resource_ready(Resource_Ready_matrix[row-1][col-1]); 428 | f[row-1][col-1]->FIFO_out(fout[row-1][col-1]); 429 | f[row-1][col-1]->row_fifo=row; 430 | f[row-1][col-1]->col_fifo=col; 431 | } 432 | } 433 | 434 | 435 | //addson 436 | SC_THREAD(readin); 437 | } 438 | 439 | 440 | }; 441 | 442 | #endif 443 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Nostrum-SystemC-simulator 2 | ========================= 3 | 4 | SystemC simulator of a highly customizable Nostrum network-on-chip (NoC). 5 | 6 | INPUT FILES: 7 | Follow the models included in the sw. There is not control on the correctness of the input files. 8 | 9 | * indata5x5: 10 | start every new cycle with a line indicating the number n of the cycle: n-cycle. 11 | for every cycle specify row by row the inputs from the resources to the fifos. 12 | So, for example, if we have specified in the map file that the NoC is 5x5, we expect to find 5 lines for each row, specifying the inputs of the 5 resources each row. 13 | 14 | Example: NoC 3x2 (3 rows, 2 columns) 15 | 16 | 1-cycle 17 | 1-row 18 | //line 1 specifying inputs from resource in position (1,1) 19 | //line 2 specifying inputs from resource in position (1,2) 20 | 2-row 21 | //line 1 specifying inputs from resource in position (2,1) 22 | //line 2 specifying inputs from resource in position (2,2) 23 | 3-row 24 | //line 1 specifying inputs from resource in position (3,1) 25 | //line 2 specifying inputs from resource in position (3,2) 26 | 2-cycle 27 | 1-row 28 | ... 29 | 30 | every input packet is specified in this way: 31 | empty_bit | destination_addr_row | destination_addr_col | payload 32 | 1 -4 4 101 33 | 34 | with a single space between the numbers 35 | 36 | 1-cycle 37 | 1-row 38 | 1 -4 4 101 39 | ... 40 | 41 | * map.txt: 42 | in this file we give the informations about how the NoC is configured. 43 | 44 | First line: it specifies the total dimension of the NoC. It needs 3 words (in the example, "dimensione totale rete(row,col):"). 45 | We could also write "total NoC dimension(row,col):". Then 2 numbers divided by spaces must follow: the first is the rows number, the second the columns number. 46 | 47 | Second line: 3 words ("number of subnets:") and 1 number representing it. 48 | 49 | Following lines: for each subnet we need to specify 4 lines. 50 | 1) 3 words ("subnet 0 dimension(row,col):") and the subnet dimension as 2 numbers; 51 | 2) 3 words ("subnet 0 position(row,col):") and then 2 numbers indicating the coordinates (row,col) of the top left switch of the subnet; 52 | 3) 3 words ("subnet 0 clock period(SC_NS):") and the number specifying N 53 | 4) 3 words ("subnet 0 N:") and the number specifying N 54 | 55 | the example attached to the sw create a noc like the following: 56 | 57 | 22333 58 | 22333 59 | 55544 60 | 55544 61 | 62 | OUTPUT FILES: 63 | 64 | * example.txt: main output file, describing time step by time step how each switch looks like (which packets are in, which packets are out) 65 | Used to check traffic in the network with low level details! 66 | 67 | * fifo.txt: describes time step by time step how each fifo looks like (which packets are in, which packets are out) 68 | 69 | * tx_file.txt: file showing how to debug / analyze GRLS wrapper 70 | 71 | * wave.vcd, wave2.vcd: visualize how packets go through the GRLS wrapper 72 | 73 | HOW TO COMPILE 74 | 75 | * run the makefile. If SystemC is not in the path of your shell, you can add it 76 | or modify the makefile following the instruction provided in the "Makefile" file. 77 | 78 | HOW TO RUN 79 | 80 | * as it is today, a successful compilation generates an executable named "run.x" 81 | Running the executable without any flag (./run.x) is enough to run the simulation. 82 | 83 | * as it is today, input files are "hardcoded" in the C code. Future work is to pass them 84 | as parameters, eventually setting flags to decide what to generate (between the output files) 85 | so that the simulation time can be reduced. 86 | 87 | COMPARISON WITH SIMILAR PROJECTS: 88 | 89 | The most similar project is the Semla simulator: http://www.ict.kth.se/nostrum/NNSE/ 90 | 91 | Semla additional features: 92 | * permits to model an application (transport layer), not only packets! 93 | * more abstract model of the NoC-based system (divided in layers), simulator optimized for speed. 94 | * check their routing algorithm, if it is exactly the same! 95 | 96 | Our additional features: 97 | * GRLS supprt 98 | * it is a lower abstraction level (network layer) but higher details (which details on each packet, where it is located in a specific time slot) 99 | 100 | -------------------------------------------------------------------------------- /RX_package.cpp: -------------------------------------------------------------------------------- 1 | #include "RX_package.h" 2 | 3 | sc_bit strobeget(sc_bit strobe,sc_time strobelastchange,int Tsu) 4 | { 5 | sc_bit sampled_strobe; 6 | sc_time diff_time; 7 | //double actual_time, tsetup; 8 | 9 | //diff_time=sc_time_stamp()-sc_time(25,SC_PS); 10 | diff_time=sc_time_stamp()-sc_time(Tsu,SC_PS); 11 | 12 | //actual_time=sc_simulation_time(); 13 | //tsetup=to_double(sc_time(25,SC_PS)); 14 | 15 | //if(strobelastchange 10 | 11 | //-------------------------------------------------------------------------------------- 12 | 13 | //#define Tsw 100 //sc_PS 14 | /// 0=random function, 1=always sample correct (lucky case of solving metastab), 2=always sample uncorrect (unlucky case of solving metastab) 15 | #define SOLVE_METASTAB 0 // 0=random function, 1=always sample correct (lucky case of solving metastab), 2=always sample uncorrect (unlucky case of solving metastab) 16 | 17 | /// function simulating metastability sampling the strobe 18 | sc_bit strobeget(sc_bit strobe,sc_time strobelastchange,int Tsu); 19 | 20 | #endif -------------------------------------------------------------------------------- /SWok.cpp: -------------------------------------------------------------------------------- 1 | /// \file SWok.cpp 2 | /// \brief File containing the description of the processes of the SWITCH component. 3 | /// 4 | /// See also SWok.h 5 | 6 | #include "SWok.h" 7 | 8 | 9 | //descrizione del process 10 | ///This process is activated when something changes on the switch inputs and the time is right to calculate where to send the data inputs. 11 | ///It is divided in different phases: 12 | /// * evaluate input and output priority 13 | /// * calculation of where to send the valid input packets using the ctrl_box function (see NoC_package) 14 | /// * update outputs: if there is a valid packet to send, put it on the correct output, if not, leave the old output with the empty bit=0 15 | void SWok::prc_SWok() 16 | { 17 | 18 | if (clk==true) 19 | { // inizio if clk'event and clk==1 20 | if(rst_n==(sc_bit)1){ 21 | 22 | d_Ns=d_N; 23 | d_Ss=d_S; 24 | d_Ws=d_W; 25 | d_Es=d_E; 26 | if (Resource_ready_old==(sc_bit)1) 27 | d_Rs=d_R; 28 | 29 | sample_in_N=d_N; 30 | sample_in_S=d_S; 31 | sample_in_W=d_W; 32 | sample_in_E=d_E; 33 | if (Resource_ready_old==(sc_bit)1) 34 | sample_in_R=d_R; 35 | 36 | sample_in_NorthLoad=NorthLoad; 37 | sample_in_SouthLoad=SouthLoad; 38 | sample_in_EastLoad=EastLoad; 39 | sample_in_WestLoad=WestLoad; 40 | 41 | 42 | 43 | //------------------------------------DECIDE IF TO NOTIFY OR NOT-------------------------------------------------- 44 | 45 | 46 | 47 | //if all input packets are empty 48 | if ((sample_in_N.empty==false)&&(sample_in_S.empty==false)&&(sample_in_W.empty==false)&&(sample_in_E.empty==false)&&(sample_in_R.empty==false)) 49 | { 50 | old_out_N.empty=false; 51 | d_No=old_out_N; 52 | old_out_S.empty=false; 53 | d_So=old_out_S; 54 | old_out_W.empty=false; 55 | d_Wo=old_out_W; 56 | old_out_E.empty=false; 57 | d_Eo=old_out_E; 58 | old_out_R.empty=false; 59 | d_Ro=old_out_R; 60 | 61 | cout<<"ALL IN packets emtpy"< disattivo il clk indipendedtemente da validit�; 247 | { 248 | d_Resource_ready=(sc_bit)1; //empty==(sc_bit)(true): empty mi � arrivato=> disattivo il clk 249 | infotoclk=0; 250 | } 251 | else 252 | infotoclk=1;*/ 253 | }//end if rst_n 254 | else{ 255 | sample_in_N.empty=false; 256 | sample_in_S.empty=false; 257 | sample_in_W.empty=false; 258 | sample_in_E.empty=false; 259 | sample_in_R.empty=false; 260 | 261 | sample_in_N.dest_addr_R=0; 262 | sample_in_S.dest_addr_R=0; 263 | sample_in_W.dest_addr_R=0; 264 | sample_in_E.dest_addr_R=0; 265 | sample_in_R.dest_addr_R=0; 266 | 267 | sample_in_N.dest_addr_C=0; 268 | sample_in_S.dest_addr_C=0; 269 | sample_in_W.dest_addr_C=0; 270 | sample_in_E.dest_addr_C=0; 271 | sample_in_R.dest_addr_C=0; 272 | 273 | sample_in_N.HC=0; 274 | sample_in_S.HC=0; 275 | sample_in_W.HC=0; 276 | sample_in_E.HC=0; 277 | sample_in_R.HC=0; 278 | 279 | sample_in_N.payload=0; 280 | sample_in_S.payload=0; 281 | sample_in_W.payload=0; 282 | sample_in_E.payload=0; 283 | sample_in_R.payload=0; 284 | 285 | sample_in_N.source_addr_R=0; 286 | sample_in_S.source_addr_R=0; 287 | sample_in_W.source_addr_R=0; 288 | sample_in_E.source_addr_R=0; 289 | sample_in_R.source_addr_R=0; 290 | 291 | sample_in_N.source_addr_C=0; 292 | sample_in_S.source_addr_C=0; 293 | sample_in_W.source_addr_C=0; 294 | sample_in_E.source_addr_C=0; 295 | sample_in_R.source_addr_C=0; 296 | 297 | old_out_N.empty=false; 298 | old_out_S.empty=false; 299 | old_out_W.empty=false; 300 | old_out_E.empty=false; 301 | old_out_R.empty=false; 302 | 303 | old_out_N.dest_addr_R=0; 304 | old_out_S.dest_addr_R=0; 305 | old_out_W.dest_addr_R=0; 306 | old_out_E.dest_addr_R=0; 307 | old_out_R.dest_addr_R=0; 308 | 309 | old_out_N.dest_addr_C=0; 310 | old_out_S.dest_addr_C=0; 311 | old_out_W.dest_addr_C=0; 312 | old_out_E.dest_addr_C=0; 313 | old_out_R.dest_addr_C=0; 314 | 315 | old_out_N.HC=0; 316 | old_out_S.HC=0; 317 | old_out_W.HC=0; 318 | old_out_E.HC=0; 319 | old_out_R.HC=0; 320 | 321 | old_out_N.payload=0; 322 | old_out_S.payload=0; 323 | old_out_W.payload=0; 324 | old_out_E.payload=0; 325 | old_out_R.payload=0; 326 | 327 | old_out_N.source_addr_R=0; 328 | old_out_S.source_addr_R=0; 329 | old_out_W.source_addr_R=0; 330 | old_out_E.source_addr_R=0; 331 | old_out_R.source_addr_R=0; 332 | 333 | old_out_N.source_addr_C=0; 334 | old_out_S.source_addr_C=0; 335 | old_out_W.source_addr_C=0; 336 | old_out_E.source_addr_C=0; 337 | old_out_R.source_addr_C=0; 338 | 339 | d_No=sample_in_N; 340 | d_So=sample_in_S; 341 | d_Wo=sample_in_W; 342 | d_Eo=sample_in_E; 343 | d_Ro=sample_in_R; 344 | d_Resource_ready=(sc_bit)1; 345 | 346 | average_vector[0]=0;average_vector[1]=0;average_vector[2]=0;average_vector[3]=0; 347 | sample_in_NorthLoad=0;sample_in_SouthLoad=0;sample_in_WestLoad=0;sample_in_EastLoad=0; 348 | 349 | printout(&sample_in_N,&sample_in_S,&sample_in_W,&sample_in_E,&sample_in_R,&d_Ns,&d_Ss,&d_Ws,&d_Es,&d_Rs,row_sw,col_sw,&myfile); //<----- print new 350 | 351 | }//end else rst_n 352 | 353 | 354 | }//fine if clk'event and clk==1 355 | 356 | } 357 | 358 | -------------------------------------------------------------------------------- /SWok.h: -------------------------------------------------------------------------------- 1 | /// \file SWok.h 2 | /// \brief File containing the entity of the Switch unclocked. 3 | /// 4 | /// See also SWok.cpp 5 | 6 | #ifndef SWok_H 7 | #define SWok_H 8 | #include "systemc.h" 9 | #include "NOC_package.h" 10 | 11 | /*! \class SWok 12 | \brief SystemC description of the unclocked switch module (structural description). 13 | 14 | Structural description of the unclocked switch. 15 | */ 16 | SC_MODULE(SWok) 17 | //class SWok : public sc_module 18 | { 19 | //input port 20 | ///Inputs for the datas from the adjacent switches 21 | sc_in d_N; 22 | ///Inputs for the datas from the adjacent switches 23 | sc_in d_S; 24 | ///Inputs for the datas from the adjacent switches 25 | sc_in d_W; 26 | ///Inputs for the datas from the adjacent switches 27 | sc_in d_E; 28 | ///Inputs for the datas from the adjacent switches 29 | sc_in d_R; 30 | 31 | ///Asynchronous reset 32 | sc_in rst_n; 33 | ///Clock signal 34 | sc_in clk; 35 | ///Inputs for the average loads from the adjacent switches 36 | sc_in NorthLoad; 37 | ///Inputs for the average loads from the adjacent switches 38 | sc_in SouthLoad; 39 | ///Inputs for the average loads from the adjacent switches 40 | sc_in EastLoad; 41 | ///Inputs for the average loads from the adjacent switches 42 | sc_in WestLoad; 43 | 44 | public: 45 | /// indication of the postition of the switch in the NoC 46 | int row_sw; 47 | /// indication of the postition of the switch in the NoC 48 | int col_sw; 49 | //int t_ACTUAL; 50 | 51 | 52 | //output port 53 | ///Outputs for the datas to the adjacent switches 54 | sc_out d_No; 55 | ///Outputs for the datas to the adjacent switches 56 | sc_out d_So; 57 | ///Outputs for the datas to the adjacent switches 58 | sc_out d_Wo; 59 | ///Outputs for the datas to the adjacent switches 60 | sc_out d_Eo; 61 | ///Outputs for the datas to the adjacent switches 62 | sc_out d_Ro; 63 | ///Output to the fifo 64 | sc_out d_Resource_ready; 65 | ///Outputs for the averageload to the adjacent switches 66 | sc_out averageload; 67 | 68 | 69 | ///Packet variable used to memorize immefiately the value of the input (signals need evaluate-update cycle) 70 | Packet d_Ns; 71 | ///Packet variable used to memorize immefiately the value of the input (signals need evaluate-update cycle) 72 | Packet d_Ss; 73 | ///Packet variable used to memorize immefiately the value of the input (signals need evaluate-update cycle) 74 | Packet d_Ws; 75 | ///Packet variable used to memorize immefiately the value of the input (signals need evaluate-update cycle) 76 | Packet d_Es; 77 | ///Packet variable used to memorize immefiately the value of the input (signals need evaluate-update cycle) 78 | Packet d_Rs; 79 | ///Packet variable used to memorize immefiately the value of the output (signals need evaluate-update cycle) 80 | Packet d_Nso; 81 | ///Packet variable used to memorize immefiately the value of the output (signals need evaluate-update cycle) 82 | Packet d_Sso; 83 | ///Packet variable used to memorize immefiately the value of the output (signals need evaluate-update cycle) 84 | Packet d_Wso; 85 | ///Packet variable used to memorize immefiately the value of the output (signals need evaluate-update cycle) 86 | Packet d_Eso; 87 | ///Packet variable used to memorize immefiately the value of the output (signals need evaluate-update cycle) 88 | Packet d_Rso; 89 | ///Packets variables used to memorize immefiately the value of the input (signals need evaluate-update cycle) 90 | Packet sample_in_N; 91 | ///Packets variables used to memorize immefiately the value of the output (signals need evaluate-update cycle) 92 | Packet old_out_N; 93 | ///Packets variables used to memorize immefiately the value of the input (signals need evaluate-update cycle) 94 | Packet sample_in_S; 95 | ///Packets variables used to memorize immefiately the value of the output (signals need evaluate-update cycle) 96 | Packet old_out_S; 97 | ///Packets variables used to memorize immefiately the value of the input (signals need evaluate-update cycle) 98 | Packet sample_in_W; 99 | ///Packets variables used to memorize immefiately the value of the output (signals need evaluate-update cycle) 100 | Packet old_out_W; 101 | ///Packets variables used to memorize immefiately the value of the input (signals need evaluate-update cycle) 102 | Packet sample_in_E; 103 | ///Packets variables used to memorize immefiately the value of the output (signals need evaluate-update cycle) 104 | Packet old_out_E; 105 | ///Packets variables used to memorize immefiately the value of the input (signals need evaluate-update cycle) 106 | Packet sample_in_R; 107 | ///Packets variables used to memorize immefiately the value of the output (signals need evaluate-update cycle) 108 | Packet old_out_R; 109 | ///Vector used to calculate average load 110 | int average_vector[4]; 111 | ///Variable used to memorize immefiately the value of the input (signals need evaluate-update cycle) 112 | int sample_in_NorthLoad; 113 | ///Variable used to memorize immefiately the value of the input (signals need evaluate-update cycle) 114 | int sample_in_SouthLoad; 115 | ///Variable used to memorize immefiately the value of the input (signals need evaluate-update cycle) 116 | int sample_in_WestLoad; 117 | ///Variable used to memorize immefiately the value of the input (signals need evaluate-update cycle) 118 | int sample_in_EastLoad; 119 | ///output debug file 120 | ofstream myfile; 121 | ///Used to decide if to sample or not the data from the resource 122 | sc_bit Resource_ready_old; 123 | 124 | //prototipo del process tipo method 125 | ///Main process: it is activated when the switch has to send packets in the NoC 126 | void prc_SWok(); 127 | 128 | //constructor (contiene definizione process + sensitivity list associata) 129 | //SC_CTOR(SWok) 130 | /// Indication that we want to explicit the constructor 131 | SC_HAS_PROCESS(SWok); 132 | /// Constructor: Initializes the switch and open the output file to write on it. 133 | SWok(sc_module_name name_ , int row_noc , int col_noc) : sc_module(name_), m_row_noc(row_noc), m_col_noc(col_noc) 134 | { 135 | SC_METHOD(prc_SWok); 136 | sensitive< FIFO_in; 22 | /// reset signal 23 | sc_in rst_n; 24 | /// Input of the resource ready signal. If the resource is ready (true) i can output values from the fifo every clock period. 25 | sc_in Resource_ready; 26 | /// It gives packets to the switch only when the switch is ready to take a new packet (see resourceready signal). 27 | sc_out FIFO_out; 28 | 29 | /// Row and column of the switch in the Network. 30 | public: 31 | /// Row of the switch in the Network. 32 | int row_fifo; 33 | /// Col of the switch in the Network. 34 | int col_fifo; 35 | 36 | /*! Main clocked process of the fifo module. 37 | */ 38 | void prc_fifo(); 39 | 40 | /// Useful to see how many elements are memorized in the fifo. 41 | int FIFO_LastPosition; 42 | 43 | /// Useful to see how many elements are memorized in the fifo. 44 | struct Packet FIFO_vector[10]; 45 | /// Variable used to memorize the next output value of the fifo. 46 | struct Packet FIFO_reg; 47 | /// Counter for loops. 48 | int i; 49 | /// Clock of the fifo 50 | sc_clock clkfifo; 51 | /// Open a file in order to write on it. 52 | ofstream fifofile; 53 | /// Signal which samples the input. 54 | struct Packet FIFO_in_s,FIFO_reg_appoggio; 55 | 56 | /// Constructor: Initializes the fifo (all zeros) and open the fifofile to write on it. 57 | SC_CTOR(fifo):clkfifo("clkfifo",1,SC_NS) 58 | { 59 | SC_METHOD(prc_fifo); 60 | sensitive< 12 | //#include "windows.h" 13 | #include "NOC_package.h" 14 | #include "fifo.h" 15 | #include "NoC_WR.h" 16 | 17 | 18 | /// \brief Main function of the progam. 19 | /// 20 | /// It's the most important function. 21 | /// Generate the NoC system instantiating the NoC1 component. 22 | /// Windows users: check the simulation time using 2 SYSTEMTIME variables and the function GetSystemTime from "windows.h". 23 | /// For testing or to generate waves: use the technique shown in the code between //#INIT_WAVE and //#FINISH_WAVE. If not interested in waves, it is possible to cancel that part of code. 24 | int sc_main (int argc,char *argv[]) 25 | { 26 | 27 | 28 | NoC_WR *NoC1; 29 | NoC1=new NoC_WR("NoC1"); 30 | 31 | 32 | 33 | //SYSTEMTIME now,now1; 34 | 35 | //#INIT_WAVE 36 | sc_trace_file* tracefile; 37 | tracefile=sc_create_vcd_trace_file("wave"); 38 | 39 | sc_trace(tracefile,NoC1->wrapperNS[4-1][1-1]->clkL,"clkL"); 40 | sc_trace(tracefile,NoC1->wrapperNS[4-1][1-1]->clkR,"clkR"); 41 | sc_trace(tracefile,NoC1->wrapperNS[4-1][1-1]->L_datain,"L_datain"); 42 | sc_trace(tracefile,NoC1->wrapperNS[4-1][1-1]->R_datain,"R_datain"); 43 | sc_trace(tracefile,NoC1->wrapperNS[4-1][1-1]->L_dataout,"L_dataout"); 44 | sc_trace(tracefile,NoC1->wrapperNS[4-1][1-1]->R_dataout,"R_dataout"); 45 | sc_trace(tracefile,NoC1->wrapperNS[4-1][1-1]->L_strobe_s,"L_strobe_s"); 46 | sc_trace(tracefile,NoC1->wrapperNS[4-1][1-1]->R_strobe_s,"R_strobe_s"); 47 | sc_trace(tracefile,NoC1->wrapperNS[4-1][1-1]->L_datac_s,"L_datac_s"); 48 | sc_trace(tracefile,NoC1->wrapperNS[4-1][1-1]->R_datac_s,"R_datac_s"); 49 | sc_trace(tracefile,NoC1->wrapperNS[4-1][1-1]->rx_RtoL.save_register_N,"save_register_N"); 50 | sc_trace(tracefile,NoC1->wrapperNS[4-1][1-1]->rx_RtoL.save_register_P,"save_register_P"); 51 | sc_trace(tracefile,NoC1->wrapperNS[4-1][1-1]->rx_RtoL.saved_packet,"saved_packet"); 52 | 53 | sc_trace_file* tracefile2; 54 | tracefile2=sc_create_vcd_trace_file("wave2"); 55 | 56 | sc_trace(tracefile2,NoC1->wrapperWE[5-1][3-1]->clkL,"clkL"); 57 | sc_trace(tracefile2,NoC1->wrapperWE[5-1][3-1]->clkR,"clkR"); 58 | sc_trace(tracefile2,NoC1->wrapperWE[5-1][3-1]->L_datain,"L_datain"); 59 | sc_trace(tracefile2,NoC1->wrapperWE[5-1][3-1]->R_datain,"R_datain"); 60 | sc_trace(tracefile2,NoC1->wrapperWE[5-1][3-1]->L_dataout,"L_dataout"); 61 | sc_trace(tracefile2,NoC1->wrapperWE[5-1][3-1]->R_dataout,"R_dataout"); 62 | sc_trace(tracefile2,NoC1->wrapperWE[5-1][3-1]->L_strobe_s,"L_strobe_s"); 63 | sc_trace(tracefile2,NoC1->wrapperWE[5-1][3-1]->R_strobe_s,"R_strobe_s"); 64 | sc_trace(tracefile2,NoC1->wrapperWE[5-1][3-1]->L_datac_s,"L_datac_s"); 65 | sc_trace(tracefile2,NoC1->wrapperWE[5-1][3-1]->R_datac_s,"R_datac_s"); 66 | sc_trace(tracefile2,NoC1->wrapperWE[5-1][3-1]->rx_LtoR.datac_container[0],"datac_container[0]"); 67 | sc_trace(tracefile2,NoC1->wrapperWE[5-1][3-1]->rx_LtoR.datac_container[1],"datac_container[1]"); 68 | //#FINISH_WAVE 69 | 70 | //GetSystemTime(&now); 71 | 72 | sc_start(1000,SC_NS); 73 | 74 | //GetSystemTime(&now1); 75 | //cout<<(now1.wMilliseconds-now.wMilliseconds)<(m_N_T*2)) 80 | { 81 | sample_container[0][0]=sample_container[0][actual_sample-1]; 82 | sample_container[1][0]=sample_container[1][actual_sample-1]; 83 | actual_sample=1; 84 | 85 | } 86 | 87 | } 88 | 89 | wait(); 90 | } 91 | } 92 | 93 | void receiver::update_P() 94 | { 95 | if (rst_n==(sc_bit)0) 96 | { 97 | save_register_P=empty_NL_PDU; 98 | } 99 | else if (must_i_sample[actual_sample]==true)//event 100 | save_register_P=datac_container[0]; 101 | else 102 | save_register_P=empty_NL_PDU; 103 | output_update.notify(); 104 | return; 105 | } 106 | 107 | void receiver::update_N() 108 | { 109 | if (rst_n==(sc_bit)0) 110 | { 111 | save_register_N=empty_NL_PDU; 112 | } 113 | else if (must_i_sample[actual_sample]==true) //event 114 | save_register_N=datac_container[0]; 115 | else 116 | save_register_N=empty_NL_PDU; 117 | //output_update.notify(); 118 | return; 119 | } 120 | 121 | void receiver::receiver_register() 122 | { 123 | if (rst_n==(sc_bit)0) 124 | { 125 | dataout=empty_NL_PDU; 126 | saved_packet=empty_NL_PDU; 127 | vs_flag=false; 128 | error_flag=false; 129 | } 130 | /*else if ((datac_container[1].payload==save_register.payload)||(save_register.payload==0)) 131 | dataout=datac_container[1]; 132 | else 133 | dataout=save_register;*/ 134 | else if (vs_flag==false) 135 | { 136 | 137 | if(save_register_P.empty==true && synch_reg_out.empty==true) 138 | { 139 | if(m_N_R>=m_N_T) 140 | vs_flag=true; 141 | dataout=synch_reg_out; 142 | saved_packet=save_register_P; 143 | } 144 | else if(save_register_P.empty==false && synch_reg_out.empty==true) 145 | { 146 | vs_flag=false; 147 | dataout=synch_reg_out; 148 | } 149 | else if(save_register_P.empty==true && synch_reg_out.empty==false) 150 | { 151 | vs_flag=false; 152 | dataout=save_register_P; 153 | } 154 | else // false,false 155 | { 156 | vs_flag=false; 157 | dataout=empty_NL_PDU; 158 | } 159 | } 160 | else 161 | { 162 | 163 | if(save_register_P.empty==true && synch_reg_out.empty==true) //not possible 164 | { 165 | error_flag=true; 166 | } 167 | else if(save_register_P.empty==false && synch_reg_out.empty==true) 168 | { 169 | vs_flag=true; 170 | dataout=saved_packet; 171 | saved_packet=synch_reg_out; 172 | } 173 | else if(save_register_P.empty==true && synch_reg_out.empty==false) 174 | { 175 | vs_flag=true; 176 | dataout=saved_packet; 177 | saved_packet=save_register_P; 178 | } 179 | else // false,false 180 | { 181 | vs_flag=false; 182 | dataout=saved_packet; 183 | saved_packet=empty_NL_PDU; 184 | } 185 | } 186 | 187 | return; 188 | } 189 | 190 | void receiver::time_strobe() 191 | { 192 | sc_bit strobe_s; 193 | 194 | strobe_s=strobe; 195 | 196 | strobelastchange=sc_time_stamp(); 197 | 198 | //manage case in which strobe and clkR change at the same time 199 | if (synchro_delta_cycle==strobelastchange) 200 | { 201 | sample_container[0][actual_sample]=strobeget(strobe_s,strobelastchange,m_Tsu); 202 | cout<<"actual_sample: "< 9 | #include "NOC_package.h" 10 | #include "RX_package.h" 11 | 12 | /*! \class receiver 13 | \brief SystemC description of the receiver module. 14 | 15 | It is the receiver block of the GRLS wrapper. 16 | */ 17 | SC_MODULE(receiver) 18 | //class receiver : public sc_module 19 | { 20 | /// Input port for datac from the transmitter 21 | sc_in datac; 22 | /// Input port for the strobe from the transmitter 23 | sc_in strobe; 24 | /// reset port 25 | sc_in rst_n; 26 | /// clock port 27 | sc_in clk; 28 | 29 | /// output port for the data to the receiver switch 30 | sc_out dataout; 31 | 32 | /// analysis of the strobe and decision if to sample or not the next PC 33 | void strobe_analysis(); 34 | /// manage the output, deciding from which FF to take the results (pos edge triggered, neg edge triggered, or synch reg) 35 | void receiver_register(); 36 | /// evaluate when the strobe has changed the last time 37 | void time_strobe(); 38 | /// manage the positive edge sensitive input FF 39 | void update_P(); 40 | /// manage the negative edge sensitive input FF 41 | void update_N(); 42 | /// manage the synchronisation register 43 | void synch_reg_module(); 44 | 45 | /// matrix of 2 lines. In the first line i put the samples sampled on clkR edge, on the second one the ones from clkR2 46 | bool** sample_container; 47 | /// used to manage the output 48 | Packet datac_container[2]; 49 | /// counter to decide which column of sample_container i'm analyzing 50 | int actual_sample; 51 | /// general counter 52 | int i; //general counter 53 | /// vector used to decide when to sample on clkR1 edge 54 | bool* must_i_sample; 55 | /// when strobe has changed the last time 56 | sc_time strobelastchange; 57 | /// manage particular case in which strobe and clkR change simultaneously 58 | sc_time synchro_delta_cycle; //in case strobe and clkR change simultaneously, strobechange is evaluated BEFORE strobeget function 59 | 60 | /// manage kernel 61 | sc_event update_event_P; 62 | /// manage kernel 63 | sc_event update_event_N; 64 | /// manage kernel 65 | sc_event output_update; 66 | 67 | /// info in reg_N 68 | Packet save_register_N; 69 | /// info in reg_P 70 | Packet save_register_P; 71 | /// info to output 72 | Packet saved_packet; 73 | /// info from synchreg 74 | Packet synch_reg_out; 75 | 76 | /// vs flag 77 | bool vs_flag; 78 | /// flag set in case of error 79 | bool error_flag; 80 | 81 | //SC_CTOR(receiver) 82 | SC_HAS_PROCESS(receiver); 83 | /// constructor of the transmitter 84 | receiver(sc_module_name name_ , int N_R , int N_T, int Tsw, int Tsu) : sc_module(name_), m_N_R(N_R), m_N_T(N_T),m_Tsw(Tsw),m_Tsu(Tsu) 85 | { 86 | sample_container = new bool*[2]; 87 | sample_container[0] = new bool[(m_N_T*2)+1]; 88 | sample_container[1] = new bool[(m_N_T*2)+1]; 89 | 90 | must_i_sample = new bool[(m_N_T*2)+1]; 91 | 92 | SC_METHOD(receiver_register); 93 | //sensitive< m_N_T) 27 | c=m_N_R; 28 | } 29 | else // if clk'event and clk=1 30 | { 31 | 32 | if(data_in_s.empty==true) 33 | { 34 | FIFO[last_pos]=data_in_s; 35 | last_pos++; 36 | if(last_pos>=m_fifo_tx_dim) 37 | { 38 | full=(sc_bit)1; 39 | last_pos=0; 40 | } 41 | } 42 | 43 | //ALGORITMO1 44 | if (m_N_R<=m_N_T) 45 | { 46 | //always send 47 | strobe = ~strobe; 48 | datac=FIFO[0]; 49 | for (i=0;i0) 53 | { 54 | last_pos--; 55 | 56 | } 57 | } 58 | else if(m_N_R > m_N_T) 59 | { 60 | if(c>(m_N_R-m_N_T)) 61 | { 62 | //send 63 | datac=FIFO[0]; 64 | for (i=0;i0) 68 | { 69 | last_pos--; 70 | cout<<"ciuz"<name() <<" data_in: " < 9 | #include "NOC_package.h" 10 | 11 | /*! \class transmitter 12 | \brief SystemC description of the transmitter module. 13 | 14 | It is the transmitter bolck of the GRLS wrapper. 15 | */ 16 | SC_MODULE(transmitter) 17 | //class transmitter : public sc_module 18 | { 19 | /// Input port for datas from the switch 20 | sc_in datain; 21 | /// reset port 22 | sc_in rst_n; 23 | /// clk port 24 | sc_in clk; 25 | 26 | /// full port. If it's set it indicates that the fifo of the transmitter is to small to contain all datas 27 | sc_out full; 28 | /// strobe output port.It changes with datac 29 | sc_out strobe; 30 | /// data to the receiver sub-block of the wrapper 31 | sc_out datac; 32 | 33 | /// main process of the transmitter module 34 | void evaluate(); 35 | //Packet FIFO[FIFO_TX_DIM]; 36 | /// fifo used to manage case of fast transmitter 37 | Packet* FIFO; 38 | int i,last_pos,c; 39 | 40 | ofstream tx_file; 41 | 42 | //SC_CTOR(transmitter) 43 | /// constructor of the transmitter 44 | SC_HAS_PROCESS(transmitter); 45 | transmitter(sc_module_name name_ , int N_R , int N_T, int fifo_tx_dim) : sc_module(name_), m_N_R(N_R), m_N_T(N_T),m_fifo_tx_dim(fifo_tx_dim) 46 | { 47 | SC_METHOD(evaluate); 48 | sensitive< m_N_T) 58 | c=m_N_R; 59 | 60 | tx_file.open ("tx_file.txt",ios::trunc); 61 | tx_file << "SIMULATION STARTS NOW: "< L_datain; 29 | ///data output port of the left side of the wrapper 30 | sc_out L_dataout; 31 | 32 | ///data input port of the right side of the wrapper 33 | sc_in R_datain; 34 | ///data output port of the right side of the wrapper 35 | sc_out R_dataout; 36 | 37 | 38 | ///clock input form the switch on the left side of the wrapper 39 | sc_in clkL; 40 | ///clock input form the switch on the right side of the wrapper 41 | sc_in clkR; 42 | ///reset input 43 | sc_in rst_n; 44 | 45 | ///instantiation of the transmitters sub-blocks 46 | transmitter tx_LtoR; 47 | ///instantiation of the transmitters sub-blocks 48 | transmitter tx_RtoL; 49 | ///instantiation of the receivers sub-blocks 50 | receiver rx_LtoR; 51 | ///instantiation of the receivers sub-blocks 52 | receiver rx_RtoL; 53 | 54 | ///stobe signal for the left to right couple of tx and rx 55 | sc_signal L_strobe_s; 56 | ///full signal for the left to right couple of tx and rx 57 | sc_signal L_full_s; 58 | ///stobe signal for the right to left couple of tx and rx 59 | sc_signal R_strobe_s; 60 | ///full signal for the right to left couple of tx and rx 61 | sc_signal R_full_s; 62 | 63 | ///data signal for the left to right couple of tx and rx 64 | sc_signal L_datac_s; 65 | ///data signal for the right to left couple of tx and rx 66 | sc_signal R_datac_s; 67 | 68 | //SC_CTOR(wrapper_mod):tx_LtoR("tx_LtoR",5,3,7),tx_RtoL("tx_RtoL",3,5,7),rx_LtoR("rx_LtoR",5,3,100,25),rx_RtoL("rx_RtoL",3,5,100,25) 69 | /// indication that we want to explicit the constructor 70 | SC_HAS_PROCESS(wrapper_mod); 71 | /// constructor of the wrapper 72 | wrapper_mod(sc_module_name name_ , int N_left , int N_right) : sc_module(name_), m_N_left(N_left), m_N_right(N_right) ,tx_LtoR("tx_LtoR",m_N_left,m_N_right,7),tx_RtoL("tx_RtoL",m_N_right,m_N_left,7),rx_LtoR("rx_LtoR",m_N_left,m_N_right,100,25),rx_RtoL("rx_RtoL",m_N_right,m_N_left,100,25) 73 | { 74 | tx_LtoR.datain(L_datain); 75 | tx_LtoR.rst_n(rst_n); 76 | tx_LtoR.clk(clkL); 77 | tx_LtoR.full(L_full_s); 78 | tx_LtoR.datac(L_datac_s); 79 | tx_LtoR.strobe(L_strobe_s); 80 | rx_LtoR.datac(L_datac_s); 81 | rx_LtoR.strobe(L_strobe_s); 82 | rx_LtoR.clk(clkR); 83 | rx_LtoR.rst_n(rst_n); 84 | rx_LtoR.dataout(R_dataout); 85 | 86 | tx_RtoL.datain(R_datain); 87 | tx_RtoL.rst_n(rst_n); 88 | tx_RtoL.clk(clkR); 89 | tx_RtoL.full(R_full_s); 90 | tx_RtoL.datac(R_datac_s); 91 | tx_RtoL.strobe(R_strobe_s); 92 | rx_RtoL.datac(R_datac_s); 93 | rx_RtoL.strobe(R_strobe_s); 94 | rx_RtoL.clk(clkL); 95 | rx_RtoL.rst_n(rst_n); 96 | rx_RtoL.dataout(L_dataout); 97 | 98 | } 99 | 100 | }; 101 | 102 | 103 | #endif 104 | --------------------------------------------------------------------------------