cloudFPGA (cF) API  1.0
The documentation of the source code of cloudFPGA (cF)

This is the Memtest platform stressing project. The FPGA tests its DRAM memory. More...

Collaboration diagram for Memtest:

Modules

 Memtest Testbench
 This is a subgroup of Memtest accelerated function with only testbench-related functions/classes.
 
 Memtest HLS
 This is a subgroup of Memtest accelerated function with only synthesizable (HLS) functions/classes.
 
 Memtest Host
 This is a subgroup of Memtest accelerated function with only host code software.
 

Files

file  config.h
 The configuration of a Memtest Example application (UDP or TCP)
 
file  memtest_host.cpp
 Memtest userspace application for cF (x86, ppc64).
 

Classes

struct  MemoryTestResult
 

Macros

#define MAX_TESTABLE_ADDRESS   8000000000
 
#define MAX_TEST_REPETITION_BITWIDTH   16
 
#define MAX_BURST_SIZE   4096
 
#define OK   true
 
#define KO   false
 
#define CEIL(a, b)   (((a) + (b-1)) / (b))
 
#define TRACE_OFF   0x0000
 
#define TRACE_URIF   1 << 1
 
#define TRACE_UAF   1 << 2
 
#define TRACE_MMIO   1 << 3
 
#define TRACE_ALL   0xFFFF
 
#define DEBUG_LEVEL   (TRACE_ALL)
 
#define PACK_SIZE   1024
 
#define BUF_LEN   65540
 
#define TB_SIM_CFP_VITIS
 
#define NET_TYPE   udp
 
#define tcp   0
 
#define udp   1
 
#define MAX_MEM_SIZE_BENCHMARKING_POWER_OF_TWO   33
 
#define MIN_MEM_SIZE_BENCHMARKING_POWER_OF_TWO   6
 
#define MAX_BURST_SIZE_BENCHMARKING   MAX_BURST_SIZE
 
#define MIN_BURST_SIZE_BENCHMARKING   1
 
#define REPETITIONS_BENCHMARKING   2
 

Functions

void print_cFpMemtest (void)
 
void delay (unsigned int mseconds)
 
void printBits (size_t const size, void const *const ptr)
 print the binary representation of a target pointer buffer of a given size. Assumes little endian. More...
 
void ascii2hex (const string &in, string &out)
 Convert a ascii string to a hexadecimal string. More...
 
template<unsigned int bytes_per_line = 8>
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. More...
 
template<unsigned int bytes_per_line = 8>
string createMemTestStopCommand ()
 
unsigned char hexval (unsigned char c)
 convert a char to its hexadecimal representation. More...
 
void hex2ascii (const string &in, string &out)
 Convert a hexadecimal string to a ascii string. More...
 
template<typename T >
void number2hexString (const T in, char *out, size_t byteSize)
 
template<unsigned int bytes_per_line = 8>
string dumpFileToStringRawDataString (const string inpFileName, int *rawdatalines, size_t outputSize)
 Initialize an input data stream from a file with only data. More...
 
void ascii2hexWithSize (const string &in, string &out, size_t bytesize)
 Convert a ascii string to a hexadecimal string. More...
 
bool findCharNullPos (char *str)
 
void printStringHex (const string inStr, size_t strSize)
 print byte-per-byte a given string in hexadecimal format More...
 
void printCharBuffHex (const char *inStr, size_t strSize)
 print byte-per-byte a given char buff in hexadecimal format More...
 
void printCharBuffHexSafe (const char *inStr, size_t strSize)
 
void string2hexnumerics (const string &in, char *out, size_t byteSize)
 
 MemoryTestResult::MemoryTestResult ()
 
 MemoryTestResult::MemoryTestResult (unsigned long long int target_address, unsigned int fault_cntr, unsigned int first_fault_address, unsigned long long int clock_cycles_write, unsigned long long int clock_cycles_read)
 
template<unsigned int bytes_per_line = 8>
std::vector< MemoryTestResultparseMemoryTestOutput (const string longbuf, size_t charOutputSize, int rawdatalines)
 Parse the memory test output contained in astring with a given size. More...
 
void createAVGLogFile ()
 
void logTheAvgResult (unsigned int iters, unsigned long long int trgt_address, unsigned int brst_size, unsigned int wr_words, double rd_bw, double wr_bw, unsigned int faults)
 
void createItLogFile ()
 
void logTheSingleResult (unsigned int iters, unsigned long long int trgt_address, unsigned int brst_size, unsigned int wr_words, double rd_bw, double wr_bw, unsigned int faults, unsigned long long int first_faulty_address)
 
int main (int argc, char *argv[])
 

Variables

unsigned long long int MemoryTestResult::target_address
 
unsigned int MemoryTestResult::fault_cntr
 
unsigned int MemoryTestResult::first_fault_address
 
unsigned long long int MemoryTestResult::clock_cycles_read
 
unsigned long long int MemoryTestResult::clock_cycles_write
 
std::ofstream loggingAVGFile
 
const std::string loggingAVGFileName ="cfp_vitis_memtest_avg.csv"
 
std::ofstream loggingMultiItFile
 
const std::string loggingMultiItFileName ="cfp_vitis_memtest_multi.csv"
 

Detailed Description

This is the Memtest platform stressing project. The FPGA tests its DRAM memory.

Macro Definition Documentation

◆ BUF_LEN

#define BUF_LEN   65540

Larger than maximum UDP packet size

Definition at line 54 of file config.h.

◆ CEIL

#define CEIL (   a,
 
)    (((a) + (b-1)) / (b))

Ceiling function without using math.h

Definition at line 37 of file config.h.

◆ DEBUG_LEVEL

#define DEBUG_LEVEL   (TRACE_ALL)

Definition at line 47 of file config.h.

◆ KO

#define KO   false

Definition at line 66 of file common.hpp.

◆ MAX_BURST_SIZE

#define MAX_BURST_SIZE   4096

Definition at line 59 of file common.hpp.

◆ MAX_BURST_SIZE_BENCHMARKING

#define MAX_BURST_SIZE_BENCHMARKING   MAX_BURST_SIZE

Definition at line 46 of file memtest_host.cpp.

◆ MAX_MEM_SIZE_BENCHMARKING_POWER_OF_TWO

#define MAX_MEM_SIZE_BENCHMARKING_POWER_OF_TWO   33

Definition at line 43 of file memtest_host.cpp.

◆ MAX_TEST_REPETITION_BITWIDTH

#define MAX_TEST_REPETITION_BITWIDTH   16

Definition at line 58 of file common.hpp.

◆ MAX_TESTABLE_ADDRESS

#define MAX_TESTABLE_ADDRESS   8000000000

Definition at line 57 of file common.hpp.

◆ MIN_BURST_SIZE_BENCHMARKING

#define MIN_BURST_SIZE_BENCHMARKING   1

Definition at line 47 of file memtest_host.cpp.

◆ MIN_MEM_SIZE_BENCHMARKING_POWER_OF_TWO

#define MIN_MEM_SIZE_BENCHMARKING_POWER_OF_TWO   6

Definition at line 45 of file memtest_host.cpp.

◆ NET_TYPE

#define NET_TYPE   udp

The network socket type: tcp or udp

Definition at line 60 of file config.h.

◆ OK

#define OK   true

Definition at line 65 of file common.hpp.

◆ PACK_SIZE

#define PACK_SIZE   1024

This is our custom MTU. We must use a multiple of 8 (Bytes per transaction)! 1450 4086 udp pack size; note that OSX limits < 8100 bytes

Definition at line 51 of file config.h.

◆ REPETITIONS_BENCHMARKING

#define REPETITIONS_BENCHMARKING   2

Definition at line 48 of file memtest_host.cpp.

