cloudFPGA (cF) API  1.0
The documentation of the source code of cloudFPGA (cF)
test_udp_app_flash_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 // .e.g: DEBUG_LEVEL = (MDL_TRACE | IPS_TRACE)
51 //---------------------------------------------------------
52 #define THIS_NAME "TB_UAF_TOP"
53 
54 #ifndef __SYNTHESIS__
55  extern unsigned int gSimCycCnt;
56  extern unsigned int gMaxSimCycles;
57 #endif
58 
59 
62 int main(int argc, char *argv[]) {
63 
64  gSimCycCnt = 0;
65 
66  //------------------------------------------------------
67  //-- TESTBENCH LOCAL VARIABLES
68  //------------------------------------------------------
69  int nrErr = 0;
70  EchoCtrl tbCtrlMode = ECHO_CTRL_DISABLED;
71 
72  //------------------------------------------------------
73  //-- NONE-STREAM-BASED INTERFACES
74  //------------------------------------------------------
75  // INFO - The UAF is specified to use the block-level IO protocol
76  // 'ap_ctrl_none'. This core uses also a few configurations signals
77  // which are not stream-based and which prevent the design from
78  // being verified in C/RTL co-simulation mode. In oder to comply
79  // with the 'Interface Synthesis Requirements' of UG902, the design
80  // is compiled with a preprocessor macro that statically defines the
81  // testbench mode of operation. This avoid the following error issued
82  // when trying to C/RTL co-simulate this component:
83  // @E [SIM-345] Cosim only supports the following 'ap_ctrl_none'
84  // designs: (1) combinational designs; (2) pipelined design with
85  // task interval of 1; (3) designs with array streaming or
86  // hls_stream ports.
87  // @E [SIM-4] *** C/RTL co-simulation finished: FAIL **
88  //------------------------------------------------------
89  CmdBit sSHL_UAF_Mmio_Enable = CMD_ENABLE;
90 #if TB_MODE == 0
91  ap_uint<2> sSHL_UAF_Mmio_EchoCtrl = ECHO_CTRL_DISABLED;
92  ap_uint<1> sSHL_UAF_Mmio_PostPktEn = 0;
93  ap_uint<1> sSHL_UAF_Mmio_CaptPktEn = 0;
94 #elif TB_MODE == 1
95  ap_uint<2> sSHL_UAF_Mmio_EchoCtrl = ECHO_PATH_THRU;
96  ap_uint<1> sSHL_UAF_Mmio_PostPktEn = 0;
97  ap_uint<1> sSHL_UAF_Mmio_CaptPktEn = 0;
98 #elif TB_MODE == 2
99  ap_uint<2> sSHL_UAF_Mmio_EchoCtrl = ECHO_STORE_FWD;
100  ap_uint<1> sSHL_UAF_Mmio_PostPktEn = 0;
101  ap_uint<1> sSHL_UAF_Mmio_CaptPktEn = 0;
102 #else
103  ap_uint<2> sSHL_UAF_Mmio_EchoCtrl = ECHO_OFF;
104  ap_uint<1> sSHL_UAF_Mmio_PostPktEn = 0;
105  ap_uint<1> sSHL_UAF_Mmio_CaptPktEn = 0;
106 #endif
107 
108  //------------------------------------------------------
109  //-- DUT STREAM INTERFACES and RELATED VARIABLEs
110  //------------------------------------------------------
111  stream<UdpAppData> ssUSIF_UAF_Data ("ssUSIF_UAF_Data");
112  stream<UdpAppMeta> ssUSIF_UAF_Meta ("ssUSIF_UAF_Meta");
113  stream<UdpAppDLen> ssUSIF_UAF_DLen ("ssUSIF_UAF_DLen");
114  stream<UdpAppData> ssUAF_USIF_Data ("ssUAF_USIF_Data");
115  stream<UdpAppMeta> ssUAF_USIF_Meta ("ssUAF_USIF_Meta");
116  stream<UdpAppDLen> ssUAF_USIF_DLen ("ssUAF_USIF_DLen");
117 
118  //------------------------------------------------------
119  //-- PARSING THE TESBENCH ARGUMENTS
120  //------------------------------------------------------
121  if (argc < 3) {
122  printFatal(THIS_NAME, "Expected a minimum of 2 parameters with the following synopsis:\n \t\t mode(0|1|2) siUAF_<Filename>.dat\n");
123  }
124  tbCtrlMode = EchoCtrl(atoi(argv[1]));
125  if (tbCtrlMode != sSHL_UAF_Mmio_EchoCtrl) {
126  printFatal(THIS_NAME, "tbCtrlMode (%d) does not match TB_MODE (%d). Modify the CFLAG and re-compile.\n", tbCtrlMode, TB_MODE);
127  }
128 
129  switch (tbCtrlMode) {
130  case ECHO_CTRL_DISABLED:
131  break;
132  case ECHO_PATH_THRU:
133  case ECHO_STORE_FWD:
134  case ECHO_OFF:
135  printFatal(THIS_NAME, "The 'ECHO' mode %d is no longer supported since the removal of the MMIO EchoCtrl bits. \n", tbCtrlMode);
136  break;
137  default:
138  printFatal(THIS_NAME, "Unknown testing mode '%d' (or not yet implemented). \n");
139  }
140 
141  printf("#####################################################\n");
142  printf("## TESTBENCH STARTS HERE ##\n");
143  printf("#####################################################\n");
144  printInfo(THIS_NAME, "This testbench will be executed with the following parameters: \n");
145  printInfo(THIS_NAME, "\t==> TB Mode = %c\n", *argv[1]);
146  for (int i=2; i<argc; i++) {
147  printInfo(THIS_NAME, "\t==> Param[%d] = %s\n", (i-1), argv[i]);
148  }
149  printf("\n");
150 
151  if (tbCtrlMode == ECHO_CTRL_DISABLED) {
152 
153  //-- DUT OUTPUT TRAFFIC AS STREAMS ------------------------------
154  ofstream ofsUSIF_Data; // APP data streams delivered to USIF
155  const char *ofsUSIF_Data_FileName = "../../../../test/simOutFiles/soUSIF_Data.dat";
156  ofstream ofsUSIF_Meta; // APP meta streams delivered to USIF
157  const char *ofsUSIF_Meta_FileName = "../../../../test/simOutFiles/soUSIF_Meta.dat";
158  ofstream ofsUSIF_DLen; // APP data len streams delivered to USIF
159  const char *ofsUSIF_DLen_FileName = "../../../../test/simOutFiles/soUSIF_DLen.dat";
160 
161  string ofsUSIF_Data_Gold_FileName = "../../../../test/simOutFiles/soUSIF_Data_Gold.dat";
162  string ofsUSIF_Meta_Gold_FileName = "../../../../test/simOutFiles/soUSIF_Meta_Gold.dat";
163  string ofsUSIF_DLen_Gold_FileName = "../../../../test/simOutFiles/soUSIF_DLen_Gold.dat";
164 
165  //-- STEP-1: The setting of the ECHO mode is already done via CFLAGS
166  printInfo(THIS_NAME, "### TEST_MODE = ECHO_CTRL_DISABLED #########\n");
167 
168  //-- STEP-2: Remove previous old files and open new files
169  if (not isDatFile(ofsUSIF_Data_FileName)) {
170  printError(THIS_NAME, "File \'%s\' is not of type \'DAT\'.\n", ofsUSIF_Data_FileName);
171  nrErr++;
172  }
173  else {
174  remove(ofsUSIF_Data_FileName);
175  }
176  if (not isDatFile(ofsUSIF_Meta_FileName)) {
177  printError(THIS_NAME, "File \'%s\' is not of type \'DAT\'.\n", ofsUSIF_Meta_FileName);
178  nrErr++;
179  }
180  else {
181  remove(ofsUSIF_Meta_FileName);
182  if (!ofsUSIF_Meta.is_open()) {
183  ofsUSIF_Meta.open(ofsUSIF_Meta_FileName, ofstream::out);
184  if (!ofsUSIF_Meta) {
185  printError(THIS_NAME, "Cannot open the file: \'%s\'.\n", ofsUSIF_Meta_FileName);
186  nrErr++;
187  }
188  }
189  }
190  if (not isDatFile(ofsUSIF_DLen_FileName)) {
191  printError(THIS_NAME, "File \'%s\' is not of type \'DAT\'.\n", ofsUSIF_DLen_FileName);
192  nrErr++;
193  }
194  else {
195  remove(ofsUSIF_DLen_FileName);
196  if (!ofsUSIF_DLen.is_open()) {
197  ofsUSIF_DLen.open(ofsUSIF_DLen_FileName, ofstream::out);
198  if (!ofsUSIF_DLen) {
199  printError(THIS_NAME, "Cannot open the file: \'%s\'.\n", ofsUSIF_DLen_FileName);
200  nrErr++;
201  }
202  }
203  }
204 
205  //-- STEP-3: Create golden Tx files
206  queue<UdpAppMeta> udpMetaQueue;
207  queue<UdpAppDLen> udpDLenQueue;
208  if (NTS_OK == createGoldenTxFiles(tbCtrlMode, string(argv[2]), udpMetaQueue, udpDLenQueue,
209  ofsUSIF_Data_Gold_FileName, ofsUSIF_Meta_Gold_FileName, ofsUSIF_DLen_Gold_FileName) != NTS_OK) {
210  printError(THIS_NAME, "Failed to create golden Tx files. \n");
211  nrErr++;
212  }
213 
214  //-- STEP-4: Create the USIF->UAF INPUT {Data,Meta} as streams
215  int nrUSIF_UAF_Chunks=0;
216  if (not createUdpRxTraffic(ssUSIF_UAF_Data, "ssUSIF_UAF_Data",
217  ssUSIF_UAF_Meta, "ssUSIF_UAF_Meta",
218  ssUSIF_UAF_DLen, "ssUSIF_UAF_DLen",
219  string(argv[2]),
220  udpMetaQueue, udpDLenQueue,
221  nrUSIF_UAF_Chunks)) {
222  printFatal(THIS_NAME, "Failed to create the USIF->UAF traffic as streams.\n");
223  }
224 
225  //-- STEP-5: Run simulation
226  int tbRun = (nrErr == 0) ? (nrUSIF_UAF_Chunks + TB_GRACE_TIME) : 0;
227  while (tbRun) {
229  //-- SHELL / Mmio Interfaces
230  &sSHL_UAF_Mmio_Enable,
231  //[NOT_USED] sSHL_UAF_Mmio_EchoCtrl,
232  //[NOT_USED] sSHL_UAF_Mmio_PostPktEn,
233  //[NOT_USED] sSHL_UAF_Mmio_CaptPktEn,
234  //-- USIF / Rx Data Interfaces
235  ssUSIF_UAF_Data,
236  ssUSIF_UAF_Meta,
237  ssUSIF_UAF_DLen,
238  //-- USIF / Tx Data Interfaces
239  ssUAF_USIF_Data,
240  ssUAF_USIF_Meta,
241  ssUAF_USIF_DLen);
242  tbRun--;
243  stepSim();
244  }
245 
246  printInfo(THIS_NAME, "############################################################################\n");
247  printInfo(THIS_NAME, "## TESTBENCH 'test_udp_app_flash' ENDS HERE ##\n");
248  printInfo(THIS_NAME, "############################################################################\n");
249  stepSim();
250 
251  //-- STEP-6a: Drain UAF-->USIF DATA OUTPUT STREAM
252  int nrUAF_USIF_DataChunks=0, nrUAF_USIF_DataGrams=0, nrUAF_USIF_DataBytes=0;
253  if (not drainAxisToFile(ssUAF_USIF_Data, "ssUAF_USIF_Data",
254  ofsUSIF_Data_FileName, nrUAF_USIF_DataChunks, nrUAF_USIF_DataGrams, nrUAF_USIF_DataBytes)) {
255  printError(THIS_NAME, "Failed to drain UAF-to-USIF data traffic from DUT. \n");
256  nrErr++;
257  }
258  else {
259  printInfo(THIS_NAME, "Done with the draining of the UAF-to-USIF data traffic:\n");
260  printInfo(THIS_NAME, "\tReceived %d chunks in %d datagrams, for a total of %d bytes.\n\n",
261  nrUAF_USIF_DataChunks, nrUAF_USIF_DataGrams, nrUAF_USIF_DataBytes);
262  }
263  //-- STEP-6b: Drain UAF-->USIF META OUTPUT STREAM
264  int nrUAF_USIF_MetaChunks=0, nrUAF_USIF_MetaGrams=0, nrUAF_USIF_MetaBytes=0;
265  if (not drainUdpMetaStreamToFile(ssUAF_USIF_Meta, "ssUAF_USIF_Meta",
266  ofsUSIF_Meta_FileName, nrUAF_USIF_MetaChunks, nrUAF_USIF_MetaGrams, nrUAF_USIF_MetaBytes)) {
267  printError(THIS_NAME, "Failed to drain UAF-to-USIF meta traffic from DUT. \n");
268  nrErr++;
269  }
270  //-- STEP-6c: Drain UAF-->USIF DLEN OUTPUT STREAM
271  int nrUAF_USIF_DLenChunks=0, nrUAF_USIF_DLenGrams=0, nrUAF_USIF_DLenBytes=0;
272  if (not drainUdpDLenStreamToFile(ssUAF_USIF_DLen, "ssUAF_USIF_DLen",
273  ofsUSIF_DLen_FileName, nrUAF_USIF_DLenChunks, nrUAF_USIF_DLenGrams, nrUAF_USIF_DLenBytes)) {
274  printError(THIS_NAME, "Failed to drain UAF-to-USIF dlen traffic from DUT. \n");
275  nrErr++;
276  }
277 
278  //-- STEP-7: Compare output DAT vs gold DAT
279  int res;
280  ifstream ifsFile;
281 
282  ifsFile.open(ofsUSIF_Data_FileName, ofstream::in);
283  if (!ifsFile) {
284  printError(THIS_NAME, "Cannot open the file: \'%s\'.\n", ofsUSIF_Data_FileName);
285  nrErr++;
286  }
287  else if (not (ifsFile.peek() == ifstream::traits_type::eof())) {
288  res = myDiffTwoFiles(std::string(ofsUSIF_Data_FileName),
289  std::string(ofsUSIF_Data_Gold_FileName));
290  if (res) {
291  printError(THIS_NAME, "File \'%s\' does not match \'%s\'.\n", \
292  ofsUSIF_Data_FileName, ofsUSIF_Data_Gold_FileName.c_str());
293  nrErr += 1;
294  }
295  }
296  else {
297  printError(THIS_NAME, "File \"%s\" is empty.\n", ofsUSIF_Data_FileName);
298  nrErr++;
299  }
300  ifsFile.close();
301 
302  ifsFile.open(ofsUSIF_DLen_FileName, ofstream::in);
303  if (!ifsFile) {
304  printError(THIS_NAME, "Cannot open the file: \'%s\'.\n", ofsUSIF_DLen_FileName);
305  nrErr++;
306  }
307  else if (not (ifsFile.peek() == ifstream::traits_type::eof())) {
308  res = myDiffTwoFiles(std::string(ofsUSIF_DLen_FileName),
309  std::string(ofsUSIF_DLen_Gold_FileName));
310  if (res) {
311  printError(THIS_NAME, "File \'%s\' does not match \'%s\'.\n", \
312  ofsUSIF_DLen_FileName, ofsUSIF_DLen_Gold_FileName.c_str());
313  nrErr += 1;
314  }
315  }
316  else {
317  printError(THIS_NAME, "File \"%s\" is empty.\n", ofsUSIF_DLen_FileName);
318  nrErr++;
319  }
320  ifsFile.close();
321 
322  } // End-of: if (tbCtrlMode == ECHO_CTRL_DISABLED) {
323 
324 
325  //---------------------------------------------------------------
326  //-- PRINT TESTBENCH STATUS
327  //---------------------------------------------------------------
328  printf("\n\n");
329  printInfo(THIS_NAME, "This testbench was executed with the following parameters: \n");
330  printInfo(THIS_NAME, "\t==> TB Mode = %c\n", *argv[1]);
331  for (int i=2; i<argc; i++) {
332  printInfo(THIS_NAME, "\t==> Param[%d] = %s\n", (i-1), argv[i]);
333  }
334 
335  if (nrErr) {
336  printError(THIS_NAME, "###########################################################\n");
337  printError(THIS_NAME, "#### TEST BENCH FAILED : TOTAL NUMBER OF ERROR(S) = %2d ####\n", nrErr);
338  printError(THIS_NAME, "###########################################################\n\n");
339 
340  printInfo(THIS_NAME, "FYI - You may want to check for \'ERROR\' and/or \'WARNING\' alarms in the LOG file...\n\n");
341  }
342  else {
343  printInfo(THIS_NAME, "#############################################################\n");
344  printInfo(THIS_NAME, "#### SUCCESSFUL END OF TEST ####\n");
345  printInfo(THIS_NAME, "#############################################################\n");
346  }
347 
348  return nrErr;
349 
350 }
351 
int main()
Definition: tb_fmc.cpp:380
EchoCtrl
Definition: memtest.hpp:49
#define TB_GRACE_TIME
Definition: test_arp.hpp:54
void stepSim()
Increment the simulation counter.
Definition: test_arp.cpp:54
bool isDatFile(string fileName)
Checks if a file has a ".dat" extension.
Definition: SimNtsUtils.cpp:52
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.
int myDiffTwoFiles(string dataFileName, string goldFileName)
Compares 2 files line-by-line, up to length of the 2nd file.
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
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 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 printError(callerName, format,...)
A macro to print an error message.
Definition: nts_utils.hpp:195
#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 printFatal(callerName, format,...)
A macro to print a fatal error message and exit.
Definition: nts_utils.hpp:208
unsigned int gMaxSimCycles
Definition: test_arp.hpp:69
int createUdpRxTraffic(stream< AxisApp > &ssData, const string ssDataName, stream< UdpAppMeta > &ssMeta, const string ssMetaName, stream< UdpAppDLen > &ssDLen, const string ssMDLenName, string datFile, queue< UdpAppMeta > &metaQueue, queue< UdpAppDLen > &dlenQueue, int &nrFeededChunks)
Create the UDP Rx traffic as streams from an input test file.
unsigned int gSimCycCnt
Definition: tb_nal.cpp:150
#define THIS_NAME
void udp_app_flash_top(CmdBit *piSHL_Mmio_En, stream< UdpAppData > &siUSIF_Data, stream< UdpAppMeta > &siUSIF_Meta, stream< UdpAppDLen > &siUSIF_DLen, stream< UdpAppData > &soUSIF_Data, stream< UdpAppMeta > &soUSIF_Meta, stream< UdpAppDLen > &soUSIF_DLen)
Top of UDP Application Flash (UAF)
@ ECHO_STORE_FWD
Definition: memtest.hpp:51
@ ECHO_CTRL_DISABLED
@ ECHO_OFF
Definition: memtest.hpp:52
@ ECHO_PATH_THRU
Definition: memtest.hpp:50
out
Definition: test.py:12
: Testbench for toplevel of the UDP Application Flash.