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