◆ TB_SIM_CFP_VITIS

#define TB_SIM_CFP_VITIS

Definition at line 57 of file config.h.

◆ tcp

cat GET request dos socat stdio shut none time cat post_role socat shut none tcp   0

Definition at line 65 of file config.h.

◆ TRACE_ALL

#define TRACE_ALL   0xFFFF

Definition at line 46 of file config.h.

◆ TRACE_MMIO

#define TRACE_MMIO   1 << 3

Definition at line 45 of file config.h.

◆ TRACE_OFF

#define TRACE_OFF   0x0000

Definition at line 42 of file config.h.

◆ TRACE_UAF

#define TRACE_UAF   1 << 2

Definition at line 44 of file config.h.

◆ TRACE_URIF

#define TRACE_URIF   1 << 1

Definition at line 43 of file config.h.

◆ udp

#define udp   1

Definition at line 66 of file config.h.

Function Documentation

◆ ascii2hex()

void ascii2hex ( const string &  in,
string &  out 
)

Convert a ascii string to a hexadecimal string.

Parameters
[in]inthe input ascii string
[out]outthe output hexadecimal string

Definition at line 119 of file common.hpp.

120 {
121  std::stringstream sstream;
122  for ( string::const_iterator item = in.begin(); item != in.end(); item++){
123  sstream << std::hex << int(*item);
124  }
125  out=sstream.str();
126 }
out
Definition: test.py:12

◆ ascii2hexWithSize()

void ascii2hexWithSize ( const string &  in,
string &  out,
size_t  bytesize 
)

Convert a ascii string to a hexadecimal string.

Parameters
[in]inthe input ascii string
[out]outthe output hexadecimal string
[in]bytesizethe input ascii string size

Definition at line 331 of file common.hpp.

332 {
333  std::stringstream sstream;
334  for ( int i=0; i<bytesize; i++){
335  sstream << std::hex << int(in[i]);
336  }
337  out=sstream.str();
338 }
Here is the caller graph for this function:

◆ createAVGLogFile()

void createAVGLogFile ( )

Definition at line 557 of file common.hpp.

557  {
558  if (FILE *file = fopen(loggingAVGFileName.c_str(), "r")){
559  fclose(file);
560  }else{
561  loggingAVGFile.open(loggingAVGFileName, std::ios_base::app);
562  loggingAVGFile << "TimeStamp,Iterations[#],Trgt_Address[Byte],Brst_size[#beats],WrittenWords[512b],AVG_RD_BW[Gbit/s],AVG_WR_BW[Gbit/s],AVG_faults[#],PowOfTwoBytes\n";
563  loggingAVGFile.close();
564  }
565 }
const std::string loggingAVGFileName
Definition: common.hpp:555
std::ofstream loggingAVGFile
Definition: common.hpp:554
Here is the caller graph for this function:

◆ createItLogFile()

void createItLogFile ( )

Definition at line 586 of file common.hpp.

586  {
587  if (FILE *file = fopen(loggingMultiItFileName.c_str(), "r")){
588  fclose(file);
589  }else{
590  loggingMultiItFile.open(loggingMultiItFileName, std::ios_base::app);
591  loggingMultiItFile << "TimeStamp,Iteration[#],Trgt_Address[Byte],";
592  loggingMultiItFile << "Brst_size[#beats],WrittenWords[512b],RD_BW[Gbit/s],WR_BW[Gbit/s],";
593  loggingMultiItFile << "faults[#],first_faulty_address[byte],PowOfTwoBytes\n";
594  loggingMultiItFile.close();
595  }
596 }
std::ofstream loggingMultiItFile
Definition: common.hpp:582
const std::string loggingMultiItFileName
Definition: common.hpp:583
Here is the caller graph for this function:

◆ createMemTestCommands()

template<unsigned int bytes_per_line = 8>
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.

Parameters
[in]mem_addressmax target address to test
[out]outthe output string with start/max address-nops4trgtCCsNeeded-stop
[in]testingNumberthe number of tests to perform on the memory

Definition at line 137 of file common.hpp.

138 {
139  string out;
140  char start_cmd [bytes_per_line];
141  char stop_cmd [bytes_per_line];
142  char value_cmd[bytes_per_line];
143  char burst_cmd[bytes_per_line];
144  //WARNING: currently hardcoded way of start and stop commands with a 1 and 2 for start and stop respectively
145  for (unsigned int k = 0; k < bytes_per_line; k++) {
146  value_cmd[k] = (char)0;
147  if (k != 0) {
148  stop_cmd[k] = (char)0;
149  start_cmd[k] = (char)0;
150  burst_cmd[k] = (char)0;
151  }
152  else {
153  start_cmd[k] = (char)1;
154  stop_cmd[k] = (char)2;
155  burst_cmd[k] = (char)4;
156  }
157  }
158  memcpy(start_cmd+1, (char*)&testingNumber, 2);
159  out = out.append(start_cmd,3);
160  memcpy(value_cmd, (char*)&mem_address, 5);
161  out = out.append(value_cmd,5);
162  memcpy(burst_cmd+1,(char*)&burst_size,2);
163  out = out.append(burst_cmd,8);
164  return string(out);
165  }
Here is the caller graph for this function:

◆ createMemTestStopCommand()

template<unsigned int bytes_per_line = 8>
string createMemTestStopCommand ( )

Definition at line 168 of file common.hpp.

169 {
170  string out;
171  char stop_cmd [bytes_per_line];
172  for (unsigned int k = 0; k < bytes_per_line; k++) {
173  if (k != 0) {
174  stop_cmd[k] = (char)0;
175  }
176  else {
177  stop_cmd[k] = (char)2;
178  }
179  }
180  out.append(stop_cmd,bytes_per_line);
181  return out;
182 }
Here is the caller graph for this function:

◆ delay()

void delay ( unsigned int  mseconds)

Definition at line 85 of file common.hpp.

86 {
87  clock_t goal = mseconds + clock();
88  while (goal > clock());
89 }
def clock()
Definition: common.py:174
Here is the call graph for this function:
Here is the caller graph for this function:

◆ dumpFileToStringRawDataString()

template<unsigned int bytes_per_line = 8>
string dumpFileToStringRawDataString ( const string  inpFileName,
int *  rawdatalines,
size_t  outputSize 
)

Initialize an input data stream from a file with only data.

Parameters
[in]inpFileNamethe name of the input file to read from.
[out]strOutputthe output string to set.
Returns
OK if successful otherwise KO.

Definition at line 279 of file common.hpp.

279  {
280  string strLine;
281  string tmp_Out;
282  ifstream inpFileStream;
283  string datFile = inpFileName;
284  string charOutput;
285  //charOutput.reserve(outputSize);
286  //strLine.reserve(outputSize);
287  //tmp_Out.reserve(bytes_per_line);
288  unsigned long long int mylongunsigned;
289  unsigned long long int zero_byte=0;
290  unsigned int i = 0;
291  char my_tmp_buf [bytes_per_line];
292  //-- STEP-1 : OPEN FILE
293  inpFileStream.open(datFile.c_str());
294 
295  if ( !inpFileStream ) {
296  cout << "### ERROR : Could not open the input data file " << datFile << endl;
297  return "";
298  }
299 
300  //-- STEP-2 : SET DATA STREAM
301  while (inpFileStream) {
302 
303  if (!inpFileStream.eof()) {
304 
305  getline(inpFileStream, strLine);
306  memcpy(my_tmp_buf,&zero_byte, bytes_per_line);
307  if (strLine.empty()) continue;
308  *rawdatalines+=1;
309  mylongunsigned=stoul(strLine,nullptr,16);
310  hex2ascii(strLine, tmp_Out);
311  // Write to strOutput
312  memcpy(my_tmp_buf,(char *)&mylongunsigned, sizeof(unsigned long long int));
313  charOutput.append(my_tmp_buf, bytes_per_line);
314  i++;
315  }
316  }
317  //-- STEP-3: CLOSE FILE
318  inpFileStream.close();
319  //tmp_Out.clear();
320 
321  return string(charOutput);
322 }
void hex2ascii(const string &in, string &out)
Convert a hexadecimal string to a ascii string.
Definition: common.hpp:251
Here is the call graph for this function:
Here is the caller graph for this function:

