cloudFPGA (cF) API  1.0
The documentation of the source code of cloudFPGA (cF)
test_tcp_shell_if_top.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 
44 
45 using namespace hls;
46 using namespace std;
47 
48 //---------------------------------------------------------
49 // HELPERS FOR THE DEBUGGING TRACES
50 //---------------------------------------------------------
51 #define THIS_NAME "TB_TSIF_TOP"
52 
53 #ifndef __SYNTHESIS__
54  extern unsigned int gSimCycCnt;
55  extern unsigned int gMaxSimCycles;
56 #endif
57 
58 #define TRACE_OFF 0x0000
59 #define TRACE_DDC 1 << 1
60 #define TRACE_ALL 0xFFFF
61 
62 #define DEBUG_LEVEL (TRACE_OFF)
63 
64 
72 template<typename T> bool drainDebugCounter(stream<T> &ss, string ssName) {
73  int nr=0;
74  const char *myName = concat3(THIS_NAME, "/", "DDC");
75  T currCount;
76  T prevCount=0;
77 
78  //-- READ FROM STREAM
79  while (!(ss.empty())) {
80  ss.read(currCount);
81  if (currCount != prevCount) {
82  if (DEBUG_LEVEL & TRACE_DDC) {
83  printInfo(myName, "Detected a change on stream '%s' (currCounter=%d). \n",
84  ssName.c_str(), currCount.to_uint());
85  }
86  }
87  prevCount = currCount;
88  }
89  return(NTS_OK);
90 }
91 
92 
93 
103 int main(int argc, char *argv[]) {
104 
105  //------------------------------------------------------
106  //-- TESTBENCH GLOBAL VARIABLES
107  //------------------------------------------------------
108  gSimCycCnt = 0; // Simulation cycle counter as a global variable
109 
110  //------------------------------------------------------
111  //-- DUT SIGNAL INTERFACES
112  //------------------------------------------------------
113  //-- SHL / Mmio Interface
114  CmdBit sMMIO_TSIF_Enable;
115  //-- TOE / Ready Signal
116  StsBit sTOE_MMIO_Ready;
117  //-- TSIF / Session Connect Id Interface
118  SessionId sTSIF_TAF_SConId;
119 
120  //------------------------------------------------------
121  //-- DUT STREAM INTERFACES
122  //------------------------------------------------------
123  //-- TAF / Rx Data Interface
124  stream<TcpAppData> ssTAF_TSIF_Data ("ssTAF_TSIF_Data");
125  stream<TcpSessId> ssTAF_TSIF_SessId("ssTAF_TSIF_SessId");
126  stream<TcpDatLen> ssTAF_TSIF_DatLen("ssTAF_TSIF_DatLen");
127  //-- TSIF / Tx Data Interface
128  stream<TcpAppData> ssTSIF_TAF_Data ("ssTSIF_TAF_Data");
129  stream<TcpSessId> ssTSIF_TAF_SessId("ssTSIF_TAF_SessId");
130  stream<TcpDatLen> ssTSIF_TAF_DatLen("ssTSIF_TAF_DatLen");
131  //-- TOE / Rx Data Interfaces
132  stream<TcpAppNotif> ssTOE_TSIF_Notif ("ssTOE_TSIF_Notif");
133  stream<TcpAppData> ssTOE_TSIF_Data ("ssTOE_TSIF_Data");
134  stream<TcpAppMeta> ssTOE_TSIF_Meta ("ssTOE_TSIF_Meta");
135  //-- TSIF / Rx Data Interface
136  stream<TcpAppRdReq> ssTSIF_TOE_DReq ("ssTSIF_TOE_DReq");
137  //-- TOE / Listen Interface
138  stream<TcpAppLsnRep> ssTOE_TSIF_LsnRep("ssTOE_TSIF_LsnRep");
139  //-- TSIF / Listen Interface
140  stream<TcpAppLsnReq> ssTSIF_TOE_LsnReq("ssTSIF_TOE_LsnReq");
141  //-- TOE / Tx Data Interfaces
142  stream<TcpAppSndRep> ssTOE_TSIF_SndRep("ssTOE_TSIF_SndRep");
143  //-- TSIF / Tx Data Interfaces
144  stream<TcpAppData> ssTSIF_TOE_Data ("ssTSIF_TOE_Data");
145  stream<TcpAppSndReq> ssTSIF_TOE_SndReq("ssTSIF_TOE_SndReq");
146  //-- TOE / Connect Interfaces
147  stream<TcpAppOpnRep> ssTOE_TSIF_OpnRep("ssTOE_TSIF_OpnRep");
148  //-- TSIF / Connect Interfaces
149  stream<TcpAppOpnReq> ssTSIF_TOE_OpnReq("ssTSIF_TOE_OpnReq");
150  stream<TcpAppClsReq> ssTSIF_TOE_ClsReq("ssTSIF_TOE_ClsReq");
151  //-- DEBUG Interface
152  stream<ap_uint<32> > ssTSIF_DBG_SinkCnt("ssTSIF_DBG_SinkCnt");
153  stream<ap_uint<16> > ssTSIF_DBG_InpBufSpace("ssTSIF_DBG_InpBufSpace");
154 
155  //------------------------------------------------------
156  //-- TESTBENCH VARIABLES
157  //------------------------------------------------------
158  int nrErr = 0; // Total number of testbench errors
159  ofstream ofTAF_Data; // APP byte streams delivered to TAF
160  const char *ofTAF_DataName = "../../../../test/simOutFiles/soTAF.dat";
161  ofstream ofTAF_Gold; // Gold reference file for 'ofTAF_Data'
162  const char *ofTAF_GoldName = "../../../../test/simOutFiles/soTAF.gold";
163  ofstream ofTOE_Data; // Data streams delivered to TOE
164  const char *ofTOE_DataName = "../../../../test/simOutFiles/soTOE_Data.dat";
165  ofstream ofTOE_Gold; // Gold streams to compare with
166  const char *ofTOE_GoldName = "../../../../test/simOutFiles/soTOE_Gold.dat";
167 
168  const int defaultLenOfSegmentEcho = 42;
169  const int defaultDestHostIpv4Test = 0xC0A80096; // 192.168.0.150
170  const int defaultDestHostPortTest = 2718;
171  const int defaultLenOfSegmentTest = 43;
172 
173  int echoLenOfSegment = defaultLenOfSegmentEcho;
174  ap_uint<32> testDestHostIpv4 = defaultDestHostIpv4Test;
175  ap_uint<16> testDestHostPort = defaultDestHostIpv4Test;
176  int testLenOfSegment = defaultLenOfSegmentTest;
177 
178  //------------------------------------------------------
179  //-- PARSING THE TESBENCH ARGUMENTS
180  //------------------------------------------------------
181  if (argc >= 2) {
182  if ((atoi(argv[1]) < 1) or (atoi(argv[1]) > 0x4000)) {
184  "Argument 'len' is out of range [1:16384].\n");
185  return NTS_KO;
186  } else {
187  echoLenOfSegment = atoi(argv[1]);
188  }
189  }
190  if (argc >= 3) {
191  if (isDottedDecimal(argv[2])) {
192  testDestHostIpv4 = myDottedDecimalIpToUint32(argv[2]);
193  } else {
194  testDestHostIpv4 = atoi(argv[2]);
195  }
196  if ((testDestHostIpv4 < 0x00000000)
197  or (testDestHostIpv4 > 0xFFFFFFFF)) {
199  "Argument 'IPv4' is out of range [0x00000000:0xFFFFFFFF].\n");
200  return NTS_KO;
201  }
202  }
203  if (argc >= 4) {
204  testDestHostPort = atoi(argv[3]);
205  if ((testDestHostPort < 0x0000) or (testDestHostPort >= 0x10000)) {
207  "Argument 'port' is out of range [0:65535].\n");
208  return NTS_KO;
209  }
210  }
211  if (argc >= 5) {
212  testLenOfSegment = atoi(argv[4]);
213  if ((testLenOfSegment < 1) or (testLenOfSegment > 0x4000)) {
215  "Argument 'len' is out of range [1:16384].\n");
216  return NTS_KO;
217  }
218  }
219 
220  //------------------------------------------------------
221  //-- ASSESS THE TESTBENCH ARGUMENTS
222  //------------------------------------------------------
223  int totalRxBytes = (cNrSessToSend * (testLenOfSegment + 8 + 8 + 2*echoLenOfSegment));
224  if (totalRxBytes > cIBuffBytes) {
225  printFatal(THIS_NAME, "The total amount of Rx bytes (%d) exceeds the size of the input TSIF read buffer (%d).\n",
226  totalRxBytes, cIBuffBytes);
227  }
228  if (testLenOfSegment > cIBuffBytes) {
229  printFatal(THIS_NAME, "The length of the test segment (%d) exceeds the size of the input TSIF read buffer (%d).\n",
230  testLenOfSegment, cIBuffBytes);
231  }
232 
233  //------------------------------------------------------
234  //-- UPDATE THE LOCAL VARIABLES ACCORDINGLY
235  //------------------------------------------------------
236  SockAddr testSock(testDestHostIpv4, testDestHostPort);
238  * (((echoLenOfSegment * (cNrSegToSend / 2))
239  + (testLenOfSegment * (cNrSegToSend / 2))));
240 
241  //------------------------------------------------------
242  //-- REMOVE PREVIOUS OLD SIM FILES and OPEN NEW ONES
243  //------------------------------------------------------
244  remove(ofTAF_DataName);
245  ofTAF_Data.open(ofTAF_DataName);
246  if (!ofTAF_Data) {
248  "Cannot open the Application Tx file: \n\t %s \n",
249  ofTAF_DataName);
250  return -1;
251  }
252  remove(ofTAF_GoldName);
253  ofTAF_Gold.open(ofTAF_GoldName);
254  if (!ofTAF_Gold) {
256  "Cannot open the Application Tx gold file: \n\t %s \n",
257  ofTAF_GoldName);
258  return -1;
259  }
260  remove(ofTOE_DataName);
261  if (!ofTOE_Data.is_open()) {
262  ofTOE_Data.open(ofTOE_DataName, ofstream::out);
263  if (!ofTOE_Data) {
264  printError(THIS_NAME, "Cannot open the file: \'%s\'.\n",
265  ofTOE_DataName);
266  }
267  }
268  remove(ofTOE_GoldName);
269  if (!ofTOE_Gold.is_open()) {
270  ofTOE_Gold.open(ofTOE_GoldName, ofstream::out);
271  if (!ofTOE_Gold) {
272  printError(THIS_NAME, "Cannot open the file: \'%s\'.\n",
273  ofTOE_GoldName);
274  return (NTS_KO);
275  }
276  }
277 
279  "############################################################################\n");
281  "## TESTBENCH 'test_tcp_shell' STARTS HERE ##\n");
283  "############################################################################\n\n");
284  if (argc > 1) {
286  "This testbench will be executed with the following parameters: \n");
287  for (int i = 1; i < argc; i++) {
288  printInfo(THIS_NAME, "\t==> Param[%d] = %s\n", (i - 1), argv[i]);
289  }
290  }
291 
292  //-----------------------------------------------------
293  //-- MAIN LOOP
294  //-----------------------------------------------------
295  do {
296  //-------------------------------------------------
297  //-- EMULATE TOE
298  //-------------------------------------------------
299  pTOE(nrErr, ofTAF_Gold, ofTOE_Gold, ofTOE_Data, echoLenOfSegment,
300  testSock, testLenOfSegment,
301  //-- TOE / Ready Signal
302  &sTOE_MMIO_Ready,
303  //-- TOE / Tx Data Interfaces
304  ssTOE_TSIF_Notif, ssTSIF_TOE_DReq,
305  ssTOE_TSIF_Data, ssTOE_TSIF_Meta,
306  //-- TOE / Listen Interfaces
307  ssTSIF_TOE_LsnReq, ssTOE_TSIF_LsnRep,
308  //-- TOE / Tx Data Interfaces
309  ssTSIF_TOE_Data, ssTSIF_TOE_SndReq, ssTOE_TSIF_SndRep,
310  //-- TOE / Open Interfaces
311  ssTSIF_TOE_OpnReq, ssTOE_TSIF_OpnRep);
312 
313  //-------------------------------------------------
314  //-- EMULATE SHELL/MMIO
315  //-------------------------------------------------
316  pMMIO(
317  //-- TOE / Ready Signal
318  &sTOE_MMIO_Ready,
319  //-- MMIO / Enable Layer-7 (.i.e APP alias ROLE)
320  &sMMIO_TSIF_Enable);
321 
322  //-------------------------------------------------
323  //-- RUN DUT
324  //-------------------------------------------------
326  //-- SHELL / Mmio Interface
327  &sMMIO_TSIF_Enable,
328  //-- TAF / Rx & Tx Data Interfaces
329  ssTAF_TSIF_Data, ssTAF_TSIF_SessId, ssTAF_TSIF_DatLen,
330  ssTSIF_TAF_Data, ssTSIF_TAF_SessId, ssTSIF_TAF_DatLen,
331  //-- TOE / Rx Data Interfaces
332  ssTOE_TSIF_Notif, ssTSIF_TOE_DReq, ssTOE_TSIF_Data,
333  ssTOE_TSIF_Meta,
334  //-- TOE / Listen Interfaces
335  ssTSIF_TOE_LsnReq, ssTOE_TSIF_LsnRep,
336  //-- TOE / Tx Data Interfaces
337  ssTSIF_TOE_Data, ssTSIF_TOE_SndReq, ssTOE_TSIF_SndRep,
338  //-- TOE / Tx Open Interfaces
339  ssTSIF_TOE_OpnReq, ssTOE_TSIF_OpnRep,
340  //-- TOE / Close Interfaces
341  ssTSIF_TOE_ClsReq,
342  //-- DEBUG Interfaces
343  ssTSIF_DBG_SinkCnt,
344  ssTSIF_DBG_InpBufSpace);
345 
346  //-------------------------------------------------
347  //-- EMULATE ROLE/TcpApplicationFlash
348  //-------------------------------------------------
349  pTAF(ofTAF_Data,
350  //-- TSIF / Data Interface
351  ssTSIF_TAF_Data, ssTSIF_TAF_SessId, ssTSIF_TAF_DatLen,
352  //-- TAF / Data Interface
353  ssTAF_TSIF_Data, ssTAF_TSIF_SessId, ssTAF_TSIF_DatLen);
354 
355  //------------------------------------------------------
356  //-- INCREMENT SIMULATION COUNTER
357  //------------------------------------------------------
358  stepSim();
359 
360  } while ((gSimCycCnt < gMaxSimCycles) and (!gFatalError) and (nrErr < 10));
361 
363  "############################################################################\n");
365  "## TESTBENCH 'test_tcp_shell_if' ENDS HERE ##\n");
367  "############################################################################\n");
368  stepSim();
369 
370  //---------------------------------------------------------------
371  //-- DRAIN THE TSIF SINK and FREESPACE COUNTER STREAMS
372  //---------------------------------------------------------------
373  if (not drainDebugSinkCounter(ssTSIF_DBG_SinkCnt, "ssTSIF_DBG_SinkCnt")) {
374  printError(THIS_NAME, "Failed to drain debug sink counter from DUT. \n");
375  nrErr++;
376  }
377  if (not drainDebugSpaceCounter(ssTSIF_DBG_InpBufSpace, "ssTSIF_DBG_InpBufSpace")) {
378  printError(THIS_NAME, "Failed to drain debug space counter from DUT. \n");
379  nrErr++;
380  }
381 
382  //---------------------------------------------------------------
383  //-- COMPARE RESULT DATA FILE WITH GOLDEN FILE
384  //---------------------------------------------------------------
385  if (ofTAF_Data.tellp() != 0) {
386  int res = system(
387  ("diff --brief -w " + std::string(ofTAF_DataName) + " "
388  + std::string(ofTAF_GoldName) + " ").c_str());
389  if (res != 0) {
390  printError(THIS_NAME, "File \"%s\" differs from file \"%s\" \n",
391  ofTAF_DataName, ofTAF_GoldName);
392  nrErr++;
393  }
394  } else {
395  printError(THIS_NAME, "File \"%s\" is empty.\n", ofTAF_DataName);
396  nrErr++;
397  }
398  if (ofTOE_Data.tellp() != 0) {
399  int res = system(
400  ("diff --brief -w " + std::string(ofTOE_DataName) + " "
401  + std::string(ofTOE_GoldName) + " ").c_str());
402  if (res != 0) {
403  printError(THIS_NAME, "File \"%s\" differs from file \"%s\" \n",
404  ofTOE_DataName, ofTOE_GoldName);
405  nrErr++;
406  }
407  } else {
408  printError(THIS_NAME, "File \"%s\" is empty.\n", ofTOE_DataName);
409  nrErr++;
410  }
411 
412  //---------------------------------------------------------------
413  //-- PRINT TESTBENCH STATUS
414  //---------------------------------------------------------------
415  printf("\n");
417  "This testbench was executed with the following parameters: \n");
418  for (int i = 1; i < argc; i++) {
419  printInfo(THIS_NAME, "\t==> Param[%d] = %s\n", (i - 1), argv[i]);
420  }
421  printf("\n");
422 
423  if (nrErr) {
425  "###########################################################\n");
427  "#### TEST BENCH FAILED : TOTAL NUMBER OF ERROR(S) = %2d ####\n",
428  nrErr);
430  "###########################################################\n");
431  } else {
433  "#############################################################\n");
435  "#### SUCCESSFUL END OF TEST ####\n");
437  "#############################################################\n");
438  }
439 
440  //---------------------------------
441  //-- CLOSING OPEN FILES
442  //---------------------------------
443  ofTAF_Data.close();
444  ofTAF_Gold.close();
445  ofTOE_Data.close();
446  ofTOE_Gold.close();
447 
448  return (nrErr);
449 }
450 
int main()
Definition: tb_fmc.cpp:380
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
bool gFatalError
Definition: tb_nal.cpp:152
void stepSim()
Increment the simulation counter.
Definition: test_arp.cpp:54
bool isDottedDecimal(string ipStr)
Checks if a string contains an IP address represented in dot-decimal notation.
Definition: SimNtsUtils.cpp:72
ap_uint< 32 > myDottedDecimalIpToUint32(string ipStr)
Converts an IPv4 address represented with a dotted-decimal string into an UINT32.
#define NTS_KO
Definition: nts_types.hpp:56
ap_uint< 16 > SessionId
Definition: nts_types.hpp:136
#define printError(callerName, format,...)
A macro to print an error message.
Definition: nts_utils.hpp:195
ap_uint< 1 > StsBit
Definition: nts_types.hpp:116
#define NTS_OK
Definition: nts_types.hpp:55
#define printInfo(callerName, format,...)
A macro to print an information message.
Definition: nts_utils.hpp:169
ap_uint< 1 > CmdBit
Definition: nts_types.hpp:108
#define concat3(firstCharConst, secondCharConst, thirdCharConst)
Definition: nts_utils.hpp:161
#define printFatal(callerName, format,...)
A macro to print a fatal error message and exit.
Definition: nts_utils.hpp:208
bool drainDebugSpaceCounter(stream< ap_uint< 16 > > &ss, string ssName)
Empty the DebugSpaceCounter stream and check its last value.
#define TRACE_DDC
void pMMIO(StsBit *piSHL_Ready, CmdBit *poTSIF_Enable)
Emulate the behavior of the SHELL & MMIO.
unsigned int gMaxSimCycles
Definition: test_arp.hpp:69
unsigned int gSimCycCnt
Definition: tb_nal.cpp:150
#define THIS_NAME
bool drainDebugSinkCounter(stream< ap_uint< 32 > > &ss, string ssName)
Empty the DebugSinkCounter stream and throw it away.
const int cNrSessToSend
const int cIBuffBytes
const int cNrSegToSend
bool drainDebugCounter(stream< T > &ss, string ssName)
Empty a debug stream and throw it away.
#define DEBUG_LEVEL
void pTAF(ofstream &ofTAF_Data, stream< TcpAppData > &siTSIF_Data, stream< TcpSessId > &siTSIF_SessId, stream< TcpDatLen > &siTSIF_DatLen, stream< TcpAppData > &soTSIF_Data, stream< TcpSessId > &soTSIF_Meta, stream< TcpSessId > &soTSIF_DLen)
Emulate the behavior of the ROLE/TcpAppFlash (TAF).
void tcp_shell_if_top(CmdBit *piSHL_Mmio_En, stream< TcpAppData > &siTAF_Data, stream< TcpSessId > &siTAF_SessId, stream< TcpDatLen > &siTAF_DatLen, stream< TcpAppData > &soTAF_Data, stream< TcpSessId > &soTAF_SessId, stream< TcpDatLen > &soTAF_DatLen, stream< TcpAppNotif > &siSHL_Notif, stream< TcpAppRdReq > &soSHL_DReq, stream< TcpAppData > &siSHL_Data, stream< TcpAppMeta > &siSHL_Meta, stream< TcpAppLsnReq > &soSHL_LsnReq, stream< TcpAppLsnRep > &siSHL_LsnRep, stream< TcpAppData > &soSHL_Data, stream< TcpAppSndReq > &soSHL_SndReq, stream< TcpAppSndRep > &siSHL_SndRep, stream< TcpAppOpnReq > &soSHL_OpnReq, stream< TcpAppOpnRep > &siSHL_OpnRep, stream< TcpAppClsReq > &soSHL_ClsReq, stream< ap_uint< 32 > > &soDBG_SinkCnt, stream< ap_uint< 16 > > &soDBG_InpBufSpace)
Top of TCP Shell Interface (TSIF)
out
Definition: test.py:12
: Testbench for the toplevel of TCP Shell Interface (TSIF).