cloudFPGA (cF) API  1.0
The documentation of the source code of cloudFPGA (cF)
test_memtest.cpp
Go to the documentation of this file.
1 
20 #include "../../memtest/include/memtest.hpp"
21 #include "../../common/src/common.cpp"
22 #include <math.h>
23 
24 using namespace std;
25 
26 //---------------------------------------------------------
27 // HELPERS FOR THE DEBUGGING TRACES
28 // .e.g: DEBUG_LEVEL = (MDL_TRACE | IPS_TRACE)
29 //---------------------------------------------------------
30 #define THIS_NAME "TB"
31 
32 #define TRACE_OFF 0x0000
33 #define TRACE_URIF 1 << 1
34 #define TRACE_UAF 1 << 2
35 #define TRACE_MMIO 1 << 3
36 #define TRACE_ALL 0xFFFF
37 #define DEBUG_MULTI_RUNS True
38 #define TB_MULTI_RUNS_ITERATIONS 2
39 #define DEBUG_LEVEL (TRACE_ALL)
40 
41 
42 //------------------------------------------------------
43 //-- TESTBENCH DEFINES
44 //------------------------------------------------------
45 #define OK true
46 #define KO false
47 #define VALID true
48 #define UNVALID false
49 #define DEBUG_TRACE true
50 
51 #define ENABLED (ap_uint<1>)1
52 #define DISABLED (ap_uint<1>)0
53 
54 
55 
56 //------------------------------------------------------
57 //-- DUT INTERFACES AS GLOBAL VARIABLES
58 //------------------------------------------------------
59 
60 //-- SHELL / Uaf / Mmio / Config Interfaces
61 //ap_uint<2> piSHL_This_MmioEchoCtrl;
64 
65 //-- SHELL / Uaf / Udp Interfaces
66 stream<UdpWord> sSHL_Uaf_Data ("sSHL_Uaf_Data");
67 stream<UdpWord> sUAF_Shl_Data ("sUAF_Shl_Data");
68 stream<UdpWord> image_stream_from_memtest ("image_stream_from_memtest");
69 
70 ap_uint<32> s_udp_rx_ports = 0x0;
71 stream<NetworkMetaStream> siUdp_meta ("siUdp_meta");
72 stream<NetworkMetaStream> soUdp_meta ("soUdp_meta");
73 ap_uint<32> node_rank;
74 ap_uint<32> cluster_size;
75 
76 //------------------------------------------------------
77 //-- TESTBENCH GLOBAL VARIABLES
78 //------------------------------------------------------
79 unsigned int simCnt;
80 
81 
82 //------------------------------------------------------
83 //-- SHELL / Role / Mem / Mp1 Interface
84 //------------------------------------------------------
85 #ifdef ENABLE_DDR
86 #define MEMORY_LINES_512 TOTMEMDW_512 /* 64 KiB */
89 #endif
90 
94 void stepDut() {
95  memtest(
100  #ifdef ENABLE_DDR
101  ,
102  lcl_mem0,
103  lcl_mem0
104  #endif
105  );
106  simCnt++;
107  #if DEBUG_LEVEL > TRACE_OFF
108  printf("[%4.4d] STEP DUT \n", simCnt);
109  #endif
110 }
111 
112 
113 
114 
119 int main(int argc, char** argv) {
120 
121  //------------------------------------------------------
122  //-- TESTBENCH LOCAL VARIABLES
123  //------------------------------------------------------
124  int nrErr = 0;
125 
126  printf("#####################################################\n");
127  printf("## TESTBENCH STARTS HERE ##\n");
128  printf("#####################################################\n");
129 // consider to execute : ulimit -s unlimited
130 // if any stack/memory related issue before executing
131 
132  if (argc < 3 || argc > 5) {
133  printf("Usage : %s <number of address to test> , <testing times> , <burst size> <command string ready2go> ;provided %d\n", argv[0], argc);
134  return -1;
135  }
136 
137  //------------------------------------------------------
138  //-- TESTBENCH Input parsing
139  //------------------------------------------------------
140  string strInput_memaddrUT = argv[1];
141  string strInput_nmbrTest = argv[2];
142  string strInput_burstSize = argv[3];
143  string strInput_commandstring= "";
144  if(argc > 4)
145  {
146  strInput_commandstring.assign(argv[4]);
147  }
148  unsigned long long int memory_addr_under_test=0;
149  unsigned int testingNumber = 1;
150  unsigned int burst_size = 1;
151  if (!strInput_memaddrUT.length() || !strInput_nmbrTest.length()) {
152  printf("ERROR: Empty string provided. Aborting...\n");
153  return -1;
154  }
155  else {
156  try
157  {
158  memory_addr_under_test = stoull(strInput_memaddrUT);
159  }
160  catch(const std::exception& e)
161  {
162  std::cerr << e.what() << '\n';
163  memory_addr_under_test = 65; //at least a fault
164  }
165  try
166  {
167  testingNumber = stoul(strInput_nmbrTest);
168  }
169  catch(const std::exception& e)
170  {
171  std::cerr << e.what() << '\n';
172  testingNumber = 3; //at least see the fault
173  }
174 
175  try
176  {
177  burst_size = stoul(strInput_burstSize);
178  }
179  catch(const std::exception& e)
180  {
181  std::cerr << e.what() << '\n';
182  burst_size = 1; //at least see the fault
183  }
184 
185 
186  printf("Succesfully loaded string ... %s\n", argv[1]);
187  printf("Succesfully loaded the address number %u and the number of testings %u, with busrt size %u\n", memory_addr_under_test, testingNumber, burst_size);
188  // Ensure that the selection of MTU is a multiple of 8 (Bytes per transaction)
189  assert(PACK_SIZE % 8 == 0);
190  }
191 
192  //------------------------------------------------------
193  //-- TESTBENCH LOCAL VARIABLES FOR MEMTEST
194  //------------------------------------------------------
195  //unsigned int sim_time = testingNumber * ((2 * (memory_addr_under_test/64+2)) + 5 + 1) + 2 + 1 + 20; // # of tests*((2*(rd/wr addresses + 2 state update))+start+out*4) + meta+start + 10 random cycles
196  unsigned int sim_time = 1 + 3 + testingNumber * (1 + 2 + 5) + 1 + 2 + 10; // meta-pckt-brst testnmbr*(strt-wr-rd-out1-out2-out3-out4-out5) + final cntstart + 2 tx + 10 rand
197  size_t charInputSize = 8*2; //a single tdata is the current command dimension for this test, plus the burst cmd
198  size_t charOutputSize = 8*1+((8 * (2 + 1 + 1 + 1)) * testingNumber); //overdimensioned: eventual stop, 4 (address, fault cntr, flt addr, ccs) for each test foreach test
199 
200  unsigned int tot_input_transfers = CEIL(( 2 ) * 8,PACK_SIZE);// only a single tx + 1
201  unsigned int tot_output_transfers = charOutputSize%PACK_SIZE==0 ? charOutputSize/PACK_SIZE : charOutputSize/PACK_SIZE + 1; // check if bigger output than mtu
202  // if(charOutputSize>PACK_SIZE){
203  // tot_output_transfers = charOutputSize%PACK_SIZE==0 ? charOutputSize/PACK_SIZE : charOutputSize/PACK_SIZE + 1;
204  // }
205 
206  char *charOutput = (char*)malloc((charOutputSize)* sizeof(char)); //
207  //char * charOutput = new char[(charOutputSize)* sizeof(char)];
208  char *charInput = (char*)malloc(charInputSize* sizeof(char)); //
209  //char * charInput = new char[(charInputSize)* sizeof(char)]; //
210 
211  if (!charOutput || !charInput) {
212  printf("ERROR: Cannot allocate memory for output string. Aborting...\n");
213  return -1;
214  }
215  std::vector<MemoryTestResult> testResults_vector;
216 
217  //------------------------------------------------------
218  //-- STEP-1.1 : CREATE MEMORY FOR OUTPUT IMAGES
219  //------------------------------------------------------
220  unsigned int bytes_per_line = 8;
221  string strInput;
222  strInput.reserve(charInputSize+1);
223  string strGold;
224  strGold.reserve(charOutputSize+1);
225 
226 #ifdef SIM_STOP_COMPUTATION // stop the comptuation with a stop command after some CCs
227 
228  std::string strStop;
229  char stop_cmd [bytes_per_line];
230  for (unsigned int k = 0; k < bytes_per_line; k++) {
231  if (k != 0) {
232  stop_cmd[k] = (char)0;
233  }
234  else {
235  stop_cmd[k] = (char)2;
236  }
237  }
238  strStop.append(stop_cmd,8);
239 #endif //SIM_STOP_COMPUTATION
240 
241 
242  simCnt = 0;
243  nrErr = 0;
244 // Assumption: if the user knows how to format the command stream she/he does by itself (
245 // otheriwse the TB takes care and create the commands based on the inputs
246  if(!strInput_commandstring.length()){
247  strInput=createMemTestCommands(memory_addr_under_test, testingNumber, burst_size);
248  }else{
252  //char * char_command = new char[strInput_commandstring.length()+1];
253  char * char_command = (char*)malloc((strInput_commandstring.length()+1)* sizeof(char));
254  char_command[0]='\0';//initi just for the sake
255  char tmp_char_cmd [1];
256  tmp_char_cmd[1] = (char)0;
257  unsigned int tmp_int_cmd = 0;
258  //char_command = new char[strInput_commandstring.length()];
259  // cout << strInput_commandstring << endl;
260  // for (int i = 0; i < strInput_commandstring.length(); i++)
261  // {
262  // tmp_char_cmd[1] = strInput_commandstring[i];
263  // tmp_int_cmd = (unsigned int)atoi(tmp_char_cmd);
264  // memcpy(char_command+i,(char*)&tmp_int_cmd, sizeof(char));
265  // tmp_char_cmd[1] = (char)0;
266  // tmp_int_cmd = 0;
267  // }
268  // strInput.append(char_command,strInput_commandstring.length());
269  // printStringHex(strInput_commandstring, strInput_commandstring.length());
270  // printCharBuffHex(char_command, strInput_commandstring.length());
271  // printStringHex(strInput, strInput_commandstring.length());
272  strInput=createMemTestCommands(memory_addr_under_test, testingNumber, burst_size);
273  if(char_command != NULL){
274  cout << "Clearing the char command" << endl;
275  delete[] char_command;
276  char_command = NULL;
277  }
278  }
279  //Create the expected result
280  strGold = createMemTestGoldenOutput(memory_addr_under_test, testingNumber, true);
281 
282  if (!dumpStringToFile(strInput, "ifsSHL_Uaf_Data.dat", simCnt)) {
283  nrErr++;
284  }
285  //Set the tlast every PACK_SIZE/8 commands if big output tests
286  if (!dumpStringToFileWithLastSetEveryGnoPackets(strGold, "verify_UAF_Shl_Data.dat", simCnt, PACK_SIZE/8)){
287  nrErr++;
288  }
289 
290 #ifdef SIM_STOP_COMPUTATION // stop the comptuation with a stop command after some CCs
291  if (!dumpStringToFile(strStop, "ifsSHL_Uaf_STOPData.dat", simCnt)){
292  nrErr++;
293  }
294 #endif // SIM_STOP_COMPUTATION
295 
296 
297 #ifdef DEBUG_MULTI_RUNS // test if the HLS kernel has reinit issues with streams leftovers or other stuffs
298 for(int iterations=0; iterations < TB_MULTI_RUNS_ITERATIONS; iterations++){
299 #endif //DEBUG_MULTI_RUNS
300 
301 #ifdef ENABLE_DDR
302 for(int i=0; i < MEMORY_LINES_512; i++){
303  lcl_mem0[i]=0;
304  lcl_mem1[i]=0;
305 }
306 #endif//ENABLE_DDR
307  //------------------------------------------------------
308  //-- STEP-2.1 : CREATE TRAFFIC AS INPUT STREAMS
309  //------------------------------------------------------
310  if (nrErr == 0) {
311  if (!setInputDataStream(sSHL_Uaf_Data, "sSHL_Uaf_Data", "ifsSHL_Uaf_Data.dat", simCnt)) {
312  printf("### ERROR : Failed to set input data stream \"sSHL_Uaf_Data\". \n");
313  nrErr++;
314  }
315  //there are tot_input_transfers streams from the the App to the Role
317  for (unsigned int i=0; i<tot_input_transfers; i++) {
318  siUdp_meta.write(NetworkMetaStream(tmp_meta));
319  }
320 
321  //set correct node_rank and cluster_size
322  node_rank = 1;
323  cluster_size = 2;
324  }
325  //------------------------------------------------------
326  //-- STEP-3 : MAIN TRAFFIC LOOP
327  //------------------------------------------------------
328  while (!nrErr) {
329  // Keep enough simulation time for sequntially executing the FSMs of the main functions
330  // (Rx-Tx)
331  if (simCnt < sim_time)
332  {
333  //+1
334  stepDut();
335  if(simCnt > 2)
336  {
337  assert(s_udp_rx_ports == 0x1);
338  }
339 
340  #ifdef SIM_STOP_COMPUTATION // stop the comptuation with a stop command after some CCs manual insertion with define
341  if(simCnt == testingNumber * ((2 * (memory_addr_under_test+1))) + 2){
342  if (!setInputDataStream(sSHL_Uaf_Data, "sSHL_Uaf_Data", "ifsSHL_Uaf_STOPData.dat", simCnt)) {
343  printf("### ERROR : Failed to set input data stream \"sSHL_Uaf_Data\". \n");
344  nrErr++;
345  }
346  //there are tot_input_transfers streams from the the App to the Role
348  for (unsigned int i=0; i<tot_input_transfers; i++) {
349  siUdp_meta.write(NetworkMetaStream(tmp_meta));
350  }
351  //set correct node_rank and cluster_size
352  node_rank = 1;
353  cluster_size = 2;
354  }
355  #endif //SIM_STOP_COMPUTATION
356  } else {
357  printf("## End of simulation at cycle=%3d. \n", simCnt);
358  break;
359  }
360 
361  } // End: while()
362 
363  //-------------------------------------------------------
364  //-- STEP-4 : DRAIN AND WRITE OUTPUT FILE STREAMS
365  //-------------------------------------------------------
366  //---- UAF-->SHELL Data ----
367  if (!getOutputDataStream(sUAF_Shl_Data, "sUAF_Shl_Data", "ofsUAF_Shl_Data.dat", simCnt))
368  {
369  nrErr++;
370  }
371  //---- UAF-->SHELL META ----
372  if( !soUdp_meta.empty())
373  {
374  unsigned int i = 0;
375  while( !soUdp_meta.empty())
376  {
377  i++;
378  NetworkMetaStream tmp_meta = soUdp_meta.read();
379  printf("NRC received NRCmeta stream from rank %d to rank %d.\n", (int) tmp_meta.tdata.src_rank, (int) tmp_meta.tdata.dst_rank);
380  assert(tmp_meta.tdata.src_rank == node_rank);
381  //ensure forwarding behavior
382  assert(tmp_meta.tdata.dst_rank == ((tmp_meta.tdata.src_rank + 1) % cluster_size));
383  }
384  //verify the output prediction
385  assert(i == tot_output_transfers);
386  }
387  else {
388  printf("Error No metadata received...\n");
389  nrErr++;
390  }
391 
392  //-------------------------------------------------------
393  //-- STEP-5 : FROM THE OUTPUT FILE CREATE AN ARRAY
394  //-------------------------------------------------------
395  if (!dumpFileToString("ifsSHL_Uaf_Data.dat", charInput, simCnt)) {
396  printf("### ERROR : Failed to set string from file \"ofsUAF_Shl_Data.dat\". \n");
397  nrErr++;
398  }
399  printf("Input string : ");
400  for (unsigned int i = 0; i < charInputSize; i++)
401  printf("%x", charInput[i]); //hex print since not real chars
402  printf("\n");
403  if (!dumpFileToString("ofsUAF_Shl_Data.dat", charOutput, simCnt)) {
404  printf("### ERROR : Failed to set string from file \"ofsUAF_Shl_Data.dat\". \n");
405  nrErr++;
406  }
407 
408  //__file_write("./hls_out.txt", charOutput, charOutputSize);
409  string out_string;
410  out_string.reserve(charOutputSize);
411  string tmpToDebug = string(charOutput,charOutputSize);
412  out_string.append(tmpToDebug,0, charOutputSize);
413  dumpStringToFileOnlyRawData(out_string, "./hls_out.txt", simCnt, charOutputSize);
414  printf("Output string: ");
415  for (unsigned int i = 0; i < charOutputSize; i++)
416  printf("%x", charOutput[i]); //hex print since not real chars
417  printf("\n");
418  out_string.clear();
419 
420  //------------------------------------------------------
421  //-- STEP-6 : COMPARE GOLD AND OUTPUT FILE STREAMS
422  //------------------------------------------------------
423  int rc1 = system("diff --brief -w -i -y ../../../../test/ofsUAF_Shl_Data.dat \
424  ../../../../test/verify_UAF_Shl_Data.dat");
425 
426  if (rc1)
427  {
428  printf("## Error : File \'ofsUAF_Shl_Data.dat\' does not match \'verify_UAF_Shl_Data.dat\'.\n");
429  } else {
430  printf("Output data in file \'ofsUAF_Shl_Data.dat\' verified.\n");
431  }
432 
433 // #ifdef ENABLE_DDR
434 // for(int i=0; i < MEMORY_LINES_512; i++){
435 // if(lcl_mem0[i]!=lcl_mem1[i]){
436 // cout << "Main mem difference :" << lcl_mem0[i] << " " << lcl_mem1[i] << endl;
437 // }else{
438 // cout << "ok ";
439 // }
440 // }
441 // #endif//ENABLE_DDR
442 
443  //------------------------------------------------------
444  //-- STEP-7 [OPTIONAL] : Parse the output stream
445  //------------------------------------------------------
446  const string ouf_file ="./hls_out.txt";
447  int rawdatalines=0;
448  string longbuf_string;
449  longbuf_string.reserve(charOutputSize);
450  longbuf_string = dumpFileToStringRawDataString(ouf_file, &rawdatalines, charOutputSize);
451 
452  testResults_vector=parseMemoryTestOutput(longbuf_string,charOutputSize,rawdatalines);
453  //------------------------------------------------------
454  //-- STEP-8 : Clear everything
455  //------------------------------------------------------
456  longbuf_string.clear();
457  testResults_vector.clear();
458  cout<< endl << " End the TB with iteration " << iterations << endl << endl;
459 
460  nrErr += rc1;
461 
462  printf("#####################################################\n");
463  if (nrErr)
464  {
465  printf("## ERROR - TESTBENCH FAILED (RC=%d) !!! ##\n", nrErr);
466  } else {
467  printf("## SUCCESSFULL END OF TESTBENCH (RC=0) ##\n");
468  }
469  printf("#####################################################\n");
470 
471  simCnt = 0;//reset sim counter
472  nrErr=0;
473 #ifdef DEBUG_MULTI_RUNS
474 }
475  #endif//DEBUG_MULTI_RUNS
476 
477 
478 //free dynamic memory
479 if(charOutput != NULL){
480  free(charOutput);
481  charOutput = NULL;
482 }
483 if(charInput != NULL){
484  free(charInput);
485  charInput = NULL;
486 }
487  return(nrErr);
488 }
489 
490 
491 
bool dumpStringToFileOnlyRawData(const std::string s, const std::string outFileName, int simCnt, size_t out_size)
Fill an output file with data from an image.
bool dumpFileToString(const std::string inpFileName, std::string strOutput, int simCnt)
Initialize an input data stream from a file.
bool dumpStringToFileWithLastSetEveryGnoPackets(std::string s, const std::string outFileName, int simCnt, int gno)
Fill an output file with data from a string and set the tlast every gno packets.
std::string createMemTestGoldenOutput(unsigned long long int mem_address, int testingNumber)
Create the expected output results for the memory test (with FAULT INJECTION)
bool dumpStringToFile(std::string s, const std::string outFileName, int simCnt)
Initialize an input data stream from a file.
void memtest(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, membus_t *lcl_mem0, membus_t *lcl_mem1)
Main process of the Memtest Application directives.
Definition: memtest.cpp:39
#define ENABLE_DDR
Definition: memtest.hpp:42
membus_512_t membus_t
Definition: memtest.hpp:92
unsigned int simCnt
stream< NetworkMetaStream > siUdp_meta("siUdp_meta")
int main(int argc, char **argv)
Main testbench of Hrris.
stream< NetworkMetaStream > soUdp_meta("soUdp_meta")
stream< UdpWord > image_stream_from_memtest("image_stream_from_memtest")
#define TB_MULTI_RUNS_ITERATIONS
ap_uint< 1 > piSHL_This_MmioCaptPktEn
ap_uint< 1 > piSHL_This_MmioPostPktEn
membus_t lcl_mem0[16384]
membus_t lcl_mem1[16384]
void stepDut()
Run a single iteration of the DUT model.
#define MEMORY_LINES_512
ap_uint< 32 > cluster_size
ap_uint< 32 > s_udp_rx_ports
stream< UdpWord > sSHL_Uaf_Data("sSHL_Uaf_Data")
ap_uint< 32 > node_rank
stream< UdpWord > sUAF_Shl_Data("sUAF_Shl_Data")
std::vector< MemoryTestResult > parseMemoryTestOutput(const string longbuf, size_t charOutputSize, int rawdatalines)
Parse the memory test output contained in astring with a given size.
Definition: common.hpp:444
string dumpFileToStringRawDataString(const string inpFileName, int *rawdatalines, size_t outputSize)
Initialize an input data stream from a file with only data.
Definition: common.hpp:279
string createMemTestCommands(unsigned long long int mem_address, unsigned int testingNumber, unsigned int burst_size)
Create the commands for a memory test with start/max address to test-nop to execute-stop.
Definition: common.hpp:137
#define PACK_SIZE
Definition: config.h:51
#define CEIL(a, b)
Definition: config.h:37
bool setInputDataStream(stream< UdpAppData > &sDataStream, const string dataStreamName, const string inpFileName)
Initialize an input data stream from a file.
Definition: tb_nal.cpp:214
#define DEFAULT_RX_PORT
Definition: nal.hpp:139
bool getOutputDataStream(stream< UdpAppData > &sDataStream, const string dataStreamName, const string outFileName)
Fill an output file with data from an output stream.
Definition: tb_nal.cpp:526
NetworkMeta tdata
Definition: network.hpp:109
NodeId dst_rank
Definition: network.hpp:95
NodeId src_rank
Definition: network.hpp:97