◆ findCharNullPos()

bool findCharNullPos ( char *  str)

Definition at line 340 of file common.hpp.

340  {
341  unsigned int len = strlen(str);
342  bool f = false;
343  for(unsigned int i=0; i<=len; i++) {
344  if(str[i]=='\0') {
345  printf("DEBUG: null character position: %d\n",i+1);
346  f = true;
347  }
348  }
349  if(f == false) {
350  printf("DEBUG: null character not found\n");
351  }
352  return f;
353 }
Here is the caller graph for this function:

◆ hex2ascii()

void hex2ascii ( const string &  in,
string &  out 
)

Convert a hexadecimal string to a ascii string.

Parameters
[in]inthe input hexadecimal string
[out]outthe output ascii string

Definition at line 251 of file common.hpp.

252 {
253  out.clear();
254  out.reserve(in.length() / 2);
255  for (string::const_iterator p = in.begin(); p != in.end(); p++)
256  {
257  unsigned char c = hexval(*p);
258  p++;
259  if (p == in.end()) break; // incomplete last digit - should report error
260  c = (c << 4) + hexval(*p); // + takes precedence over <<
261  out.push_back(c);
262  }
263 }
unsigned char hexval(unsigned char c)
convert a char to its hexadecimal representation.
Definition: common.hpp:234
Here is the call graph for this function:
Here is the caller graph for this function:

◆ hexval()

unsigned char hexval ( unsigned char  c)

convert a char to its hexadecimal representation.

Parameters
[in]cthe standard char value to convert to hex
Returns
the hexadecimal value of the input

Definition at line 234 of file common.hpp.

235 {
236  if ('0' <= c && c <= '9')
237  return c - '0';
238  else if ('a' <= c && c <= 'f')
239  return c - 'a' + 10;
240  else if ('A' <= c && c <= 'F')
241  return c - 'A' + 10;
242  else abort();
243 }
Here is the caller graph for this function:

◆ logTheAvgResult()

void logTheAvgResult ( unsigned int  iters,
unsigned long long int  trgt_address,
unsigned int  brst_size,
unsigned int  wr_words,
double  rd_bw,
double  wr_bw,
unsigned int  faults 
)

Definition at line 567 of file common.hpp.

571  {
572  loggingAVGFile.open(loggingAVGFileName, std::ios_base::app);
573  std::time_t instant_time = std::time(0); // get time now
574  std::tm* now = std::localtime(&instant_time);
575  loggingAVGFile << (now->tm_year + 1900)<< '-' << (now->tm_mon + 1) << '-' << now->tm_mday << "," << iters<< ",";
576  loggingAVGFile<<trgt_address<< ","<<brst_size<< ","<<wr_words<< ",";
577  loggingAVGFile<<rd_bw<< ","<<wr_bw<< ","<< faults <<",";
578  loggingAVGFile << (int) log2(trgt_address)<<"\n";
579  loggingAVGFile.close();
580 }
Here is the caller graph for this function:

◆ logTheSingleResult()

void logTheSingleResult ( unsigned int  iters,
unsigned long long int  trgt_address,
unsigned int  brst_size,
unsigned int  wr_words,
double  rd_bw,
double  wr_bw,
unsigned int  faults,
unsigned long long int  first_faulty_address 
)

Definition at line 598 of file common.hpp.

603  {
604  loggingMultiItFile.open(loggingMultiItFileName, std::ios_base::app);
605  std::time_t instant_time = std::time(0); // get time now
606  std::tm* now = std::localtime(&instant_time);
607  loggingMultiItFile << (now->tm_year + 1900)<< '-' << (now->tm_mon + 1) << '-' << now->tm_mday << "," << iters<< ",";
608  loggingMultiItFile<<trgt_address<< ","<<brst_size<< ","<<wr_words<< ",";
609  loggingMultiItFile<<rd_bw<< ","<<wr_bw<< ","<< faults;
610  loggingMultiItFile<<","<<first_faulty_address<<"," << (int) log2(trgt_address)<<"\n";
611  loggingMultiItFile.close();
612 }
Here is the caller graph for this function:

◆ main()

int main ( int  argc,
char *  argv[] 
)

Main testbench and user-application for Memtest on host. Client

Returns
O on success, 1 on fail

Definition at line 59 of file memtest_host.cpp.

