cloudFPGA (cF) API  1.0
The documentation of the source code of cloudFPGA (cF)
test_udp.cpp
Go to the documentation of this file.
1 
17 
42 #include "../src/udp.hpp"
43 
44 using namespace std;
45 
46 #define maxOverflowValue 2000
47 
48 uint32_t clockCounter = 0;
49 
50 ap_uint<64> convertString(std::string stringToConvert) {
51  ap_uint<64> tempOutput = 0;
52  unsigned short int tempValue = 16;
53  static const char* const lut = "0123456789ABCDEF";
54 
55  for (unsigned short int i = 0; i<stringToConvert.size();++i) {
56  tempValue = 16;
57  for (unsigned short int j = 0;j<16;++j) {
58  if (lut[j] == stringToConvert[i]) {
59  tempValue = j;
60  break;
61  }
62  }
63  if (tempValue != 16) {
64  for (short int k = 3;k>=0;--k) {
65  if (tempValue >= pow(2.0, k)) {
66  tempOutput.bit(63-(4*i+(3-k))) = 1;
67  tempValue -= static_cast <unsigned short int>(pow(2.0, k));
68  }
69  }
70  }
71  else return -1;
72  }
73  return tempOutput;
74 }
75 
76 std::vector<std::string> parseLine(std::string stringBuffer)
77 {
78  std::vector<std::string> tempBuffer;
79  bool found = false;
80 
81  while (stringBuffer.find(" ") != std::string::npos) // Search for spaces delimiting the different data words
82  {
83  std::string temp = stringBuffer.substr(0, stringBuffer.find(" ")); // Split the the string
84  stringBuffer = stringBuffer.substr(stringBuffer.find(" ")+1, stringBuffer.length()); // into two
85  tempBuffer.push_back(temp); // and store the new part into the vector. Continue searching until no more spaces are found.
86  }
87  tempBuffer.push_back(stringBuffer); // and finally push the final part of the string into the vector when no more spaces are present.
88  return tempBuffer;
89 }
90 
91 string decodeApUint64(ap_uint<64> inputNumber) {
92  std::string outputString = "0000000000000000";
93  unsigned short int tempValue = 16;
94  static const char* const lut = "0123456789ABCDEF";
95  for (int i = 15;i>=0;--i) {
96  tempValue = 0;
97  for (unsigned short int k = 0;k<4;++k) {
98  if (inputNumber.bit((i+1)*4-k-1) == 1)
99  tempValue += static_cast <unsigned short int>(pow(2.0, 3-k));
100  }
101  outputString[15-i] = lut[tempValue];
102  }
103  return outputString;
104 }
105 
106 string decodeApUint32(ap_uint<32> inputNumber) {
107  std::string outputString = "00000000";
108  unsigned short int tempValue = 16;
109  static const char* const lut = "0123456789ABCDEF";
110  for (int i = 7;i>=0;--i) {
111  tempValue = 0;
112  for (unsigned short int k = 0;k<4;++k) {
113  if (inputNumber.bit((i+1)*4-k-1) == 1)
114  tempValue += static_cast <unsigned short int>(pow(2.0, 3-k));
115  }
116  outputString[7-i] = lut[tempValue];
117  }
118  return outputString;
119 }
120 
121 string decodeApUint16(ap_uint<16> inputNumber) {
122  std::string outputString = "0000";
123  unsigned short int tempValue = 16;
124  static const char* const lut = "0123456789ABCDEF";
125  for (int i = 3;i>=0;--i) {
126  tempValue = 0;
127  for (unsigned short int k = 0;k<4;++k) {
128  if (inputNumber.bit((i+1)*4-k-1) == 1)
129  tempValue += static_cast <unsigned short int>(pow(2.0, 3-k));
130  }
131  outputString[4-i] = lut[tempValue];
132  }
133  return outputString;
134 }
135 
136 string decodeApUint8(ap_uint<8> inputNumber) {
137  string outputString = "00";
138  unsigned short int tempValue = 16;
139  static const char* const lut = "0123456789ABCDEF";
140  for (int i = 1;i>=0;--i) {
141  tempValue = 0;
142  for (unsigned short int k = 0;k<4;++k) {
143  if (inputNumber.bit((i+1)*4-k-1) == 1)
144  tempValue += static_cast <unsigned short int>(pow(2.0, 3-k));
145  }
146  outputString[1-i] = lut[tempValue];
147  }
148  return outputString;
149 }
150 
151 ap_uint<64> encodeApUint64(string dataString){
152  ap_uint<64> tempOutput = 0;
153  unsigned short int tempValue = 16;
154  static const char* const lut = "0123456789ABCDEF";
155 
156  for (unsigned short int i = 0; i<dataString.size();++i) {
157  for (unsigned short int j = 0;j<16;++j) {
158  if (lut[j] == dataString[i]) {
159  tempValue = j;
160  break;
161  }
162  }
163  if (tempValue != 16) {
164  for (short int k = 3;k>=0;--k) {
165  if (tempValue >= pow(2.0, k)) {
166  tempOutput.bit(63-(4*i+(3-k))) = 1;
167  tempValue -= static_cast <unsigned short int>(pow(2.0, k));
168  }
169  }
170  }
171  }
172  return tempOutput;
173 }
174 
175 ap_uint<32> encodeApUint32(string parseString){
176  ap_uint<32> tempOutput = 0;
177  unsigned short int tempValue = 16;
178  static const char* const lut = "0123456789ABCDEF";
179 
180  for (unsigned short int i = 0; i<8;++i) {
181  for (unsigned short int j = 0;j<16;++j) {
182  if (lut[j] == parseString[i]) {
183  tempValue = j;
184  break;
185  }
186  }
187  if (tempValue != 16) {
188  for (short int k = 3;k>=0;--k) {
189  if (tempValue >= pow(2.0, k)) {
190  tempOutput.bit(31-(4*i+(3-k))) = 1;
191  tempValue -= static_cast <unsigned short int>(pow(2.0, k));
192  }
193  }
194  }
195  }
196  return tempOutput;
197 }
198 
199 ap_uint<8> encodeApUint8(string keepString){
200  ap_uint<8> tempOutput = 0;
201  unsigned short int tempValue = 16;
202  static const char* const lut = "0123456789ABCDEF";
203 
204  for (unsigned short int i = 0; i<2;++i) {
205  for (unsigned short int j = 0;j<16;++j) {
206  if (lut[j] == keepString[i]) {
207  tempValue = j;
208  break;
209  }
210  }
211  if (tempValue != 16) {
212  for (short int k = 3;k>=0;--k) {
213  if (tempValue >= pow(2.0, k)) {
214  tempOutput.bit(7-(4*i+(3-k))) = 1;
215  tempValue -= static_cast <unsigned short int>(pow(2.0, k));
216  }
217  }
218  }
219  }
220  return tempOutput;
221 }
222 
223 ap_uint<16> encodeApUint16(string parseString){
224  ap_uint<16> tempOutput = 0;
225  unsigned short int tempValue = 16;
226  static const char* const lut = "0123456789ABCDEF";
227 
228  for (unsigned short int i = 0; i<4;++i) {
229  for (unsigned short int j = 0;j<16;++j) {
230  if (lut[j] == parseString[i]) {
231  tempValue = j;
232  break;
233  }
234  }
235  if (tempValue != 16) {
236  for (short int k = 3;k>=0;--k) {
237  if (tempValue >= pow(2.0, k)) {
238  tempOutput.bit(15-(4*i+(3-k))) = 1;
239  tempValue -= static_cast <unsigned short int>(pow(2.0, k));
240  }
241  }
242  }
243  }
244  return tempOutput;
245 }
246 
247 int main(int argc, char *argv[]) {
248 
249  stream<axiWord> inputPathInDataFIFO("inputPathInDataFIFO");
250  stream<axiWord> inputPathOutDataFIFO("inputPathOutDataFIFO");
251  stream<ap_uint<16> > openPortFIFO("openPortFIFO");
252  stream<bool> confirmPortStatusFIFO("confirmPortStatusFIFO");
253  stream<ap_uint<16> > inputPathPortRealeaseFIFO("inputPathPortRealeaseFIFO");
254  stream<metadata> inputPathOutputMetadataFIFO("inputPathOutputMetadataFIFO");
255  stream<axiWord> outputPathInDataFIFO("outputPathInDataFIFO");
256  stream<axiWord> outputPathOutDataFIFO("outputPathOutDataFIFO");
257  stream<metadata> outputPathInMetadataFIFO("outputPathInMetadataFIFO");
258  stream<ap_uint<16> > outputpathInLengthFIFO("outputpathInLengthFIFO");
259  stream<ipTuple> outIPaddressesFIFO("outIPaddressesFIFO");
260  stream<axiWord> outPortUnreachableFIFO("outPortUnreachableFIFO");
261 
262  axiWord inputPathInputData = axiWord(0, 0, 0);
263  ipTuple incomingPacketIPData = ipTuple(0, 0);
264  metadata inputPathInputMetadata = metadata(sockaddr_in(0, 0), sockaddr_in(0, 0));
265  axiWord inputPathOutputData = axiWord(0, 0, 0);
266  ap_uint<16> openPortData = 0;
267  bool portStatusData = false;
268  metadata inputPathOutputMetadata = metadata(sockaddr_in(0, 0), sockaddr_in(0, 0));
269  axiWord outputPathInData = axiWord(0, 0, 0);
270  axiWord outputPathOutData = axiWord(0, 0, 0);
271  ap_uint<16> outputPathInputLength = 0;
272  metadata outputPathInputMetadata = metadata(sockaddr_in(0, 0), sockaddr_in(0, 0));
273  ipTuple outputPathOutputIPAddresses = ipTuple(0, 0); // Source & Destination IP for Tx packet to be used by the lower layer
275  uint16_t inputSourceIP = 0;
276  uint16_t inputDestinationIP = 0;
277  //uint64_t dataString = 0;
278  std::string dataString;
279  ipTuple inputIP = ipTuple(0, 0);
280  axiWord inputData = axiWord(0, 0, 0);
281  uint16_t sop = 0;
282  uint16_t eop = 0;
283  uint16_t mod = 0;
284  uint16_t valid = 0;
285  uint32_t errCount = 0;
286 
287  ifstream rxInput;
288  ifstream txInput;
289  ofstream rxOutput;
290  ofstream txOutput;
291  ofstream portStatus;
292  ifstream goldenOutputRx;
293  ifstream goldenOutputTx;
294 
295  uint32_t overflowCounter = 0;
296  errCount = 0;
297  int counter = 0;
298  if (argc != 3) {
299  std::cout << "You need to provide at least one parameter (the input file name)!" << std::endl;
300  return -1;
301  }
302  rxInput.open(argv[1]);
303  if (!rxInput) {
304  std::cout << " Error opening Rx input file!" << std::endl;
305  return -1;
306  }
307  txInput.open(argv[2]);
308  if (!txInput) {
309  std::cout << " Error opening Tx input file!" << std::endl;
310  return -1;
311  }
312  rxOutput.open("rxOutput.dat");
313  if (!rxOutput) {
314  std::cout << " Error opening output file!" << std::endl;
315  return -1;
316  }
317  portStatus.open("portStatus.dat");
318  if (!portStatus) {
319  std::cout << " Error opening port status file!" << std::endl;
320  return -1;
321  }
322  txOutput.open("txOutput.dat");
323  if (!txOutput) {
324  cout << "Error openingn Tx Output file!" << endl;
325  return -1;
326  }
327  goldenOutputRx.open("../../../../sources/goldenOutput/rxGoldenOutput.short.dat");
328  if (!goldenOutputRx) {
329  cout << "Error opening golden output file for the Rx side. Check that the correct path is provided!" << endl;
330  return -1;
331  }
332  goldenOutputTx.open("../../../../sources/goldenOutput/txGoldenOutput.short.dat");
333  if (!goldenOutputTx) {
334  cout << "Error opening golden output file for the Tx side. Check that the correct path is provided!" << endl;
335  return -1;
336  }
337  std::cerr << "Input File: " << argv[1] << std::endl << std::endl;
338  // Test 1: Attempt to close a port that isn't open. Expected response is: Nothing
339  inputPathPortRealeaseFIFO.write(0x1532);
340  for (short int i= 0;i<10;++i)
341  udp(inputPathInDataFIFO, inputPathOutDataFIFO, openPortFIFO, confirmPortStatusFIFO, // Input Path Streams
342  inputPathOutputMetadataFIFO, inputPathPortRealeaseFIFO, outputPathInDataFIFO, outputPathOutDataFIFO, outputPathInMetadataFIFO, outputpathInLengthFIFO, outPortUnreachableFIFO); // Output Path Streams
343  //std::cerr << ".";
344  // Test 2: Atempt to open a new port. Expected response is: Port opened successfully
345  bool temp = 0;
346  openPortFIFO.write(0x80);
347  for (short int i= 0;i<3;++i)
348  udp(inputPathInDataFIFO, inputPathOutDataFIFO, openPortFIFO, confirmPortStatusFIFO, // Input Path Streams
349  inputPathOutputMetadataFIFO, inputPathPortRealeaseFIFO, outputPathInDataFIFO, outputPathOutDataFIFO, outputPathInMetadataFIFO, outputpathInLengthFIFO, outPortUnreachableFIFO); // Output Path Streams
350  //std::cerr << ".";
351  if (!confirmPortStatusFIFO.empty()) {
352  temp = confirmPortStatusFIFO.read();
353  std::cerr << "Port opened successfully!" << std::endl;
354  }
355  else {
356  std::cerr << "Error, port not opened successfully." << std::endl;
357  return -1;
358  }
359  //Test 3: Close an already open port
360  inputPathPortRealeaseFIFO.write(temp);
361  for (short int i= 0;i<10;++i)
362  udp(inputPathInDataFIFO, inputPathOutDataFIFO, openPortFIFO, confirmPortStatusFIFO, // Input Path Streams
363  inputPathOutputMetadataFIFO, inputPathPortRealeaseFIFO, outputPathInDataFIFO, outputPathOutDataFIFO, outputPathInMetadataFIFO, outputpathInLengthFIFO, outPortUnreachableFIFO); // Output Path Streams
364  //std::cerr << ".";
365  //Test 4: Read in the test input data for the Rx side without opening the port.
366  uint32_t noOfLines = 0;
367  while (!rxInput.eof()) {
368  std::string stringBuffer;
369  getline(rxInput, stringBuffer);
370  std::vector<std::string> stringVector = parseLine(stringBuffer);
371  string dataString = stringVector[0];
372  string keepString = stringVector[2];
373  inputPathInputData.data = encodeApUint64(dataString);
374  inputPathInputData.keep = encodeApUint8(keepString);
375  inputPathInputData.last = atoi(stringVector[1].c_str());
376  inputPathInDataFIFO.write(inputPathInputData);
377  //noOfLines++;
378  }
379  //noOfLines = 0;
380  while (!inputPathInDataFIFO.empty() || overflowCounter < maxOverflowValue) {
381  udp(inputPathInDataFIFO, inputPathOutDataFIFO, openPortFIFO, confirmPortStatusFIFO, inputPathOutputMetadataFIFO, // Input Path Streams
382  inputPathPortRealeaseFIFO, outputPathInDataFIFO, outputPathOutDataFIFO, outputPathInMetadataFIFO, outputpathInLengthFIFO, outPortUnreachableFIFO); // Output Path Streams
383  //std::cerr << ".";
384  //noOfLines++;
385  if (inputPathInDataFIFO.empty())
386  overflowCounter++;
387  }
388  rxInput.close();
389  rxInput.open(argv[1]);
390  //Test 6: Read in the test input data for the Rx side. First re-open the port to which data is to be sent.
391  cerr << endl << "Test 4: Exercising the Rx Path" << endl;
392  openPortFIFO.write(0x80);
393  for (short int i= 0;i<3;++i)
394  udp(inputPathInDataFIFO, inputPathOutDataFIFO, openPortFIFO, confirmPortStatusFIFO, // Input Path Streams
395  inputPathOutputMetadataFIFO, inputPathPortRealeaseFIFO, outputPathInDataFIFO, outputPathOutDataFIFO, outputPathInMetadataFIFO, outputpathInLengthFIFO, outPortUnreachableFIFO); // Output Path Streams
396  //std::cerr << ".";
397  if (!confirmPortStatusFIFO.empty()) {
398  temp = confirmPortStatusFIFO.read();
399  std::cerr << endl << "Port opened successfully!" << std::endl;
400  }
401  else {
402  std::cerr << endl << "Error, port not opened successfully." << std::endl;
403  return -1;
404  }
405  // And then send the data in
406  //uint32_t noOfLines = 0;
407  while (!rxInput.eof()) {
408  std::string stringBuffer;
409  getline(rxInput, stringBuffer);
410  std::vector<std::string> stringVector = parseLine(stringBuffer);
411  string dataString = stringVector[0];
412  string keepString = stringVector[2];
413  inputPathInputData.data = encodeApUint64(dataString);
414  inputPathInputData.keep = encodeApUint8(keepString);
415 
416  inputPathInputData.last = atoi(stringVector[1].c_str());
417  inputPathInDataFIFO.write(inputPathInputData);
418  //noOfLines++;
419  }
420  //noOfLines = 0;
421  while (!inputPathInDataFIFO.empty() || overflowCounter < maxOverflowValue) {
422  udp(inputPathInDataFIFO, inputPathOutDataFIFO, openPortFIFO, confirmPortStatusFIFO, inputPathOutputMetadataFIFO, // Input Path Streams
423  inputPathPortRealeaseFIFO, outputPathInDataFIFO, outputPathOutDataFIFO, outputPathInMetadataFIFO, outputpathInLengthFIFO, outPortUnreachableFIFO); // Output Path Streams
424  //std::cerr << ".";
425  //noOfLines++;
426  if (inputPathInDataFIFO.empty())
427  overflowCounter++;
428  }
429  //noOfLines = 0;
430  cerr << endl << "Rx test complete." << endl;
431  overflowCounter = 0;
432  // Test 5: Tx path
433  cerr << endl << "Test 5: Exercising the Tx Path" << endl;
434  noOfLines = 0;
435  overflowCounter = 0;
436  while (!txInput.eof()) {
437  std::string stringBuffer;
438  getline(txInput, stringBuffer);
439  std::vector<std::string> stringVector = parseLine(stringBuffer);
440  string sourcePort = stringVector[0];
441  string destinationPort = stringVector[1];
442  string sourceIP = stringVector[2];
443  string destinationIP = stringVector[3];
444  string payloadLength = stringVector[4];
445  string dataString = stringVector[5];
446  string keepString = stringVector[6];
447  outputPathInData.data = encodeApUint64(dataString);
448  outputPathInData.keep = encodeApUint8(keepString);
449  outputPathInData.last = atoi(stringVector[7].c_str());
450  outputPathInputMetadata.sourceSocket.port = encodeApUint16(sourcePort);
451  outputPathInputMetadata.sourceSocket.addr = encodeApUint32(sourceIP);
452  outputPathInputMetadata.destinationSocket.port = encodeApUint16(destinationPort);
453  outputPathInputMetadata.destinationSocket.addr = encodeApUint32(destinationIP);
454  outputPathInputLength = encodeApUint16(payloadLength);
455  outputPathInDataFIFO.write(outputPathInData);
456  if (outputPathInputLength != 0) {
457  outputPathInMetadataFIFO.write(outputPathInputMetadata);
458  outputpathInLengthFIFO.write(outputPathInputLength);
459  }
460  noOfLines++;
461  }
462  noOfLines = 0;
463  while (!outputPathInDataFIFO.empty() || overflowCounter < maxOverflowValue) {
464  udp(inputPathInDataFIFO, inputPathOutDataFIFO, openPortFIFO, confirmPortStatusFIFO, inputPathOutputMetadataFIFO, // Input Path Streams
465  inputPathPortRealeaseFIFO, outputPathInDataFIFO, outputPathOutDataFIFO, outputPathInMetadataFIFO, outputpathInLengthFIFO, outPortUnreachableFIFO); // Output Path Streams
466  //std::cerr << ".";
467  noOfLines++;
468  if (outputPathInDataFIFO.empty())
469  overflowCounter++;
470  }
471  cerr << endl;
472  overflowCounter = 0;
473  cerr << endl << "Tx test complete. Verifying result." << endl;
474  axiWord txCompareOutput = axiWord(0, 0, 0);
475  while (!outputPathOutDataFIFO.empty()) {
476  axiWord tempOutput = outputPathOutDataFIFO.read();
477  goldenOutputTx >> hex >> txCompareOutput.data >> txCompareOutput.last >> txCompareOutput.keep;
478  if (txCompareOutput.data != tempOutput.data || txCompareOutput.last != tempOutput.last || txCompareOutput.keep != tempOutput.keep) {
479  errCount++;
480  cerr << "X";
481  }
482  else
483  cerr << ".";
484  string dataOutput = decodeApUint64(tempOutput.data);
485  string keepOutput = decodeApUint8(tempOutput.keep);
486  txOutput << dataOutput << " " << tempOutput.last << " " << keepOutput << endl;
487  }
488  /*if (errCount != 0) {
489  cerr << endl << "Errors during Tx testing. Check the output file." << endl;
490  }
491  else
492  cerr << endl << "Tx Tests passed succesfully." << endl;*/
493  axiWord compareWord = axiWord(0, 0, 0);
494  while (!inputPathOutDataFIFO.empty() && !goldenOutputRx.eof()) {
495  //noOfLines++;
496  //counter++;
497  //cerr << counter << " ";
498  axiWord tempOutput = inputPathOutDataFIFO.read();
499  goldenOutputRx >> hex >> compareWord.data >> compareWord.last;
500  if (compareWord.data != tempOutput.data || compareWord.last != tempOutput.last) {
501  errCount++;
502  //cerr << "X";
503  }
504  //else
505  //cerr << ".";
506  string dataOutput = decodeApUint64(tempOutput.data);
507  rxOutput << dataOutput << " " << tempOutput.last << endl;
508  }
509  if (errCount != 0) {
510  cerr << endl << "Errors during testing. Check the output file." << endl;
511  }
512  else
513  cerr << endl << "All Tests passed succesfully." << endl;
514  errCount = 0;
515  while(!outPortUnreachableFIFO.empty())
516  outPortUnreachableFIFO.read();
517  while(!inputPathOutputMetadataFIFO.empty())
518  inputPathOutputMetadataFIFO.read();
519  while(!inputPathOutDataFIFO.empty())
520  inputPathOutDataFIFO.read();
521 
522  rxInput.close();
523  rxOutput.close();
524  txInput.close();
525  txOutput.close();
526  portStatus.close();
527  return 0;
528 }
#define udp
Definition: config.h:66
ap_uint< 8 > keep
Definition: tcp_ip.hpp:41
ap_uint< 64 > data
Definition: tcp_ip.hpp:40
ap_uint< 1 > last
Definition: tcp_ip.hpp:42
Definition: udp.hpp:91
Definition: udp.hpp:83
sockaddr_in destinationSocket
Definition: udp.hpp:85
sockaddr_in sourceSocket
Definition: udp.hpp:84
ap_uint< 32 > addr
Definition: udp.hpp:77
ap_uint< 16 > port
Definition: udp.hpp:76
ap_uint< 16 > encodeApUint16(string parseString)
Definition: test_udp.cpp:223
#define maxOverflowValue
Definition: test_udp.cpp:46
int main(int argc, char *argv[])
Definition: test_udp.cpp:247
uint32_t clockCounter
Definition: test_udp.cpp:48
ap_uint< 64 > encodeApUint64(string dataString)
Definition: test_udp.cpp:151
string decodeApUint32(ap_uint< 32 > inputNumber)
Definition: test_udp.cpp:106
ap_uint< 32 > encodeApUint32(string parseString)
Definition: test_udp.cpp:175
string decodeApUint8(ap_uint< 8 > inputNumber)
Definition: test_udp.cpp:136
ap_uint< 8 > encodeApUint8(string keepString)
Definition: test_udp.cpp:199
std::vector< std::string > parseLine(std::string stringBuffer)
Definition: test_udp.cpp:76
string decodeApUint16(ap_uint< 16 > inputNumber)
Definition: test_udp.cpp:121
string decodeApUint64(ap_uint< 64 > inputNumber)
Definition: test_udp.cpp:91
ap_uint< 64 > convertString(std::string stringToConvert)
Definition: test_udp.cpp:50