cloudFPGA (cF) API  1.0
The documentation of the source code of cloudFPGA (cF)
test_uoe.cpp
Go to the documentation of this file.
1 /*
2  * Copyright 2016 -- 2021 IBM Corporation
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 
30 #include "test_uoe.hpp"
31 
32 using namespace hls;
33 using namespace std;
34 
35 //---------------------------------------------------------
36 // HELPERS FOR THE DEBUGGING TRACES
37 // .e.g: DEBUG_LEVEL = (MDL_TRACE | IPS_TRACE)
38 //---------------------------------------------------------
39 #define THIS_NAME "TB"
40 
41 #define TRACE_OFF 0x0000
42 #define TRACE_CGRF 1 << 1
43 #define TRACE_CGTF 1 << 2
44 #define TRACE_DUMTF 1 << 3
45 #define TRACE_ALL 0xFFFF
46 #define DEBUG_LEVEL (TRACE_OFF)
47 
48 
51 void stepSim() {
52  gSimCycCnt++;
53  if (gTraceEvent || ((gSimCycCnt % 1000) == 0)) {
54  printInfo(THIS_NAME, "-- [@%4.4d] -----------------------------\n", gSimCycCnt);
55  gTraceEvent = false;
56  }
57  else if (0) {
58  printInfo(THIS_NAME, "------------------- [@%d] ------------\n", gSimCycCnt);
59  }
60 }
61 
62 
74 bool drainUdpMetaStreamToFile(stream<UdpAppMeta> &ss, string ssName,
75  string datFile, int &nrChunks, int &nrFrames, int &nrBytes) {
76  ofstream outFileStream;
77  char currPath[FILENAME_MAX];
78  UdpAppMeta udpMeta;
79 
80  const char *myName = concat3(THIS_NAME, "/", "DUMTF");
81 
82  //-- REMOVE PREVIOUS FILE
83  remove(ssName.c_str());
84 
85  //-- OPEN FILE
86  if (!outFileStream.is_open()) {
87  outFileStream.open(datFile.c_str(), ofstream::out);
88  if (!outFileStream) {
89  printError(THIS_NAME, "Cannot open the file: \'%s\'.\n", datFile.c_str());
90  return(NTS_KO);
91  }
92  }
93 
94  // Assess that file has ".dat" extension
95  if ( datFile.find_last_of ( '.' ) != string::npos ) {
96  string extension ( datFile.substr( datFile.find_last_of ( '.' ) + 1 ) );
97  if (extension != "dat") {
98  printError(THIS_NAME, "Cannot dump SocketPair stream to file \'%s\' because file is not of type \'DAT\'.\n", datFile.c_str());
99  outFileStream.close();
100  return(NTS_KO);
101  }
102  }
103 
104  //-- READ FROM STREAM AND WRITE TO FILE
105  outFileStream << std::hex << std::noshowbase;
106  outFileStream << std::setfill('0');
107  outFileStream << std::uppercase;
108  while (!(ss.empty())) {
109  ss.read(udpMeta);
110  SocketPair socketPair(SockAddr(udpMeta.ip4SrcAddr,
111  udpMeta.udpSrcPort),
112  SockAddr(udpMeta.ip4DstAddr,
113  udpMeta.udpDstPort));
114  writeSocketPairToFile(socketPair, outFileStream);
115  nrChunks++;
116  nrBytes += 12;
117  nrFrames++;
118  if (DEBUG_LEVEL & TRACE_DUMTF) {
119  printInfo(myName, "Writing new socket-pair to file:\n");
120  printSockPair(myName, socketPair);
121  }
122  }
123 
124  //-- CLOSE FILE
125  outFileStream.close();
126 
127  return(NTS_OK);
128 }
129 
130 
142 bool drainUdpDLenStreamToFile(stream<UdpAppDLen> &ss, string ssName,
143  string datFile, int &nrChunks, int &nrFrames, int &nrBytes) {
144  ofstream outFileStream;
145  char currPath[FILENAME_MAX];
146  UdpAppDLen udpDLen;
147 
148  const char *myName = concat3(THIS_NAME, "/", "DUMTF");
149 
150  //-- REMOVE PREVIOUS FILE
151  remove(ssName.c_str());
152 
153  //-- OPEN FILE
154  if (!outFileStream.is_open()) {
155  outFileStream.open(datFile.c_str(), ofstream::out);
156  if (!outFileStream) {
157  printError(THIS_NAME, "Cannot open the file: \'%s\'.\n", datFile.c_str());
158  return(NTS_KO);
159  }
160  }
161 
162  // Assess that file has ".dat" extension
163  if ( datFile.find_last_of ( '.' ) != string::npos ) {
164  string extension ( datFile.substr( datFile.find_last_of ( '.' ) + 1 ) );
165  if (extension != "dat") {
166  printError(THIS_NAME, "Cannot dump DataLength stream to file \'%s\' because file is not of type \'DAT\'.\n", datFile.c_str());
167  outFileStream.close();
168  return(NTS_KO);
169  }
170  }
171 
172  //-- READ FROM STREAM AND WRITE TO FILE
173  outFileStream << std::hex << std::noshowbase;
174  outFileStream << std::setfill('0');
175  outFileStream << std::uppercase;
176  while (!(ss.empty())) {
177  ss.read(udpDLen);
178  writeApUintToFile(udpDLen, outFileStream);
179  nrChunks++;
180  nrBytes += 2;
181  nrFrames++;
182  if (DEBUG_LEVEL & TRACE_DUMTF) {
183  printInfo(myName, "Writing a new data-length to file:\n");
184  }
185  }
186 
187  //-- CLOSE FILE
188  outFileStream.close();
189 
190  return(NTS_OK);
191 }
192 
193 
201 bool drainMmioDropCounter(stream<ap_uint<16> > &ss, string ssName) {
202 
203  int nr=0;
204  const char *myName = concat3(THIS_NAME, "/", "DUMTF");
205  ap_uint<16> currDropCount;
206  ap_uint<16> prevDropCount=0;
207 
208  //-- READ FROM STREAM
209  while (!(ss.empty())) {
210  ss.read(currDropCount);
211  if (currDropCount != prevDropCount) {
212  printWarn(myName, "A datagram has been dropped (currDropCounter=%d). \n", currDropCount.to_ushort());
213  }
214  prevDropCount = currDropCount;
215  }
216  return(NTS_OK);
217 }
218 
219 
236  stream<AxisApp> &ssData, const string ssDataName,
237  stream<UdpAppMeta> &ssMeta, const string ssMetaName,
238  stream<UdpAppDLen> &ssDLen, const string ssDLenName,
239  string datFile,
240  queue<UdpAppMeta> &metaQueue,
241  queue<UdpAppDLen> &dlenQueue,
242  int &nrFeededChunks)
243 {
244 
245  int nrUAIF_UOE_MetaChunks = 0;
246  int nrUAIF_UOE_MetaGrams = 0;
247  int nrUAIF_UOE_MetaBytes = 0;
248 
249  //-- STEP-1: FEED AXIS DATA STREAM FROM DAT FILE --------------------------
250  int nrDataChunks=0, nrDataGrams=0, nrDataBytes=0;
251  if (feedAxisFromFile(ssData, ssDataName, datFile,
252  nrDataChunks, nrDataGrams, nrDataBytes)) {
253  printInfo(THIS_NAME, "Done with the creation of UDP-Data traffic as a stream:\n");
254  printInfo(THIS_NAME, "\tGenerated %d chunks in %d datagrams, for a total of %d bytes.\n\n",
255  nrDataChunks, nrDataGrams, nrDataBytes);
256  nrFeededChunks = nrDataChunks;
257  }
258  else {
259  printError(THIS_NAME, "Failed to create UDP-Data traffic as input stream. \n");
260  return NTS_KO;
261  }
262 
263  //-- STEP-2: FEED METADATA STREAM FROM QUEUE ------------------------------
264  while (!metaQueue.empty()) {
265  ssMeta.write(metaQueue.front());
266  metaQueue.pop();
267  }
268  // Try appending a fake metadata to avoid problems at end of RTL/CoSim
269  ssMeta.write(UdpAppMeta(SockAddr(0,0), SockAddr(0,0)));
270 
271  //-- STEP-3: FEED DATA-LENGTH STREAM FROM QUEUE ---------------------------
272  while(!dlenQueue.empty()) {
273  ssDLen.write(dlenQueue.front());
274  dlenQueue.pop();
275  }
276  // Try appending a fake metadata to avoid problems at end of RTL/CoSim
277  ssDLen.write(UdpAppDLen(0));
278 
279  return NTS_OK;
280 } // End-of: createUdpTxTraffic()
281 
282 
297 bool readDatagramFromFile(const char *myName, SimUdpDatagram &appDatagram,
298  ifstream &ifsData, UdpAppMeta &udpAppMeta,
299  queue<UdpAppMeta> &udpMetaQueue, queue<UdpAppDLen> &updDLenQueue,
300  int &inpChunks, int &inpDgrms, int &inpBytes, char tbMode) {
301 
302  string stringBuffer;
303  vector<string> stringVector;
304  //SockAddr hostLsnSock;
305  //SockAddr fpgaSndSock;
306  UdpAppData udpAppData;
307  int currDgrmLenght=0;
308  bool endOfDgm=false;
309  bool rc;
310 
311  do {
312  //-- Read one line at a time from the input test DAT file
313  getline(ifsData, stringBuffer);
314  stringVector = myTokenizer(stringBuffer, ' ');
315  //-- Read the Host Listen Socket Address from line (if present)
316  SockAddr hostSockAddr;
317  rc = readHostSocketFromLine(hostSockAddr, stringBuffer);
318  if (rc) {
319  udpAppMeta.ip4DstAddr = hostSockAddr.addr;
320  udpAppMeta.udpDstPort = hostSockAddr.port;
321  if (DEBUG_LEVEL & TRACE_CGTF) {
322  printInfo(myName, "Read a new HOST socket address from DAT file:\n");
323  printSockAddr(myName, hostSockAddr);
324  }
325  }
326  //-- Read the Fpga Send Port from line (if present)
327  rc = readFpgaSndPortFromLine(udpAppMeta.udpSrcPort, stringBuffer);
328  if (rc) {
329  if (DEBUG_LEVEL & TRACE_CGTF) {
330  printInfo(myName, "Read a new FPGA send port from DAT file:\n");
331  printSockAddr(myName, SockAddr(udpAppMeta.ip4SrcAddr, udpAppMeta.udpSrcPort));
332  }
333  }
334  //-- Read an AxisChunk from line
335  rc = readAxisRawFromLine(udpAppData, stringBuffer);
336  if (rc) {
337  appDatagram.pushChunk(AxisUdp(udpAppData.getLE_TData(),
338  udpAppData.getLE_TKeep(),
339  udpAppData.getLE_TLast()));
340  inpChunks++;
341  currDgrmLenght += udpAppData.getLen();
342  inpBytes += udpAppData.getLen();
343  if (udpAppData.getLE_TLast() == 1) {
344  inpDgrms++;
345  endOfDgm = true;
346  udpMetaQueue.push(udpAppMeta);
347  if (tbMode == TX_DGRM_MODE) {
348  // In normal datagram mode, the length of the incoming frame
349  // is indicated by the value written in the 'DLen' interface.
350  updDLenQueue.push(currDgrmLenght);
351  }
352  else if (tbMode == TX_STRM_MODE) {
353  // Writing a zero length in the 'DLen' interface will turn
354  // the UOE into datagram streaming mode. This means that the
355  // end of the incoming data stream is solely indicated by
356  // the TLAST bit being set.
357  updDLenQueue.push(0);
358  }
359  else
360  printFatal(THIS_NAME, "Invalid TX test mode (%c). \n", tbMode);
361  }
362  }
363  } while ((ifsData.peek() != EOF) && (!endOfDgm));
364 
365  return endOfDgm;
366 }
367 
368 
382  string inpData_FileName,
383  string outData_GoldName,
384  queue<UdpAppMeta> &udpMetaQueue,
385  queue<UdpAppDLen> &updDLenQueue,
386  char tbMode)
387 {
388  const char *myName = concat3(THIS_NAME, "/", "CGTF");
389 
390  const Ip4Addr fpgaDefaultIp4Address = 0x0A0CC807; // 10.012.200.7
391  const UdpPort fpgaDefaultUdpLsnPort = 8803;
392  const UdpPort fpgaDefaultUdpSndPort = 32768+8803; // 41571
393  const Ip4Addr hostDefaultIp4Address = 0x0A0CC832; // 10.012.200.50
394  const UdpPort hostDefaultUdpLsnPort = fpgaDefaultUdpSndPort;
395  const UdpPort hostDefaultUdpSndPort = fpgaDefaultUdpLsnPort;
396 
397  ifstream ifsData;
398  ofstream ofsDataGold;
399 
400  char currPath[FILENAME_MAX];
401  int inpChunks=0, outChunks=0;
402  int inpDgrms=0, outPackets=0;
403  int inpBytes=0, outBytes=0;
404 
405  //-- STEP-1 : OPEN INPUT TEST FILE ----------------------------------------
406  if (not isDatFile(inpData_FileName)) {
407  printError(myName, "Cannot create golden file from input file \'%s\' because file is not of type \'.dat\'.\n",
408  inpData_FileName.c_str());
409  return(NTS_KO);
410  }
411  else {
412  ifsData.open(inpData_FileName.c_str());
413  if (!ifsData) {
414  getcwd(currPath, sizeof(currPath));
415  printError(myName, "Cannot open the file: %s \n\t (FYI - The current working directory is: %s) \n",
416  inpData_FileName.c_str(), currPath);
417  return(NTS_KO);
418  }
419  }
420 
421  //-- STEP-2 : OPEN THE OUTPUT GOLD FILE -----------------------------------
422  remove(outData_GoldName.c_str());
423  if (!ofsDataGold.is_open()) {
424  ofsDataGold.open (outData_GoldName.c_str(), ofstream::out);
425  if (!ofsDataGold) {
426  printFatal(THIS_NAME, "Could not open the output gold file \'%s\'. \n",
427  outData_GoldName.c_str());
428  }
429  }
430 
431  //-- STEP-3 : READ AND PARSE THE INPUT TEST FILE --------------------------
432  SockAddr hostLsnSock = SockAddr(hostDefaultIp4Address, hostDefaultUdpLsnPort);
433  SockAddr fpgaSndSock = SockAddr(fpgaDefaultIp4Address, fpgaDefaultUdpSndPort);
434  do {
435  SimUdpDatagram appDatagram(8);
436  UdpAppMeta udpAppMeta(SocketPair(fpgaSndSock, hostLsnSock));
437  bool endOfDgm=false;
438  //-- Retrieve one APP datagram from input DAT file (can be up to 2^16-1 bytes)
439  endOfDgm = readDatagramFromFile(myName, appDatagram, ifsData, udpAppMeta,
440  udpMetaQueue, updDLenQueue,
441  inpChunks, inpDgrms, inpBytes, tbMode);
442  //-- Set the header of the UDP datagram
443  appDatagram.setUdpSourcePort(udpAppMeta.udpSrcPort);
444  appDatagram.setUdpDestinationPort(udpAppMeta.udpDstPort);
445  appDatagram.setUdpLength(appDatagram.length());
446  appDatagram.setUdpChecksum(0);
447  if (endOfDgm) {
448  //-- Pull and save the datagram's header for re-use
449  SimUdpDatagram savedUdpHeader = appDatagram.pullHeader();
450  //-- Split the incoming APP datagram in one or multiple ETH frames
451  //-- The max. frame size is define by the UDP_MaximumDatagramSize)
452  while (appDatagram.length() > 0) {
453  //-- Build an IPv4 packet based on the split datagram
454  UdpLen splitLen;
455  SimIp4Packet ipPacket(20);
456  SimUdpDatagram udpHeader;
457  //-- Clone the saved UDP header
458  udpHeader.cloneHeader(savedUdpHeader);
459  //-- Adjust the datagram length of the header
460  if (appDatagram.length() <= UDP_MDS) {
461  splitLen = appDatagram.length();
462  }
463  else {
464  splitLen = UDP_MDS;
465  }
466  udpHeader.setUdpLength(UDP_HEADER_LEN+splitLen);
467  //-- Append the UDP header
468  ipPacket.addIpPayload(udpHeader, UDP_HEADER_LEN);
469  //-- Append the UDP data
470  ipPacket.addIpPayload(appDatagram, splitLen);
471  //-- Set the header of the IPv4 datagram
472  ipPacket.setIpSourceAddress(udpAppMeta.ip4SrcAddr);
473  ipPacket.setIpDestinationAddress(udpAppMeta.ip4DstAddr);
474  ipPacket.setIpTotalLength(ipPacket.length());
475  ipPacket.udpRecalculateChecksum();
476  // Write IPv4 packet to gold file
477  if (not ipPacket.writeToDatFile(ofsDataGold)) {
478  printError(myName, "Failed to write IP packet to GOLD file.\n");
479  return NTS_KO;
480  }
481  else {
482  outPackets += 1;
483  outChunks += ipPacket.size();
484  outBytes += ipPacket.length();
485  }
486  }
487  }
488 
489  } while(ifsData.peek() != EOF);
490 
491  //-- STEP-4: CLOSE FILES
492  ifsData.close();
493  ofsDataGold.close();
494 
495  //-- STEP-5: PRINT RESULTS
496  printInfo(myName, "Done with the creation of the golden file.\n");
497  printInfo(myName, "\tProcessed %5d chunks in %4d datagrams, for a total of %6d bytes.\n",
498  inpChunks, inpDgrms, inpBytes);
499  printInfo(myName, "\tGenerated %5d chunks in %4d packets, for a total of %6d bytes.\n",
500  outChunks, outPackets, outBytes);
501  return NTS_OK;
502 }
503 
504 
517  string inpData_FileName,
518  string outData_GoldName,
519  string outMeta_GoldName,
520  string outDLen_GoldName,
521  set<UdpPort> &udpPorts)
522 {
523  const char *myName = concat3(THIS_NAME, "/", "CGRF");
524 
525  ifstream ifsData;
526  ofstream ofsDataGold;
527  ofstream ofsMetaGold;
528  ofstream ofsDLenGold;
529 
530  char currPath[FILENAME_MAX];
531  int ret=NTS_OK;
532  int inpChunks=0, outChunks=0;
533  int inpPackets=0, outPackets=0;
534  int inpBytes=0, outBytes=0;
535 
536  //-- STEP-1 : OPEN INPUT TEST FILE ----------------------------------------
537  if (not isDatFile(inpData_FileName)) {
538  printError(myName, "Cannot create golden files from input file \'%s\' because file is not of type \'.dat\'.\n",
539  inpData_FileName.c_str());
540  return(NTS_KO);
541  }
542  else {
543  ifsData.open(inpData_FileName.c_str());
544  if (!ifsData) {
545  getcwd(currPath, sizeof(currPath));
546  printError(myName, "Cannot open the file: %s \n\t (FYI - The current working directory is: %s) \n",
547  inpData_FileName.c_str(), currPath);
548  return(NTS_KO);
549  }
550  }
551 
552  //-- STEP-2 : OPEN THE OUTPUT GOLD FILES ----------------------------------
553  remove(outData_GoldName.c_str());
554  remove(outMeta_GoldName.c_str());
555  remove(outDLen_GoldName.c_str());
556  if (!ofsDataGold.is_open()) {
557  ofsDataGold.open (outData_GoldName.c_str(), ofstream::out);
558  if (!ofsDataGold) {
559  printFatal(THIS_NAME, "Could not open the output gold file \'%s\'. \n",
560  outData_GoldName.c_str());
561  }
562  }
563  if (!ofsMetaGold.is_open()) {
564  ofsMetaGold.open (outMeta_GoldName.c_str(), ofstream::out);
565  if (!ofsMetaGold) {
566  printFatal(THIS_NAME, "Could not open the output gold file \'%s\'. \n",
567  outMeta_GoldName.c_str());
568  }
569  }
570  if (!ofsDLenGold.is_open()) {
571  ofsDLenGold.open (outDLen_GoldName.c_str(), ofstream::out);
572  if (!ofsDLenGold) {
573  printFatal(THIS_NAME, "Could not open the output gold file \'%s\'. \n",
574  outDLen_GoldName.c_str());
575  }
576  }
577 
578  //-- STEP-3 : READ AND PARSE THE INPUT UDP FILE ---------------------------
579  while ((ifsData.peek() != EOF) && (ret != NTS_KO)) {
580  SimIp4Packet ip4DataPkt;
581  AxisIp4 ip4RxData;
582  bool endOfPkt=false;
583  bool rc;
584  // Read one packet at a time from input file
585  while ((ifsData.peek() != EOF) && (!endOfPkt)) {
586  rc = readAxisRawFromFile(ip4RxData, ifsData);
587  if (rc) {
588  if (ip4RxData.isValid()) {
589  ip4DataPkt.pushChunk(ip4RxData);
590  if (ip4RxData.getLE_TLast()) {
591  inpPackets++;
592  endOfPkt = true;
593  }
594  }
595  else {
596  // We always abort the stream as this point by asserting
597  // 'tlast' and de-asserting 'tkeep'.
598  ip4DataPkt.pushChunk(AxisIp4(ip4RxData.getLE_TData(), 0x00, 1));
599  inpPackets++;
600  endOfPkt = true;
601  }
602  inpChunks++;
603  inpBytes += ip4RxData.getLen();
604  }
605  } // End-of: while ((ifsData.peek() != EOF) && (!endOfPkt))
606 
607  // Check consistency of the read packet
608  if (endOfPkt and rc) {
609  if (not ip4DataPkt.isWellFormed(myName)) {
610  printFatal(myName, "IP packet #%d is malformed!\n", inpPackets);
611  }
612  }
613  // Build the UDP datagram and corresponding metadata expected at the output of UOE
614  if (endOfPkt) {
615  Ip4Prot ip4Prot = ip4DataPkt.getIpProtocol();
616  if (ip4Prot != IP4_PROT_UDP) {
617  printWarn(myName, "IP packet #%d is dropped because it is not an UDP packet.\n", inpPackets);
618  printInfo(myName, " Received Ip4Prot = 0x%2.2X\n", ip4Prot.to_uchar());
619  printInfo(myName, " Expected Ip4Prot = 0x%2.2X\n", IP4_PROT_UDP);
620  continue;
621  }
622  // Retrieve the UDP datagram from the IPv4 Packet
623  SimUdpDatagram udpDatagram = ip4DataPkt.getUdpDatagram();
624  // Assess IPv4/UDP/Checksum field vs datagram checksum
625  UdpCsum udpHCsum = ip4DataPkt.getUdpChecksum();
626  UdpCsum calcCsum = udpDatagram.reCalculateUdpChecksum(ip4DataPkt.getIpSourceAddress(),
627  ip4DataPkt.getIpDestinationAddress());
628  if ((udpHCsum != 0) and (udpHCsum != calcCsum)) {
629  printWarn(myName, "IP packet #%d is dropped because the UDP checksum is invalid.\n", inpPackets);
630  printInfo(myName, " Received Checksum = 0x%2.2X\n", udpHCsum.to_ushort());
631  printInfo(myName, " Expected Checksum = 0x%2.2X\n", calcCsum.to_ushort());
632  continue;
633  }
634 
635  // Part-1: Create Metadata
636  SocketPair socketPair(SockAddr(ip4DataPkt.getIpSourceAddress(),
637  udpDatagram.getUdpSourcePort()),
638  SockAddr(ip4DataPkt.getIpDestinationAddress(),
639  udpDatagram.getUdpDestinationPort()));
640  if (udpDatagram.getUdpLength() > 8) {
641  writeSocketPairToFile(socketPair, ofsMetaGold);
642  if (DEBUG_LEVEL & TRACE_CGRF) {
643  printInfo(myName, "Writing new socket-pair to file:\n");
644  printSockPair(myName, socketPair);
645  }
646  }
647  // Part-2: Update the UDP container set
648  udpPorts.insert(ip4DataPkt.getUdpDestinationPort());
649 
650  // Part-3: Write UDP datagram payload to gold file
651  if (udpDatagram.writePayloadToDatFile(ofsDataGold) == false) {
652  printError(myName, "Failed to write UDP payload to GOLD file.\n");
653  ret = NTS_KO;
654  }
655  else {
656  outPackets += 1;
657  outChunks += udpDatagram.size();
658  outBytes += udpDatagram.length();
659  }
660 
661  // Part-4: Write datagram length to gold file
662  UdpAppDLen dgrmLen = udpDatagram.getUdpLength() - 8;
663  writeApUintToFile(dgrmLen, ofsDLenGold);
664  if (DEBUG_LEVEL & TRACE_CGRF) {
665  printInfo(myName, "Writing a new data-length to file:\n");
666  }
667 
668  } // End-of: if (endOfPkt)
669  } // End-of: while ((ifsData.peek() != EOF) && (ret != NTS_KO))
670 
671  //-- STEP-4: CLOSE FILES
672  ifsData.close();
673  ofsDataGold.close();
674  ofsMetaGold.close();
675 
676  //-- STEP-5: PRINT RESULTS
677  printInfo(myName, "Done with the creation of the golden files.\n");
678  printInfo(myName, "\tProcessed %5d chunks in %4d packets, for a total of %6d bytes.\n",
679  inpChunks, inpPackets, inpBytes);
680  printInfo(myName, "\tGenerated %5d chunks in %4d packets, for a total of %6d bytes.\n",
681  outChunks, outPackets, outBytes);
682  return(ret);
683 }
684 
685 #if HLS_VERSION != 2017
686 
711  //-- MMIO Interface
712  CmdBit piMMIO_En,
713  stream<ap_uint<16> > &soMMIO_DropCnt,
714  stream<StsBool> &soMMIO_Ready,
715  //-- IPRX / IP Rx / Data Interface
716  stream<AxisIp4> &siIPRX_Data,
717  //-- IPTX / IP Tx / Data Interface
718  stream<AxisIp4> &soIPTX_Data,
719  //-- UAIF / Control Port Interfaces
720  stream<UdpAppLsnReq> &siUAIF_LsnReq,
721  stream<UdpAppLsnRep> &soUAIF_LsnRep,
722  stream<UdpAppClsReq> &siUAIF_ClsReq,
723  stream<UdpAppClsRep> &soUAIF_ClsRep,
724  //-- UAIF / Rx Data Interfaces
725  stream<UdpAppData> &soUAIF_Data,
726  stream<UdpAppMeta> &soUAIF_Meta,
727  stream<UdpAppDLen> &soUAIF_DLen,
728  //-- UAIF / Tx Data Interfaces
729  stream<UdpAppData> &siUAIF_Data,
730  stream<UdpAppMeta> &siUAIF_Meta,
731  stream<UdpAppDLen> &siUAIF_DLen,
732  //-- ICMP / Message Data Interface (Port Unreachable)
733  stream<AxisIcmp> &soICMP_Data)
734 {
735  //-- LOCAL INPUT and OUTPUT STREAMS -------------------
736  static stream<AxisRaw> ssiIPRX_Data("ssiIPRX_Data");
737  static stream<AxisRaw> ssoIPTX_Data("ssoIPTX_Data");
738  static stream<AxisRaw> ssoICMP_Data("ssoICMP_Data");
739 
740  //-- INPUT STREAM CASTING -----------------------------
741  pAxisRawCast(siIPRX_Data, ssiIPRX_Data);
742 
743  //-- MAIN IPRX_TOP PROCESS ----------------------------
744  uoe_top(
745  piMMIO_En,
746  soMMIO_DropCnt,
747  soMMIO_Ready,
748  ssiIPRX_Data,
749  ssoIPTX_Data,
750  siUAIF_LsnReq,
751  soUAIF_LsnRep,
752  siUAIF_ClsReq,
753  soUAIF_ClsRep,
754  soUAIF_Data,
755  soUAIF_Meta,
756  soUAIF_DLen,
757  siUAIF_Data,
758  siUAIF_Meta,
759  siUAIF_DLen,
760  ssoICMP_Data);
761 
762  //-- OUTPUT STREAM CASTING ----------------------------
763  pAxisRawCast(ssoIPTX_Data, soIPTX_Data);
764  pAxisRawCast(ssoICMP_Data, soICMP_Data);
765  }
766 #endif
767 
768 
769 
793 int main(int argc, char *argv[]) {
794 
795  gSimCycCnt = 0;
796 
797  //------------------------------------------------------
798  //-- TESTBENCH LOCAL VARIABLES
799  //------------------------------------------------------
800  int nrErr = 0; // Tb error counter.
801  char tbMode = 'x'; // Indicates the TB testing mode.
802 
803  UdpPort portToOpen;
804  StsBool openReply;
805 
806  //------------------------------------------------------
807  //-- DUT SIGNAL INTERFACES and RELATED VARIABLEs
808  //------------------------------------------------------
809  CmdBit sMMIO_UOE_Enable = CMD_ENABLE;
810 
811  //------------------------------------------------------
812  //-- DUT STREAM INTERFACES and RELATED VARIABLEs
813  //------------------------------------------------------
814  stream<StsBool> ssUOE_MMIO_Ready ("ssUOE_MMIO_Ready");
815  stream<ap_uint<16> > ssUOE_MMIO_DropCnt ("ssUOE_MMIO_DropCnt");
816 
817  stream<AxisIp4> ssIPRX_UOE_Data ("ssIPRX_UOE_Data");
818  stream<AxisIp4> ssUOE_IPTX_Data ("ssUOE_IPTX_Data");
819 
820  stream<UdpPort> ssUAIF_UOE_LsnReq ("ssUAIF_UOE_LsnReq");
821  stream<StsBool> ssUOE_UAIF_LsnRep ("ssUOE_UAIF_LsnRep");
822  stream<UdpPort> ssUAIF_UOE_ClsReq ("ssUAIF_UOE_ClsReq");
823  stream<StsBool> ssUOE_UAIF_ClsRep ("ssUOE_UAIF_ClsRep");
824 
825  stream<AxisApp> ssUOE_UAIF_Data ("ssUOE_UAIF_Data");
826  stream<UdpAppMeta> ssUOE_UAIF_Meta ("ssUOE_UAIF_Meta");
827  stream<UdpAppDLen> ssUOE_UAIF_DLen ("ssUOE_UAIF_DLen");
828 
829  stream<AxisApp> ssUAIF_UOE_Data ("ssUAIF_UOE_Data");
830  stream<UdpAppMeta> ssUAIF_UOE_Meta ("ssUAIF_UOE_Meta");
831  stream<UdpAppDLen> ssUAIF_UOE_DLen ("ssUAIF-UOE_DLen");
832 
833  stream<AxisIcmp> ssUOE_ICMP_Data ("ssUOE_ICMP_Data");
834 
835  //------------------------------------------------------
836  //-- PARSING THE TESBENCH ARGUMENTS
837  //------------------------------------------------------
838  if (argc > 1) {
839  tbMode = *argv[1]; // Retrieve the TB testing mode.
840  }
841  switch (tbMode) {
842  case RX_MODE:
843  case TX_DGRM_MODE:
844  case TX_STRM_MODE:
845  case DROP_MODE:
846  if (argc < 3) {
847  printFatal(THIS_NAME, "Expected a minimum of 2 parameters with one of the following synopsis:\n \t\t mode(0) siIPRX_<Filename>.dat\n \t\t mode(1|2) siUAIF_<Filename>.dat\n");
848  }
849  break;
850  case BIDIR_MODE:
851  printFatal(THIS_NAME, "BIDIR_MODE - Not yet implemented...\n");
852  break;
853  case ECHO_MODE:
854  printFatal(THIS_NAME, "ECHO_MODE - Not yet implemented...\n");
855  break;
856  case OPEN_MODE:
857  if (argc > 2) {
858  printFatal(THIS_NAME, "Found more than one parameter.\n \t\t Expected a single parameter to be = '3' \n");
859  }
860  break;
861  default:
862  printFatal(THIS_NAME, "Expected a minimum of 2 or 3 parameters with one of the following synopsis:\n \t\t mode(0|3) siIPRX_<Filename>.dat\n \t\t mode(1) siUAIF_<Filename>.dat\n \t\t mode(2) siIPRX_<Filename>.dat siUAIF_<Filename>.dat\n");
863  }
864 
865  printInfo(THIS_NAME, "############################################################################\n");
866  printInfo(THIS_NAME, "## TESTBENCH 'test_uoe' STARTS HERE ##\n");
867  printInfo(THIS_NAME, "############################################################################\n\n");
868  printInfo(THIS_NAME, "This testbench will be executed with the following parameters: \n");
869  printInfo(THIS_NAME, "\t==> TB Mode = %c\n", *argv[1]);
870  for (int i=2; i<argc; i++) {
871  printInfo(THIS_NAME, "\t==> Param[%d] = %s\n", (i-1), argv[i]);
872  }
873  printf("\n\n");
874 
875  if (tbMode == OPEN_MODE) {
876  // Wait until UOE is ready (~2^16 cycles)
877  bool isReady = false;
878  do {
879  #if HLS_VERSION == 2017
880  uoe_top(
881  sMMIO_UOE_Enable,
882  ssUOE_MMIO_DropCnt,
883  ssUOE_MMIO_Ready,
884  ssIPRX_UOE_Data,
885  ssUOE_IPTX_Data,
886  ssUAIF_UOE_LsnReq,
887  ssUOE_UAIF_LsnRep,
888  ssUAIF_UOE_ClsReq,
889  ssUOE_UAIF_ClsRep,
890  ssUOE_UAIF_Data,
891  ssUOE_UAIF_Meta,
892  ssUOE_UAIF_DLen,
893  ssUAIF_UOE_Data,
894  ssUAIF_UOE_Meta,
895  ssUAIF_UOE_DLen,
896  ssUOE_ICMP_Data);
897  #else
898  uoe_top_wrap(
899  sMMIO_UOE_Enable,
900  ssUOE_MMIO_DropCnt,
901  ssUOE_MMIO_Ready,
902  ssIPRX_UOE_Data,
903  ssUOE_IPTX_Data,
904  ssUAIF_UOE_LsnReq,
905  ssUOE_UAIF_LsnRep,
906  ssUAIF_UOE_ClsReq,
907  ssUOE_UAIF_ClsRep,
908  ssUOE_UAIF_Data,
909  ssUOE_UAIF_Meta,
910  ssUOE_UAIF_DLen,
911  ssUAIF_UOE_Data,
912  ssUAIF_UOE_Meta,
913  ssUAIF_UOE_DLen,
914  ssUOE_ICMP_Data);
915  #endif
916  if (!ssUOE_MMIO_Ready.empty()) {
917  isReady = ssUOE_MMIO_Ready.read();
918  }
919  stepSim();
920  } while (!isReady);
921 
922  //---------------------------------------------------------------
923  //-- OPEN_MODE: Attempt to close a port that isn't open.
924  //-- Expected response is: Nothing.
925  //---------------------------------------------------------------
926  printInfo(THIS_NAME, "== OPEN-TEST #1 : Request to close a port that isn't open.\n");
927  ssUAIF_UOE_ClsReq.write(0x1532);
928  for (int i=0; i<10; ++i) {
929  #if HLS_VERSION == 2017
930  uoe_top(
931  sMMIO_UOE_Enable,
932  ssUOE_MMIO_DropCnt,
933  ssUOE_MMIO_Ready,
934  ssIPRX_UOE_Data,
935  ssUOE_IPTX_Data,
936  ssUAIF_UOE_LsnReq,
937  ssUOE_UAIF_LsnRep,
938  ssUAIF_UOE_ClsReq,
939  ssUOE_UAIF_ClsRep,
940  ssUOE_UAIF_Data,
941  ssUOE_UAIF_Meta,
942  ssUOE_UAIF_DLen,
943  ssUAIF_UOE_Data,
944  ssUAIF_UOE_Meta,
945  ssUAIF_UOE_DLen,
946  ssUOE_ICMP_Data);
947  #else
948  uoe_top_wrap(
949  sMMIO_UOE_Enable,
950  ssUOE_MMIO_DropCnt,
951  ssUOE_MMIO_Ready,
952  ssIPRX_UOE_Data,
953  ssUOE_IPTX_Data,
954  ssUAIF_UOE_LsnReq,
955  ssUOE_UAIF_LsnRep,
956  ssUAIF_UOE_ClsReq,
957  ssUOE_UAIF_ClsRep,
958  ssUOE_UAIF_Data,
959  ssUOE_UAIF_Meta,
960  ssUOE_UAIF_DLen,
961  ssUAIF_UOE_Data,
962  ssUAIF_UOE_Meta,
963  ssUAIF_UOE_DLen,
964  ssUOE_ICMP_Data);
965  #endif
966  if (!ssUOE_MMIO_Ready.empty()) {
967  isReady = ssUOE_MMIO_Ready.read();
968  }
969  //-- INCREMENT GLOBAL SIMULATION COUNTER
970  stepSim();
971  }
972  printInfo(THIS_NAME, "== OPEN-TEST #1 : Done.\n\n");
973 
974  //---------------------------------------------------------------
975  //-- OPEN_MODE: Attempt to open a new port.
976  //-- Expected response is: Port opened successfully
977  //---------------------------------------------------------------
978  printInfo(THIS_NAME, "== OPEN-TEST #2 : Request to open a port.\n");
979  portToOpen = 0x80;
980  printInfo(THIS_NAME, "Now - Trying to open port #%d.\n", portToOpen.to_int());
981  ssUAIF_UOE_LsnReq.write(0x80);
982  for (int i=0; i<3; ++i) {
983  #if HLS_VERSION == 2017
984  uoe_top(
985  sMMIO_UOE_Enable,
986  ssUOE_MMIO_DropCnt,
987  ssUOE_MMIO_Ready,
988  ssIPRX_UOE_Data,
989  ssUOE_IPTX_Data,
990  ssUAIF_UOE_LsnReq,
991  ssUOE_UAIF_LsnRep,
992  ssUAIF_UOE_ClsReq,
993  ssUOE_UAIF_ClsRep,
994  ssUOE_UAIF_Data,
995  ssUOE_UAIF_Meta,
996  ssUOE_UAIF_DLen,
997  ssUAIF_UOE_Data,
998  ssUAIF_UOE_Meta,
999  ssUAIF_UOE_DLen,
1000  ssUOE_ICMP_Data);
1001  #else
1002  uoe_top_wrap(
1003  sMMIO_UOE_Enable,
1004  ssUOE_MMIO_DropCnt,
1005  ssUOE_MMIO_Ready,
1006  ssIPRX_UOE_Data,
1007  ssUOE_IPTX_Data,
1008  ssUAIF_UOE_LsnReq,
1009  ssUOE_UAIF_LsnRep,
1010  ssUAIF_UOE_ClsReq,
1011  ssUOE_UAIF_ClsRep,
1012  ssUOE_UAIF_Data,
1013  ssUOE_UAIF_Meta,
1014  ssUOE_UAIF_DLen,
1015  ssUAIF_UOE_Data,
1016  ssUAIF_UOE_Meta,
1017  ssUAIF_UOE_DLen,
1018  ssUOE_ICMP_Data);
1019  #endif
1020  if (!ssUOE_MMIO_Ready.empty()) {
1021  isReady = ssUOE_MMIO_Ready.read();
1022  }
1023  //-- INCREMENT GLOBAL SIMULATION COUNTER
1024  stepSim();
1025  }
1026  openReply = false;
1027  if (!ssUOE_UAIF_LsnRep.empty()) {
1028  openReply = ssUOE_UAIF_LsnRep.read();
1029  if (openReply) {
1030  printInfo(THIS_NAME, "OK - Port #%d was successfully opened.\n", portToOpen.to_int());
1031  }
1032  else {
1033  printError(THIS_NAME, "KO - Failed to open port #%d.\n", portToOpen.to_int());
1034  nrErr++;
1035  }
1036  }
1037  else {
1038  printError(THIS_NAME, "NoReply - Failed to open port #%d.\n", portToOpen.to_int());
1039  nrErr++;
1040  }
1041  printInfo(THIS_NAME, "== OPEN-TEST #2 : Done.\n\n");
1042 
1043  //---------------------------------------------------------------
1044  //-- OPEN_MODE: Close an already open port
1045  //---------------------------------------------------------------
1046  printInfo(THIS_NAME, "== OPEN-TEST #3 : Request to close an opened port.\n");
1047  UdpPort portToClose = portToOpen;
1048  printInfo(THIS_NAME, "Now - Trying to close port #%d.\n", portToOpen.to_int());
1049  ssUAIF_UOE_ClsReq.write(portToClose);
1050  for (int i=0; i<10; ++i) {
1051  #if HLS_VERSION == 2017
1052  uoe_top(
1053  sMMIO_UOE_Enable,
1054  ssUOE_MMIO_DropCnt,
1055  ssUOE_MMIO_Ready,
1056  ssIPRX_UOE_Data,
1057  ssUOE_IPTX_Data,
1058  ssUAIF_UOE_LsnReq,
1059  ssUOE_UAIF_LsnRep,
1060  ssUAIF_UOE_ClsReq,
1061  ssUOE_UAIF_ClsRep,
1062  ssUOE_UAIF_Data,
1063  ssUOE_UAIF_Meta,
1064  ssUOE_UAIF_DLen,
1065  ssUAIF_UOE_Data,
1066  ssUAIF_UOE_Meta,
1067  ssUAIF_UOE_DLen,
1068  ssUOE_ICMP_Data);
1069  #else
1070  uoe_top_wrap(
1071  sMMIO_UOE_Enable,
1072  ssUOE_MMIO_DropCnt,
1073  ssUOE_MMIO_Ready,
1074  ssIPRX_UOE_Data,
1075  ssUOE_IPTX_Data,
1076  ssUAIF_UOE_LsnReq,
1077  ssUOE_UAIF_LsnRep,
1078  ssUAIF_UOE_ClsReq,
1079  ssUOE_UAIF_ClsRep,
1080  ssUOE_UAIF_Data,
1081  ssUOE_UAIF_Meta,
1082  ssUOE_UAIF_DLen,
1083  ssUAIF_UOE_Data,
1084  ssUAIF_UOE_Meta,
1085  ssUAIF_UOE_DLen,
1086  ssUOE_ICMP_Data);
1087  #endif
1088  if (!ssUOE_MMIO_Ready.empty()) {
1089  isReady = ssUOE_MMIO_Ready.read();
1090  }
1091  //-- INCREMENT GLOBAL SIMULATION COUNTER
1092  stepSim();
1093  }
1094  printInfo(THIS_NAME, "== OPEN-TEST #3 : Done.\n\n");
1095 
1096  //---------------------------------------------------------------
1097  //-- OPEN_MODE: Attempt to send traffic to a closed port.
1098  //-- Expected response is: Packet is dropped and an ICMP message
1099  // with'PORT_UNREAHCHABLE' is generated.
1100  //---------------------------------------------------------------
1101  printInfo(THIS_NAME, "== OPEN-TEST #4 : Send IPv4 traffic to a closed port.\n");
1102 
1103  const Ip4Addr fpgaDefaultIp4Address = 0x0A0CC807; // 10.012.200.7
1104  const Ip4Addr hostDefaultIp4Address = 0x0A0CC832; // 10.012.200.50
1105 
1106  //-- Build an UDP datagram over an IPv4 packet
1107  SimUdpDatagram udpDatagram(UDP_HEADER_LEN);
1108  AxisUdp udpChunk1(0xCAFFE000000CAFFE, 0xFF, 0);
1109  AxisUdp udpChunk2(0x000000FAB0000000, 0xFF, 1);
1110  udpDatagram.pushChunk(udpChunk1);
1111  udpDatagram.pushChunk(udpChunk2);
1112  udpDatagram.setUdpSourcePort(0xcafe);
1113  udpDatagram.setUdpDestinationPort(0xDEAD); // This must be a closed port
1114  udpDatagram.setUdpLength(udpDatagram.length());
1115  SimIp4Packet ipPacket(20);
1116  ipPacket.addIpPayload(udpDatagram);
1117  ipPacket.setIpSourceAddress(hostDefaultIp4Address);
1118  ipPacket.setIpDestinationAddress(hostDefaultIp4Address);
1119  ipPacket.setIpTotalLength(ipPacket.length());
1120  ipPacket.udpRecalculateChecksum();
1121  int pktSize = ipPacket.size();
1122  for (int i=0; i<pktSize; i++) {
1123  ssIPRX_UOE_Data.write(ipPacket.pullChunk());
1124  }
1125 
1126  int tbRun = ipPacket.size() + TB_GRACE_TIME;
1127  while (tbRun) {
1128  #if HLS_VERSION == 2017
1129  uoe_top(
1130  sMMIO_UOE_Enable,
1131  ssUOE_MMIO_DropCnt,
1132  ssUOE_MMIO_Ready,
1133  ssIPRX_UOE_Data,
1134  ssUOE_IPTX_Data,
1135  ssUAIF_UOE_LsnReq,
1136  ssUOE_UAIF_LsnRep,
1137  ssUAIF_UOE_ClsReq,
1138  ssUOE_UAIF_ClsRep,
1139  ssUOE_UAIF_Data,
1140  ssUOE_UAIF_Meta,
1141  ssUOE_UAIF_DLen,
1142  ssUAIF_UOE_Data,
1143  ssUAIF_UOE_Meta,
1144  ssUAIF_UOE_DLen,
1145  ssUOE_ICMP_Data);
1146  #else
1147  uoe_top_wrap(
1148  sMMIO_UOE_Enable,
1149  ssUOE_MMIO_DropCnt,
1150  ssUOE_MMIO_Ready,
1151  ssIPRX_UOE_Data,
1152  ssUOE_IPTX_Data,
1153  ssUAIF_UOE_LsnReq,
1154  ssUOE_UAIF_LsnRep,
1155  ssUAIF_UOE_ClsReq,
1156  ssUOE_UAIF_ClsRep,
1157  ssUOE_UAIF_Data,
1158  ssUOE_UAIF_Meta,
1159  ssUOE_UAIF_DLen,
1160  ssUAIF_UOE_Data,
1161  ssUAIF_UOE_Meta,
1162  ssUAIF_UOE_DLen,
1163  ssUOE_ICMP_Data);
1164  #endif
1165  if (!ssUOE_MMIO_Ready.empty()) {
1166  isReady = ssUOE_MMIO_Ready.read();
1167  }
1168  if (!ssUOE_UAIF_Data.empty()) {
1169  UdpAppData appData = ssUOE_UAIF_Data.read();
1170  printError(THIS_NAME, "Received unexpected data from [UOE]");
1171  printAxisRaw(THIS_NAME, appData);
1172  nrErr++;
1173  }
1174  tbRun--;
1175  stepSim();
1176  }
1177 
1178  // Drain the ICMP packet
1179  printInfo(THIS_NAME, "Draining the following ICMP packet from UOE:\n\t FYI, it should contain the IPv4 header and the UDP header.\n ");
1180 
1181  AxisIcmp axisChunk;
1182  int noChunks=0;
1183  while (!ssUOE_ICMP_Data.empty()) {
1184  ssUOE_ICMP_Data.read(axisChunk);
1185  printAxisRaw(THIS_NAME, "\t ICMP chunk = ", axisChunk);
1186  noChunks++;
1187  }
1188  if (noChunks != 4) {
1189  printError(THIS_NAME, "Wrong number of chunks issued by UOe. \n\t Expected 4 - Received %d. \n", noChunks);
1190  nrErr++;
1191  }
1192 
1193  if (nrErr == 0) {
1194  printInfo(THIS_NAME, "== OPEN-TEST #4 : Passed.\n\n");
1195  }
1196  else {
1197  printError(THIS_NAME, "== OPEN-TEST #4 : Failed. \n\n");
1198  }
1199  } // End-of: if (tbMode == OPEN_MODE)
1200 
1201  else if (tbMode == RX_MODE) {
1202  //---------------------------------------------------------------
1203  //-- RX_MODE: Read in the test input data for the IPRX side.
1204  //-- This run will start by opening all the required ports in
1205  //-- listen mode.
1206  //---------------------------------------------------------------
1207  printInfo(THIS_NAME, "== RX-TEST : Send IPv4 traffic to an opened port.\n");
1208 
1209  //-- CREATE DUT OUTPUT TRAFFIC AS STREAMS -------------------
1210  string ofsUAIF_Data_FileName = "../../../../test/simOutFiles/soUAIF_Data.dat";
1211  string ofsUAIF_Meta_FileName = "../../../../test/simOutFiles/soUAIF_Meta.dat";
1212  string ofsUAIF_DLen_FileName = "../../../../test/simOutFiles/soUAIF_DLen.dat";
1213  string ofsUAIF_Gold_Data_FileName = "../../../../test/simOutFiles/soUAIF_Gold_Data.dat";
1214  string ofsUAIF_Gold_Meta_FileName = "../../../../test/simOutFiles/soUAIF_Gold_Meta.dat";
1215  string ofsUAIF_Gold_DLen_FileName = "../../../../test/simOutFiles/soUAIF_Gold_DLen.dat";
1216  vector<string> ofNames;
1217  ofNames.push_back(ofsUAIF_Data_FileName);
1218  ofNames.push_back(ofsUAIF_Meta_FileName);
1219  ofNames.push_back(ofsUAIF_DLen_FileName);
1220  ofstream ofStreams[ofNames.size()]; // Stored in the same order
1221 
1222  //-- Remove all previous '.dat' files and open new files
1223  string rmCmd = "rm ../../../../test/simOutFiles/*.dat";
1224  system(rmCmd.c_str());
1225  for (int i = 0; i < ofNames.size(); i++) {
1226  if (not isDatFile(ofNames[i])) {
1227  printError(THIS_NAME, "File \'%s\' is not of type \'DAT\'.\n", ofNames[i].c_str());
1228  nrErr++;
1229  continue;
1230  }
1231  if (!ofStreams[i].is_open()) {
1232  ofStreams[i].open(ofNames[i].c_str(), ofstream::out);
1233  if (!ofStreams[i]) {
1234  printError(THIS_NAME, "Cannot open the file: \'%s\'.\n", ofNames[i].c_str());
1235  nrErr++;
1236  continue;
1237  }
1238  }
1239  }
1240 
1241  //-- Create golden Rx files
1242  set<UdpPort> udpDstPorts;
1243  if (createGoldenRxFiles(string(argv[2]), ofsUAIF_Gold_Data_FileName,
1244  ofsUAIF_Gold_Meta_FileName, ofsUAIF_Gold_DLen_FileName, udpDstPorts) != NTS_OK) {
1245  printError(THIS_NAME, "Failed to create golden Rx files. \n");
1246  nrErr++;
1247  }
1248 
1249  // Wait until UOE is ready (~2^16 cycles)
1250  bool isReady = false;
1251  do {
1252  #if HLS_VERSION == 2017
1253  uoe_top(
1254  sMMIO_UOE_Enable,
1255  ssUOE_MMIO_DropCnt,
1256  ssUOE_MMIO_Ready,
1257  ssIPRX_UOE_Data,
1258  ssUOE_IPTX_Data,
1259  ssUAIF_UOE_LsnReq,
1260  ssUOE_UAIF_LsnRep,
1261  ssUAIF_UOE_ClsReq,
1262  ssUOE_UAIF_ClsRep,
1263  ssUOE_UAIF_Data,
1264  ssUOE_UAIF_Meta,
1265  ssUOE_UAIF_DLen,
1266  ssUAIF_UOE_Data,
1267  ssUAIF_UOE_Meta,
1268  ssUAIF_UOE_DLen,
1269  ssUOE_ICMP_Data);
1270  #else
1271  uoe_top_wrap(
1272  sMMIO_UOE_Enable,
1273  ssUOE_MMIO_DropCnt,
1274  ssUOE_MMIO_Ready,
1275  ssIPRX_UOE_Data,
1276  ssUOE_IPTX_Data,
1277  ssUAIF_UOE_LsnReq,
1278  ssUOE_UAIF_LsnRep,
1279  ssUAIF_UOE_ClsReq,
1280  ssUOE_UAIF_ClsRep,
1281  ssUOE_UAIF_Data,
1282  ssUOE_UAIF_Meta,
1283  ssUOE_UAIF_DLen,
1284  ssUAIF_UOE_Data,
1285  ssUAIF_UOE_Meta,
1286  ssUAIF_UOE_DLen,
1287  ssUOE_ICMP_Data);
1288  #endif
1289  if (!ssUOE_MMIO_Ready.empty()) {
1290  isReady = ssUOE_MMIO_Ready.read();
1291  }
1292  stepSim();
1293  } while (!isReady);
1294 
1295  // Request to open a set of UDP ports in listen mode
1296  for (set<UdpPort>::iterator it=udpDstPorts.begin(); it!=udpDstPorts.end(); ++it) {
1297  portToOpen = *it;
1298  ssUAIF_UOE_LsnReq.write(portToOpen);
1299  for (int i=0; i<2; ++i) {
1300  #if HLS_VERSION == 2017
1301  uoe_top(
1302  sMMIO_UOE_Enable,
1303  ssUOE_MMIO_DropCnt,
1304  ssUOE_MMIO_Ready,
1305  ssIPRX_UOE_Data,
1306  ssUOE_IPTX_Data,
1307  ssUAIF_UOE_LsnReq,
1308  ssUOE_UAIF_LsnRep,
1309  ssUAIF_UOE_ClsReq,
1310  ssUOE_UAIF_ClsRep,
1311  ssUOE_UAIF_Data,
1312  ssUOE_UAIF_Meta,
1313  ssUOE_UAIF_DLen,
1314  ssUAIF_UOE_Data,
1315  ssUAIF_UOE_Meta,
1316  ssUAIF_UOE_DLen,
1317  ssUOE_ICMP_Data);
1318  #else
1319  uoe_top_wrap(
1320  sMMIO_UOE_Enable,
1321  ssUOE_MMIO_DropCnt,
1322  ssUOE_MMIO_Ready,
1323  ssIPRX_UOE_Data,
1324  ssUOE_IPTX_Data,
1325  ssUAIF_UOE_LsnReq,
1326  ssUOE_UAIF_LsnRep,
1327  ssUAIF_UOE_ClsReq,
1328  ssUOE_UAIF_ClsRep,
1329  ssUOE_UAIF_Data,
1330  ssUOE_UAIF_Meta,
1331  ssUOE_UAIF_DLen,
1332  ssUAIF_UOE_Data,
1333  ssUAIF_UOE_Meta,
1334  ssUAIF_UOE_DLen,
1335  ssUOE_ICMP_Data);
1336  #endif
1337  stepSim();
1338  }
1339  }
1340  // Check that port were successfully opened
1341  for (set<UdpPort>::iterator it=udpDstPorts.begin(); it!=udpDstPorts.end(); ++it) {
1342  portToOpen = *it;
1343  openReply = false;
1344  if (!ssUOE_UAIF_LsnRep.empty()) {
1345  openReply = ssUOE_UAIF_LsnRep.read();
1346  if (not openReply) {
1347  printError(THIS_NAME, "KO - Failed to open port #%d (0x%4.4X).\n",
1348  portToOpen.to_int(), portToOpen.to_int());
1349  }
1350  }
1351  else {
1352  printError(THIS_NAME, "NoReply - Failed to open port #%d (0x%4.4X).\n",
1353  portToOpen.to_int(), portToOpen.to_int());
1354  nrErr++;
1355  }
1356  }
1357 
1358  //-- CREATE IPRX->UOE INPUT TRAFFIC AS A STREAM -----------------------
1359  int nrIPRX_UOE_Chunks = 0;
1360  int nrIPRX_UOE_Packets = 0;
1361  int nrIPRX_UOE_Bytes = 0;
1362  if (feedAxisFromFile(ssIPRX_UOE_Data, "ssIPRX_UOE_Data", string(argv[2]),
1363  nrIPRX_UOE_Chunks, nrIPRX_UOE_Packets, nrIPRX_UOE_Bytes)) {
1364  printInfo(THIS_NAME, "Done with the creation of the Rx input traffic as streams:\n");
1365  printInfo(THIS_NAME, "\tGenerated %d chunks in %d IP packets, for a total of %d bytes.\n\n",
1366  nrIPRX_UOE_Chunks, nrIPRX_UOE_Packets, nrIPRX_UOE_Bytes);
1367  }
1368  else {
1369  printFatal(THIS_NAME, "Failed to create traffic as input stream. \n");
1370  nrErr++;
1371  }
1372 
1373  //-- RUN SIMULATION FOR IPRX->UOE INPUT TRAFFIC -----------------------
1374  int tbRun = (nrErr == 0) ? (nrIPRX_UOE_Chunks + TB_GRACE_TIME) : 0;
1375  while (tbRun) {
1376  #if HLS_VERSION == 2017
1377  uoe_top(
1378  sMMIO_UOE_Enable,
1379  ssUOE_MMIO_DropCnt,
1380  ssUOE_MMIO_Ready,
1381  ssIPRX_UOE_Data,
1382  ssUOE_IPTX_Data,
1383  ssUAIF_UOE_LsnReq,
1384  ssUOE_UAIF_LsnRep,
1385  ssUAIF_UOE_ClsReq,
1386  ssUOE_UAIF_ClsRep,
1387  ssUOE_UAIF_Data,
1388  ssUOE_UAIF_Meta,
1389  ssUOE_UAIF_DLen,
1390  ssUAIF_UOE_Data,
1391  ssUAIF_UOE_Meta,
1392  ssUAIF_UOE_DLen,
1393  ssUOE_ICMP_Data);
1394  #else
1395  uoe_top_wrap(
1396  sMMIO_UOE_Enable,
1397  ssUOE_MMIO_DropCnt,
1398  ssUOE_MMIO_Ready,
1399  ssIPRX_UOE_Data,
1400  ssUOE_IPTX_Data,
1401  ssUAIF_UOE_LsnReq,
1402  ssUOE_UAIF_LsnRep,
1403  ssUAIF_UOE_ClsReq,
1404  ssUOE_UAIF_ClsRep,
1405  ssUOE_UAIF_Data,
1406  ssUOE_UAIF_Meta,
1407  ssUOE_UAIF_DLen,
1408  ssUAIF_UOE_Data,
1409  ssUAIF_UOE_Meta,
1410  ssUAIF_UOE_DLen,
1411  ssUOE_ICMP_Data);
1412  #endif
1413  if (!ssUOE_MMIO_Ready.empty()) {
1414  isReady = ssUOE_MMIO_Ready.read();
1415  }
1416  tbRun--;
1417  stepSim();
1418  }
1419 
1420  printInfo(THIS_NAME, "############################################################################\n");
1421  printInfo(THIS_NAME, "## TESTBENCH 'test_uoe' ENDS HERE ##\n");
1422  printInfo(THIS_NAME, "############################################################################\n");
1423  stepSim();
1424 
1425  //-- DRAIN UOE-->UAIF DATA OUTPUT STREAM ------------------------------
1426  int nrUOE_UAIF_DataChunks=0, nrUOE_UAIF_DataGrams=0, nrUOE_UAIF_DataBytes=0;
1427  if (not drainAxisToFile(ssUOE_UAIF_Data, "ssUOE_UAIF_Data",
1428  ofNames[0], nrUOE_UAIF_DataChunks, nrUOE_UAIF_DataGrams, nrUOE_UAIF_DataBytes)) {
1429  printError(THIS_NAME, "Failed to drain UOE-to-UAIF data traffic from DUT. \n");
1430  nrErr++;
1431  }
1432  else {
1433  printInfo(THIS_NAME, "Done with the draining of the UOE-to-UAIF data traffic:\n");
1434  printInfo(THIS_NAME, "\tReceived %d chunks in %d datagrams, for a total of %d bytes.\n\n",
1435  nrUOE_UAIF_DataChunks, nrUOE_UAIF_DataGrams, nrUOE_UAIF_DataBytes);
1436  }
1437  //-- DRAIN UOE-->UAIF META OUTPUT STREAM -------------------------------
1438  int nrUOE_UAIF_MetaChunks=0, nrUOE_UAIF_MetaGrams=0, nrUOE_UAIF_MetaBytes=0;
1439  if (not drainUdpMetaStreamToFile(ssUOE_UAIF_Meta, "ssUOE_UAIF_Meta",
1440  ofNames[1], nrUOE_UAIF_MetaChunks, nrUOE_UAIF_MetaGrams, nrUOE_UAIF_MetaBytes)) {
1441  printError(THIS_NAME, "Failed to drain UOE-to-UAIF meta traffic from DUT. \n");
1442  nrErr++;
1443  }
1444  //-- DRAIN UOE-->UAIF DLEN OUTPUT STREAM -------------------------------
1445  int nrUOE_UAIF_DLenChunks=0, nrUOE_UAIF_DLenGrams=0, nrUOE_UAIF_DLenBytes=0;
1446  if (not drainUdpDLenStreamToFile(ssUOE_UAIF_DLen, "ssUOE_UAIF_DLen",
1447  ofNames[2], nrUOE_UAIF_DLenChunks, nrUOE_UAIF_DLenGrams, nrUOE_UAIF_DLenBytes)) {
1448  printError(THIS_NAME, "Failed to drain UOE-to-UAIF dlen traffic from DUT. \n");
1449  nrErr++;
1450  }
1451  //-- DRAIN UOE-->MMIO RX DROP COUNTER STREAM ---------------------------
1452  if (not drainMmioDropCounter(ssUOE_MMIO_DropCnt, "ssUOE_MMIO_DropCnt")) {
1453  printError(THIS_NAME, "Failed to drain UOE-to-MMIO drop counter from DUT. \n");
1454  nrErr++;
1455  }
1456 
1457  //---------------------------------------------------------------
1458  //-- COMPARE OUTPUT DAT and GOLD STREAMS
1459  //---------------------------------------------------------------
1460  int res = system(("diff --brief -w " + \
1461  std::string(ofsUAIF_Data_FileName) + " " + \
1462  std::string(ofsUAIF_Gold_Data_FileName) + " ").c_str());
1463  if (res) {
1464  printError(THIS_NAME, "File \'%s\' does not match \'%s\'.\n", \
1465  ofsUAIF_Data_FileName.c_str(), ofsUAIF_Gold_Data_FileName.c_str());
1466  nrErr += 1;
1467  }
1468  res = system(("diff --brief -w " + \
1469  std::string(ofsUAIF_Meta_FileName) + " " + \
1470  std::string(ofsUAIF_Gold_Meta_FileName) + " ").c_str());
1471  if (res) {
1472  printError(THIS_NAME, "File \'%s\' does not match \'%s\'.\n", \
1473  ofsUAIF_Meta_FileName.c_str(), ofsUAIF_Gold_Meta_FileName.c_str());
1474  nrErr += 1;
1475  }
1476  res = system(("diff --brief -w " + \
1477  std::string(ofsUAIF_DLen_FileName) + " " + \
1478  std::string(ofsUAIF_Gold_DLen_FileName) + " ").c_str());
1479  if (res) {
1480  printError(THIS_NAME, "File \'%s\' does not match \'%s\'.\n", \
1481  ofsUAIF_DLen_FileName.c_str(), ofsUAIF_Gold_DLen_FileName.c_str());
1482  nrErr += 1;
1483  }
1484 
1485  } // End-of: if (tbMode == RX_MODE)
1486 
1487  else if ((tbMode == TX_DGRM_MODE) or (tbMode == TX_STRM_MODE)) {
1488  //---------------------------------------------------------------
1489  //-- TX_MODE: Read in the test input data for the UAIF side.
1490  //---------------------------------------------------------------
1491  printInfo(THIS_NAME, "== TX-TEST : Send UDP datagram traffic to DUT.\n");
1492 
1493  ofstream ofsIPTX_Data;
1494  string ofsIPTX_Data_FileName = "../../../../test/simOutFiles/soIPTX_Data.dat";
1495  string ofsIPTX_Gold_FileName = "../../../../test/simOutFiles/soIPTX_Gold.dat";
1496 
1497  //-- Remove all previous 'dat' files and open a new file
1498  if (not isDatFile(ofsIPTX_Data_FileName)) {
1499  printFatal(THIS_NAME, "File \'%s\' is not of type \'DAT\'.\n", ofsIPTX_Data_FileName.c_str());
1500  }
1501  else {
1502  string rmCmd = "rm ../../../../test/simOutFiles/*.dat";
1503  system(rmCmd.c_str());
1504  if (!ofsIPTX_Data.is_open()) {
1505  ofsIPTX_Data.open(ofsIPTX_Data_FileName.c_str(), ofstream::out);
1506  if (!ofsIPTX_Data) {
1507  printError(THIS_NAME, "Cannot open the file: \'%s\'.\n", ofsIPTX_Data_FileName.c_str());
1508  nrErr++;
1509  }
1510  }
1511  }
1512 
1513  //-- CREATE THE GOLDEN UOE->IPTX OUTPUT FILES -------------------------
1514  queue<UdpAppMeta> udpAppMeta;
1515  queue<UdpAppDLen> updDataLengths;
1516  if (not createGoldenTxFiles(string(argv[2]), ofsIPTX_Gold_FileName,
1517  udpAppMeta, updDataLengths, tbMode)) {
1518  printFatal(THIS_NAME, "Failed to create golden UOE->IPTX file. \n");
1519  }
1520 
1521  //-- CREATE THE UAIF->UOE INPUT {DATA,META,DLEN} AS STREAMS -----------
1522  int nrUAIF_UOE_Chunks=0;
1523  if (not createUdpTxTraffic(ssUAIF_UOE_Data, "ssUAIF_UOE_Data",
1524  ssUAIF_UOE_Meta, "ssUAIF_UOE_Meta",
1525  ssUAIF_UOE_DLen, "ssUAIF_UOE_DLen",
1526  string(argv[2]),
1527  udpAppMeta,
1528  updDataLengths,
1529  nrUAIF_UOE_Chunks)) {
1530  printFatal(THIS_NAME, "Failed to create the UAIF->UOE traffic as streams.\n");
1531  }
1532 
1533  //-- RUN SIMULATION ---------------------------------------------------
1534  int tbRun = (nrErr == 0) ? (nrUAIF_UOE_Chunks + TB_GRACE_TIME) : 0;
1535  while (tbRun) {
1536  #if HLS_VERSION == 2017
1537  uoe_top(
1538  sMMIO_UOE_Enable,
1539  ssUOE_MMIO_DropCnt,
1540  ssUOE_MMIO_Ready,
1541  ssIPRX_UOE_Data,
1542  ssUOE_IPTX_Data,
1543  ssUAIF_UOE_LsnReq,
1544  ssUOE_UAIF_LsnRep,
1545  ssUAIF_UOE_ClsReq,
1546  ssUOE_UAIF_ClsRep,
1547  ssUOE_UAIF_Data,
1548  ssUOE_UAIF_Meta,
1549  ssUOE_UAIF_DLen,
1550  ssUAIF_UOE_Data,
1551  ssUAIF_UOE_Meta,
1552  ssUAIF_UOE_DLen,
1553  ssUOE_ICMP_Data);
1554  #else
1555  uoe_top_wrap(
1556  sMMIO_UOE_Enable,
1557  ssUOE_MMIO_DropCnt,
1558  ssUOE_MMIO_Ready,
1559  ssIPRX_UOE_Data,
1560  ssUOE_IPTX_Data,
1561  ssUAIF_UOE_LsnReq,
1562  ssUOE_UAIF_LsnRep,
1563  ssUAIF_UOE_ClsReq,
1564  ssUOE_UAIF_ClsRep,
1565  ssUOE_UAIF_Data,
1566  ssUOE_UAIF_Meta,
1567  ssUOE_UAIF_DLen,
1568  ssUAIF_UOE_Data,
1569  ssUAIF_UOE_Meta,
1570  ssUAIF_UOE_DLen,
1571  ssUOE_ICMP_Data);
1572  #endif
1573  tbRun--;
1574  stepSim();
1575  }
1576 
1577  printInfo(THIS_NAME, "############################################################################\n");
1578  printInfo(THIS_NAME, "## TESTBENCH 'test_uoe' ENDS HERE ##\n");
1579  printInfo(THIS_NAME, "############################################################################\n");
1580  stepSim();
1581 
1582  //-- DRAIN UOE-->IPTX DATA OUTPUT STREAM -----------------------------
1583  int nrUOE_IPTX_Chunks=0, nrUOE_IPTX_Packets=0, nrUOE_IPTX_Bytes=0;
1584  if (not drainAxisToFile(ssUOE_IPTX_Data, "ssUOE_IPTX_Data",
1585  ofsIPTX_Data_FileName, nrUOE_IPTX_Chunks, nrUOE_IPTX_Packets, nrUOE_IPTX_Bytes)) {
1586  printError(THIS_NAME, "Failed to drain UOE-to-IPTX data traffic from DUT. \n");
1587  nrErr++;
1588  }
1589  else {
1590  printInfo(THIS_NAME, "Done with the draining of the UOE-to-IPTX data traffic:\n");
1591  printInfo(THIS_NAME, "\tReceived %d chunks in %d packets, for a total of %d bytes.\n\n",
1592  nrUOE_IPTX_Chunks, nrUOE_IPTX_Packets, nrUOE_IPTX_Bytes);
1593  }
1594 
1595  //---------------------------------------------------------------
1596  //-- COMPARE OUTPUT DAT and GOLD STREAMS
1597  //---------------------------------------------------------------
1598  int res = myDiffTwoFiles(std::string(ofsIPTX_Data_FileName),
1599  std::string(ofsIPTX_Gold_FileName));
1600  if (res) {
1601  printError(THIS_NAME, "File \'%s\' does not match \'%s\'.\n", \
1602  ofsIPTX_Data_FileName.c_str(), ofsIPTX_Gold_FileName.c_str());
1603  nrErr += 1;
1604  }
1605 
1606  } // End-of: if (tbMode == TX_MODE)
1607 
1608  else if (tbMode == DROP_MODE) {
1609 
1610  //---------------------------------------------------------------
1611  //-- DROP_MODE: This run will feed the UOE with input data for
1612  //-- the IPRX side but will expect all the traffic to be
1613  //-- dropped because the UOE is disabled or because the ROLE
1614  //-- does not drain the UOE.
1615  //---------------------------------------------------------------
1616  if (0) {
1617  printInfo(THIS_NAME, "== DROP-MODE : Fill up UOE with IPv4 traffic and expect packets to be dropped.\n");
1618  }
1619  else {
1620  //-- DE-ASSERT THE UOE ENABLE SIGNAL
1621  printInfo(THIS_NAME, "== DISABLE-MODE : Send IPv4 traffic to the disabled UOE.\n");
1622  sMMIO_UOE_Enable = CMD_DISABLE;
1623  }
1624 
1625  //-- CREATE DUT OUTPUT TRAFFIC AS STREAMS -------------------
1626  string ofsUAIF_Data_FileName = "../../../../test/simOutFiles/soUAIF_Data.dat";
1627  string ofsUAIF_Meta_FileName = "../../../../test/simOutFiles/soUAIF_Meta.dat";
1628  string ofsUAIF_DLen_FileName = "../../../../test/simOutFiles/soUAIF_DLen.dat";
1629  string ofsUAIF_Gold_Data_FileName = "../../../../test/simOutFiles/soUAIF_Gold_Data.dat";
1630  string ofsUAIF_Gold_Meta_FileName = "../../../../test/simOutFiles/soUAIF_Gold_Meta.dat";
1631  string ofsUAIF_Gold_DLen_FileName = "../../../../test/simOutFiles/soUAIF_Gold_DLen.dat";
1632  vector<string> ofNames;
1633  ofNames.push_back(ofsUAIF_Data_FileName);
1634  ofNames.push_back(ofsUAIF_Meta_FileName);
1635  ofNames.push_back(ofsUAIF_DLen_FileName);
1636  ofstream ofStreams[ofNames.size()]; // Stored in the same order
1637 
1638  //-- Remove all previous '.dat' files and open new files
1639  string rmCmd = "rm ../../../../test/simOutFiles/*.dat";
1640  system(rmCmd.c_str());
1641  for (int i = 0; i < ofNames.size(); i++) {
1642  if (not isDatFile(ofNames[i])) {
1643  printError(THIS_NAME, "File \'%s\' is not of type \'DAT\'.\n", ofNames[i].c_str());
1644  nrErr++;
1645  continue;
1646  }
1647  if (!ofStreams[i].is_open()) {
1648  ofStreams[i].open(ofNames[i].c_str(), ofstream::out);
1649  if (!ofStreams[i]) {
1650  printError(THIS_NAME, "Cannot open the file: \'%s\'.\n", ofNames[i].c_str());
1651  nrErr++;
1652  continue;
1653  }
1654  }
1655  }
1656 
1657  //-- Create empty golden Rx files
1658  string touchCmd;
1659  touchCmd = "touch " + ofsUAIF_Gold_Data_FileName;
1660  system(touchCmd.c_str());
1661  touchCmd = "touch " + ofsUAIF_Gold_Meta_FileName;
1662  system(touchCmd.c_str());
1663  touchCmd = "touch " + ofsUAIF_Gold_DLen_FileName;
1664  system(touchCmd.c_str());
1665 
1666  //-- CREATE IPRX->UOE INPUT TRAFFIC AS A STREAM -----------------------
1667  int nrIPRX_UOE_Chunks = 0;
1668  int nrIPRX_UOE_Packets = 0;
1669  int nrIPRX_UOE_Bytes = 0;
1670  if (feedAxisFromFile(ssIPRX_UOE_Data, "ssIPRX_UOE_Data", string(argv[2]),
1671  nrIPRX_UOE_Chunks, nrIPRX_UOE_Packets, nrIPRX_UOE_Bytes)) {
1672  printInfo(THIS_NAME, "Done with the creation of the Rx input traffic as streams:\n");
1673  printInfo(THIS_NAME, "\tGenerated %d chunks in %d IP packets, for a total of %d bytes.\n\n",
1674  nrIPRX_UOE_Chunks, nrIPRX_UOE_Packets, nrIPRX_UOE_Bytes);
1675  }
1676  else {
1677  printFatal(THIS_NAME, "Failed to create traffic as input stream. \n");
1678  nrErr++;
1679  }
1680 
1681  //-- RUN SIMULATION FOR IPRX->UOE INPUT TRAFFIC -----------------------
1682  int tbRun = (nrErr == 0) ? (nrIPRX_UOE_Chunks + TB_GRACE_TIME) : 0;
1683  while (tbRun) {
1684  #if HLS_VERSION == 2017
1685  uoe_top(
1686  sMMIO_UOE_Enable,
1687  ssUOE_MMIO_DropCnt,
1688  ssUOE_MMIO_Ready,
1689  ssIPRX_UOE_Data,
1690  ssUOE_IPTX_Data,
1691  ssUAIF_UOE_LsnReq,
1692  ssUOE_UAIF_LsnRep,
1693  ssUAIF_UOE_ClsReq,
1694  ssUOE_UAIF_ClsRep,
1695  ssUOE_UAIF_Data,
1696  ssUOE_UAIF_Meta,
1697  ssUOE_UAIF_DLen,
1698  ssUAIF_UOE_Data,
1699  ssUAIF_UOE_Meta,
1700  ssUAIF_UOE_DLen,
1701  ssUOE_ICMP_Data);
1702  #else
1703  uoe_top_wrap(
1704  sMMIO_UOE_Enable,
1705  ssUOE_MMIO_DropCnt,
1706  ssUOE_MMIO_Ready,
1707  ssIPRX_UOE_Data,
1708  ssUOE_IPTX_Data,
1709  ssUAIF_UOE_LsnReq,
1710  ssUOE_UAIF_LsnRep,
1711  ssUAIF_UOE_ClsReq,
1712  ssUOE_UAIF_ClsRep,
1713  ssUOE_UAIF_Data,
1714  ssUOE_UAIF_Meta,
1715  ssUOE_UAIF_DLen,
1716  ssUAIF_UOE_Data,
1717  ssUAIF_UOE_Meta,
1718  ssUAIF_UOE_DLen,
1719  ssUOE_ICMP_Data);
1720  #endif
1721  if (!ssUOE_MMIO_Ready.empty()) {
1722  ssUOE_MMIO_Ready.read();
1723  }
1724  tbRun--;
1725  stepSim();
1726  }
1727 
1728  printInfo(THIS_NAME, "############################################################################\n");
1729  printInfo(THIS_NAME, "## TESTBENCH 'test_uoe' ENDS HERE ##\n");
1730  printInfo(THIS_NAME, "############################################################################\n");
1731  stepSim();
1732 
1733  //-- DRAIN UOE-->MMIO RX DROP COUNTER STREAM ---------------------------
1734  if (not drainMmioDropCounter(ssUOE_MMIO_DropCnt, "ssUOE_MMIO_DropCnt")) {
1735  printError(THIS_NAME, "Failed to drain UOE-to-MMIO drop counter from DUT. \n");
1736  nrErr++;
1737  }
1738 
1739  //---------------------------------------------------------------
1740  //-- COMPARE OUTPUT DAT and GOLD STREAMS
1741  //---------------------------------------------------------------
1742  int res = system(("diff --brief -w " + \
1743  std::string(ofsUAIF_Data_FileName) + " " + \
1744  std::string(ofsUAIF_Gold_Data_FileName) + " ").c_str());
1745  if (res) {
1746  printError(THIS_NAME, "File \'%s\' does not match \'%s\'.\n", \
1747  ofsUAIF_Data_FileName.c_str(), ofsUAIF_Gold_Data_FileName.c_str());
1748  nrErr += 1;
1749  }
1750  res = system(("diff --brief -w " + \
1751  std::string(ofsUAIF_Meta_FileName) + " " + \
1752  std::string(ofsUAIF_Gold_Meta_FileName) + " ").c_str());
1753  if (res) {
1754  printError(THIS_NAME, "File \'%s\' does not match \'%s\'.\n", \
1755  ofsUAIF_Meta_FileName.c_str(), ofsUAIF_Gold_Meta_FileName.c_str());
1756  nrErr += 1;
1757  }
1758  res = system(("diff --brief -w " + \
1759  std::string(ofsUAIF_DLen_FileName) + " " + \
1760  std::string(ofsUAIF_Gold_DLen_FileName) + " ").c_str());
1761  if (res) {
1762  printError(THIS_NAME, "File \'%s\' does not match \'%s\'.\n", \
1763  ofsUAIF_DLen_FileName.c_str(), ofsUAIF_Gold_DLen_FileName.c_str());
1764  nrErr += 1;
1765  }
1766  } // End-of: if (tbMode == DROP_MODE)
1767 
1768  else {
1769  nrErr = 1;
1770  printFatal(THIS_NAME, "The test mode (%c) is not yet implemented...\n", tbMode);
1771  }
1772 
1773  //---------------------------------------------------------------
1774  //-- PRINT TESTBENCH STATUS
1775  //---------------------------------------------------------------
1776  printf("\n\n");
1777  printInfo(THIS_NAME, "This testbench was executed with the following parameters: \n");
1778  printInfo(THIS_NAME, "\t==> TB Mode = %c\n", *argv[1]);
1779  for (int i=2; i<argc; i++) {
1780  printInfo(THIS_NAME, "\t==> Param[%d] = %s\n", (i-1), argv[i]);
1781  }
1782 
1783  if (nrErr) {
1784  printError(THIS_NAME, "###########################################################\n");
1785  printError(THIS_NAME, "#### TEST BENCH FAILED : TOTAL NUMBER OF ERROR(S) = %2d ####\n", nrErr);
1786  printError(THIS_NAME, "###########################################################\n\n");
1787 
1788  printInfo(THIS_NAME, "FYI - You may want to check for \'ERROR\' and/or \'WARNING\' alarms in the LOG file...\n\n");
1789  }
1790  else {
1791  printInfo(THIS_NAME, "#############################################################\n");
1792  printInfo(THIS_NAME, "#### SUCCESSFUL END OF TEST ####\n");
1793  printInfo(THIS_NAME, "#############################################################\n");
1794  }
1795 
1796  return nrErr;
1797 }
1798 
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
int getLen() const
Definition: AxisRaw.hpp:411
bool isValid() const
Definition: AxisRaw.hpp:434
LE_tLast getLE_TLast() const
Definition: AxisRaw.hpp:268
Class IPv4 Packet for simulation.
void setIpTotalLength(int totLen)
UdpCsum udpRecalculateChecksum()
Recalculate checksum of an UDP datagram after it was modified.
void setIpSourceAddress(int addr)
bool isWellFormed(const char *callerName, bool checkIp4TotLen=true, bool checkIp4HdrCsum=true, bool checkUdpLen=true, bool checkLy4Csum=true)
Checks if the IP header and embedded protocol fields are properly set.
Ip4Addr getIpSourceAddress()
UdpCsum getUdpChecksum()
void pushChunk(AxisIp4 ip4Chunk)
SimUdpDatagram getUdpDatagram()
void setIpDestinationAddress(int addr)
UdpPort getUdpDestinationPort()
Ip4Addr getIpDestinationAddress()
bool addIpPayload(SimUdpDatagram &udpDgm, int len=-1)
Append some data to this packet from a UDP datagram.
bool writeToDatFile(ofstream &outFileStream)
Dump this IP packet as AxisIp4 chunks into a file.
AxisIp4 pullChunk()
Class UDP Datagram.
void setUdpChecksum(UdpCsum csum)
void pushChunk(AxisUdp udpChunk)
SimUdpDatagram pullHeader()
Pull the header of this datagram.
void setUdpLength(UdpLen len)
void cloneHeader(SimUdpDatagram &udpDgm)
Clone the header of a UDP datagram.
UdpCsum reCalculateUdpChecksum(Ip4Addr ipSa, Ip4Addr ipDa)
Recalculate the UDP checksum of a datagram.
void setUdpDestinationPort(int port)
void setUdpSourcePort(int port)
bool writePayloadToDatFile(ofstream &outFileStream)
Dump the payload of this datagram as AxisUdp chunks into a file.
Ip4Addr addr
Definition: nts_types.hpp:209
Ly4Port port
Definition: nts_types.hpp:210
Ly4Port udpDstPort
Definition: nts.hpp:229
Ly4Port udpSrcPort
Definition: nts.hpp:227
Ip4Addr ip4SrcAddr
Definition: nts.hpp:226
Ip4Addr ip4DstAddr
Definition: nts.hpp:228
UdpLen UdpAppDLen
Definition: nal.hpp:255
bool StsBool
Definition: nal.hpp:246
ap_uint< 16 > UdpLen
Definition: nal.hpp:250
unsigned int gSimCycCnt
Definition: tb_nal.cpp:150
bool gTraceEvent
Definition: tb_nal.cpp:151
ap_uint< 16 > UdpPort
Definition: nal.hpp:249
#define TB_GRACE_TIME
Definition: test_arp.hpp:54
bool readHostSocketFromLine(SockAddr &hostSock, string stringBuffer)
Retrieve a Host socket from a string.
bool readAxisRawFromLine(AxisRaw &axisRaw, string stringBuffer)
Retrieve an AxisRaw chunk from a string.
bool writeApUintToFile(ap_uint< D > &data, ofstream &outFileStream)
Dump an AP_UINT to a file.
vector< string > myTokenizer(string strBuff, char delimiter)
Brakes a string into tokens by using the 'delimiter' character.
bool isDatFile(string fileName)
Checks if a file has a ".dat" extension.
Definition: SimNtsUtils.cpp:52
bool feedAxisFromFile(stream< AXIS_T > &ss, const string ssName, string datFile, int &nrChunks, int &nrFrames, int &nrBytes)
Initialize an Axi4-Stream (Axis) from a DAT file.
bool drainAxisToFile(stream< AXIS_T > &ss, const string ssName, string datFile, int &nrChunks, int &nrFrames, int &nrBytes)
Empty an Axi4-Stream (Axis) to a DAT file.
bool writeSocketPairToFile(SocketPair &socketPair, ofstream &outFileStream)
Dump a SocketPair to a file.
int myDiffTwoFiles(string dataFileName, string goldFileName)
Compares 2 files line-by-line, up to length of the 2nd file.
bool readAxisRawFromFile(AxisRaw &axisRaw, ifstream &inpFileStream)
Retrieve an Axis raw data chunk from a file.
bool readFpgaSndPortFromLine(Ly4Port &port, string stringBuffer)
Retrieve an FPGA send port from a string.
@ BIDIR_MODE
@ ECHO_MODE
@ RX_MODE
int createGoldenTxFiles(string inpData_FileName, string outData_GoldName, queue< UdpAppMeta > &udpMetaQueue, queue< UdpAppDLen > &updDLenQueue, char tbMode)
Create the golden IPTX reference file from an input UAIF test file.
Definition: test_uoe.cpp:381
void uoe_top_wrap(CmdBit piMMIO_En, stream< ap_uint< 16 > > &soMMIO_DropCnt, stream< StsBool > &soMMIO_Ready, stream< AxisIp4 > &siIPRX_Data, stream< AxisIp4 > &soIPTX_Data, stream< UdpAppLsnReq > &siUAIF_LsnReq, stream< UdpAppLsnRep > &soUAIF_LsnRep, stream< UdpAppClsReq > &siUAIF_ClsReq, stream< UdpAppClsRep > &soUAIF_ClsRep, stream< UdpAppData > &soUAIF_Data, stream< UdpAppMeta > &soUAIF_Meta, stream< UdpAppDLen > &soUAIF_DLen, stream< UdpAppData > &siUAIF_Data, stream< UdpAppMeta > &siUAIF_Meta, stream< UdpAppDLen > &siUAIF_DLen, stream< AxisIcmp > &soICMP_Data)
A wrapper for the Toplevel of the UDP Offload Engine (UOE)
Definition: test_uoe.cpp:710
int main(int argc, char *argv[])
Main function.
Definition: test_uoe.cpp:793
bool drainUdpDLenStreamToFile(stream< UdpAppDLen > &ss, string ssName, string datFile, int &nrChunks, int &nrFrames, int &nrBytes)
Empty an UdpDLen stream to a DAT file.
Definition: test_uoe.cpp:142
bool drainMmioDropCounter(stream< ap_uint< 16 > > &ss, string ssName)
Empty the DropCounter stream and throw it away.
Definition: test_uoe.cpp:201
void stepSim()
Increment the simulation counter.
Definition: test_uoe.cpp:51
bool readDatagramFromFile(const char *myName, SimUdpDatagram &appDatagram, ifstream &ifsData, UdpAppMeta &udpAppMeta, queue< UdpAppMeta > &udpMetaQueue, queue< UdpAppDLen > &updDLenQueue, int &inpChunks, int &inpDgrms, int &inpBytes, char tbMode)
Read a datagram from a DAT file.
Definition: test_uoe.cpp:297
int createGoldenRxFiles(string inpData_FileName, string outData_GoldName, string outMeta_GoldName, string outDLen_GoldName, set< UdpPort > &udpPorts)
Create the golden Rx APP reference files from an input IPRX test file.
Definition: test_uoe.cpp:516
#define TRACE_CGRF
Definition: test_uoe.cpp:42
#define TRACE_CGTF
Definition: test_uoe.cpp:43
#define THIS_NAME
Definition: test_uoe.cpp:39
bool drainUdpMetaStreamToFile(stream< UdpAppMeta > &ss, string ssName, string datFile, int &nrChunks, int &nrFrames, int &nrBytes)
Empty an UdpMeta stream to a DAT file.
Definition: test_uoe.cpp:74
#define TRACE_DUMTF
Definition: test_uoe.cpp:44
#define DEBUG_LEVEL
Definition: test_uoe.cpp:46
int createUdpTxTraffic(stream< AxisApp > &ssData, const string ssDataName, stream< UdpAppMeta > &ssMeta, const string ssMetaName, stream< UdpAppDLen > &ssDLen, const string ssDLenName, string datFile, queue< UdpAppMeta > &metaQueue, queue< UdpAppDLen > &dlenQueue, int &nrFeededChunks)
Create the UDP Tx traffic as streams from an input test file.
Definition: test_uoe.cpp:235
@ TX_DGRM_MODE
Definition: test_uoe.hpp:62
@ OPEN_MODE
Definition: test_uoe.hpp:63
@ TX_STRM_MODE
Definition: test_uoe.hpp:62
@ DROP_MODE
Definition: test_uoe.hpp:64
void uoe_top(CmdBit piMMIO_En, stream< ap_uint< 16 > > &soMMIO_DropCnt, stream< StsBool > &soMMIO_Ready, stream< AxisRaw > &siIPRX_Data, stream< AxisRaw > &soIPTX_Data, stream< UdpAppLsnReq > &siUAIF_LsnReq, stream< UdpAppLsnRep > &soUAIF_LsnRep, stream< UdpAppClsReq > &siUAIF_ClsReq, stream< UdpAppClsRep > &soUAIF_ClsRep, stream< UdpAppData > &soUAIF_Data, stream< UdpAppMeta > &soUAIF_Meta, stream< UdpAppDLen > &soUAIF_DLen, stream< UdpAppData > &siUAIF_Data, stream< UdpAppMeta > &siUAIF_Meta, stream< UdpAppDLen > &siUAIF_DLen, stream< AxisRaw > &soICMP_Data)
Top of UDP Offload Engine (UOE)
Definition: uoe.cpp:2042
#define NTS_KO
Definition: nts_types.hpp:56
ap_uint< 8 > Ip4Prot
Definition: AxisIp4.hpp:164
#define printError(callerName, format,...)
A macro to print an error message.
Definition: nts_utils.hpp:195
#define IP4_PROT_UDP
Definition: nts_types.hpp:185
void printAxisRaw(const char *callerName, AxisRaw chunk)
Prints an Axis raw data chunk (used for debugging).
Definition: nts_utils.cpp:46
#define CMD_DISABLE
Definition: nts_types.hpp:64
ap_uint< 32 > Ip4Addr
Definition: AxisIp4.hpp:169
void pAxisRawCast(hls::stream< TypeIn > &si, hls::stream< TypeOut > &so)
AxisRaw cast - Casts an AxisRaw stream to/from an AxisRaw derived class.
Definition: AxisRaw.hpp:148
void printSockAddr(const char *callerName, SockAddr sockAddr)
Print a socket address.
Definition: nts_utils.cpp:174
#define NTS_OK
Definition: nts_types.hpp:55
#define printInfo(callerName, format,...)
A macro to print an information message.
Definition: nts_utils.hpp:169
#define CMD_ENABLE
Definition: nts_types.hpp:63
ap_uint< 1 > CmdBit
Definition: nts_types.hpp:108
#define UDP_HEADER_LEN
Definition: AxisUdp.hpp:81
#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
ap_uint< 16 > UdpCsum
Definition: AxisUdp.hpp:101
void printSockPair(const char *callerName, SocketPair sockPair)
Print a socket pair association.
Definition: nts_utils.cpp:114
#define printFatal(callerName, format,...)
A macro to print a fatal error message and exit.
Definition: nts_utils.hpp:208
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
out
Definition: test.py:12
: Testbench for the UDP Offload Engine (UOE).