60 {
61  if ((argc < 3) || (argc > 7)) { // Test for correct number of arguments
62  cerr << "Usage: " << argv[0] << " <Server> <Server Port> <number of address to test> <testing times> <burst size> <optional list/interactive mode (type list or nothing)>\n";
63  exit(1);
64  }
65 #endif
66  cout << argc << endl;
67 
68  //------------------------------------------------------
69  //-- STEP-1 : Socket and variables definition
70  //------------------------------------------------------
71 
72  #ifndef PY_WRAP
73  assert (argc >= 6);
74  string s_servAddress = argv[1]; // First arg: server address
75  char *s_servPort = argv[2];
76  bool net_type = NET_TYPE;
77  #endif
78 
79  string servAddress = s_servAddress;
80  unsigned short servPort;
81  if (net_type == udp) {
82  servPort = Socket::resolveService(s_servPort, "udp");
83  }
84  else if (net_type == tcp) {
85  servPort = atoi(s_servPort);
86  }
87  else {
88  cout << "ERROR: Invalid type of socket type provided: " << net_type << " Choosed one of (tcp=0 or udp=1)" << endl;
89  }
90 
91  char buffer[BUF_LEN]; // Buffer for echo string
92  unsigned int recvMsgSize; // Size of received message
93  unsigned int num_frame = 0;
94  std::string input_string;
95  std::string strInput_memaddrUT;
96  std::string strInput_nmbrTest;
97  std::string strInput_burstSize;
98 
99  std::string strInput_listMode;
100 
101  unsigned long long int memory_addr_under_test=0;
102  unsigned int testingNumber = 1;
103  unsigned int burst_size = 1;
104  //UDPSocket *udpsock_p;
105  //TCPSocket *tcpsock_p;
106 
108 
109  try {
113  //------------------------------------------------------
114  //-- STEP-2 : Initialize socket connection
115  //------------------------------------------------------
119  #if NET_TYPE == udp
120  #ifndef TB_SIM_CFP_VITIS
121  UDPSocket udpsock(servPort); // NOTE: It is very important to set port here in order to call
122  // bind() in the UDPSocket constructor
123  #else // TB_SIM_CFP_VITIS
124  UDPSocket udpsock; // NOTE: In HOST TB the port is already binded by memtest_host_fwd_tb.cpp
125  #endif // TB_SIM_CFP_VITIS
126  // udpsock_p = &udpsock;
127  #else // tcp
128  TCPSocket tcpsock(servAddress, servPort);
129  // tcpsock_p = &tcpsock;
130  #endif // udp/tcp
131 
132  //------------------------------------------------------------------------------------
133  //-- STEP-3 : Create a string from input argument
134  //------------------------------------------------------------------------------------
135  #ifdef PY_WRAP
136  input_string.assign(input_str); //TBC
137  #else
138  strInput_memaddrUT.assign(argv[3]);
139  strInput_nmbrTest.assign(argv[4]);
140  strInput_burstSize.assign(argv[5]);
141  #endif
142  // memory_addr_under_test = stoull(strInput_memaddrUT);
143  // testingNumber = stoul(strInput_nmbrTest);
144  // burst_size = stoul(strInput_burstSize);
145 
146  try{
147  memory_addr_under_test = stoull(strInput_memaddrUT);
148  } catch (const std::exception& e) {
149  std::cerr << e.what() << '\n';
150  cout << "WARNING something bad happened in the insertion, hence default used" << endl;
151  memory_addr_under_test = 64;
152  }
153  if(memory_addr_under_test > MAX_TESTABLE_ADDRESS || memory_addr_under_test<=0){
154  cout << "WARNING the address inserted is not allowed, hence default use" << endl;
155  memory_addr_under_test = 64;
156  strInput_memaddrUT.assign(to_string(memory_addr_under_test));
157  }
158  unsigned int max_testingNumber = ((int) pow(2,MAX_TEST_REPETITION_BITWIDTH) - 1);
159  try{
160  testingNumber = stoul(strInput_nmbrTest);
161  } catch (const std::exception& e) {
162  std::cerr << e.what() << '\n';
163  cout << "WARNING something bad happened in the insertion, hence default used" << endl;
164  testingNumber = 2;
165  }
166  if(testingNumber > max_testingNumber || testingNumber<=0){
167  cout << "WARNING the repetition inserted is not allowed, hence default use" << endl;
168  testingNumber = 2;
169  strInput_nmbrTest.assign(to_string(testingNumber));
170  }
171  try{
172  burst_size = stoul(strInput_burstSize);
173  } catch (const std::exception& e) {
174  std::cerr << e.what() << '\n';
175  cout << "WARNING something bad happened in the insertion, hence default used" << endl;
176  burst_size = 16;
177  }
178  if(burst_size > MAX_BURST_SIZE || burst_size<=0){
179  cout << "WARNING the burst size inserted is not allowed, hence default use" << endl;
180  burst_size = 16;
181  strInput_burstSize.assign(to_string(burst_size));
182  }
183 
184 
185  unsigned long long int max_size_mem_size = pow(2,MAX_MEM_SIZE_BENCHMARKING_POWER_OF_TWO);
186  unsigned long long int min_size_mem_size = pow(2,MIN_MEM_SIZE_BENCHMARKING_POWER_OF_TWO);
187  unsigned int max_burst_size = MAX_BURST_SIZE_BENCHMARKING;
188  unsigned int min_burst_size = MIN_BURST_SIZE_BENCHMARKING;
189  unsigned int desired_repetitions = REPETITIONS_BENCHMARKING;
190  unsigned int burst_size_opposite = min_burst_size;
191 
192  if(argc==7){
193  strInput_listMode.assign(argv[6]);
194  }else{
195  strInput_listMode.assign("");
196  }
197  bool use_the_list_mode=false;
198  if(strInput_listMode.compare("list")==0){
199  use_the_list_mode=true;
200  std::cout << "Employing the List mode with max of " << max_size_mem_size << std::endl;
201  }
202 
203  //------------------------------------------------------------------------------------
204  //-- STEP-4 : Infinite Loop for reexecutinge the application! :D
205  //------------------------------------------------------------------------------------
206  string user_choice = "r";
208  createItLogFile();
209  if(use_the_list_mode){
210  testingNumber=desired_repetitions;
211  memory_addr_under_test=min_size_mem_size;
212  burst_size=max_burst_size;
213  }//else take user params
214  //Iterating and interactive loop
215  while (user_choice.compare("q") != 0 ) // quit
216  {
217 
218  unsigned int test_pack = 1;
219  size_t charOutputSizeRoughBytes=8*1+((8 * (2 + 1 + 1 + 1)) * testingNumber);
220  test_pack = charOutputSizeRoughBytes%PACK_SIZE==0 ? charOutputSizeRoughBytes/PACK_SIZE : charOutputSizeRoughBytes/PACK_SIZE + 1;
221  size_t charOutputSize = PACK_SIZE*(test_pack);
222  string initial_input_string(input_string);
223 
224  cout << " Creating mem test commands with " << memory_addr_under_test << " " << testingNumber << " " << burst_size << " as addr, iters, brst" << endl;
225  input_string=createMemTestCommands(memory_addr_under_test, testingNumber,burst_size);
226  size_t charInputSize = 8*2; //a single tdata*burst
227 
228  if (input_string.length() == 0) {
229  cerr << "Empty string provided. Aborting...\n\n" << endl;
230  exit(1);
231  }
232 
233  clock_t start_cycle_main = clock();
234  cout << " ___________________________________________________________________ " << endl;
235  cout << "/ \\" << endl;
236  cout << "INFO: Batch # " << ++num_frame << endl;
237 
238  // Ensure that the selection of MTU is a multiple of 8 (Bytes per transaction)
239  assert(PACK_SIZE % 8 == 0);
240 
241  //packt host2FPGA
242  unsigned int total_out_pack = 1 + (input_string.length() - 1) / PACK_SIZE;// only a single tx
243  unsigned int total_out_bytes = charInputSize;
244  unsigned int bytes_out_last_pack = input_string.length() - (total_out_pack-1) * PACK_SIZE;
245 
246  //packt FPGA2host
247  unsigned int total_in_pack = test_pack;
248  unsigned int total_in_bytes = total_in_pack * PACK_SIZE;
249  unsigned int bytes_in_last_pack_in = charOutputSizeRoughBytes - (total_in_pack - 1) * PACK_SIZE;
250 
251  cout << "INFO: Network socket : " << ((net_type == tcp) ? "TCP" : "UDP") << endl;
252  cout << "INFO: Total packets to send = " << total_out_pack << endl;
253  cout << "INFO: Total packets to receive = " << total_in_pack << endl;
254  cout << "INFO: Total bytes to send = " << total_out_bytes << endl;
255  cout << "INFO: Total bytes to receive = " << total_in_bytes << endl;
256  cout << "INFO: Total bytes rx " << total_in_bytes << " packets = " << total_in_pack << endl;
257  cout << "INFO: Bytes in last packet tx = " << bytes_out_last_pack << endl;
258  cout << "INFO: Bytes in last packet rx = " << bytes_in_last_pack_in << endl;
259  cout << "INFO: Packet size (custom MTU) = " << PACK_SIZE << endl;
260 
261  //------------------------------------------------------
262  //-- STEP-5 : RUN MEMTEST FROM cF (HW)
263  //------------------------------------------------------
264  clock_t start_cycle_memtest_hw = clock();
265 
266  //------------------------------------------------------
267  //-- STEP-5.1 : TX Loop
268  //------------------------------------------------------
269  clock_t last_cycle_tx = clock();
270  unsigned int sending_now = PACK_SIZE;
271  for (unsigned int i = 0; i < total_out_pack; i++) {
272  if ( i == total_out_pack - 1 ) {
273  sending_now = bytes_out_last_pack;
274  }
275  #if NET_TYPE == udp
276  //printStringHex(input_string,charInputSize*sizeof(char));
277  //printBits(charInputSize,input_string.c_str());
278  udpsock.sendTo( & input_string[i * PACK_SIZE], sending_now, servAddress, servPort);
279  #else
280  tcpsock.send( & input_string[i * PACK_SIZE], sending_now);
281  #endif
282  delay(1000);
283  }
284  clock_t next_cycle_tx = clock();
285  double duration_tx = (next_cycle_tx - last_cycle_tx) / (double) CLOCKS_PER_SEC;
286  cout << "INFO: Effective SPS TX:" << (1 / duration_tx) << " \tkbps:" << (PACK_SIZE *
287  total_out_pack / duration_tx / 1024 * 8) << endl;
288  last_cycle_tx = next_cycle_tx;
289 
290 
291  //------------------------------------------------------
292  //-- STEP-5.2 : RX Loop
293  //------------------------------------------------------
294  clock_t last_cycle_rx = clock();
295  unsigned int bytes_received = 0;
296  unsigned int receiving_now = PACK_SIZE;
297  cout << "INFO: Expecting length of packs:" << total_in_pack << endl;
298  char * longbuf = new char[PACK_SIZE * total_in_pack+1];
299  for (unsigned int i = 0; i < total_in_pack; ) {
300  if ( i == total_in_pack - 1 ) {
301  receiving_now = bytes_in_last_pack_in;
302  }
303  #if NET_TYPE == udp
304  recvMsgSize = udpsock.recvFrom(buffer, BUF_LEN, servAddress, servPort);
305  #else
306  recvMsgSize = tcpsock.recv(buffer, BUF_LEN);
307  #endif
308  if (recvMsgSize != receiving_now) {
309  cerr << "WARNING: Received unexpected size pack:" << recvMsgSize << ". Expected: " <<
310  receiving_now << endl;
311  }
312  memcpy( longbuf+(i*bytes_received), buffer, recvMsgSize);
313  cout << "DEBUG: recvMsgSize=" << recvMsgSize << endl;
314  bytes_received += recvMsgSize;
315  i ++;
316  }
317 
318  cout << "INFO: Received packet from " << servAddress << ":" << servPort << endl;
319 
320  #ifdef PY_WRAP
321  char *output_string = output_str;
322  #else
323  char *output_string = new char [(PACK_SIZE * total_in_pack*sizeof(char))];
324  #endif
325  memcpy( output_string, longbuf, bytes_received*sizeof(char));
326  output_string[PACK_SIZE * total_in_pack]='\0';
327  cout << "INFO: Received string : " << output_string << endl;
328  //printCharBuffHex(output_string,bytes_received);
329 
330  clock_t next_cycle_rx = clock();
331  double duration_rx = (next_cycle_rx - last_cycle_rx) / (double) CLOCKS_PER_SEC;
332  cout << "INFO: Effective SPS RX:" << (1 / duration_rx) << " \tkbps:" << (PACK_SIZE *
333  total_in_pack / duration_rx / 1024 * 8) << endl;
334  last_cycle_rx = next_cycle_rx;
335 
336  clock_t end_cycle_memtest_hw = next_cycle_rx;
337 
338  double duration_memtest_hw = (end_cycle_memtest_hw - start_cycle_memtest_hw) /
339  (double) CLOCKS_PER_SEC;
340  cout << "INFO: HW exec. time:" << duration_memtest_hw << " seconds" << endl;
341  cout << "INFO: Effective SPS HW:" << (1 / duration_memtest_hw) << " \tkbps:" <<
342  (PACK_SIZE * total_in_pack / duration_memtest_hw / 1024 * 8) << endl;
343 
344  double duration_main = (clock() - start_cycle_main) / (double) CLOCKS_PER_SEC;
345  cout << "INFO: Effective SPS E2E:" << (1 / duration_main) << endl;
346  cout << "\\___________________________________________________________________/" << endl
347  << endl;
351  //------------------------------------------------------
352  //-- STEP-5.3 : Parsing and displaying
353  //------------------------------------------------------
357  cout << " ___________________________________________________________________ " << endl;
358  cout << "/ \\" << endl;
359  cout <<"INFO: Entering in the output parsing section "<< endl;
360  std::vector<MemoryTestResult> testResults_vector;
361  string output_to_parse_string;
362  output_to_parse_string.append(output_string,charOutputSizeRoughBytes);
363  int rawdatalines = charOutputSizeRoughBytes / 8;;
364  testResults_vector=parseMemoryTestOutput(output_to_parse_string,charOutputSizeRoughBytes,rawdatalines);
365  //otuput showing
366  cout << "INFO: Test Results appearing" << endl;
367  cout << " The Memory test run for " << testResults_vector.size() << " iterations " << endl;
368  unsigned int mem_word_size = 512;
369  unsigned int mem_word_byte_size = mem_word_size/8;
370  double rd_bndwdth=0.0;
371  double wr_bndwdth=0.0;
372  double avg_rd_bndwdth=0.0;
373  double avg_wr_bndwdth=0.0;
374  int avg_fault_cnt = 0;
375  int iterations=0;
376  unsigned long long int written_words=0;
377  for(auto it = std::begin(testResults_vector); it != std::end(testResults_vector); ++it) {
378  cout << " Test number " << it - testResults_vector.begin() << " stress " << it->target_address << " addresses " << endl;
379  cout << " it presented " << it->fault_cntr << " faults " << endl;
380  cout << " and the first faulty address (if any) was " << it->first_fault_address << endl;
381  written_words = ((it->target_address) %mem_word_byte_size) == 0 ? ((it->target_address)/mem_word_byte_size) : (((it->target_address)/mem_word_byte_size) + 1);
382  rd_bndwdth = ( (double)written_words*(double)mem_word_size / ( (double)it->clock_cycles_read * 6.4 ) ); // Gbit/T
383  wr_bndwdth = ( (double)written_words*(double)mem_word_size / ( (double)it->clock_cycles_write * 6.4 ) );
384  cout << " RD BW " << rd_bndwdth << "[GBit/s], with " << it->clock_cycles_read << " ccs" << endl;
385  cout << " WR BW " << wr_bndwdth << "[GBit/s], with " << it->clock_cycles_write << " ccs" << endl;
386  cout << endl << endl;
387  avg_rd_bndwdth += rd_bndwdth;
388  avg_wr_bndwdth += wr_bndwdth;
389  avg_fault_cnt += it->fault_cntr;
390  iterations++;
391 
392  logTheSingleResult(iterations, it->target_address, burst_size, written_words, rd_bndwdth, wr_bndwdth, it->fault_cntr, it->first_fault_address);
393  }
394  avg_rd_bndwdth = avg_rd_bndwdth / iterations;
395  avg_wr_bndwdth = avg_wr_bndwdth / iterations;
396  avg_fault_cnt = avg_fault_cnt / iterations;
397  cout << "Based on " << iterations << " iterations, AVG WR " << avg_wr_bndwdth << " AVG RD " << avg_rd_bndwdth << " AVG faults " << avg_fault_cnt << endl;
398 
399  logTheAvgResult(iterations, memory_addr_under_test, burst_size, written_words, avg_rd_bndwdth, avg_wr_bndwdth, avg_fault_cnt);
400  //clear dynamic memory
401  delete [] longbuf;
402  delete [] output_string;
403  testResults_vector.clear();
404  output_to_parse_string.clear();
405  input_string.clear();
406  initial_input_string.clear();
407  strInput_memaddrUT.clear();
408  strInput_nmbrTest.clear();
412  //------------------------------------------------------
413  //-- STEP-5.4 : Interaction part
414  //------------------------------------------------------
418  //Need to close the application and send to the accelerator a stop for signaling a termination
419  if (user_choice.compare("rq")==0)
420  {
421  cout << "INFO: going to close the application and send a stop command as the user requested." << endl;
422  user_choice.clear();
423  string cmd_string = createMemTestStopCommand();
424  char stop_char_buff [8];
425  memcpy(stop_char_buff, cmd_string.data(), 8);
426  sending_now = 8;
427  //printCharBuffHex(stop_char_buff,8);
428  #if NET_TYPE == udp
429  udpsock.sendTo(stop_char_buff, sending_now, servAddress, servPort);
430  #else
431  tcpsock.send(stop_char_buff, sending_now);
432  #endif
433  delay(1000);
434  #if NET_TYPE == udp
435  recvMsgSize = udpsock.recvFrom(buffer, BUF_LEN, servAddress, servPort);
436  #else
437  recvMsgSize = tcpsock.recv(buffer, BUF_LEN);
438  #endif
439  delay(1000);
440  char output_stop [8];
441  memcpy(output_stop,buffer,8);
442  if(strcmp(output_stop,stop_char_buff)==0){
443  cout << "INFO: Accelerator answered ok" << endl;
444  }else{
445  cout << "INFO: Bad answer received, take care "<< endl;
446  //printStringHex(output_stop,8);
447  }
448  cout << "INFO: IBM ZRL Memtest is closing." << endl<< "Goodbye :D" << endl;
449  break;
450  }
451 
452  user_choice.clear();
453  string confirmation="";
454 
455  cout << "That is all from this application." << endl;
456 
457  if(use_the_list_mode){
458  user_choice.assign("r");
459  testingNumber=desired_repetitions;
460  burst_size=burst_size/2;
461  burst_size_opposite=burst_size_opposite*2;
462  cout << " burst size " << burst_size << " burst oppostit " << burst_size_opposite << endl;
463  if(burst_size_opposite>max_burst_size){ //if iterated all the burst sizes quit
464  // memory_addr_under_test=min_size_mem_size;
465  burst_size=max_burst_size;
466  burst_size_opposite=min_burst_size;
467  memory_addr_under_test=memory_addr_under_test*2;
468  memory_addr_under_test=memory_addr_under_test==max_size_mem_size ? memory_addr_under_test-64 : memory_addr_under_test;
469  if(memory_addr_under_test>max_size_mem_size){ //if iterated all the mem trgt address increment the burst
470  user_choice.assign("q");
471  }
472  }
473  //unsigned long long int max_gb = 8*pow(10,9);
474  //memory_addr_under_test=memory_addr_under_test%max_gb;
475 
476  }else{
477 
478  while (user_choice.empty() || (confirmation.compare("y")!=0) || ( (confirmation.compare("y")==0) && (user_choice.compare("r")!=0 && user_choice.compare("q")!=0) && user_choice.compare("rq")!=0) )
479  {
480  cout << "What do you want to do now?" << endl;
481  cout << " <r>: run a new test, <q>: quit, <rq>: run a new test and quit "<<endl;
482  cout << "Please type your choice "<<endl;
483  cin >> user_choice;
484  cout << "Your choice is " << user_choice << ", is it ok? (y/n) " << endl;
485  cin >> confirmation;
486  }
487  if (user_choice.compare("q")!=0)
488  {
489  confirmation.clear();
490  const unsigned long long int max_testable_address = MAX_TESTABLE_ADDRESS;
491  while ( strInput_memaddrUT.empty() || strInput_nmbrTest.empty() || strInput_burstSize.empty() || (confirmation.compare("y")!=0))
492  {
493  cout << "Please type in the maximum address to test (no more than "<< to_string(max_testable_address) << ")"<< endl;
494  cin >> strInput_memaddrUT;
495  try{
496  memory_addr_under_test = stoull(strInput_memaddrUT);
497  } catch (const std::exception& e) {
498  std::cerr << e.what() << '\n';
499  cout << "WARNING something bad happened in the insertion, hence default used" << endl;
500  memory_addr_under_test = 64;
501  }
502  if(memory_addr_under_test > MAX_TESTABLE_ADDRESS || memory_addr_under_test<=0){
503  cout << "WARNING the address inserted is not allowed, hence default use" << endl;
504  memory_addr_under_test = 64;
505  strInput_memaddrUT.assign(to_string(memory_addr_under_test));
506  }
507  unsigned int max_testingNumber = ((int) pow(2,MAX_TEST_REPETITION_BITWIDTH) - 1);
508  cout << "Please type in the repetition of the test (no more than " << to_string(max_testingNumber) << ")"<< endl;
509  cin >> strInput_nmbrTest;
510  try{
511  testingNumber = stoul(strInput_nmbrTest);
512  } catch (const std::exception& e) {
513  std::cerr << e.what() << '\n';
514  cout << "WARNING something bad happened in the insertion, hence default used" << endl;
515  testingNumber = 3;
516  }
517  if(testingNumber > max_testingNumber || testingNumber<=0){
518  cout << "WARNING something bad happened in the insertion, hence default used" << endl;
519  testingNumber = 2;
520  strInput_nmbrTest.assign(to_string(testingNumber));
521  }
522  cout << "Please type in the desired burst size (no more than "<< to_string(MAX_BURST_SIZE) << ")"<< endl;
523  cin >> strInput_burstSize;
524  try{
525  burst_size = stoul(strInput_burstSize);
526  } catch (const std::exception& e) {
527  std::cerr << e.what() << '\n';
528  cout << "WARNING something bad happened in the insertion, hence default used" << endl;
529  burst_size = 16;
530  }
531  if(burst_size > MAX_BURST_SIZE || burst_size<=0){
532  cout << "WARNING the burst size inserted is not allowed, hence default use" << endl;
533  burst_size = 16;
534  strInput_burstSize.assign(to_string(burst_size));
535  }
536  cout << "Your choice is to test " << testingNumber << " times up to address " << memory_addr_under_test << " burst size " << burst_size << ", is it ok? (y/n) " << endl;
537  cin >> confirmation;
538  }
539  }
540  } //else interactive
541  if (user_choice.compare("q")==0)
542  {
543  cout << "INFO: IBM ZRL Memtest is closing." << endl<< "Goodbye :D" << endl;
544  user_choice.clear();
545  string cmd_string = createMemTestStopCommand();
546  char stop_char_buff [8];
547  memcpy(stop_char_buff, cmd_string.data(), 8);
548  sending_now = 8;
549  //printCharBuffHex(stop_char_buff,8);
550  #if NET_TYPE == udp
551  udpsock.sendTo(stop_char_buff, sending_now, servAddress, servPort);
552  #else
553  tcpsock.send(stop_char_buff, sending_now);
554  #endif
555  delay(1000);
556  #if NET_TYPE == udp
557  recvMsgSize = udpsock.recvFrom(buffer, BUF_LEN, servAddress, servPort);
558  #else
559  recvMsgSize = tcpsock.recv(buffer, BUF_LEN);
560  #endif
561  delay(1000);
562  char output_stop [8];
563  memcpy(output_stop,buffer,8);
564  if(strcmp(output_stop,stop_char_buff)==0){
565  cout << "INFO: Accelerator answered ok" << endl;
566  }else{
567  cout << "INFO: Bad answer received, take care "<< endl;
568  //printStringHex(output_stop,8);
569  }
570  cout << "INFO: IBM ZRL Memtest is closing." << endl<< "Goodbye :D" << endl;
571  break;
572  } // if to quit
573 
574  }//end of while loop
575 
582 // Destructor closes the socket
583 }catch (SocketException & e) {
584  cerr << e.what() << endl;
585  cout << "INFO: there was a SocketException, now aborting" << endl;
586  exit(1);
587 }
588 
589 
590  return 0;
591 }
cat GET request dos socat stdio tcp
Definition: commands.txt:1
#define udp
Definition: config.h:66
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
#define MAX_TESTABLE_ADDRESS
Definition: common.hpp:57
void createAVGLogFile()
Definition: common.hpp:557
#define NET_TYPE
Definition: config.h:60
#define MAX_BURST_SIZE_BENCHMARKING
#define MIN_MEM_SIZE_BENCHMARKING_POWER_OF_TWO
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 REPETITIONS_BENCHMARKING
#define BUF_LEN
Definition: config.h:54
#define MAX_MEM_SIZE_BENCHMARKING_POWER_OF_TWO
void createItLogFile()
Definition: common.hpp:586
string createMemTestStopCommand()
Definition: common.hpp:168
void logTheAvgResult(unsigned int iters, unsigned long long int trgt_address, unsigned int brst_size, unsigned int wr_words, double rd_bw, double wr_bw, unsigned int faults)
Definition: common.hpp:567
void delay(unsigned int mseconds)
Definition: common.hpp:85
void logTheSingleResult(unsigned int iters, unsigned long long int trgt_address, unsigned int brst_size, unsigned int wr_words, double rd_bw, double wr_bw, unsigned int faults, unsigned long long int first_faulty_address)
Definition: common.hpp:598
void print_cFpMemtest(void)
Definition: common.hpp:69
#define MAX_BURST_SIZE
Definition: common.hpp:59
#define PACK_SIZE
Definition: config.h:51
#define MIN_BURST_SIZE_BENCHMARKING
#define MAX_TEST_REPETITION_BITWIDTH
Definition: common.hpp:58
Here is the call graph for this function:

