cloudFPGA (cF) API  1.0
The documentation of the source code of cloudFPGA (cF)
tb_nal.cpp
Go to the documentation of this file.
1 
17 
30 #include <stdio.h>
31 #include <hls_stream.h>
32 #include <inttypes.h>
33 
34 #include "../src/nal.hpp"
35 #include "../../simulation_utils.hpp"
36 #include "../../NTS/nts_utils.hpp"
37 
38 using namespace std;
39 
40 
41 //#define OK true
42 //#define KO false
43 #define VALID true
44 #define UNVALID false
45 #define DEBUG_TRACE true
46 
47 //---------------------------------------------------------
48 // HELPERS FOR THE DEBUGGING TRACES
49 // .e.g: DEBUG_LEVEL = (MDL_TRACE | IPS_TRACE)
50 //---------------------------------------------------------
51 #define THIS_NAME "TB"
52 
53 #define TRACE_OFF 0x0000
54 #define TRACE_TOE 1 << 1
55 #define TRACE_ROLE 1 << 2
56 #define TRACE_ALL 0xFFFF
57 
58 #define DEBUG_LEVEL (TRACE_TOE | TRACE_ROLE)
59 
60 //------------------------------------------------------
61 //-- TESTBENCH GLOBAL VARIABLES
62 //------------------------------------------------------
63 #define MAX_SIM_CYCLES 450
64 //---------------------------------------------------------
65 //-- DEFAULT LOCAL FPGA AND FOREIGN HOST SOCKETS
66 //-- By default, the following sockets will be used by the
67 //-- testbench, unless the user specifies new ones via one
68 //-- of the test vector files.
69 //---------------------------------------------------------
70 #define DEFAULT_FPGA_IP4_ADDR 0x0A0CC801 // TOE's local IP Address = 10.12.200.01
71 #define DEFAULT_FPGA_LSN_PORT 0x0057 // TOE listens on port = 87 (static ports must be 0..32767)
72 #define DEFAULT_HOST_IP4_ADDR 0x0A0CC832 // TB's foreign IP Address = 10.12.200.50
73 #define DEFAULT_HOST_LSN_PORT 0x80 // TB listens on port = 128
74 
75 #define DEFAULT_SESSION_ID 42
76 #define DEFAULT_SESSION_LEN 32
77 
78 //#define DEFAULT_TCP_LEN_REP 1000 //less than ZYC2_MSS
79 #define DEFAULT_TCP_LEN_REP 16 //to test pWBu?
80 
81 
82 //------------------------------------------------------
83 //-- DUT INTERFACES AS GLOBAL VARIABLES
84 //------------------------------------------------------
85 //-- UOE / Control Port Interfaces
86 stream<UdpPort> sNRC_UOE_LsnReq ("sNRC_UOE_LsnReq");
87 stream<StsBool> sUOE_NRC_LsnRep ("sUOE_NRC_LsnRep");
88 stream<UdpPort> sNRC_UOE_ClsReq ("sNRC_UOE_ClsReq");
89 stream<StsBool> sUOE_NRC_ClsRep ("sUOE_NRC_ClsRep");
90 
91 //-- UOE / Rx Data Interfaces
92 stream<UdpAppData> sUOE_NRC_Data ("sUOE_NRC_Data");
93 stream<UdpAppMeta> sUOE_NRC_Meta ("sUOE_NRC_Meta");
94 stream<UdpAppDLen> sUOE_NRC_DLen ("sUOE_NRC_DLen");
95 
96 //-- UOE / Tx Data Interfaces
97 stream<UdpAppData> sNRC_UOE_Data ("sNRC_UOE_Data");
98 stream<UdpAppMeta> sNRC_UOE_Meta ("sNRC_UOE_Meta");
99 stream<UdpAppDLen> sNRC_UOE_DLen ("sNRC_UOE_DLen");
100 //-- ROLE UDP
101 stream<NetworkMetaStream> siUdp_meta ("siUdp_meta");
102 stream<NetworkMetaStream> soUdp_meta ("soUdp_meta");
103 stream<NetworkWord> sROLE_NRC_Data ("sROLE_NRC_Data");
104 stream<NetworkWord> sNRC_Role_Data ("sNRC_Role_Data");
105 //-- TCP / ROLE IF
106 stream<NetworkWord> sROLE_Nrc_Tcp_data ("sROLE_Nrc_Tcp_data");
107 stream<NetworkMetaStream> sROLE_Nrc_Tcp_meta ("sROLE_Nrc_Tcp_meta");
108 stream<NetworkWord> sNRC_Role_Tcp_data ("sNRC_Role_Tcp_data");
109 stream<NetworkMetaStream> sNRC_Role_Tcp_meta ("sNRC_Role_Tcp_meta");
110 //--FMC TCP connection
111 stream<NetworkWord> sFMC_Nrc_Tcp_data ("sFMC_Nrc_Tcp_data");
112 stream<TcpSessId> sFMC_Nrc_Tcp_sessId ("sFMC_Nrc_Tcp_sessId");
113 //ap_uint<1> piFMC_Tcp_data_FIFO_prog_full = 0;
114 stream<NetworkWord> sNRC_FMC_Tcp_data ("sNRC_FMC_Tcp_data");
115 //ap_uint<1> piFMC_Tcp_sessid_FIFO_prog_full = 0;
116 stream<TcpSessId> sNRC_FMC_Tcp_sessId ("sNRC_FMC_Tcp_sessId");
117 //--TOE connection
118 stream<TcpAppNotif> sTOE_Nrc_Notif ("sTOE_Nrc_Notif");
119 stream<TcpAppRdReq> sNRC_Toe_DReq ("sNrc_TOE_DReq");
120 stream<TcpAppData> sTOE_Nrc_Data ("sTOE_Nrc_Data");
121 stream<TcpAppMeta> sTOE_Nrc_SessId ("sTOE_Nrc_SessId");
122 stream<TcpAppLsnReq> sNRC_Toe_LsnReq ("sNRC_TOE_LsnReq");
123 stream<TcpAppLsnRep> sTOE_Nrc_LsnAck ("sTOE_Nrc_LsnAck");
124 stream<TcpAppData> sNRC_Toe_Data ("sNRC_TOE_Data");
125 stream<TcpAppSndReq> sNRC_Toe_SndReq ("sNRC_TOE_SndReq");
126 stream<TcpAppSndRep> sTOE_Nrc_SndRep ("sTOE_NRC_SndRep");
127 stream<TcpAppOpnReq> sNRC_Toe_OpnReq ("sNRC_Toe_OpnReq");
128 stream<TcpAppOpnRep> sTOE_Nrc_OpnRep ("sTOE_NRC_OpenRep");
129 stream<TcpAppClsReq> sNRC_Toe_ClsReq ("sNRC_TOE_ClsReq");
130 
131 
132 ap_uint<1> layer_4_enabled = 0b1;
133 ap_uint<1> layer_7_enabled = 0b1;
134 ap_uint<1> role_decoupled = 0b0;
135 ap_uint<1> sNTS_Nrc_ready = 0b1;
136 ap_uint<32> sIpAddress = 0x0a0b0c0d;
138 ap_uint<32> s_udp_rx_ports = 0x1;
139 ap_uint<32> s_tcp_rx_ports = 0x1;
140 ap_uint<32> myIpAddress;
141 ap_uint<16> sMMIO_FmcLsnPort = 8803;
142 //ap_uint<32> sMMIO_CfrmIp4Addr = 0x0A0CC884;
144 
145 //---------------------------------------------------------
146 //-- TESTBENCH GLOBAL VARIABLES
147 //-- These variables might be updated/overwritten by the
148 //-- content of a test-vector file.
149 //---------------------------------------------------------
150 unsigned int gSimCycCnt = 0;
151 bool gTraceEvent = false;
152 bool gFatalError = false;
153 //unsigned int gMaxSimCycles = 0x8000 + 200;
154 
155 //------------------------------------------------------
156 //-- TESTBENCH GLOBAL VARIABLES
157 //------------------------------------------------------
158 unsigned int simCnt;
159 
165 
166 
171 void stepDut() {
172  nal_main(
173  ctrlLink,
179  &sIpAddress,
187  //&piFMC_Tcp_data_FIFO_prog_full,
189  //&piFMC_Tcp_sessid_FIFO_prog_full,
200  );
201  simCnt++;
202  printf("[%4.4d] STEP DUT \n", simCnt);
203 }
204 
205 
214 bool setInputDataStream(stream<UdpAppData> &sDataStream, const string dataStreamName, const string inpFileName) {
215  string strLine;
216  ifstream inpFileStream;
217  string datFile = "../../../../test/" + inpFileName;
218 
219  //-- STEP-1 : OPEN FILE
220  inpFileStream.open(datFile.c_str());
221  if ( !inpFileStream ) {
222  cout << "### ERROR : Could not open the input data file " << datFile << endl;
223  return(KO);
224  }
225 
226  //-- STEP-2 : SET DATA STREAM
227  while (inpFileStream) {
228 
229  if (!inpFileStream.eof()) {
230 
231  getline(inpFileStream, strLine);
232  if (strLine.empty())
233  {
234  continue;
235  }
236  uint64_t newd = 0x0;
237  uint32_t newk = 0; //sscanf expects 32bit
238  uint32_t newl = 0; //sscanf expects 32bit
239  //printf(strLine.c_str()); printf("\n");
240  //sscanf(strLine.c_str(), "%u" PRIx64 " %x %d", &newd, &newk, &newl);
241  sscanf(strLine.c_str(), "%llx %x %d", &newd, &newk, &newl);
242  UdpAppData udpWord;
243  udpWord.setTData(newd); //BE version
244  udpWord.setTKeep(newk); //BE version
245  udpWord.setTLast(newl); //BE version
246  //printf("scanff reads %llx, %x %d\n", newd, newk, newl);
247  //UdpAppData udpWord(newd, newk, newl);
248 
249  // Write to sDataStream
250  if (sDataStream.full()) {
251  printf("### ERROR : Stream is full. Cannot write stream with data from file \"%s\".\n", inpFileName.c_str());
252  return(KO);
253  } else {
254  sDataStream.write(udpWord);
255  // Print Data to console
256  printf("[%4.4d] TB is filling input stream [%s] - Data write = {D=0x%16.16llX, K=0x%2.2X, L=%d} \n",
257  simCnt, dataStreamName.c_str(),
258  udpWord.getTData().to_uint64(), udpWord.getTKeep().to_int(), udpWord.getTLast().to_int());
259  }
260  }
261  }
262 
263  //-- STEP-3: CLOSE FILE
264  inpFileStream.close();
265 
266  return(OK);
267 }
268 //ROLE version
269 bool setInputDataStream(stream<NetworkWord> &sDataStream, const string dataStreamName, const string inpFileName) {
270  string strLine;
271  ifstream inpFileStream;
272  string datFile = "../../../../test/" + inpFileName;
273 
274  //-- STEP-1 : OPEN FILE
275  inpFileStream.open(datFile.c_str());
276  if ( !inpFileStream ) {
277  cout << "### ERROR : Could not open the input data file " << datFile << endl;
278  return(KO);
279  }
280 
281  //-- STEP-2 : SET DATA STREAM
282  while (inpFileStream) {
283 
284  if (!inpFileStream.eof()) {
285 
286  getline(inpFileStream, strLine);
287  if (strLine.empty())
288  {
289  continue;
290  }
291  uint64_t newd = 0x0;
292  uint32_t newk = 0; //sscanf expects 32bit
293  uint32_t newl = 0; //sscanf expects 32bit
294  //printf(strLine.c_str()); printf("\n");
295  //sscanf(strLine.c_str(), "%u" PRIx64 " %x %d", &newd, &newk, &newl);
296  sscanf(strLine.c_str(), "%llx %x %d", &newd, &newk, &newl);
297  UdpAppData udpWordTmp;
298  udpWordTmp.setTData(newd); //BE version
299  udpWordTmp.setTKeep(newk); //BE version
300  udpWordTmp.setTLast(newl); //BE version
301  NetworkWord udpWord = NetworkWord(udpWordTmp.getLE_TData(), udpWordTmp.getLE_TKeep(), udpWordTmp.getLE_TLast());
302  //printf("scanff reads %llx, %x %d\n", newd, newk, newl);
303 
304  // Write to sDataStream
305  if (sDataStream.full()) {
306  printf("### ERROR : Stream is full. Cannot write stream with data from file \"%s\".\n", inpFileName.c_str());
307  return(KO);
308  } else {
309  sDataStream.write(udpWord);
310  // Print Data to console
311  printf("[%4.4d] TB is filling input stream [%s] - Data write = {D=0x%16.16llX, K=0x%2.2X, L=%d} \n",
312  simCnt, dataStreamName.c_str(),
313  udpWord.tdata.to_uint64(), udpWord.tkeep.to_int(), udpWord.tlast.to_int());
314  }
315  }
316  }
317 
318  //-- STEP-3: CLOSE FILE
319  inpFileStream.close();
320 
321  return(OK);
322 }
323 
324 
333 bool setInputMetaStream(stream<UdpAppMeta> &sMetaStream, const string dataStreamName, const string inpFileName) {
334  string strLine;
335  ifstream inpFileStream;
336  string datFile = "../../../../test/" + inpFileName;
337  UdpWord udpWord;
338  UdpAppMeta udpMeta;
339 
340  //-- STEP-1 : OPEN FILE
341  inpFileStream.open(datFile.c_str());
342  if ( !inpFileStream ) {
343  cout << "### ERROR : Could not open the input data file " << datFile << endl;
344  return(KO);
345  }
346 
347  //-- STEP-2 : SET DATA STREAM
348  while (inpFileStream) {
349 
350  if (!inpFileStream.eof()) {
351 
352  getline(inpFileStream, strLine);
353  if (strLine.empty()) continue;
354  sscanf(strLine.c_str(), "%llx %x %d", &udpWord.tdata, &udpWord.tkeep, &udpWord.tlast);
355 
356  // Check if the LAST bit is set
357  if (udpWord.tlast) {
358 
359  // Create an connection association {{SrcPort, SrcAdd}, {DstPort, DstAdd}}
360  //socketPair = (UdpMeta) {{DEFAULT_RX_PORT, 0x0A0B0C01}, {DEFAULT_RX_PORT, 0x0A0B0C0E}};
361  udpMeta = UdpAppMeta(DEFAULT_RX_PORT, 0x0A0B0C01, DEFAULT_RX_PORT, 0x0A0B0C0E);
362 
363  // Write to sMetaStream
364  if (sMetaStream.full()) {
365  printf("### ERROR : Stream is full. Cannot write stream with data from file \"%s\".\n", inpFileName.c_str());
366  return(KO);
367  }
368  else {
369  sMetaStream.write(udpMeta);
370  // Print Metadata to console
371  printf("[%4.4d] TB is filling input stream [%s] - Metadata = {{SP=0x%4.4X,SA=0x%8.8X} {DP=0x%4.4X,DA=0x%8.8X}} \n",
372  simCnt, dataStreamName.c_str(),
373  udpMeta.udpSrcPort.to_int(), udpMeta.ip4SrcAddr.to_int(), udpMeta.udpDstPort.to_int(), udpMeta.ip4DstAddr.to_int());
374  }
375  }
376  }
377  }
378 
379  //-- STEP-3: CLOSE FILE
380  inpFileStream.close();
381 
382  return(OK);
383 }
384 
385 
395 bool readDataStream(stream <UdpAppData> &sDataStream, UdpAppData *udpWord) {
396  // Get the DUT/Data results
397  sDataStream.read(*udpWord);
398  return(VALID);
399 }
400 
401 
410 bool readMetaStream(stream <UdpAppMeta> &sMetaStream, const string metaStreamName,
411  UdpAppMeta *udpMeta) {
412  // Get the DUT/Metadata results
413  sMetaStream.read(*udpMeta);
414  // Print DUT/Metadata to console
415  printf("[%4.4d] TB is draining output stream [%s] - Metadata = {{SP=0x%4.4X,SA=0x%8.8X} {DP=0x%4.4X,DA=0x%8.8X}} \n",
416  simCnt, metaStreamName.c_str(),
417  udpMeta->udpSrcPort.to_int(), udpMeta->ip4SrcAddr.to_int(), udpMeta->udpDstPort.to_int(), udpMeta->ip4DstAddr.to_int());
418  return(VALID);
419 }
420 
421 
431 bool readPLenStream(stream <UdpPLen> &sPLenStream, const string plenStreamName,
432  UdpPLen *udpPLen) {
433  // Get the DUT/PayloadLength results
434  sPLenStream.read(*udpPLen);
435  // Print DUT/PayloadLength to console
436  printf("[%4.4d] TB is draining output stream [%s] - Payload length = %d from DUT.\n",
437  simCnt, plenStreamName.c_str(), udpPLen->to_int());
438  return(VALID);
439 }
440 
441 
449 bool dumpDataToFile(UdpAppData *udpWord, ofstream &outFileStream) {
450  if (!outFileStream.is_open()) {
451  printf("### ERROR : Output file stream is not open. \n");
452  return(KO);
453  }
454  outFileStream << hex << noshowbase << uppercase << setfill('0') << setw(16) << udpWord->getTData().to_uint64();
455  outFileStream << " ";
456  outFileStream << hex << noshowbase << nouppercase << setfill('0') << setw(2) << udpWord->getTKeep().to_int();
457  outFileStream << " ";
458  outFileStream << setw(1) << udpWord->getTLast().to_int() << "\n";
459  return(OK);
460 }
461 //ROLE Version
462 bool dumpDataToFile(NetworkWord *udpWord, ofstream &outFileStream) {
463  if (!outFileStream.is_open()) {
464  printf("### ERROR : Output file stream is not open. \n");
465  return(KO);
466  }
467  outFileStream << hex << noshowbase << uppercase << setfill('0') << setw(16) << udpWord->tdata.to_uint64();
468  outFileStream << " ";
469  outFileStream << hex << noshowbase << nouppercase << setfill('0') << setw(2) << udpWord->tkeep.to_int();
470  outFileStream << " ";
471  outFileStream << setw(1) << udpWord->tlast.to_int() << "\n";
472  return(OK);
473 }
474 
475 
483 bool dumpMetaToFile(UdpAppMeta *udpMeta, ofstream &outFileStream) {
484  if (!outFileStream.is_open()) {
485  printf("### ERROR : Output file stream is not open. \n");
486  return(KO);
487  }
488  outFileStream << hex << noshowbase << setfill('0') << setw(4) << udpMeta->udpSrcPort.to_int();
489  outFileStream << " ";
490  outFileStream << hex << noshowbase << setfill('0') << setw(8) << udpMeta->ip4SrcAddr.to_int();
491  outFileStream << " ";
492  outFileStream << hex << noshowbase << setfill('0') << setw(4) << udpMeta->udpDstPort.to_int();
493  outFileStream << " ";
494  outFileStream << hex << noshowbase << setfill('0') << setw(8) << udpMeta->ip4DstAddr.to_int();
495  outFileStream << "\n";
496  return(OK);
497 }
498 
499 
507 bool dumpPLenToFile(UdpPLen *udpPLen, ofstream &outFileStream) {
508  if (!outFileStream.is_open()) {
509  printf("### ERROR : Output file stream is not open. \n");
510  return(KO);
511  }
512  outFileStream << hex << noshowbase << setfill('0') << setw(4) << udpPLen->to_int();
513  outFileStream << "\n";
514  return(OK);
515 }
516 
517 
526 bool getOutputDataStream(stream<UdpAppData> &sDataStream,
527  const string dataStreamName, const string outFileName)
528 {
529  string strLine;
530  ofstream outFileStream;
531  string datFile = "../../../../test/" + outFileName;
532  UdpAppData udpWord;
533  bool rc = OK;
534 
535  //-- STEP-1 : OPEN FILE
536  outFileStream.open(datFile.c_str());
537  if ( !outFileStream ) {
538  cout << "### ERROR : Could not open the output data file " << datFile << endl;
539  return(KO);
540  }
541 
542  //-- STEP-2 : EMPTY STREAM AND DUMP DATA TO FILE
543  while (!sDataStream.empty()) {
544  if (readDataStream(sDataStream, &udpWord) == VALID) {
545  // Print DUT/Data to console
546  printf("[%4.4d] TB is draining output stream [%s] - Data read = {D=0x%16.16llX, K=0x%2.2X, L=%d} \n",
547  simCnt, dataStreamName.c_str(),
548  udpWord.getTData().to_uint64(), udpWord.getTKeep().to_int(), udpWord.getTLast().to_int());
549  if (!dumpDataToFile(&udpWord, outFileStream)) {
550  rc = KO;
551  break;
552  }
553  }
554  }
555 
556  //-- STEP-3: CLOSE FILE
557  outFileStream.close();
558 
559  return(rc);
560 }
561 //ROLE version
562 bool getOutputDataStream(stream<NetworkWord> &sDataStream,
563  const string dataStreamName, const string outFileName)
564 {
565  string strLine;
566  ofstream outFileStream;
567  string datFile = "../../../../test/" + outFileName;
568  UdpAppData udpWord;
569  bool rc = OK;
570 
571  //-- STEP-1 : OPEN FILE
572  outFileStream.open(datFile.c_str());
573  if ( !outFileStream ) {
574  cout << "### ERROR : Could not open the output data file " << datFile << endl;
575  return(KO);
576  }
577 
578  //-- STEP-2 : EMPTY STREAM AND DUMP DATA TO FILE
579  while (!sDataStream.empty()) {
580  NetworkWord wordtmp = sDataStream.read();
581  udpWord = UdpAppData(wordtmp.tdata, wordtmp.tkeep, wordtmp.tlast);
582  // Print DUT/Data to console
583  printf("[%4.4d] TB is draining output stream [%s] - Data read = {D=0x%16.16llX, K=0x%2.2X, L=%d} \n",
584  simCnt, dataStreamName.c_str(),
585  udpWord.getTData().to_uint64(), udpWord.getTData().to_int(), udpWord.getTData().to_int());
586  if (!dumpDataToFile(&udpWord, outFileStream)) {
587  rc = KO;
588  break;
589  }
590  }
591 
592  //-- STEP-3: CLOSE FILE
593  outFileStream.close();
594 
595  return(rc);
596 }
597 
598 
607 bool getOutputMetaStream(stream<UdpAppMeta> &sMetaStream,
608  const string metaStreamName, const string outFileName)
609 {
610  string strLine;
611  ofstream outFileStream;
612  string datFile = "../../../../test/" + outFileName;
613  UdpAppMeta udpMeta;
614  bool rc = OK;
615 
616  //-- STEP-1 : OPEN FILE
617  outFileStream.open(datFile.c_str());
618  if ( !outFileStream ) {
619  cout << "### ERROR : Could not open the output data file " << datFile << endl;
620  return(KO);
621  }
622 
623  //-- STEP-2 : EMPTY STREAM AND DUMP METADATA TO FILE
624  while (!sMetaStream.empty()) {
625  if (readMetaStream(sMetaStream, metaStreamName, &udpMeta) == VALID) {
626  if (!dumpMetaToFile(&udpMeta, outFileStream)) {
627  rc = KO;
628  break;
629  }
630  }
631  }
632 
633  //-- STEP-3: CLOSE FILE
634  outFileStream.close();
635 
636  return(rc);
637 }
638 
639 
648 bool getOutputPLenStream(stream<UdpPLen> &sPLenStream,
649  const string plenStreamName, const string outFileName)
650 {
651  string strLine;
652  ofstream outFileStream;
653  string datFile = "../../../../test/" + outFileName;
654  UdpPLen udpPLen;
655  bool rc = OK;
656 
657  //-- STEP-1 : OPEN FILE
658  outFileStream.open(datFile.c_str());
659  if ( !outFileStream ) {
660  cout << "### ERROR : Could not open the output data file " << datFile << endl;
661  return(KO);
662  }
663 
664  //-- STEP-2 : EMPTY STREAM AND DUMP PAYLOAD LENGTH TO FILE
665  while (!sPLenStream.empty()) {
666  if (readPLenStream(sPLenStream, plenStreamName, &udpPLen) == VALID) {
667  if (!dumpPLenToFile(&udpPLen, outFileStream)) {
668  rc = KO;
669  break;
670  }
671  }
672  }
673 
674  //-- STEP-3: CLOSE FILE
675  outFileStream.close();
676 
677  return(rc);
678 }
679 
680 
682 
693 void pFMC(
694  //-- TRIF / Rx Data Interface
695  stream<NetworkWord> &siTRIF_Data,
696  stream<TcpSessId> &siTRIF_SessId,
697  //-- TRIF / Tx Data Interface
698  stream<NetworkWord> &soTRIF_Data,
699  stream<TcpSessId> &soTRIF_SessId)
700 {
701  NetworkWord currWord;
702  TcpSessId tcpSessId;
703 
704  const char *myRxName = concat3(THIS_NAME, "/", "FMC-Rx");
705  const char *myTxName = concat3(THIS_NAME, "/", "FMC-Tx");
706 
707  switch (rxFsmState ) {
708  case RX_WAIT_META:
709  if (!siTRIF_SessId.empty() and !soTRIF_SessId.full()) {
710  //tcpSessId = siTRIF_SessId.read().tdata;
711  tcpSessId = siTRIF_SessId.read();
712  soTRIF_SessId.write(tcpSessId);
714  printf("FMC received sessionID: %d\n", tcpSessId.to_uint());
715  }
716  break;
717  case RX_STREAM:
718  if (!siTRIF_Data.empty() && !soTRIF_Data.full()) {
719  siTRIF_Data.read(currWord);
720  //if (DEBUG_LEVEL & TRACE_ROLE) {
721  printAxiWord(myRxName, currWord);
722  //}
723  soTRIF_Data.write(currWord);
724  if (currWord.tlast == 1) {
726  }
727  }
728  break;
729  }
730 
731 }
732 
733 
735 
746 void pROLE(
747  //-- TRIF / Rx Data Interface
748  stream<NetworkWord> &siTRIF_Data,
749  stream<NetworkMetaStream> &siTRIF_meta,
750  //-- TRIF / Tx Data Interface
751  stream<NetworkWord> &soTRIF_Data,
752  stream<NetworkMetaStream> &soTRIF_meta)
753 {
754  NetworkWord currWord;
755  NetworkMetaStream meta_stream_in;
756  NetworkMetaStream meta_stream_out;
757 
758  const char *myRxName = concat3(THIS_NAME, "/", "ROLE-Rx");
759  const char *myTxName = concat3(THIS_NAME, "/", "ROLE-Tx");
760 
761  switch (roleFsmState ) {
762  case ROLE_WAIT_META:
763  if (!siTRIF_meta.empty() && !soTRIF_meta.full()) {
764  siTRIF_meta.read(meta_stream_in);
765  meta_stream_out = NetworkMetaStream();
766  meta_stream_out.tkeep = 0xFFFF;
767  meta_stream_out.tlast = 1;
768  meta_stream_out.tdata.dst_rank = meta_stream_in.tdata.src_rank;
769  meta_stream_out.tdata.dst_port = meta_stream_in.tdata.src_port;
770  meta_stream_out.tdata.src_port = NAL_RX_MIN_PORT;
771  if(meta_stream_in.tdata.dst_port == 2718)
772  {
773  meta_stream_out.tdata.len = meta_stream_in.tdata.len;
774  } else {
775  meta_stream_out.tdata.len = 0; //test streaming mode
776  }
777  printf("ROLE received stream from Node %d:%d (recv. port %d, length %d)\n", (int) meta_stream_in.tdata.src_rank, (int) meta_stream_in.tdata.src_port, (int) meta_stream_in.tdata.dst_port, (int) meta_stream_in.tdata.len);
778  soTRIF_meta.write(meta_stream_out);
780  }
781  break;
782  case ROLE_STREAM:
783  if (!siTRIF_Data.empty() && !soTRIF_Data.full()) {
784  siTRIF_Data.read(currWord);
785  if (DEBUG_LEVEL & TRACE_ROLE) {
786  printAxiWord(myRxName, currWord);
787  }
788  soTRIF_Data.write(currWord);
789  if (currWord.tlast)
791  } else {
792  printf("[%4.4d] \tERROR: pROLE cant write to NRC.\n", simCnt);
793  }
794  break;
795  }
796 
797 }
798 
814 int loop = 1;
815 
820 
822 //int rxpStartupDelay = 0x8000 + 100;
823 int rxpStartupDelay = 100;
825 
829 int byteCnt = 0;
830 int segCnt = 0;
831 int nrSegToSend = 3;
832 ap_uint<64> data=0;
834 
835 const char *myLsnName = concat3(THIS_NAME, "/", "TOE/Listen");
836 const char *myOpnName = concat3(THIS_NAME, "/", "TOE/OpnCon");
837 const char *myRxpName = concat3(THIS_NAME, "/", "TOE/RxPath");
838 const char *myTxpName = concat3(THIS_NAME, "/", "TOE/TxPath");
839 
840 void pTOE(
841  int &nrErr,
842  //-- TOE / Tx Data Interfaces
843  stream<TcpAppNotif> &soTRIF_Notif,
844  stream<TcpAppRdReq> &siTRIF_DReq,
845  stream<TcpAppData> &soTRIF_Data,
846  stream<TcpAppMeta> &soTRIF_SessId,
847  //-- TOE / Listen Interfaces
848  stream<TcpAppLsnReq> &siTRIF_LsnReq,
849  stream<TcpAppLsnRep> &soTRIF_LsnAck,
850  //-- TOE / Rx Data Interfaces
851  stream<TcpAppData> &siTRIF_Data,
852  stream<TcpAppSndReq> &siTRIF_SndReq,
853  stream<TcpAppSndRep> &soTRIF_SndRep,
854  //-- TOE / Open Interfaces
855  stream<TcpAppOpnReq> &siTRIF_OpnReq,
856  stream<TcpAppOpnRep> &soTRIF_OpnRep)
857 {
858 
859  //------------------------------------------------------
860  //-- FSM #1 - LISTENING
861  //------------------------------------------------------
862  static TcpAppLsnReq appLsnPortReq;
863 
864  switch (lsnState) {
865  case LSN_WAIT_REQ: // CHECK IF A LISTENING REQUEST IS PENDING
866  if (!siTRIF_LsnReq.empty()) {
867  siTRIF_LsnReq.read(appLsnPortReq);
868  printInfo(myLsnName, "Received a listen port request #%d from [TRIF].\n",
869  appLsnPortReq.to_int());
871  }
872  //else {
873  // printWarn(myLsnName, "Waiting for listen port request.\n");
874  //}
875  break;
876  case LSN_SEND_ACK: // SEND ACK BACK TO [TRIF]
877  if (!soTRIF_LsnAck.full()) {
878  soTRIF_LsnAck.write(true);
879  //fpgaLsnPort = appLsnPortReq.to_int();
881  }
882  else {
883  printWarn(myLsnName, "Cannot send listen reply back to [TRIF] because stream is full.\n");
884  }
885  break;
886  } // End-of: switch (lsnState) {
887 
888  //------------------------------------------------------
889  //-- FSM #2 - OPEN CONNECTION
890  //------------------------------------------------------
891  TcpAppOpnReq HostSockAddr(DEFAULT_HOST_IP4_ADDR,
893 
895  if (!opnStartupDelay) {
896  switch(opnState) {
897  case OPN_WAIT_REQ:
898  if (!siTRIF_OpnReq.empty()) {
899  siTRIF_OpnReq.read(HostSockAddr);
900  printInfo(myOpnName, "Received a request to open the following remote socket address:\n");
901  printSockAddr(myOpnName, HostSockAddr);
903  }
904  break;
905  case OPN_SEND_REP:
906  if (!soTRIF_OpnRep.full()) {
907  soTRIF_OpnRep.write(opnReply);
909  }
910  else {
911  printWarn(myOpnName, "Cannot send open connection reply back to [TRIF] because stream is full.\n");
912  }
913  break;
914  default: //Timeout etc.
915  break;
916  } // End-of: switch (opnState) {
917  }
918  else
919  opnStartupDelay--;
920 
921  //------------------------------------------------------
922  //-- FSM #3 - RX DATA PATH
923  //------------------------------------------------------
924  ap_uint< 8> keep;
925  ap_uint< 1> last;
926  if (!rxpStartupDelay) {
927  switch (rxpState) {
928  case RXP_SEND_NOTIF: // SEND A DATA NOTIFICATION TO [TRIF]
929  printf("Send packet from %4.4x to FPGA:%d\n",(int) hostIp4Addr, (int) fpgaLsnPort);
930  if (!soTRIF_Notif.full()) {
931  soTRIF_Notif.write(TcpAppNotif(sessionId, tcpSegLen,
933  printInfo(myRxpName, "Sending notification #%d to [TRIF] (sessId=%d, segLen=%d).\n",
934  segCnt, sessionId.to_int(), tcpSegLen.to_int());
936  }
937  break;
938  case RXP_WAIT_DREQ: // WAIT FOR A DATA REQUEST FROM [TRIF]
939  if (!siTRIF_DReq.empty()) {
940  siTRIF_DReq.read(appRdReq);
941  printInfo(myRxpName, "Received a data read request from [TRIF] (sessId=%d, segLen=%d).\n",
942  appRdReq.sessionID.to_int(), appRdReq.length.to_int());
943  byteCnt = 0;
944  //rxpState = RXP_SEND_DATA;
945  //rxpState = RXP_DONE;
947  }
948  break;
949  case RXP_SEND_META:
950  if (!soTRIF_SessId.full()) {
951  soTRIF_SessId.write(sessionId);
953  //rxpState = RXP_DONE;
954  }
955  break;
956  case RXP_SEND_DATA: // FORWARD DATA AND METADATA TO [TRIF]
957  // Note: We always assume 'tcpSegLen' is multiple of 8B.
958  keep = 0xFF;
959  if (byteCnt == 0) {
960  //if (!soTRIF_SessId.full() && !soTRIF_Data.full()) {
961  if (!soTRIF_Data.full()) {
962  soTRIF_Data.write(TcpAppData(data, keep, last));
963  if (DEBUG_LEVEL & TRACE_TOE)
964  printAxiWord(myRxpName, NetworkWord(data, keep, last));
965  byteCnt += 8;
966  data += 8;
967  }
968  else {
969  printf("[TB-INFO-2] NRC not ready to receive TCP data.\n");
970  break;
971  }
972  }
973  else if (byteCnt < tcpSegLen) {
974  if (!soTRIF_Data.full()) {
975  byteCnt += 8;
976  last = (byteCnt>=(tcpSegLen-1)) ? 1 : 0;
977  soTRIF_Data.write(TcpAppData(data, keep, last));
978  if (DEBUG_LEVEL & TRACE_TOE)
979  printAxiWord(myRxpName, NetworkWord(data, keep, last));
980  data += 8;
981  if(last == 1)
982  {
983  segCnt++;
985  if (segCnt >= nrSegToSend) {
986  rxpState = RXP_DONE;
987  } else {
989  }
990  }
991  }
992  }
993  break;
994  case RXP_DONE: // END OF THE RX PATH SEQUENCE
995  // ALL SEGMENTS HAVE BEEN SENT
996  // Reset for next run
997  byteCnt = 0;
998  segCnt = 0;
999  //wait here
1000  break;
1001  } // End-of: switch())
1002  }
1003  else
1004  rxpStartupDelay--;
1005 
1006  //printInfo(myRxpName, "POST FSM state %d\n", (int) rxpState);
1007 
1008  //------------------------------------------------------
1009  //-- FSM #4 - TX DATA PATH
1010  //-- (Always drain the data coming from [TRIF])
1011  //------------------------------------------------------
1012  static TcpSessId curr_sessId;
1013  if (!txpStartupDelay) {
1014  switch (txpState) {
1015  case TXP_WAIT_REQ:
1016  if (!siTRIF_SndReq.empty() && !soTRIF_SndRep.full()) {
1017  TcpAppSndReq app_req;
1018  siTRIF_SndReq.read(app_req);
1019  curr_sessId = app_req.sessId;
1020  TcpDatLen len = app_req.length;
1021  if (DEBUG_LEVEL & TRACE_TOE) {
1022  printInfo(myTxpName, "Receiving TX Request for session #%d with length %d; \t Approve up to length %d\n",
1023  curr_sessId.to_int(), len.to_int(), DEFAULT_TCP_LEN_REP);
1024  }
1025  TcpAppSndErr err_rep = NO_ERROR;
1026  if(len > DEFAULT_TCP_LEN_REP)
1027  {
1028  err_rep = NO_SPACE;
1030  }
1031  TcpAppSndRep app_rep = TcpAppSndRep(curr_sessId, len, DEFAULT_TCP_LEN_REP, err_rep);
1032  soTRIF_SndRep.write(app_rep);
1034  }
1035  break;
1036  case TXP_WAIT_DATA:
1037  //TODO: acturally, there must not come data after a request, there could also be another request
1038  //but the current pTcpWBu is not using this flexibility
1039  if( !siTRIF_Data.empty())
1040  {
1041  TcpAppData appData;
1042  siTRIF_Data.read(appData);
1043  if (DEBUG_LEVEL & TRACE_TOE) {
1044  printInfo(myTxpName, "Receiving data for session #%d\n", curr_sessId.to_int());
1045  printAxiWord(myTxpName, appData);
1046  }
1047  if (!appData.getTLast() == 1)
1048  {
1050  } else {
1052  tcp_packets_recv++;
1053  }
1054 
1055  }
1056  break;
1057  case TXP_RECV_DATA:
1058  if (!siTRIF_Data.empty()) {
1059  TcpAppData appData;
1060  siTRIF_Data.read(appData);
1061  if (DEBUG_LEVEL & TRACE_TOE)
1062  printAxiWord(myTxpName, appData);
1063  if (appData.getTLast() == 1) {
1065  tcp_packets_recv++;
1066  }
1067  }
1068  break;
1069  }
1070  }
1071  else {
1072  txpStartupDelay--;
1073  }
1074 
1075  //printInfo(myTxpName, "POST FSM state %d\n", (int) txpState);
1076 }
1077 
1078 
1079 
1084 int main() {
1085 
1086  //------------------------------------------------------
1087  //-- TESTBENCH LOCAL VARIABLES
1088  //------------------------------------------------------
1089  int nrErr = 0;
1090 
1091  printf("#####################################################\n");
1092  printf("## TESTBENCH 'tb_nrc' STARTS HERE ##\n");
1093  printf("#####################################################\n");
1094 
1095  simCnt = 0;
1096  nrErr = 0;
1097 
1098  //prepare MRT (routing table)
1099  for(int i = 0; i < MAX_MRT_SIZE + NUMBER_CONFIG_WORDS + NUMBER_STATUS_WORDS; i++)
1100  {
1101  ctrlLink[i] = 0;
1102  }
1103 
1104  //ctrlLink[0] = 1; //own rank
1106  ctrlLink[NUMBER_CONFIG_WORDS + NUMBER_STATUS_WORDS + 0] = 0x0a0b0c01; //10.11.12.1
1107  ctrlLink[NUMBER_CONFIG_WORDS + NUMBER_STATUS_WORDS + 1] = 0x0a0b0c0d; //10.11.12.13
1108  ctrlLink[NUMBER_CONFIG_WORDS + NUMBER_STATUS_WORDS + 2] = 0x0a0b0c0e; //10.11.12.14
1109 
1110  //------------------------------------------------------
1111  //-- STEP-1 : OPEN PORT REQUEST
1112  //------------------------------------------------------
1113  //printf("========================= BEGIN UDP Port Opening =========================\n");
1114  //for (int i=0; i<32; ++i) {
1115  // //we need ~18 cycles to copy all configs, and then a few more to copy the MRT
1116  // stepDut();
1117  // if ( !sNRC_UOE_LsnReq.empty() ) {
1118  // sNRC_UOE_LsnReq.read();
1119  // printf("[%4.4d] NRC->UOE_OpnReq : DUT is requesting to open a port.\n", simCnt);
1120  // stepDut();
1121  // sUOE_NRC_LsnRep.write(true);
1122  // printf("[%4.4d] NRC->UOE_OpnAck : TB acknowledges the port opening.\n", simCnt);
1123  // }
1124  //}
1125  //printf("========================= END UDP Port Opening =========================\n");
1126 
1130  //if (nrErr == 0) {
1131  // if (!setInputDataStream(sROLE_NRC_Data, "sROLE_NRC_Data", "ifsROLE_Urif_Data.dat")) {
1132  // printf("### ERROR : Failed to set input data stream \"sROLE_DataStream\". \n");
1133  // nrErr++;
1134  // }
1135  //
1136  // //there are 2 streams from the ROLE to UDMX
1137  // NetworkMeta tmp_meta = NetworkMeta(1,DEFAULT_RX_PORT,2,DEFAULT_RX_PORT,0);
1138  // siUdp_meta.write(NetworkMetaStream(tmp_meta));
1139  // siUdp_meta.write(NetworkMetaStream(tmp_meta));
1140 
1141  // if (!setInputDataStream(sUOE_NRC_Data, "sUOE_NRC_Data", "ifsUDMX_Urif_Data.dat")) {
1142  // printf("### ERROR : Failed to set input data stream \"sUOE_DataStream\". \n");
1143  // nrErr++;
1144  // }
1145  // //if (!setInputMetaStream(sUDMX_Urif_Meta, "sUDMX_Urif_Meta", "ifsUDMX_Urif_Data.dat")) {
1146  // // printf("### ERROR : Failed to set input meta stream \"sUDMX_MetaStream\". \n");
1147  // // nrErr++;
1148  // //}
1149  // //there are 3 streams from the UDMX to NRC
1150  // //UdpMeta socketPair = SocketPair({DEFAULT_RX_PORT, 0x0A0B0C0E}, {DEFAULT_RX_PORT, 0x0A0B0C01});
1151  // UdpMeta socketPair = SocketPair({0x0A0B0C0E, DEFAULT_RX_PORT}, {0x0A0B0C01, DEFAULT_RX_PORT});
1152  // sUOE_NRC_Meta.write(socketPair);
1153  // sUOE_NRC_Meta.write(socketPair);
1154  // sUOE_NRC_Meta.write(socketPair);
1155  // // Print Metadata to console
1156  // printf("[%4.4d] TB is filling input stream [Meta] - Metadata = {{SP=0x%4.4X,SA=0x%8.8X} {DP=0x%4.4X,DA=0x%8.8X}} \n",
1157  // simCnt, socketPair.udpSrcPort.to_int(), socketPair.ip4SrcAddr.to_int(), socketPair.udpDstPort.to_int(), socketPair.ip4DstAddr.to_int());
1158  //}
1159 
1160  //------------------------------------------------------
1161  //-- STEP-3 : MAIN TRAFFIC LOOP
1162  //------------------------------------------------------
1163  bool sof = true;
1164  gSimCycCnt = simCnt; // Simulation cycle counter as a global variable
1165  nrErr = 0; // Total number of testbench errors
1166 
1167  printf("#####################################################\n");
1168  printf("## MAIN LOOP STARTS HERE ##\n");
1169  printf("#####################################################\n");
1170 
1171  //Test FMC first
1175  fpgaLsnPort = 8803;
1176 
1177 
1178  while (!nrErr)
1179  {
1180 
1181  //if (simCnt < 42)
1182  if (gSimCycCnt < MAX_SIM_CYCLES)
1183  {
1184 
1185  if(simCnt < 32)
1186  {
1187  //UDP port logic
1188  if ( !sNRC_UOE_LsnReq.empty() ) {
1189  sNRC_UOE_LsnReq.read();
1190  printf("[%4.4d] NRC->UOE_OpnReq : DUT is requesting to open a port.\n", simCnt);
1191  sUOE_NRC_LsnRep.write(true);
1192  printf("[%4.4d] NRC->UOE_OpnAck : TB acknowledges the port opening.\n", simCnt);
1193  }
1194  }
1195 
1196  //------------------------------------------------------
1197  //-- CREATE UDP TRAFFIC AS INPUT STREAMS
1198  //------------------------------------------------------
1199  if (simCnt == 32)
1200  {
1201  //by now, the config should have been copied
1202 
1203  if (!setInputDataStream(sROLE_NRC_Data, "sROLE_NRC_Data", "ifsROLE_Urif_Data.dat")) {
1204  printf("### ERROR : Failed to set input data stream \"sROLE_DataStream\". \n");
1205  nrErr++;
1206  }
1207 
1208  //there are 2 streams from the ROLE to UDMX
1210  siUdp_meta.write(NetworkMetaStream(tmp_meta));
1211  siUdp_meta.write(NetworkMetaStream(tmp_meta));
1212 
1213  if (!setInputDataStream(sUOE_NRC_Data, "sUOE_NRC_Data", "ifsUDMX_Urif_Data.dat")) {
1214  printf("### ERROR : Failed to set input data stream \"sUOE_DataStream\". \n");
1215  nrErr++;
1216  }
1217  //if (!setInputMetaStream(sUDMX_Urif_Meta, "sUDMX_Urif_Meta", "ifsUDMX_Urif_Data.dat")) {
1218  // printf("### ERROR : Failed to set input meta stream \"sUDMX_MetaStream\". \n");
1219  // nrErr++;
1220  //}
1221  //there are 3 streams from the UDMX to NRC
1222  //UdpMeta socketPair = SocketPair({0x0A0B0C0E, DEFAULT_RX_PORT}, {0x0A0B0C01, DEFAULT_RX_PORT});
1223  UdpAppMeta udpMeta = UdpAppMeta(0x0A0B0C0E, DEFAULT_RX_PORT, 0x0A0B0C01, DEFAULT_RX_PORT);
1224  sUOE_NRC_Meta.write(udpMeta);
1225  sUOE_NRC_Meta.write(udpMeta);
1226  sUOE_NRC_Meta.write(udpMeta);
1227  //the length of the streams are in ifsUDMX_Urif_Data.dat
1228  sUOE_NRC_DLen.write(38);
1229  sUOE_NRC_DLen.write(23);
1230  sUOE_NRC_DLen.write(60);
1231 
1232  // Print Metadata to console
1233  //printf("[%4.4d] TB is filling input stream [Meta] - Metadata = {{SP=0x%4.4X,SA=0x%8.8X} {DP=0x%4.4X,DA=0x%8.8X}} \n",
1234  //simCnt, socketPair.udpSrcPort.to_int(), socketPair.ip4SrcAddr.to_int(), socketPair.udpDstPort.to_int(), socketPair.ip4DstAddr.to_int());
1235  }
1236 
1237  //-------------------------------------------------
1238  //-- EMULATE TOE
1239  //-------------------------------------------------
1240  pTOE(
1241  nrErr,
1242  //-- TOE / Tx Data Interfaces
1244  sNRC_Toe_DReq,
1245  sTOE_Nrc_Data,
1247  //-- TOE / Listen Interfaces
1250  //-- TOE / Tx Data Interfaces
1251  sNRC_Toe_Data,
1254  //sTOE_Nrc_DSts,
1255  //-- TOE / Open Interfaces
1258  );
1259 
1260  //-------------------------------------------------
1261  //-- RUN DUT
1262  //-------------------------------------------------
1263  stepDut();
1264 
1265  //UDP meta
1266  if( !soUdp_meta.empty())
1267  {
1268  NetworkMetaStream tmp_meta = soUdp_meta.read();
1269  printf("Role received NRCmeta stream from rank %d.\n", (int) tmp_meta.tdata.src_rank);
1270  }
1271 
1272  //-------------------------------------------------
1273  //-- EMULATE APP 1 (FMC)
1274  //-------------------------------------------------
1275  pFMC(
1276  //-- TRIF / Rx Data Interface
1279  //-- TRIF / Tx Data Interface
1282 
1283  //if(simCnt % 50 == 0)
1284  //{
1285  // //to update MRT version
1286  // ctrlLink[NAL_CONFIG_MRT_VERSION] = ctrlLink[NAL_NUMBER_CONFIG_WORDS + NAL_STATUS_MRT_VERSION];
1287  //}
1288 
1289  //-------------------------------------------------
1290  //-- EMULATE APP 2 (ROLE-TCP)
1291  //-------------------------------------------------
1292  pROLE(
1293  //-- TRIF / Rx Data Interface
1296  //-- TRIF / Tx Data Interface
1299 
1300  //------------------------------------------------------
1301  //-- INCREMENT SIMULATION COUNTER
1302  //------------------------------------------------------
1303  fflush(stdout);
1304  fflush(stderr);
1305  gSimCycCnt++;
1306  if (gTraceEvent || ((gSimCycCnt % 1000) == 0)) {
1307  printf("-- [@%4.4d] -----------------------------\n", gSimCycCnt);
1308  gTraceEvent = false;
1309  }
1310  if(simCnt == 180)
1311  {
1312  if(rxpState != RXP_DONE)
1313  {
1314  nrErr++;
1315  printf("[TB-ERROR] RXP engine is not in expected state!\n");
1316  }
1317  //now test ROLE
1321  fpgaLsnPort = 2718;
1323  //i.e. three segments (nrSegToSend)
1324  }
1325  if(simCnt == 210)
1326  {
1327  s_tcp_rx_ports = 0b101;
1328  //open 2720
1329  }
1330  if(simCnt == 223)
1331  {
1332  if(rxpState != RXP_DONE)
1333  {
1334  nrErr++;
1335  printf("[TB-ERROR] RXP engine is not in expected state!\n");
1336  }
1341  fpgaLsnPort = 2720;
1343  //i.e. three segments (nrSegToSend)
1344  }
1345 
1346  //if(simCnt == 243)
1347  //{
1348  // s_tcp_rx_ports = 0b1101;
1349  //}
1350  if(simCnt == 269)
1351  {
1352  if(rxpState != RXP_DONE)
1353  {
1354  nrErr++;
1355  printf("[TB-ERROR] RXP engine is not in expected state!\n");
1356  }
1357  //test again, but this time with connection timeout
1362  fpgaLsnPort = 2720;
1363  hostSrcPort = 8443;
1368  }
1369 
1370  if(simCnt >= 269 && tcp_timout_packet_drop > 0 && !sNRC_Toe_OpnReq.empty())
1371  {
1372  //drain OpnReq stream
1374  printf("=== Drain OpenReq: ");
1375  printSockAddr("Main-Loop", sNRC_Toe_OpnReq.read());
1376  }
1377 
1378  //TODO:
1379  //open other ports later?
1380 
1381  } else {
1382  printf("## End of simulation at cycle=%3d. \n", simCnt);
1383  break;
1384  }
1385 
1386  } // End: while()
1387  printf("-- [@%4.4d] -----------------------------\n", gSimCycCnt);
1388  printf("############################################################################\n");
1389  printf("## TESTBENCH 'tb_nal' ENDS HERE ##\n");
1390 
1393  {
1394  printf("\tERROR: some packets are lost: send %d TCP packets, received %d (fragmented parts %d, expected timeout for packets %d)!\n", tcp_packets_send, tcp_packets_recv-tcp_recv_frag_cnt, tcp_recv_frag_cnt, tcp_packets_expected_timeout);
1395  } else {
1396  printf("\tSummary: Send %d TCP packets, Received %d TCP packets (fragmented parts %d, expected Timout packets %d).\n",tcp_packets_send, tcp_packets_recv-tcp_recv_frag_cnt, tcp_recv_frag_cnt, tcp_packets_expected_timeout);
1397  }
1398  printf("############################################################################\n\n");
1399 
1401  {
1402  //A4L needs >161 steps to acknowledge it.
1403  printf("ERROR: NAL status is reporting the wrong MRT version (%d)!\n", (int) ctrlLink[NUMBER_CONFIG_WORDS + NAL_STATUS_MRT_VERSION]);
1404  nrErr++;
1405  }
1406 
1407  //-------------------------------------------------------
1408  //-- STEP-4 : DRAIN AND WRITE OUTPUT FILE STREAMS
1409  //-------------------------------------------------------
1410  //---- URIF-->ROLE ----
1411  if (!getOutputDataStream(sNRC_Role_Data, "sNRC_Role_Data", "ofsURIF_Role_Data.dat"))
1412  nrErr++;
1413  //---- URIF->UDMX ----
1414  if (!getOutputDataStream(sNRC_UOE_Data, "sNRC_UOE_Data", "ofsURIF_Udmx_Data.dat"))
1415  nrErr++;
1416  if (!getOutputMetaStream(sNRC_UOE_Meta, "sNRC_UOE_Meta", "ofsURIF_Udmx_Meta.dat"))
1417  nrErr++;
1418  if (!getOutputPLenStream(sNRC_UOE_DLen, "sNRC_UOE_DLen", "ofsURIF_Udmx_PLen.dat"))
1419  nrErr++;
1420 
1421  // there should be no left over data
1422  while(!sNRC_Toe_OpnReq.empty())
1423  {
1424  printf("=== Draining leftover TCP request: ");
1425  printSockAddr("Post-Loop", sNRC_Toe_OpnReq.read());
1426  printf("===\n");
1427  nrErr++;
1428  }
1429 
1430 
1431  //------------------------------------------------------
1432  //-- STEP-5 : COMPARE INPUT AND OUTPUT FILE STREAMS
1433  //------------------------------------------------------
1434  int rc1 = system("diff --brief -w -i -y ../../../../test/ofsURIF_Role_Data.dat \
1435  ../../../../test/ifsUDMX_Urif_Data.dat");
1436  if (rc1)
1437  printf("## Error : File \'ofsURIF_Role_Data.dat\' does not match \'ifsUDMX_Urif_Data.dat\'.\n");
1438 
1439  int rc2 = system("diff --brief -w -i -y ../../../../test/ofsURIF_Udmx_Data.dat \
1440  ../../../../test/ifsROLE_Urif_Data.dat");
1441  if (rc2)
1442  printf("## Error : File \'ofsURIF_Udmx_Data.dat\' does not match \'ifsROLE_Urif_Data.dat\'.\n");
1443  nrErr += rc1 + rc2;
1444 
1445  printf("#####################################################\n");
1446  if (nrErr)
1447  printf("## ERROR - TESTBENCH FAILED (RC=%d) !!! ##\n", nrErr);
1448  else
1449  printf("## SUCCESSFULL END OF TESTBENCH (RC=0) ##\n");
1450 
1451  printf("#####################################################\n");
1452 
1453  return(nrErr);
1454 }
1455 
1456 
void setTLast(tLast last)
Definition: AxisRaw.hpp:246
tData getTData(int leHi=64 -1, int leLo=0) const
Definition: AxisRaw.hpp:191
tLast getTLast() const
Definition: AxisRaw.hpp:219
LE_tKeep getLE_TKeep(int leHi=64/8-1, int leLo=0) const
Definition: AxisRaw.hpp:264
LE_tData getLE_TData(int leHi=64 -1, int leLo=0) const
Definition: AxisRaw.hpp:260
void setTKeep(tKeep keep)
Definition: AxisRaw.hpp:239
tKeep getTKeep(int leHi=64/8-1, int leLo=0) const
Definition: AxisRaw.hpp:207
void setTData(tData data)
Definition: AxisRaw.hpp:228
LE_tLast getLE_TLast() const
Definition: AxisRaw.hpp:268
TcpDatLen length
Definition: nts.hpp:117
SessionId sessionID
Definition: nts.hpp:116
TcpDatLen length
Definition: nts.hpp:130
SessionId sessId
Definition: nts.hpp:129
Ly4Port udpDstPort
Definition: nts.hpp:229
Ly4Port udpSrcPort
Definition: nts.hpp:227
Ip4Addr ip4SrcAddr
Definition: nts.hpp:226
Ip4Addr ip4DstAddr
Definition: nts.hpp:228
bool setInputDataStream(stream< UdpAppData > &sDataStream, const string dataStreamName, const string inpFileName)
Initialize an input data stream from a file.
Definition: tb_nal.cpp:214
bool readMetaStream(stream< UdpAppMeta > &sMetaStream, const string metaStreamName, UdpAppMeta *udpMeta)
Read an output metadata stream from the DUT.
Definition: tb_nal.cpp:410
stream< UdpAppMeta > sNRC_UOE_Meta("sNRC_UOE_Meta")
stream< NetworkWord > sNRC_Role_Tcp_data("sNRC_Role_Tcp_data")
#define TRACE_ROLE
Definition: tb_nal.cpp:55
stream< TcpAppLsnRep > sTOE_Nrc_LsnAck("sTOE_Nrc_LsnAck")
TcpPort hostSrcPort
Definition: tb_nal.cpp:813
const char * myRxpName
Definition: tb_nal.cpp:837
#define NUMBER_CONFIG_WORDS
Definition: nal.hpp:191
stream< TcpAppData > sTOE_Nrc_Data("sTOE_Nrc_Data")
#define DEFAULT_HOST_LSN_PORT
Definition: tb_nal.cpp:73
int tcp_packets_recv
Definition: tb_nal.cpp:161
TcpSegLen tcpSegLen
Definition: tb_nal.cpp:833
stream< UdpAppDLen > sUOE_NRC_DLen("sUOE_NRC_DLen")
TcpPort fpgaLsnPort
Definition: tb_nal.cpp:812
stream< TcpAppSndRep > sTOE_Nrc_SndRep("sTOE_NRC_SndRep")
#define DEFAULT_SESSION_ID
Definition: tb_nal.cpp:75
unsigned int simCnt
Definition: tb_nal.cpp:158
#define DEFAULT_TCP_LEN_REP
Definition: tb_nal.cpp:79
int tcp_timout_packet_drop
Definition: tb_nal.cpp:164
ap_uint< 1 > layer_7_enabled
Definition: tb_nal.cpp:133
stream< NetworkWord > sFMC_Nrc_Tcp_data("sFMC_Nrc_Tcp_data")
int nrSegToSend
Definition: tb_nal.cpp:831
stream< TcpAppRdReq > sNRC_Toe_DReq("sNrc_TOE_DReq")
stream< NetworkWord > sNRC_Role_Data("sNRC_Role_Data")
stream< NetworkMetaStream > sROLE_Nrc_Tcp_meta("sROLE_Nrc_Tcp_meta")
#define MAX_SIM_CYCLES
Definition: tb_nal.cpp:63
#define NUMBER_STATUS_WORDS
Definition: nal.hpp:192
const char * myTxpName
Definition: tb_nal.cpp:838
int tcp_packets_expected_timeout
Definition: tb_nal.cpp:163
void pROLE(stream< NetworkWord > &siTRIF_Data, stream< NetworkMetaStream > &siTRIF_meta, stream< NetworkWord > &soTRIF_Data, stream< NetworkMetaStream > &soTRIF_meta)
Emulate the behavior of the ROLE.
Definition: tb_nal.cpp:746
stream< NetworkWord > sNRC_FMC_Tcp_data("sNRC_FMC_Tcp_data")
OpnStates
Definition: tb_nal.cpp:817
bool dumpMetaToFile(UdpAppMeta *udpMeta, ofstream &outFileStream)
Dump a metadata information to a file.
Definition: tb_nal.cpp:483
stream< NetworkMetaStream > sNRC_Role_Tcp_meta("sNRC_Role_Tcp_meta")
bool readDataStream(stream< UdpAppData > &sDataStream, UdpAppData *udpWord)
Read data from a stream.
Definition: tb_nal.cpp:395
stream< TcpAppData > sNRC_Toe_Data("sNRC_TOE_Data")
enum RoleFsmStates roleFsmState
stream< TcpAppLsnReq > sNRC_Toe_LsnReq("sNRC_TOE_LsnReq")
void pTOE(int &nrErr, stream< TcpAppNotif > &soTRIF_Notif, stream< TcpAppRdReq > &siTRIF_DReq, stream< TcpAppData > &soTRIF_Data, stream< TcpAppMeta > &soTRIF_SessId, stream< TcpAppLsnReq > &siTRIF_LsnReq, stream< TcpAppLsnRep > &soTRIF_LsnAck, stream< TcpAppData > &siTRIF_Data, stream< TcpAppSndReq > &siTRIF_SndReq, stream< TcpAppSndRep > &soTRIF_SndRep, stream< TcpAppOpnReq > &siTRIF_OpnReq, stream< TcpAppOpnRep > &soTRIF_OpnRep)
Definition: tb_nal.cpp:840
stream< TcpAppMeta > sTOE_Nrc_SessId("sTOE_Nrc_SessId")
stream< NetworkMetaStream > soUdp_meta("soUdp_meta")
#define DEFAULT_RX_PORT
Definition: nal.hpp:139
void pFMC(stream< NetworkWord > &siTRIF_Data, stream< TcpSessId > &siTRIF_SessId, stream< NetworkWord > &soTRIF_Data, stream< TcpSessId > &soTRIF_SessId)
Emulate the behavior of the FMC.
Definition: tb_nal.cpp:693
stream< UdpAppData > sUOE_NRC_Data("sUOE_NRC_Data")
RxpStates
Definition: tb_nal.cpp:818
#define DEFAULT_SESSION_LEN
Definition: tb_nal.cpp:76
stream< UdpAppData > sNRC_UOE_Data("sNRC_UOE_Data")
bool dumpDataToFile(UdpAppData *udpWord, ofstream &outFileStream)
Dump a data word to a file.
Definition: tb_nal.cpp:449
enum RxFsmStates rxFsmState
stream< StsBool > sUOE_NRC_LsnRep("sUOE_NRC_LsnRep")
const char * myOpnName
Definition: tb_nal.cpp:836
ap_uint< 1 > sNTS_Nrc_ready
Definition: tb_nal.cpp:135
int tcp_recv_frag_cnt
Definition: tb_nal.cpp:162
enum LsnStates lsnState
#define NAL_STATUS_MRT_VERSION
Definition: nal.hpp:221
int rxpStartupDelay
Definition: tb_nal.cpp:823
TcpAppRdReq appRdReq
Definition: tb_nal.cpp:826
#define MAX_MRT_SIZE
Definition: nal.hpp:94
int txpStartupDelay
Definition: tb_nal.cpp:824
bool readPLenStream(stream< UdpPLen > &sPLenStream, const string plenStreamName, UdpPLen *udpPLen)
Read an output payload length stream from the DUT.
Definition: tb_nal.cpp:431
TxpStates
Definition: tb_nal.cpp:819
ap_uint< 32 > sMMIO_CfrmIp4Addr
Definition: tb_nal.cpp:143
stream< TcpSessId > sFMC_Nrc_Tcp_sessId("sFMC_Nrc_Tcp_sessId")
bool getOutputMetaStream(stream< UdpAppMeta > &sMetaStream, const string metaStreamName, const string outFileName)
Fill an output file with metadata from an output stream.
Definition: tb_nal.cpp:607
ap_uint< 64 > data
Definition: tb_nal.cpp:832
unsigned int gSimCycCnt
Definition: tb_nal.cpp:150
stream< TcpAppClsReq > sNRC_Toe_ClsReq("sNRC_TOE_ClsReq")
void nal_main(ap_uint< 32 > ctrlLink[64+16+16], ap_uint< 1 > *layer_4_enabled, ap_uint< 1 > *layer_7_enabled, ap_uint< 1 > *role_decoupled, ap_uint< 1 > *piNTS_ready, ap_uint< 16 > *piMMIO_FmcLsnPort, ap_uint< 32 > *piMMIO_CfrmIp4Addr, ap_uint< 32 > *myIpAddress, ap_uint< 32 > *pi_udp_rx_ports, stream< NetworkWord > &siUdp_data, stream< NetworkWord > &soUdp_data, stream< NetworkMetaStream > &siUdp_meta, stream< NetworkMetaStream > &soUdp_meta, ap_uint< 32 > *pi_tcp_rx_ports, stream< NetworkWord > &siTcp_data, stream< NetworkMetaStream > &siTcp_meta, stream< NetworkWord > &soTcp_data, stream< NetworkMetaStream > &soTcp_meta, stream< NetworkWord > &siFMC_data, stream< TcpSessId > &siFMC_SessId, stream< NetworkWord > &soFMC_data, stream< TcpSessId > &soFMC_SessId, stream< UdpPort > &soUOE_LsnReq, stream< StsBool > &siUOE_LsnRep, stream< UdpPort > &soUOE_ClsReq, stream< StsBool > &siUOE_ClsRep, stream< UdpAppData > &siUOE_Data, stream< UdpAppMeta > &siUOE_Meta, stream< UdpAppDLen > &siUOE_DLen, stream< UdpAppData > &soUOE_Data, stream< UdpAppMeta > &soUOE_Meta, stream< UdpAppDLen > &soUOE_DLen, stream< TcpAppNotif > &siTOE_Notif, stream< TcpAppRdReq > &soTOE_DReq, stream< TcpAppData > &siTOE_Data, stream< TcpAppMeta > &siTOE_SessId, stream< TcpAppLsnReq > &soTOE_LsnReq, stream< TcpAppLsnRep > &siTOE_LsnRep, stream< TcpAppData > &soTOE_Data, stream< TcpAppSndReq > &soTOE_SndReq, stream< TcpAppSndRep > &siTOE_SndRep, stream< TcpAppOpnReq > &soTOE_OpnReq, stream< TcpAppOpnRep > &siTOE_OpnRep, stream< TcpAppClsReq > &soTOE_ClsReq)
Main process of the Network Abstraction Layer (NAL)
Definition: nal.cpp:464
const char * myLsnName
Definition: tb_nal.cpp:835
ap_uint< 1 > layer_4_enabled
Definition: tb_nal.cpp:132
bool gTraceEvent
Definition: tb_nal.cpp:151
stream< UdpAppMeta > sUOE_NRC_Meta("sUOE_NRC_Meta")
#define THIS_NAME
Definition: tb_nal.cpp:51
stream< StsBool > sUOE_NRC_ClsRep("sUOE_NRC_ClsRep")
stream< UdpPort > sNRC_UOE_ClsReq("sNRC_UOE_ClsReq")
stream< NetworkWord > sROLE_NRC_Data("sROLE_NRC_Data")
ap_uint< 32 > s_tcp_rx_ports
Definition: tb_nal.cpp:139
int segCnt
Definition: tb_nal.cpp:830
AppMeta sessionId_reply
Definition: tb_nal.cpp:828
bool gFatalError
Definition: tb_nal.cpp:152
stream< NetworkWord > sROLE_Nrc_Tcp_data("sROLE_Nrc_Tcp_data")
ap_uint< 16 > sMMIO_FmcLsnPort
Definition: tb_nal.cpp:141
stream< TcpAppOpnRep > sTOE_Nrc_OpnRep("sTOE_NRC_OpenRep")
#define DEFAULT_HOST_IP4_ADDR
Definition: tb_nal.cpp:72
enum RxpStates rxpState
ap_uint< 1 > role_decoupled
Definition: tb_nal.cpp:134
stream< UdpPort > sNRC_UOE_LsnReq("sNRC_UOE_LsnReq")
ap_uint< 32 > sIpAddress
Definition: tb_nal.cpp:136
UdpAppDLen UdpPLen
Definition: nal.hpp:258
#define DEBUG_LEVEL
Definition: tb_nal.cpp:58
stream< NetworkMetaStream > siUdp_meta("siUdp_meta")
LsnStates
Definition: tb_nal.cpp:816
stream< TcpAppNotif > sTOE_Nrc_Notif("sTOE_Nrc_Notif")
#define TRACE_TOE
Definition: tb_nal.cpp:54
RxFsmStates
Definition: tb_nal.cpp:681
#define NAL_CONFIG_MRT_VERSION
Definition: nal.hpp:216
ap_uint< 32 > myIpAddress
Definition: tb_nal.cpp:140
int byteCnt
Definition: tb_nal.cpp:829
ap_uint< 32 > ctrlLink[64+16+16]
Definition: tb_nal.cpp:137
bool setInputMetaStream(stream< UdpAppMeta > &sMetaStream, const string dataStreamName, const string inpFileName)
Initialize an input meta stream from a file.
Definition: tb_nal.cpp:333
Ip4Addr hostIp4Addr
Emulate the behavior of the TCP Offload Engine (TOE).
Definition: tb_nal.cpp:811
void stepDut()
Run a single iteration of the DUT model.
Definition: tb_nal.cpp:171
bool getOutputPLenStream(stream< UdpPLen > &sPLenStream, const string plenStreamName, const string outFileName)
Fill an output file with payload length from an output stream.
Definition: tb_nal.cpp:648
#define VALID
Definition: tb_nal.cpp:43
int loop
Definition: tb_nal.cpp:814
int tcp_packets_send
Definition: tb_nal.cpp:160
bool dumpPLenToFile(UdpPLen *udpPLen, ofstream &outFileStream)
Dump a payload length information to a file.
Definition: tb_nal.cpp:507
int opnStartupDelay
Definition: tb_nal.cpp:821
AppMeta sessionId
Definition: tb_nal.cpp:827
stream< TcpSessId > sNRC_FMC_Tcp_sessId("sNRC_FMC_Tcp_sessId")
stream< TcpAppSndReq > sNRC_Toe_SndReq("sNRC_TOE_SndReq")
enum TxpStates txpState
int main()
Main Testbench Loop; Emulates also the behavior of the UDP Offload Engine (UOE).
Definition: tb_nal.cpp:1084
enum OpnStates opnState
stream< TcpAppOpnReq > sNRC_Toe_OpnReq("sNRC_Toe_OpnReq")
stream< UdpAppDLen > sNRC_UOE_DLen("sNRC_UOE_DLen")
ap_uint< 32 > s_udp_rx_ports
Definition: tb_nal.cpp:138
bool getOutputDataStream(stream< UdpAppData > &sDataStream, const string dataStreamName, const string outFileName)
Fill an output file with data from an output stream.
Definition: tb_nal.cpp:526
RoleFsmStates
Definition: tb_nal.cpp:734
@ OPN_SEND_REP
Definition: tb_nal.cpp:817
@ OPN_TIMEOUT
Definition: tb_nal.cpp:817
@ OPN_WAIT_REQ
Definition: tb_nal.cpp:817
@ RXP_SEND_DATA
Definition: tb_nal.cpp:818
@ RXP_SEND_NOTIF
Definition: tb_nal.cpp:818
@ RXP_SEND_META
Definition: tb_nal.cpp:818
@ RXP_WAIT_DREQ
Definition: tb_nal.cpp:818
@ RXP_DONE
Definition: tb_nal.cpp:818
@ TXP_RECV_DATA
Definition: tb_nal.cpp:819
@ TXP_WAIT_DATA
Definition: tb_nal.cpp:819
@ TXP_WAIT_REQ
Definition: tb_nal.cpp:819
@ LSN_WAIT_REQ
Definition: tb_nal.cpp:816
@ LSN_SEND_ACK
Definition: tb_nal.cpp:816
@ RX_WAIT_META
Definition: tb_nal.cpp:681
@ RX_STREAM
Definition: tb_nal.cpp:681
@ ROLE_STREAM
Definition: tb_nal.cpp:734
@ ROLE_WAIT_META
Definition: tb_nal.cpp:734
ap_uint< 16 > TcpSegLen
Definition: AxisTcp.hpp:121
AxisRaw TcpAppData
Definition: nts.hpp:68
ap_uint< 32 > Ip4Addr
Definition: AxisIp4.hpp:169
void printSockAddr(const char *callerName, SockAddr sockAddr)
Print a socket address.
Definition: nts_utils.cpp:174
TcpPort TcpAppLsnReq
Definition: nts.hpp:190
ap_uint< 16 > TcpPort
Definition: AxisTcp.hpp:105
ap_uint< 16 > TcpDatLen
Definition: AxisTcp.hpp:123
TcpAppSndErr
Definition: nts_types.hpp:304
#define printInfo(callerName, format,...)
A macro to print an information message.
Definition: nts_utils.hpp:169
#define OK
Definition: nts_types.hpp:57
#define printWarn(callerName, format,...)
A macro to print a warning message.
Definition: nts_utils.hpp:182
#define concat3(firstCharConst, secondCharConst, thirdCharConst)
Definition: nts_utils.hpp:161
#define KO
Definition: nts_types.hpp:58
AxisRaw UdpAppData
Definition: nts.hpp:214
ap_uint< 16 > TcpSessId
Definition: nts_types.hpp:137
@ ESTABLISHED
Definition: nts_types.hpp:296
@ NO_ERROR
Definition: nts_types.hpp:304
@ NO_SPACE
Definition: nts_types.hpp:304
void uppercase(ap_uint< 32 > *pi_rank, ap_uint< 32 > *pi_size, stream< NetworkWord > &siSHL_This_Data, stream< NetworkWord > &soTHIS_Shl_Data, stream< NetworkMetaStream > &siNrc_meta, stream< NetworkMetaStream > &soNrc_meta, ap_uint< 32 > *po_rx_ports)
Main process of the Uppercase Application directives.
Definition: uppercase.cpp:335
#define NAL_RX_MIN_PORT
Definition: network.hpp:89
TcpSessId AppMeta
void printAxiWord(const char *callerName, AxisRaw chunk)
Prints one chunk of a data stream (used for debugging).
ap_uint< 1 > tlast
Definition: network.hpp:111
ap_uint< 8 > tkeep
Definition: network.hpp:110
NetworkMeta tdata
Definition: network.hpp:109
NetworkDataLength len
Definition: network.hpp:99
NodeId dst_rank
Definition: network.hpp:95
NodeId src_rank
Definition: network.hpp:97
NrcPort src_port
Definition: network.hpp:98
NrcPort dst_port
Definition: network.hpp:96
ap_uint< 64 > tdata
Definition: network.hpp:49
ap_uint< 8 > tkeep
Definition: network.hpp:50
ap_uint< 1 > tlast
Definition: network.hpp:51
ap_uint< 64 > tdata
ap_uint< 1 > tlast
ap_uint< 8 > tkeep