cloudFPGA (cF) API  1.0
The documentation of the source code of cloudFPGA (cF)
test_triangle_app.cpp
Go to the documentation of this file.
1 /*
2  * Copyright 2016 -- 2022 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 
18 
28 #include <stdio.h>
29 #include <hls_stream.h>
30 
31 #include "../src/triangle_app.hpp"
32 
33 using namespace std;
34 
35 
36 #define OK true
37 #define KO false
38 #define VALID true
39 #define UNVALID false
40 #define DEBUG_TRACE true
41 
42 #define ENABLED (ap_uint<1>)1
43 #define DISABLED (ap_uint<1>)0
44 
45 //------------------------------------------------------
46 //-- DUT INTERFACES AS GLOBAL VARIABLES
47 //------------------------------------------------------
48 
49 //-- SHELL / Uaf / Mmio / Config Interfaces
50 //ap_uint<2> piSHL_This_MmioEchoCtrl;
53 
54 //-- SHELL / Uaf / Udp Interfaces
55 stream<UdpWord> sSHL_Uaf_Data ("sSHL_Uaf_Data");
56 stream<UdpWord> sUAF_Shl_Data ("sUAF_Shl_Data");
57 ap_uint<32> s_udp_rx_ports = 0x0;
58 stream<NetworkMetaStream> siUdp_meta ("siUdp_meta");
59 stream<NetworkMetaStream> soUdp_meta ("soUdp_meta");
60 ap_uint<32> node_rank;
61 ap_uint<32> size;
62 
63 //------------------------------------------------------
64 //-- TESTBENCH GLOBAL VARIABLES
65 //------------------------------------------------------
66 int simCnt;
67 
68 
69 
74 void stepDut() {
76  &node_rank, &size,
80  simCnt++;
81  printf("[%4.4d] STEP DUT \n", simCnt);
82 }
83 
84 
93 bool setInputDataStream(stream<UdpWord> &sDataStream, const string dataStreamName, const string inpFileName) {
94  string strLine;
95  ifstream inpFileStream;
96  string datFile = "../../../../test/" + inpFileName;
97  UdpWord udpWord;
98 
99  //-- STEP-1 : OPEN FILE
100  inpFileStream.open(datFile.c_str());
101  if ( !inpFileStream ) {
102  cout << "### ERROR : Could not open the input data file " << datFile << endl;
103  return(KO);
104  }
105 
106  //-- STEP-2 : SET DATA STREAM
107  while (inpFileStream) {
108 
109  if (!inpFileStream.eof()) {
110 
111  getline(inpFileStream, strLine);
112  if (strLine.empty()) continue;
113  sscanf(strLine.c_str(), "%llx %x %d", &udpWord.tdata, &udpWord.tkeep, &udpWord.tlast);
114 
115  // Write to sDataStream
116  if (sDataStream.full()) {
117  printf("### ERROR : Stream is full. Cannot write stream with data from file \"%s\".\n", inpFileName.c_str());
118  return(KO);
119  } else {
120  sDataStream.write(udpWord);
121  // Print Data to console
122  printf("[%4.4d] TB is filling input stream [%s] - Data write = {D=0x%16.16llX, K=0x%2.2X, L=%d} \n",
123  simCnt, dataStreamName.c_str(),
124  udpWord.tdata.to_long(), udpWord.tkeep.to_int(), udpWord.tlast.to_int());
125  }
126  }
127  }
128 
129  //-- STEP-3: CLOSE FILE
130  inpFileStream.close();
131 
132  return(OK);
133 }
134 
135 
136 
137 
147 bool readDataStream(stream <UdpWord> &sDataStream, UdpWord *udpWord) {
148  // Get the DUT/Data results
149  sDataStream.read(*udpWord);
150  return(VALID);
151 }
152 
153 
154 
162 bool dumpDataToFile(UdpWord *udpWord, ofstream &outFileStream) {
163  if (!outFileStream.is_open()) {
164  printf("### ERROR : Output file stream is not open. \n");
165  return(KO);
166  }
167  outFileStream << hex << noshowbase << setfill('0') << setw(16) << udpWord->tdata.to_uint64();
168  outFileStream << " ";
169  outFileStream << hex << noshowbase << setfill('0') << setw(2) << udpWord->tkeep.to_int();
170  outFileStream << " ";
171  outFileStream << setw(1) << udpWord->tlast.to_int() << "\n";
172  return(OK);
173 }
174 
175 
176 
185 bool getOutputDataStream(stream<UdpWord> &sDataStream,
186  const string dataStreamName, const string outFileName)
187 {
188  string strLine;
189  ofstream outFileStream;
190  string datFile = "../../../../test/" + outFileName;
191  UdpWord udpWord;
192  bool rc = OK;
193 
194  //-- STEP-1 : OPEN FILE
195  outFileStream.open(datFile.c_str());
196  if ( !outFileStream ) {
197  cout << "### ERROR : Could not open the output data file " << datFile << endl;
198  return(KO);
199  }
200 
201  //-- STEP-2 : EMPTY STREAM AND DUMP DATA TO FILE
202  while (!sDataStream.empty()) {
203  if (readDataStream(sDataStream, &udpWord) == VALID) {
204  // Print DUT/Data to console
205  printf("[%4.4d] TB is draining output stream [%s] - Data read = {D=0x%16.16llX, K=0x%2.2X, L=%d} \n",
206  simCnt, dataStreamName.c_str(),
207  udpWord.tdata.to_long(), udpWord.tkeep.to_int(), udpWord.tlast.to_int());
208  if (!dumpDataToFile(&udpWord, outFileStream)) {
209  rc = KO;
210  break;
211  }
212  }
213  }
214 
215  //-- STEP-3: CLOSE FILE
216  outFileStream.close();
217 
218  return(rc);
219 }
220 
221 
222 int main() {
223 
224  //------------------------------------------------------
225  //-- TESTBENCH LOCAL VARIABLES
226  //------------------------------------------------------
227  int nrErr = 0;
228 
229  printf("#####################################################\n");
230  printf("## TESTBENCH STARTS HERE ##\n");
231  printf("#####################################################\n");
232 
233  simCnt = 0;
234  nrErr = 0;
235 
236  //------------------------------------------------------
237  //-- STEP-1.1 : CREATE TRAFFIC AS INPUT STREAMS
238  //------------------------------------------------------
239  if (nrErr == 0) {
240  if (!setInputDataStream(sSHL_Uaf_Data, "sSHL_Uaf_Data", "ifsSHL_Uaf_Data.dat")) {
241  printf("### ERROR : Failed to set input data stream \"sSHL_Uaf_Data\". \n");
242  nrErr++;
243  }
244 
245  //there are 2 streams from the the App to the Role
247  siUdp_meta.write(NetworkMetaStream(tmp_meta));
248  siUdp_meta.write(NetworkMetaStream(tmp_meta));
249  //set correct node_rank and size
250  node_rank = 1;
251  size = 3;
252  }
253 
254  //------------------------------------------------------
255  //-- STEP-1.2 : SET THE PASS-THROUGH MODE
256  //------------------------------------------------------
257  //piSHL_This_MmioEchoCtrl.write(ECHO_PATH_THRU);
258  //[TODO] piSHL_This_MmioPostPktEn.write(DISABLED);
259  //[TODO] piSHL_This_MmioCaptPktEn.write(DISABLED);
260 
261  //------------------------------------------------------
262  //-- STEP-2 : MAIN TRAFFIC LOOP
263  //------------------------------------------------------
264  while (!nrErr) {
265 
266  if (simCnt < 25)
267  {
268  stepDut();
269 
270  if(simCnt > 2)
271  {
272  assert(s_udp_rx_ports == 0x1);
273  }
274 
275  //if( !soUdp_meta.empty())
276  //{
277  // NetworkMetaStream tmp_meta = soUdp_meta.read();
278  // printf("NRC received NRCmeta stream from node_rank %d.\n", (int) tmp_meta.tdata.src_rank);
279  //}
280 
281 
282  } else {
283  printf("## End of simulation at cycle=%3d. \n", simCnt);
284  break;
285  }
286 
287  } // End: while()
288 
289  //-------------------------------------------------------
290  //-- STEP-3 : DRAIN AND WRITE OUTPUT FILE STREAMS
291  //-------------------------------------------------------
292  //---- UAF-->SHELL Data ----
293  if (!getOutputDataStream(sUAF_Shl_Data, "sUAF_Shl_Data", "ofsUAF_Shl_Data.dat"))
294  {
295  nrErr++;
296  }
297  //---- UAF-->SHELL META ----
298  if( !soUdp_meta.empty())
299  {
300  int i = 0;
301  while( !soUdp_meta.empty())
302  {
303  i++;
304  NetworkMetaStream tmp_meta = soUdp_meta.read();
305  printf("NRC received NRCmeta stream to rank %d.\n", (int) tmp_meta.tdata.dst_rank);
306  //assert(tmp_meta.tdata.src_rank == node_rank); //is not relevant
307  //ensure forwarding behavior
308  assert(tmp_meta.tdata.dst_rank == ((node_rank + 1) % size));
309  }
310  assert(i == 2);
311  } else {
312  printf("Error No metadata received...\n");
313  nrErr++;
314  }
315 
316  //------------------------------------------------------
317  //-- STEP-4 : COMPARE INPUT AND OUTPUT FILE STREAMS
318  //------------------------------------------------------
319  int rc1 = system("diff --brief -w -i -y ../../../../test/ofsUAF_Shl_Data.dat \
320  ../../../../test/ifsSHL_Uaf_Data.dat");
321  if (rc1)
322  printf("## Error : File \'ofsUAF_Shl_Data.dat\' does not match \'ifsSHL_Uaf_Data.dat\'.\n");
323 
324  nrErr += rc1;
325 
326  printf("#####################################################\n");
327  if (nrErr)
328  printf("## ERROR - TESTBENCH FAILED (RC=%d) !!! ##\n", nrErr);
329  else
330  printf("## SUCCESSFULL END OF TESTBENCH (RC=0) ##\n");
331 
332  printf("#####################################################\n");
333 
334  return(nrErr);
335 }
#define DEFAULT_RX_PORT
Definition: nal.hpp:139
bool getOutputDataStream(stream< UdpWord > &sDataStream, const string dataStreamName, const string outFileName)
Fill an output file with data from an output stream.
bool readDataStream(stream< UdpWord > &sDataStream, UdpWord *udpWord)
Read data from a stream.
bool dumpDataToFile(UdpWord *udpWord, ofstream &outFileStream)
Dump a data word to a file.
void stepDut()
Run a single iteration of the DUT model.
bool setInputDataStream(stream< UdpWord > &sDataStream, const string dataStreamName, const string inpFileName)
Initialize an input data stream from a file.
NetworkMeta tdata
Definition: network.hpp:109
NodeId dst_rank
Definition: network.hpp:95
ap_uint< 64 > tdata
ap_uint< 1 > tlast
ap_uint< 8 > tkeep
stream< NetworkMetaStream > siUdp_meta("siUdp_meta")
ap_uint< 32 > size
stream< NetworkMetaStream > soUdp_meta("soUdp_meta")
int simCnt
ap_uint< 1 > piSHL_This_MmioCaptPktEn
ap_uint< 1 > piSHL_This_MmioPostPktEn
stream< UdpWord > sUAF_Shl_Data("sUAF_Shl_Data")
#define OK
#define KO
#define VALID
stream< UdpWord > sSHL_Uaf_Data("sSHL_Uaf_Data")
int main()
ap_uint< 32 > s_udp_rx_ports
ap_uint< 32 > node_rank
void triangle_app(ap_uint< 32 > *pi_rank, ap_uint< 32 > *pi_size, stream< NetworkWord > &siNrc_data, stream< NetworkWord > &soNrc_data, stream< NetworkMetaStream > &siNrc_meta, stream< NetworkMetaStream > &soNrc_meta, ap_uint< 32 > *po_rx_ports)
Main process of the UDP/TCP Triangle Application. This HLS IP receives a packet and forwards it to th...