◆ MemoryTestResult() [1/2]

MemoryTestResult::MemoryTestResult ( )
inline

Definition at line 421 of file common.hpp.

421 {}

◆ MemoryTestResult() [2/2]

MemoryTestResult::MemoryTestResult ( unsigned long long int  target_address,
unsigned int  fault_cntr,
unsigned int  first_fault_address,
unsigned long long int  clock_cycles_write,
unsigned long long int  clock_cycles_read 
)
inline

Definition at line 422 of file common.hpp.

427  :
unsigned long long int clock_cycles_read
Definition: common.hpp:418
unsigned int first_fault_address
Definition: common.hpp:417
unsigned long long int clock_cycles_write
Definition: common.hpp:419
unsigned int fault_cntr
Definition: common.hpp:416
unsigned long long int target_address
Definition: common.hpp:415

◆ number2hexString()

template<typename T >
void number2hexString ( const T  in,
char *  out,
size_t  byteSize 
)

Definition at line 266 of file common.hpp.

267 {
268  std::sprintf(out,byteSize, "%x", (char*)&in);
269 }

◆ parseMemoryTestOutput()

template<unsigned int bytes_per_line = 8>
std::vector<MemoryTestResult> parseMemoryTestOutput ( const string  longbuf,
size_t  charOutputSize,
int  rawdatalines 
)

