cloudFPGA (cF) API  1.0
The documentation of the source code of cloudFPGA (cF)
mem_test_flash.cpp
Go to the documentation of this file.
1 
18 // *****************************************************************************
19 // * cloudFPGA
20 // *----------------------------------------------------------------------------
21 // *
22 // * Title : Memory test in HSL using AXI DataMover
23 // *
24 // * Created : Dec. 2018
25 // * Authors : Burkhard Ringlein (NGL@zurich.ibm.com)
26 // *
27 // * Devices : xcku060-ffva1156-2-i
28 // * Tools : Vivado v2017.4 (64-bit)
29 // * Depends : None
30 // *
31 // *
32 // *****************************************************************************
33 
34 #include "mem_test_flash.hpp"
35 
36 using namespace std;
37 using namespace hls;
38 
39 ap_uint<8> fsmState = FSM_IDLE;
40 bool runContiniously = false;
41 ap_uint<1> wasError = 0;
42 ap_uint<33> lastCheckedAddress = 0;
43 ap_uint<33> currentPatternAdderss = 0;
44 ap_uint<64> currentMemPattern = 0;
45 ap_uint<32> patternWriteNum = 0;
46 ap_uint<16> debugVec = 0;
47 ap_uint<8> testPhase = PHASE_IDLE;
48 ap_uint<32> timeoutCnt = 0;
49 
50 ap_uint<8> STS_to_Vector(DmSts sts)
51 {
52  ap_uint<8> ret = 0;
53  ret |= sts.tag;
54  ret |= ((ap_uint<8>) sts.interr) << 4;
55  ret |= ((ap_uint<8>) sts.decerr) << 5;
56  ret |= ((ap_uint<8>) sts.slverr) << 6;
57  ret |= ((ap_uint<8>) sts.okay) << 7;
58  return ret;
59 }
60 
61 
63 
64  // ----- system reset ---
65  ap_uint<1> sys_reset,
66  // ----- MMIO ------
67  ap_uint<2> DIAG_CTRL_IN,
68  ap_uint<2> *DIAG_STAT_OUT,
69 
70  // ---- add. Debug output ----
71  ap_uint<16> *debug_out,
72 
73  //------------------------------------------------------
74  //-- SHELL / Role / Mem / Mp0 Interface
75  //------------------------------------------------------
76  //---- Read Path (MM2S) ------------
77  stream<DmCmd> &soMemRdCmdP0,
78  stream<DmSts> &siMemRdStsP0,
79  stream<Axis<512 > > &siMemReadP0,
80  //---- Write Path (S2MM) -----------
81  stream<DmCmd> &soMemWrCmdP0,
82  stream<DmSts> &siMemWrStsP0,
83  stream<Axis<512> > &soMemWriteP0
84 
85  )
86 {
87 
88 #pragma HLS INTERFACE ap_vld register port=sys_reset name=piSysReset
89 #pragma HLS INTERFACE ap_vld register port=DIAG_CTRL_IN name=piMMIO_diag_ctrl
90 #pragma HLS INTERFACE ap_ovld register port=DIAG_STAT_OUT name=poMMIO_diag_stat
91 #pragma HLS INTERFACE ap_ovld register port=debug_out name=poDebug
92 
93  // Bundling: SHELL / Role / Mem / Mp0 / Read Interface
94 #pragma HLS INTERFACE axis register both port=soMemRdCmdP0
95 #pragma HLS INTERFACE axis register both port=siMemRdStsP0
96 #pragma HLS INTERFACE axis register both port=siMemReadP0
97 
98 #pragma HLS DATA_PACK variable=soMemRdCmdP0 instance=soMemRdCmdP0
99 #pragma HLS DATA_PACK variable=siMemRdStsP0 instance=siMemRdStsP0
100 
101  // Bundling: SHELL / Role / Mem / Mp0 / Write Interface
102 #pragma HLS INTERFACE axis register both port=soMemWrCmdP0
103 #pragma HLS INTERFACE axis register both port=siMemWrStsP0
104 #pragma HLS INTERFACE axis register both port=soMemWriteP0
105 
106 #pragma HLS DATA_PACK variable=soMemWrCmdP0 instance=soMemWrCmdP0
107 #pragma HLS DATA_PACK variable=siMemWrStsP0 instance=siMemWrStsP0
108 
109 
110 
111  Axis<512> memP0;
112  DmSts memRdStsP0;
113  DmSts memWrStsP0;
114 
115  //initalize
116  memP0.tdata = 0;
117  memP0.tlast = 0;
118  memP0.tkeep = 0;
119 
120 
121  if(sys_reset == 1)
122  {
123  fsmState = FSM_IDLE;
124  runContiniously = false;
125  wasError = 0;
126  //lastCheckedAddress = 0;
127  lastCheckedAddress = MEM_END_ADDR + 1; //to stop the test
129  currentMemPattern = 0;
130  patternWriteNum = 0;
131  debugVec = 0;
133  timeoutCnt = 0;
134  return;
135  }
136 
137 
138  switch(fsmState) {
139 
140  case FSM_IDLE:
141  switch(DIAG_CTRL_IN) {
142  case 0x3: //reserved --> idle
143  case 0x0: //stay IDLE, stop test
144  *DIAG_STAT_OUT = (0 << 1) | wasError;
145  runContiniously = false;
147  break;
148  case 0x2:
149  runContiniously = true;
150  //NO break
151  case 0x1: //Run once
153  { // start new test
154  wasError = 0;
157  *DIAG_STAT_OUT = 0b10;
158  debugVec = 0;
160  currentMemPattern = 0;
161  } else if(lastCheckedAddress >= MEM_END_ADDR)
162  {//checked space completely once
163 
165  {
169  currentMemPattern = 0;
170  } else if(testPhase == PHASE_RAMP_READ)
171  {
175  currentMemPattern = 0;
176  } else if (runContiniously)
177  {
180  currentMemPattern = 0;
182  *DIAG_STAT_OUT = (1 << 1) | wasError;
183  } else { //stay here
184  fsmState = FSM_IDLE;
185  *DIAG_STAT_OUT = (0 << 1) | wasError;
186  }
187  } else { //continue current run
188 
190  {
192  } else {
194  }
195 
196  *DIAG_STAT_OUT = (1 << 1) | wasError;
197  if(testPhase == PHASE_STRESS)
198  {
199  currentMemPattern = 0;
200  }
201  }
202  break;
203  }
204 
205  //stop on error
206  if(wasError == 1)
207  {
208  fsmState = FSM_IDLE;
209  *DIAG_STAT_OUT = (0 << 1) | wasError;
210  }
211 
212  //set current address
214  {
216  } else {
218  }
219  break;
220 
221  case FSM_WR_PAT_CMD:
222  if (!soMemWrCmdP0.full()) {
223  //-- Post a memory write command to SHELL/Mem/Mp0
224  soMemWrCmdP0.write(DmCmd(currentPatternAdderss, CHECK_CHUNK_SIZE));
225  patternWriteNum = 0;
227  }
228  break;
229 
230  case FSM_WR_PAT_DATA:
231  if (!soMemWriteP0.full()) {
232  //-- Assemble a memory word and write it to DRAM
235  ap_uint<8> keepVal = 0xFF;
236  memP0.tkeep = (ap_uint<64>) (keepVal, keepVal, keepVal, keepVal, keepVal, keepVal, keepVal, keepVal);
237  //memP0.tkeep = (ap_uint<64>) (0xFF, 0xFF, 0xFF, 0xFF,0xFF, 0xFF, 0xFF, 0xFF);
238 
240  {
241  memP0.tlast = 1;
243  timeoutCnt = 0;
244  } else {
245  memP0.tlast = 0;
246  }
247  soMemWriteP0.write(memP0);
248  patternWriteNum++;
249  }
250  break;
251 
252  case FSM_WR_PAT_STS:
253  if (!siMemWrStsP0.empty()) {
254  //-- Get the memory write status for Mem/Mp0
255  siMemWrStsP0.read(memWrStsP0);
256  //latch errors
257  debugVec |= (ap_uint<16>) STS_to_Vector(memWrStsP0);
258 
260  {
261  fsmState = FSM_IDLE;
262  debugVec |= ((ap_uint<16>) STS_to_Vector(memRdStsP0) )<< 8;
264  } else {
266  currentMemPattern = 0;
267  }
268  } else {
269  timeoutCnt++;
271  {
272  wasError = 1;
273  fsmState = FSM_IDLE;
274  }
275  }
276 
277  break;
278 
279  case FSM_RD_PAT_CMD:
280  if (!soMemRdCmdP0.full()) {
281  //-- Post a memory read command to SHELL/Mem/Mp0
282  soMemRdCmdP0.write(DmCmd(currentPatternAdderss, CHECK_CHUNK_SIZE));
284  }
285  break;
286 
287  case FSM_RD_PAT_DATA:
288  if (!siMemReadP0.empty()) {
289  //-- Read a memory word from DRAM
290  siMemReadP0.read(memP0);
293  {
294  printf("error in pattern reading!\n");
295  wasError = 1;
296  }
297  /*if (memP0.tkeep != (0xFF, 0xFF, 0xFF, 0xFF,0xFF, 0xFF, 0xFF, 0xFF))
298  {
299  printf("error in tkeep\n");
300  }*/
301  //I trust that there will be a tlast (so no counting)
302  if (memP0.tlast == 1)
303  {
305  timeoutCnt = 0;
306  }
307  }
308  break;
309 
310  case FSM_RD_PAT_STS:
311  if (!siMemRdStsP0.empty()) {
312  //-- Get the memory read status for Mem/Mp0
313  siMemRdStsP0.read(memRdStsP0);
314  //latch errors
315  debugVec |= ((ap_uint<16>) STS_to_Vector(memRdStsP0) )<< 8;
316 
318  {
319  fsmState = FSM_IDLE;
320  debugVec |= ((ap_uint<16>) STS_to_Vector(memRdStsP0) )<< 8;
322  } else {
324  currentMemPattern = 0;
325  }
326  } else {
327  timeoutCnt++;
329  {
330  wasError = 1;
331  fsmState = FSM_IDLE;
332  }
333  }
334  break;
335 
336  case FSM_WR_ANTI_CMD:
337  if (!soMemWrCmdP0.full()) {
338  //-- Post a memory write command to SHELL/Mem/Mp0
339  soMemWrCmdP0.write(DmCmd(currentPatternAdderss, CHECK_CHUNK_SIZE));
340  currentMemPattern = 0;
341  patternWriteNum = 0;
343  }
344  break;
345 
346  case FSM_WR_ANTI_DATA:
347  if (!soMemWriteP0.full()) {
348  //-- Assemble a memory word and write it to DRAM
350  ap_uint<64> currentAntiPattern = ~currentMemPattern;
351  //debug
352  //printf("AntiPattern: 0x%llX\n", (uint64_t) currentAntiPattern);
353 
354  memP0.tdata = (currentAntiPattern,currentAntiPattern,currentAntiPattern,currentAntiPattern,currentAntiPattern,currentAntiPattern,currentAntiPattern,currentAntiPattern);
355  ap_uint<8> keepVal = 0xFF;
356  memP0.tkeep = (ap_uint<64>) (keepVal, keepVal, keepVal, keepVal, keepVal, keepVal, keepVal, keepVal);
357  //memP0.tkeep = (0xFF, 0xFF, 0xFF, 0xFF,0xFF, 0xFF, 0xFF, 0xFF);
358 
360  {
361  memP0.tlast = 1;
363  timeoutCnt = 0;
364  } else {
365  memP0.tlast = 0;
366  }
367  soMemWriteP0.write(memP0);
368  patternWriteNum++;
369  }
370  break;
371 
372  case FSM_WR_ANTI_STS:
373  if (!siMemWrStsP0.empty()) {
374  //-- Get the memory write status for Mem/Mp0
375  siMemWrStsP0.read(memWrStsP0);
376  //latch errors
377  debugVec |= (ap_uint<16>) STS_to_Vector(memWrStsP0);
379  } else {
380  timeoutCnt++;
382  {
383  wasError = 1;
384  fsmState = FSM_IDLE;
385  }
386  }
387  break;
388 
389  case FSM_RD_ANTI_CMD:
390  if (!soMemRdCmdP0.full()) {
391  //-- Post a memory read command to SHELL/Mem/Mp0
392  soMemRdCmdP0.write(DmCmd(currentPatternAdderss, CHECK_CHUNK_SIZE));
393  currentMemPattern = 0;
395  }
396  break;
397 
398  case FSM_RD_ANTI_DATA:
399  if (!siMemReadP0.empty()) {
400  //-- Read a memory word from DRAM
401  siMemReadP0.read(memP0);
403  ap_uint<64> currentAntiPattern = ~currentMemPattern;
404 
405  if (memP0.tdata != ((ap_uint<512>) (currentAntiPattern,currentAntiPattern,currentAntiPattern,currentAntiPattern,currentAntiPattern,currentAntiPattern,currentAntiPattern,currentAntiPattern)) )
406  {
407  printf("error in antipattern reading!\n");
408  wasError = 1;
409  }
410  /*if (memP0.tkeep != (0xFF, 0xFF, 0xFF, 0xFF,0xFF, 0xFF, 0xFF, 0xFF))
411  {
412  printf("error in tkeep\n");
413  }*/
414  //I trust that there will be a tlast (so no counting)
415  if (memP0.tlast == 1)
416  {
418  timeoutCnt = 0;
419  }
420  }
421  break;
422 
423  case FSM_RD_ANTI_STS:
424  if (!siMemRdStsP0.empty()) {
425  //-- Get the memory read status for Mem/Mp0
426  siMemRdStsP0.read(memRdStsP0);
427  //latch errors
428  debugVec |= ((ap_uint<16>) STS_to_Vector(memRdStsP0) )<< 8;
430  fsmState = FSM_IDLE;
431  } else {
432  timeoutCnt++;
434  {
435  wasError = 1;
436  fsmState = FSM_IDLE;
437  }
438  }
439  break;
440 
441  } // End: switch
442 
443  *debug_out = debugVec;
444 
445  return;
446 }
ap_uint< 8 > testPhase
ap_uint< 8 > STS_to_Vector(DmSts sts)
ap_uint< 16 > debugVec
ap_uint< 1 > wasError
ap_uint< 33 > lastCheckedAddress
void mem_test_flash_main(ap_uint< 1 > sys_reset, ap_uint< 2 > DIAG_CTRL_IN, ap_uint< 2 > *DIAG_STAT_OUT, ap_uint< 16 > *debug_out, stream< DmCmd > &soMemRdCmdP0, stream< DmSts > &siMemRdStsP0, stream< Axis< 512 > > &siMemReadP0, stream< DmCmd > &soMemWrCmdP0, stream< DmSts > &siMemWrStsP0, stream< Axis< 512 > > &soMemWriteP0)
ap_uint< 32 > timeoutCnt
ap_uint< 32 > patternWriteNum
ap_uint< 64 > currentMemPattern
ap_uint< 8 > fsmState
ap_uint< 33 > currentPatternAdderss
bool runContiniously
#define FSM_RD_ANTI_CMD
#define FSM_RD_PAT_STS
#define PHASE_RAMP_WRITE
#define FSM_RD_ANTI_DATA
#define FSM_WR_PAT_STS
#define FSM_WR_ANTI_CMD
#define MEM_START_ADDR
#define FSM_WR_ANTI_STS
#define PHASE_RAMP_READ
#define FSM_RD_ANTI_STS
#define FSM_RD_PAT_CMD
#define PHASE_STRESS
#define PHASE_IDLE
#define FSM_RD_PAT_DATA
#define FSM_WR_ANTI_DATA
#define MEM_END_ADDR
ap_uint< 1 > okay
ap_uint< 1 > decerr
ap_uint< 1 > slverr
ap_uint< 4 > tag
ap_uint< 1 > interr
#define CHECK_CHUNK_SIZE
This define configures tha AXI burst size of DDRM memory-mapped interfaces AXI4 allows 4KiB,...
Definition: harris.hpp:131
#define FSM_WR_PAT_CMD
Definition: harris.hpp:83
#define TRANSFERS_PER_CHUNK
Definition: harris.hpp:133
#define FSM_WR_PAT_DATA
Definition: harris.hpp:85
#define FSM_IDLE
Definition: harris.hpp:79
#define CYCLES_UNTIL_TIMEOUT
Definition: memtest.hpp:96
ap_uint<(D+7)/8 > tkeep
Definition: axi_utils.hpp:49
ap_uint< 1 > tlast
Definition: axi_utils.hpp:50
ap_uint< D > tdata
Definition: axi_utils.hpp:48