Parse the memory test output contained in astring with a given size.

Parameters
[in]longbufthe buffer containing the output
[in]charOutputSizethe bytesize of the buffer
[in]rawdatalinesthe number of lines in the given outbuf
Returns
vectpr of MemoryTestResult data strcuture

Definition at line 444 of file common.hpp.

445 {
446  std::vector<MemoryTestResult> testResults_vector;
447 
448  int rawiterations = charOutputSize / 8; //should be equivalent to rawdatalines
449  unsigned int mem_word_size = 512;
450  unsigned int mem_word_byte_size = mem_word_size/8;
451  bool is_stop_present = rawdatalines % (3+1+1) == 0; //guard to check if multiple data of 3 64bytes or with
452 
453  int k = 1;
454  char myTmpOutBuff [bytes_per_line];
455  for (int i = 0; i < bytes_per_line; ++i)
456  {
457  myTmpOutBuff[i]=(char)0;
458  }
459  unsigned int testingNumber_out=0, fault_cntr_out=0, fault_addr_out=0;
460  unsigned long long int max_memory_addr_out=0, clock_cycles_read=0, clock_cycles_write=0;
461  for (int i = 1; i < rawdatalines+1; i++)
462  {
463  string tmp_outbuff;
464  tmp_outbuff= longbuf.substr((i-1)*bytes_per_line,bytes_per_line);
465  if(is_stop_present && k==7){
466  cout << "DEBUG the stop is present and is here" << endl;
467  } else if( ( (i == rawdatalines-1) || (i == rawdatalines) ) && k==6){ //check it is either the last or one before the last
468  //substr extraction and parsing
469  //strncpy(myTmpOutBuff,tmp_outbuff.c_str()+1,bytes_per_line-1);
470  //testingNumber_out = *reinterpret_cast<unsigned long long*>(myTmpOutBuff);
471  memcpy(&testingNumber_out,tmp_outbuff.c_str()+1,bytes_per_line/2);
472 
473  #if DEBUG_LEVEL == TRACE_ALL
474  cout << "DEBUG last command with the iterations " << testingNumber_out << endl;
475  #endif
476  }else if(k==5){
477  //strncpy(myTmpOutBuff,tmp_outbuff.c_str(),bytes_per_line);
478  //clock_cycles_read = *reinterpret_cast<unsigned long long int*>(myTmpOutBuff);
479  memcpy(&clock_cycles_read,tmp_outbuff.c_str(),bytes_per_line);
480 
481  #if DEBUG_LEVEL == TRACE_ALL
482  cout << "DEBUG clock_cycles_read (or the fourth half data pckt) " << clock_cycles_read << endl;
483  cout << "DEBUG clock_cycles_write (or the fourth half data pckt) " << clock_cycles_write << endl;
484  #endif
485  MemoryTestResult tmpResult(max_memory_addr_out,fault_cntr_out,fault_addr_out,clock_cycles_write,clock_cycles_read);
486  testResults_vector.push_back(tmpResult);
487  if(!( (i+1 == rawdatalines-1) || (i+1 == rawdatalines) )){
488  k=0;
489  #if DEBUG_LEVEL == TRACE_ALL
490  cout << "DEBUG reinit the counter" << endl;
491  #endif
492  }
493  unsigned int written_words = max_memory_addr_out%mem_word_byte_size == 0 ? max_memory_addr_out/mem_word_byte_size : max_memory_addr_out/mem_word_byte_size + 1;
494  double rd_bndwdth = ( (double)written_words*(double)mem_word_size / ( (double)tmpResult.clock_cycles_read * ( 6.4 ) ) ); // Gbit/T
495  double wr_bndwdth = ( (double)written_words*(double)mem_word_size / ( (double)tmpResult.clock_cycles_write * ( 6.4 ) ) );
496  #if DEBUG_LEVEL == TRACE_ALL
497  cout << "Written " << written_words << " words" << endl;
498  cout << "DEBUG overall test results: target address " << tmpResult.target_address << " ";
499  cout << "Fault counter: " << tmpResult.fault_cntr << " ";
500  cout << "First fault at address: " << tmpResult.first_fault_address << " " << endl;
501  cout << " RD BW " << rd_bndwdth << "[GBit/s] with cc equal to " << tmpResult.clock_cycles_read << " " << endl;
502  cout << " WR BW " << wr_bndwdth << "[GBit/s] with cc equal to " << tmpResult.clock_cycles_write << " " << endl;
503  #endif
504  } else if(k==4){ //clock cycless
505  //char mySecondTmpOutBuff[bytes_per_line/2];
506  //string additional_string;
507  //init the buffer
508  //for(int i=0;i<bytes_per_line;i++){myTmpOutBuff[i]=(char)0;mySecondTmpOutBuff[i%(bytes_per_line/2)]=(char)0;}
509  // additional_string=tmp_outbuff.substr(bytes_per_line/2,bytes_per_line/2);
510  //
511  // tmp_outbuff = tmp_outbuff.erase(bytes_per_line/2,bytes_per_line/2);
512  // strncpy(myTmpOutBuff,tmp_outbuff.c_str(),bytes_per_line/2);
513  // clock_cycles_read = *reinterpret_cast<unsigned int*>(myTmpOutBuff);
514  //
515  // strncpy(mySecondTmpOutBuff,additional_string.c_str(),bytes_per_line/2);
516  // clock_cycles_write = *reinterpret_cast<unsigned int*>(mySecondTmpOutBuff);
517  //strncpy(myTmpOutBuff,tmp_outbuff.c_str(),bytes_per_line);
518  //clock_cycles_write = *reinterpret_cast<unsigned long long int*>(myTmpOutBuff);
519  memcpy(&clock_cycles_write,tmp_outbuff.c_str(),bytes_per_line);
520 
521  }else if(k==3){ // first fault address
522  //substr extraction and parsing
523  //strncpy(myTmpOutBuff,tmp_outbuff.c_str(),bytes_per_line);
524  //fault_addr_out = *reinterpret_cast<unsigned long long int *>(myTmpOutBuff);
525  memcpy(&fault_addr_out,tmp_outbuff.c_str(),bytes_per_line/2);
526 
527  #if DEBUG_LEVEL == TRACE_ALL
528  cout << "DEBUG first fault address (or the third data pckt) " << fault_addr_out << endl;
529  #endif
530  }else if(k==2){ // fault cntr
531  //strncpy(myTmpOutBuff,tmp_outbuff.c_str(),bytes_per_line);
532  //fault_cntr_out = *reinterpret_cast<unsigned long long int *>(myTmpOutBuff);
533  memcpy(&fault_cntr_out,tmp_outbuff.c_str(),bytes_per_line/2);
534 
535  #if DEBUG_LEVEL == TRACE_ALL
536  cout << "DEBUG the fault counters (or the second data pack) " << fault_cntr_out << endl;
537  #endif
538  }else { //max addrss
539  //substr extraction and parsing
540  // strncpy(myTmpOutBuff,tmp_outbuff.c_str(),bytes_per_line);
541  // max_memory_addr_out = *reinterpret_cast<unsigned long long *>(myTmpOutBuff);
542  memcpy(&max_memory_addr_out,tmp_outbuff.c_str(),bytes_per_line);
543  #if DEBUG_LEVEL == TRACE_ALL
544  cout << "DEBUG max address (or the first data pack) " << max_memory_addr_out << endl;
545  #endif
546  }
547  k++;
548  tmp_outbuff.clear();
549  }
550  return testResults_vector;
551 }
Here is the caller graph for this function:

◆ print_cFpMemtest()

void print_cFpMemtest ( void  )

Definition at line 69 of file common.hpp.

70 {
71  // http://patorjk.com/software/taag/#p=display&f=ANSI%20Shadow&t=cFp_Memtest
72  cout << " " << endl;
73  cout << "...build with: " << endl;
74  cout << " ██████╗███████╗██████╗ ███╗ ███╗███████╗███╗ ███╗████████╗███████╗███████╗████████╗" << endl;
75  cout << "██╔════╝██╔════╝██╔══██╗ ████╗ ████║██╔════╝████╗ ████║╚══██╔══╝██╔════╝██╔════╝╚══██╔══╝" << endl;
76  cout << "██║ █████╗ ██████╔╝ ██╔████╔██║█████╗ ██╔████╔██║ ██║ █████╗ ███████╗ ██║ " << endl;
77  cout << "██║ ██╔══╝ ██╔═══╝ ██║╚██╔╝██║██╔══╝ ██║╚██╔╝██║ ██║ ██╔══╝ ╚════██║ ██║ " << endl;
78  cout << "╚██████╗██║ ██║███████╗██║ ╚═╝ ██║███████╗██║ ╚═╝ ██║ ██║ ███████╗███████║ ██║ " << endl;
79  cout << " ╚═════╝╚═╝ ╚═╝╚══════╝╚═╝ ╚═╝╚══════╝╚═╝ ╚═╝ ╚═╝ ╚══════╝╚══════╝ ╚═╝ " << endl;
80  cout << "A cloudFPGA project from IBM ZRL v0.1 --dco " << endl;
81  cout << " " << endl;
82 }
Here is the caller graph for this function:

◆ printBits()

void printBits ( size_t const  size,
void const *const  ptr 
)

print the binary representation of a target pointer buffer of a given size. Assumes little endian.

Parameters
[in]sizethe bytesize to print from ptr.
[in]ptrthe buffer pointer.
Returns
nothing, print to stdout.

Definition at line 98 of file common.hpp.

99 {
100  unsigned char *b = (unsigned char*) ptr;
101  unsigned char byte;
102  int i, j;
103 
104  for (i = size-1; i >= 0; i--) {
105  for (j = 7; j >= 0; j--) {
106  byte = (b[i] >> j) & 1;
107  printf("%u", byte);
108  }
109  }
110  puts("");
111 }
ap_uint< 32 > size
Here is the caller graph for this function:

◆ printCharBuffHex()

void printCharBuffHex ( const char *  inStr,
size_t  strSize 
)

print byte-per-byte a given char buff in hexadecimal format

Parameters
[in]inStrchar buff to print
[in]strSizebytsize to print (can be even less, NOT more )

Definition at line 382 of file common.hpp.

382  {
383  #if DEBUG_LEVEL == TRACE_ALL
384  printf("Going to prit a hex char buff :D\n");
385  #endif
386  for (size_t i = 0; i < strSize; i++)
387  {
388  printf("%x",inStr[i]);
389  }
390  printf("\n");
391 
392 }

◆ printCharBuffHexSafe()

void printCharBuffHexSafe ( const char *  inStr,
size_t  strSize 
)

Definition at line 394 of file common.hpp.

394  {
395  printf("Going to prit a hex char buff :D\n");
396  for (size_t i = 0; i < strSize; i++)
397  {
398  char tmp = inStr[i];
399  printf("%x",tmp);
400  }
401  printf("\n");
402 
403 }

◆ printStringHex()

void printStringHex ( const string  inStr,
size_t  strSize 
)

print byte-per-byte a given string in hexadecimal format

Parameters
[in]inStrstring to print
[in]strSizebytsize to print (can be even less, NOT more )

Definition at line 363 of file common.hpp.

363  {
364  #if DEBUG_LEVEL == TRACE_ALL
365  printf("Going to print a hex string :D\n");
366  #endif
367  for (size_t i = 0; i < strSize; i++)
368  {
369  printf("%x",inStr[i]);
370  }
371  printf("\n");
372 
373 }

◆ string2hexnumerics()

void string2hexnumerics ( const string &  in,
char *  out,
size_t  byteSize 
)

Definition at line 405 of file common.hpp.

406 {
407  for (int i = 0; i < byteSize; i++)
408  {
409  std::sprintf(out+i, "%d", (int)in[i]);
410  }
411 }

Variable Documentation

◆ clock_cycles_read

unsigned long long int MemoryTestResult::clock_cycles_read

Definition at line 418 of file common.hpp.

◆ clock_cycles_write

unsigned long long int MemoryTestResult::clock_cycles_write

Definition at line 419 of file common.hpp.

◆ fault_cntr

unsigned int MemoryTestResult::fault_cntr

Definition at line 416 of file common.hpp.

◆ first_fault_address

unsigned int MemoryTestResult::first_fault_address

Definition at line 417 of file common.hpp.

◆ loggingAVGFile

std::ofstream loggingAVGFile

Definition at line 554 of file common.hpp.

◆ loggingAVGFileName

const std::string loggingAVGFileName ="cfp_vitis_memtest_avg.csv"

Definition at line 555 of file common.hpp.

◆ loggingMultiItFile

std::ofstream loggingMultiItFile

Definition at line 582 of file common.hpp.

◆ loggingMultiItFileName

const std::string loggingMultiItFileName ="cfp_vitis_memtest_multi.csv"

Definition at line 583 of file common.hpp.

◆ target_address

unsigned long long int MemoryTestResult::target_address

Definition at line 415 of file common.hpp.