OpenCores
URL https://opencores.org/ocsvn/qspiflash/qspiflash/trunk

Subversion Repositories qspiflash

[/] [qspiflash/] [trunk/] [bench/] [cpp/] [eqspiflash_tb.cpp] - Blame information for rev 16

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 12 dgisselq
////////////////////////////////////////////////////////////////////////////////
2
//
3
// Filename:    eqspiflash_tb.cpp
4
//
5 16 dgisselq
// Project:     Wishbone Controlled Quad SPI Flash Controller
6 12 dgisselq
//
7
// Purpose:     To determine whether or not the eqspiflash module works.  Run
8
//              this with no arguments, and check whether or not the last line
9
//      contains "SUCCESS" or not.  If it does contain "SUCCESS", then the
10
//      module passes all tests found within here.
11
//
12
// Creator:     Dan Gisselquist, Ph.D.
13
//              Gisselquist Technology, LLC
14
//
15
////////////////////////////////////////////////////////////////////////////////
16
//
17
// Copyright (C) 2015-2016, Gisselquist Technology, LLC
18
//
19
// This program is free software (firmware): you can redistribute it and/or
20
// modify it under the terms of  the GNU General Public License as published
21
// by the Free Software Foundation, either version 3 of the License, or (at
22
// your option) any later version.
23
//
24
// This program is distributed in the hope that it will be useful, but WITHOUT
25
// ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY or
26
// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
27
// for more details.
28
//
29
// You should have received a copy of the GNU General Public License along
30 16 dgisselq
// with this program.  (It's in the $(ROOT)/doc directory.  Run make with no
31 12 dgisselq
// target there if the PDF file isn't present.)  If not, see
32
// <http://www.gnu.org/licenses/> for a copy.
33
//
34
// License:     GPL, v3, as defined and found on www.gnu.org,
35
//              http://www.gnu.org/licenses/gpl.html
36
//
37
//
38
////////////////////////////////////////////////////////////////////////////////
39
//
40
//
41
#include "verilated.h"
42 16 dgisselq
#include "verilated_vcd_c.h"
43 12 dgisselq
#include "Veqspiflash.h"
44
#include "eqspiflashsim.h"
45
 
46
#define QSPIFLASH       0x0400000
47
const int       BOMBCOUNT = 2048;
48
 
49
class   EQSPIFLASH_TB {
50 16 dgisselq
        unsigned long           m_tickcount;
51 12 dgisselq
        Veqspiflash     *m_core;
52
        EQSPIFLASHSIM   *m_flash;
53
        bool            m_bomb;
54 16 dgisselq
        VerilatedVcdC*  m_trace;
55
 
56 12 dgisselq
public:
57
 
58
        EQSPIFLASH_TB(void) {
59 16 dgisselq
                Verilated::traceEverOn(true);
60 12 dgisselq
                m_core = new Veqspiflash;
61 16 dgisselq
                m_flash= new EQSPIFLASHSIM(24,true);
62
                m_trace= NULL;
63 12 dgisselq
        }
64
 
65
        unsigned operator[](const int index) { return (*m_flash)[index]; }
66
        void    setflash(unsigned addr, unsigned v) {
67
                m_flash->set(addr, v);
68
        }
69
        void    load(const char *fname) {
70
                m_flash->load(0,fname);
71
        }
72
 
73 16 dgisselq
        void    trace(const char *fname) {
74
                if (!m_trace) {
75
                        m_trace = new VerilatedVcdC;
76
                        m_core->trace(m_trace, 99);
77
                        m_trace->open(fname);
78
                }
79
        }
80
 
81 12 dgisselq
        void    tick(void) {
82 16 dgisselq
                // m_core->i_clk_82mhz = 0;
83
                // m_core->eval();
84 12 dgisselq
                m_core->i_qspi_dat = (*m_flash)(m_core->o_qspi_cs_n,
85
                        m_core->o_qspi_sck, m_core->o_qspi_dat);
86
 
87 16 dgisselq
                m_core->i_clk_82mhz = 1;
88
                m_core->eval();
89
// #define      DEBUGGING_OUTPUT
90
#ifdef  DEBUGGING_OUTPUT
91 12 dgisselq
                printf("%08lx-WB: %s %s/%s %s %s[%s%s%s%s%s] %s %s@0x%08x[%08x/%08x] -- SPI %s%s[%x/%x](%d,%d)",
92
                        m_tickcount,
93
                        (m_core->i_wb_cyc)?"CYC":"   ",
94
                        (m_core->i_wb_data_stb)?"DSTB":"    ",
95
                        (m_core->i_wb_ctrl_stb)?"CSTB":"    ",
96
                        (m_core->o_wb_stall)?"STALL":"     ",
97
                        (m_core->o_wb_ack)?"ACK":"   ",
98
                        (m_core->v__DOT__bus_wb_ack)?"BS":"  ",
99
                        (m_core->v__DOT__rd_data_ack)?"RD":"  ",
100
                        (m_core->v__DOT__ew_data_ack)?"EW":"  ",
101
                        (m_core->v__DOT__id_data_ack)?"ID":"  ",
102
                        (m_core->v__DOT__ct_data_ack)?"CT":"  ",
103
                        (m_core->o_cmd_accepted)?"BUS":"   ",
104
                        (m_core->i_wb_we)?"W":"R",
105
                        (m_core->i_wb_addr), (m_core->i_wb_data),
106
                        (m_core->o_wb_data),
107
                        (!m_core->o_qspi_cs_n)?"CS":"  ",
108
                        (m_core->o_qspi_sck)?"CK":"  ",
109
                        (m_core->o_qspi_dat), (m_core->i_qspi_dat),
110
                        (m_core->o_qspi_dat)&1, ((m_core->i_qspi_dat)&2)?1:0);
111
 
112
                /// printf("%08lx-EQ: ", m_tickcount);
113
                printf("EQ: ");
114
                if (m_core->v__DOT__owned) {
115
                        switch(m_core->v__DOT__owner&3) {
116
                        case 0: printf("RD"); break;
117
                        case 1: printf("EW"); break;
118
                        case 2: printf("ID"); break;
119
                        case 3: printf("CT"); break;
120
                        }
121
                } else printf("  ");
122
 
123
                printf(" REQ[%s%s%s%s]",
124
                        (m_core->v__DOT__rd_qspi_req)?"RD":"  ",
125
                        (m_core->v__DOT__ew_qspi_req)?"EW":"  ",
126
                        (m_core->v__DOT__id_qspi_req)?"ID":"  ",
127
                        (m_core->v__DOT__ct_qspi_req)?"CT":"  ");
128
 
129
                printf(" %s[%s%2d%s%s0x%08x]",
130
                        (m_core->v__DOT__spi_wr)?"CMD":"   ",
131
                        (m_core->v__DOT__spi_hold)?"HLD":"   ",
132
                        (m_core->v__DOT__spi_len+1)*8,
133
                        (m_core->v__DOT__spi_dir)?"RD":"WR",
134
                        (m_core->v__DOT__spi_spd)?"Q":" ",
135
                        (m_core->v__DOT__spi_word));
136
 
137
                printf(" STATE[%2x%s,%2x%s,%2x%s,%2x%s]",
138
                        m_core->v__DOT__rdproc__DOT__rd_state,
139
                                (m_core->v__DOT__rd_spi_wr)?"W":" ",
140
                        m_core->v__DOT__ewproc__DOT__wr_state,
141
                                (m_core->v__DOT__ew_spi_wr)?"W":" ",
142
                        m_core->v__DOT__idotp__DOT__id_state,
143
                                (m_core->v__DOT__id_spi_wr)?"W":" ",
144
                        m_core->v__DOT__ctproc__DOT__ctstate,
145
                                (m_core->v__DOT__ct_spi_wr)?"W":" ");
146
 
147
                printf(" LL:[%s%s%d(%08x)->%08x]",
148
                        (m_core->v__DOT__spi_busy)?"BSY":"   ",
149
                        (m_core->v__DOT__spi_valid)?"VAL":"   ",
150
                        (m_core->v__DOT__lowlvl__DOT__state),
151
                        (m_core->v__DOT__lowlvl__DOT__r_input),
152
                        (m_core->v__DOT__spi_out));
153
 
154
                // printf(" 0x%08x,%02x ", m_core->v__DOT__id_data, 
155
                        // m_core->v__DOT__bus_addr);
156
                printf(" %s%08x@%08x",
157
                        (m_core->v__DOT__bus_wr)?"W":"R",
158
                        m_core->v__DOT__bus_data, m_core->v__DOT__bus_addr);
159
 
160
                if (m_core->v__DOT__idotp__DOT__id_state == 5)
161
                        printf(" %s[%2x]%s",
162
                                (m_core->v__DOT__idotp__DOT__last_addr)?"LST":"   ",
163
                                (m_core->v__DOT__idotp__DOT__lcl_id_addr),
164
                                (m_core->v__DOT__idotp__DOT__id_loaded)?"LOD":"   ");
165
 
166
 
167
                printf(" %s[%08x]",
168
                        (m_core->v__DOT__idotp__DOT__nxt_data_ack)
169
                        ?"NXT":"   ", m_core->v__DOT__idotp__DOT__nxt_data);
170
                printf(" %s[%x]",
171
                        (m_core->v__DOT__idotp__DOT__set_val)?"SET":"   ",
172
                        (m_core->v__DOT__idotp__DOT__set_addr));
173
 
174
                printf(" RD:IACK[%x]",
175
                        (m_core->v__DOT__rdproc__DOT__invalid_ack_pipe));
176
                printf(" CT:IACK[%x]",
177
                        (m_core->v__DOT__ctproc__DOT__invalid_ack_pipe));
178
 
179
                {
180
                        unsigned counts = m_flash->counts_till_idle();
181
                        if (counts)
182
                                printf(" %8dI ", counts);
183
                }
184
                printf("%s%s%s%s",
185
                        (m_core->v__DOT__rdproc__DOT__accepted)?"RD-ACC":"",
186
                        (m_core->v__DOT__ewproc__DOT__accepted)?"EW-ACC":"",
187
                        (m_core->v__DOT__idotp__DOT__accepted)?"ID-ACC":"",
188
                        (m_core->v__DOT__ctproc__DOT__accepted)?"CT-ACC":"");
189
 
190
 
191 16 dgisselq
                printf("%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s",
192 12 dgisselq
                        (m_core->v__DOT__preproc__DOT__pending)?" PENDING":"",
193
                        (m_core->v__DOT__preproc__DOT__lcl_key)?" KEY":"",
194
                        (m_core->v__DOT__preproc__DOT__ctreg_stb)?" CTSTB":"",
195
                        (m_core->v__DOT__bus_ctreq)?" BUSCTRL":"",
196
                        (m_core->v__DOT__bus_other_req)?" BUSOTHER":"",
197
                        (m_core->v__DOT__preproc__DOT__wp)?" WP":"",
198
                        (m_core->v__DOT__bus_wip)?" WIP":"",
199
                        // (m_core->v__DOT__preproc__DOT__lcl_reg)?" LCLREG":"",
200
                        // (m_core->v__DOT__w_xip)?" XIP":"",
201
                        // (m_core->v__DOT__w_quad)?" QUAD":"",
202 16 dgisselq
                        (m_core->v__DOT__bus_piperd)?" RDPIPE":"",
203 12 dgisselq
                        (m_core->v__DOT__preproc__DOT__wp)?" WRWP":"",
204
                        (m_core->v__DOT__ewproc__DOT__cyc)?" WRCYC":"",
205
                        (m_core->v__DOT__bus_pipewr)?" WRPIPE":"",
206
                        (m_core->v__DOT__bus_endwr)?" ENDWR":"",
207
                        (m_core->v__DOT__ct_ack)?" CTACK":"",
208
                        (m_core->v__DOT__rd_bus_ack)?" RDACK":"",
209
                        (m_core->v__DOT__id_bus_ack)?" IDACK":"",
210
                        (m_core->v__DOT__ew_bus_ack)?" EWACK":"",
211
                        (m_core->v__DOT__preproc__DOT__lcl_ack)?" LCLACK":"",
212
                        (m_core->v__DOT__rdproc__DOT__r_leave_xip)?" LVXIP":"",
213
                        (m_core->v__DOT__preproc__DOT__new_req)?" NREQ":"");
214
 
215
                printf("%s%s%s",
216
                        (m_core->v__DOT__bus_idreq)?" BUSID":"",
217
                        (m_core->v__DOT__id_bus_ack)?" BUSAK":"",
218
                        (m_core->v__DOT__idotp__DOT__id_read_request)?" IDRD":"");
219
 
220
                if (m_core->v__DOT__rdproc__DOT__r_requested)
221
                        fputs(" RD:R_REQUESTED", stdout);
222
                if (m_core->v__DOT__rdproc__DOT__r_leave_xip)
223
                        fputs(" RD:R_LVXIP", stdout);
224
 
225
 
226
                printf("\n");
227 16 dgisselq
#endif
228 12 dgisselq
 
229 16 dgisselq
                if ((m_trace)&&(m_tickcount>0))  m_trace->dump(10*m_tickcount-2);
230
                m_core->i_clk_82mhz = 1;
231 12 dgisselq
                m_core->eval();
232 16 dgisselq
                if (m_trace)    m_trace->dump(10*m_tickcount);
233
                m_core->i_clk_82mhz = 0;
234 12 dgisselq
                m_core->eval();
235 16 dgisselq
                if (m_trace)    m_trace->dump(10*m_tickcount+5);
236 12 dgisselq
 
237
                m_tickcount++;
238
 
239
                /*
240
                if ((m_core->o_wb_ack)&&(!m_core->i_wb_cyc)) {
241
                        printf("SETTING ERR TO TRUE!!!!!  ACK w/ no CYC\n");
242
                        // m_bomb = true;
243
                }
244
                */
245
        }
246
 
247
        void wb_tick(void) {
248
                printf("WB-TICK()\n");
249
                m_core->i_wb_cyc   = 0;
250
                m_core->i_wb_data_stb = 0;
251
                m_core->i_wb_ctrl_stb = 0;
252
                tick();
253
        }
254
 
255
        unsigned wb_read(unsigned a) {
256
                int             errcount = 0;
257
                unsigned        result;
258
 
259
                printf("WB-READ(%08x)\n", a);
260
 
261
                m_core->i_wb_cyc = 1;
262
                m_core->i_wb_data_stb = (a & QSPIFLASH)?1:0;
263
                m_core->i_wb_ctrl_stb = !(m_core->i_wb_data_stb);
264
                m_core->i_wb_we  = 0;
265
                m_core->i_wb_addr= a & 0x03fffff;
266
 
267 16 dgisselq
                if (m_core->o_wb_stall) {
268 12 dgisselq
                        while((errcount++ < BOMBCOUNT)&&(m_core->o_wb_stall))
269
                                tick();
270 16 dgisselq
                } tick();
271 12 dgisselq
 
272
                m_core->i_wb_data_stb = 0;
273
                m_core->i_wb_ctrl_stb = 0;
274
 
275
                while((errcount++ <  BOMBCOUNT)&&(!m_core->o_wb_ack))
276
                        tick();
277
 
278
 
279
                result = m_core->o_wb_data;
280
 
281
                // Release the bus?
282
                m_core->i_wb_cyc = 0;
283
                m_core->i_wb_data_stb = 0;
284
                m_core->i_wb_ctrl_stb = 0;
285
 
286
                if(errcount >= BOMBCOUNT) {
287 16 dgisselq
                        printf("RD-SETTING ERR TO TRUE!!!!!\n");
288 12 dgisselq
                        m_bomb = true;
289
                } else if (!m_core->o_wb_ack) {
290
                        printf("SETTING ERR TO TRUE--NO ACK, NO TIMEOUT\n");
291
                        m_bomb = true;
292
                }
293
                tick();
294
 
295
                return result;
296
        }
297
 
298
        void    wb_read(unsigned a, int len, unsigned *buf) {
299
                int             errcount = 0;
300
                int             THISBOMBCOUNT = BOMBCOUNT * len;
301
                int             cnt, rdidx, inc;
302
 
303
                printf("WB-READ(%08x, %d)\n", a, len);
304
 
305
                while((errcount++ < BOMBCOUNT)&&(m_core->o_wb_stall))
306
                        wb_tick();
307
 
308
                if (errcount >= BOMBCOUNT) {
309
                        m_bomb = true;
310
                        return;
311
                }
312
 
313
                errcount = 0;
314
 
315
                m_core->i_wb_cyc = 1;
316
                m_core->i_wb_data_stb = (a & QSPIFLASH)?1:0;
317
                m_core->i_wb_ctrl_stb = !(m_core->i_wb_data_stb);
318
                m_core->i_wb_we  = 0;
319
                m_core->i_wb_addr= a & 0x03fffff;
320
 
321
                rdidx =0; cnt = 0;
322
                inc = (m_core->i_wb_data_stb);
323
 
324
                do {
325
                        int     s;
326
                        s = (m_core->o_wb_stall==0)?0:1;
327
                        tick();
328
                        if (!s)
329
                                m_core->i_wb_addr += inc;
330
                        cnt += (s==0)?1:0;
331
                        if (m_core->o_wb_ack)
332
                                buf[rdidx++] = m_core->o_wb_data;
333
                } while((cnt < len)&&(errcount++ < THISBOMBCOUNT));
334
 
335
                m_core->i_wb_data_stb = 0;
336
                m_core->i_wb_ctrl_stb = 0;
337
 
338
                while((rdidx < len)&&(errcount++ < THISBOMBCOUNT)) {
339
                        tick();
340
                        if (m_core->o_wb_ack)
341
                                buf[rdidx++] = m_core->o_wb_data;
342
                }
343
 
344
                // Release the bus?
345
                m_core->i_wb_cyc = 0;
346
 
347
                if(errcount >= THISBOMBCOUNT) {
348 16 dgisselq
                        printf("RDI-SETTING ERR TO TRUE!!!!! (errcount=%08x, THISBOMBCOUNT=%08x)\n", errcount, THISBOMBCOUNT);
349 12 dgisselq
                        m_bomb = true;
350
                } else if (!m_core->o_wb_ack) {
351
                        printf("SETTING ERR TO TRUE--NO ACK, NO TIMEOUT\n");
352
                        m_bomb = true;
353
                }
354
                tick();
355
        }
356
 
357
        void    wb_write(unsigned a, unsigned int v) {
358
                int errcount = 0;
359
 
360
                printf("WB-WRITE(%08x) = %08x\n", a, v);
361
                m_core->i_wb_cyc = 1;
362
                m_core->i_wb_data_stb = (a & QSPIFLASH)?1:0;
363
                m_core->i_wb_ctrl_stb = !(m_core->i_wb_data_stb);
364
                m_core->i_wb_we  = 1;
365
                m_core->i_wb_addr= a & 0x03fffff;
366
                m_core->i_wb_data= v;
367
 
368
                if (m_core->o_wb_stall)
369
                        while((errcount++ < BOMBCOUNT)&&(m_core->o_wb_stall))
370
                                tick();
371
                tick();
372
 
373
                m_core->i_wb_data_stb = 0;
374
                m_core->i_wb_ctrl_stb = 0;
375
 
376
                while((errcount++ <  BOMBCOUNT)&&(!m_core->o_wb_ack))
377
                        tick();
378
 
379
                // Release the bus?
380
                m_core->i_wb_cyc = 0;
381
                m_core->i_wb_data_stb = 0;
382
                m_core->i_wb_ctrl_stb = 0;
383
 
384
                if(errcount >= BOMBCOUNT) {
385 16 dgisselq
                        printf("WB-SETTING ERR TO TRUE!!!!!\n");
386 12 dgisselq
                        m_bomb = true;
387
                } tick();
388
        }
389
 
390
        void    wb_write(unsigned a, unsigned int ln, unsigned int *buf) {
391
                unsigned errcount = 0, nacks = 0;
392
 
393
                m_core->i_wb_cyc = 1;
394
                m_core->i_wb_data_stb = (a & QSPIFLASH)?1:0;
395
                m_core->i_wb_ctrl_stb = !(m_core->i_wb_data_stb);
396
                for(unsigned stbcnt=0; stbcnt<ln; stbcnt++) {
397
                        m_core->i_wb_we  = 1;
398
                        m_core->i_wb_addr= (a+stbcnt) & 0x03fffff;
399
                        m_core->i_wb_data= buf[stbcnt];
400
                        errcount = 0;
401
 
402
                        while((errcount++ < BOMBCOUNT)&&(m_core->o_wb_stall)) {
403
                                tick(); if (m_core->o_wb_ack) nacks++;
404
                        }
405
                        // Tick, now that we're not stalled.  This is the tick
406
                        // that gets accepted.
407
                        tick(); if (m_core->o_wb_ack) nacks++;
408
                }
409
 
410
                m_core->i_wb_data_stb = 0;
411
                m_core->i_wb_ctrl_stb = 0;
412
 
413
                errcount = 0;
414
                while((nacks < ln)&&(errcount++ < BOMBCOUNT)) {
415
                        tick();
416
                        if (m_core->o_wb_ack) {
417
                                nacks++;
418
                                errcount = 0;
419
                        }
420
                }
421
 
422
                // Release the bus
423
                m_core->i_wb_cyc = 0;
424
                m_core->i_wb_data_stb = 0;
425
                m_core->i_wb_ctrl_stb = 0;
426
 
427
                if(errcount >= BOMBCOUNT) {
428 16 dgisselq
                        printf("WBI-SETTING ERR TO TRUE!!!!!\n");
429 12 dgisselq
                        m_bomb = true;
430
                } tick();
431
        }
432
 
433
        void    wb_write_slow(unsigned a, unsigned int ln, unsigned int *buf,
434
                        int slowcounts) {
435
                unsigned errcount = 0, nacks = 0;
436
 
437
                m_core->i_wb_cyc = 1;
438
                m_core->i_wb_data_stb = (a & QSPIFLASH)?1:0;
439
                m_core->i_wb_ctrl_stb = !(m_core->i_wb_data_stb);
440
                for(unsigned stbcnt=0; stbcnt<ln; stbcnt++) {
441
                        m_core->i_wb_we  = 1;
442
                        m_core->i_wb_addr= (a+stbcnt) & 0x03fffff;
443
                        m_core->i_wb_data= buf[stbcnt];
444
                        errcount = 0;
445
 
446
                        while((errcount++ < BOMBCOUNT)&&(m_core->o_wb_stall)) {
447
                                tick(); if (m_core->o_wb_ack) nacks++;
448
                        }
449
 
450
                        // Tick, now that we're not stalled.  This is the tick
451
                        // that gets accepted.
452
                        tick(); if (m_core->o_wb_ack) nacks++;
453
 
454
 
455
                        m_core->i_wb_data_stb = 0;
456
                        m_core->i_wb_ctrl_stb = 0;
457
                        for(int j=0; j<slowcounts; j++) {
458
                                tick(); if (m_core->o_wb_ack) nacks++;
459
                        }
460
 
461
                        // Turn our strobe signal back on again, after we just
462
                        // turned it off.
463
                        m_core->i_wb_data_stb = (a & QSPIFLASH)?1:0;
464
                        m_core->i_wb_ctrl_stb = !(m_core->i_wb_data_stb);
465
                }
466
 
467
                m_core->i_wb_data_stb = 0;
468
                m_core->i_wb_ctrl_stb = 0;
469
 
470
                errcount = 0;
471
                while((nacks < ln)&&(errcount++ < BOMBCOUNT)) {
472
                        tick();
473
                        if (m_core->o_wb_ack) {
474
                                nacks++;
475
                                errcount = 0;
476
                        }
477
                }
478
 
479
                // Release the bus
480
                m_core->i_wb_cyc = 0;
481
                m_core->i_wb_data_stb = 0;
482
                m_core->i_wb_ctrl_stb = 0;
483
 
484
                if(errcount >= BOMBCOUNT) {
485 16 dgisselq
                        printf("WBS-SETTING ERR TO TRUE!!!!!\n");
486 12 dgisselq
                        m_bomb = true;
487
                } tick();
488
        }
489
 
490
        bool    bombed(void) const { return m_bomb; }
491
 
492
};
493
 
494
int main(int  argc, char **argv) {
495
        Verilated::commandArgs(argc, argv);
496
        EQSPIFLASH_TB   *tb = new EQSPIFLASH_TB;
497
        const char      *fname = "/dev/urandom";
498
        unsigned        rdv;
499
        unsigned        *rdbuf;
500
        int              idx = 4;
501
 
502
        tb->load(fname);
503
        rdbuf = new unsigned[4096];
504
        tb->setflash(0,0);
505
 
506 16 dgisselq
        tb->trace("eqspi.vcd");
507
 
508 12 dgisselq
        tb->wb_tick();
509
        rdv = tb->wb_read(QSPIFLASH);
510
        printf("READ[0] = %04x\n", rdv);
511
        if (rdv != 0)
512
                goto test_failure;
513
 
514
        tb->wb_tick();
515
        if (tb->bombed())
516
                goto test_failure;
517
 
518
        for(int i=0; (i<1000)&&(!tb->bombed()); i++) {
519
                unsigned        tblv;
520
                tblv = (*tb)[i];
521
                rdv = tb->wb_read(QSPIFLASH+i);
522
 
523
                if(tblv != rdv) {
524
                        printf("BOMB: READ[%08x] %08x, EXPECTED %08x\n", QSPIFLASH+i, rdv, tblv);
525
                        goto test_failure;
526
                        break;
527
                } else printf("MATCH: %08x == %08x\n", rdv, tblv);
528
        }
529
 
530
        printf("SINGLE-READ TEST PASSES\n");
531
 
532
        for(int i=0; i<1000; i++)
533
                rdbuf[i] = -1;
534
        tb->wb_read(QSPIFLASH+1000, 1000, rdbuf);
535
        if (tb->bombed())
536
                goto    test_failure;
537
        for(int i=0; i<1000; i++) {
538
                if ((*tb)[i+1000] != rdbuf[i]) {
539
                        printf("BOMB: V-READ[%08x] %08x, EXPECTED %08x\n", QSPIFLASH+1000+i, rdv, (*tb)[i+1000]);
540
                        goto    test_failure;
541
                }
542
        } if (tb->bombed())
543
                goto test_failure;
544
        printf("VECTOR TEST PASSES!\n");
545
 
546
        // Read the status register
547
        printf("EWCTRL-REG = %02x\n", rdv=tb->wb_read(0));
548
        if(tb->bombed()) goto test_failure;
549
        printf("STATUS-REG = %02x\n", rdv=tb->wb_read(1));
550
        if ((rdv != 0x1c)||(tb->bombed())) goto test_failure;
551
        printf("NVCONF-REG = %02x\n", tb->wb_read(2)); if(tb->bombed()) goto test_failure;
552
        printf("VCONFG-REG = %02x\n", tb->wb_read(3)); if(tb->bombed()) goto test_failure;
553
        printf("EVCONF-REG = %02x\n", tb->wb_read(4)); if(tb->bombed()) goto test_failure;
554
        printf("LOCK  -REG = %02x\n", tb->wb_read(5)); if(tb->bombed()) goto test_failure;
555
        printf("FLAG  -REG = %02x\n", tb->wb_read(6)); if(tb->bombed()) goto test_failure;
556
 
557
        if (tb->bombed())
558
                goto test_failure;
559
 
560
        printf("ID[%2d]-RG = %08x\n", 0, rdv = tb->wb_read(8+0));
561
        if (rdv != 0x20ba1810) {
562
                printf("BOMB: ID[%2d]-RG = %08x != %08x\n", 0, rdv,
563
                        0x20ba1810);
564
                goto test_failure;
565
        }
566
 
567
        for(int i=1; i<5; i++)
568
                printf("ID[%2d]-RG = %02x\n", i, tb->wb_read(8+i));
569
        if (tb->bombed())
570
                goto test_failure;
571
 
572
        for(int i=0; i<16; i++)
573
                printf("OTP[%2d]-R = %02x\n", i, tb->wb_read(16+i));
574
        if (tb->bombed())
575
                goto test_failure;
576
        printf("OTP[CT]-R = %02x\n", tb->wb_read(15)>>24);
577
 
578
        if (tb->bombed())
579
                goto test_failure;
580
 
581
        printf("Attempting to switch in Quad mode\n");
582
        // tb->wb_write(4, (tb->wb_read(4)&0x07f)); // Adjust EVconfig
583
 
584
        for(int i=0; (i<1000)&&(!tb->bombed()); i++) {
585
                unsigned        tblv;
586
                tblv = (*tb)[i];
587
                rdv = tb->wb_read(QSPIFLASH+i);
588
 
589
                if(tblv != rdv) {
590
                        printf("BOMB: READ %08x, EXPECTED %08x\n", rdv, tblv);
591
                        goto test_failure;
592
                        break;
593
                } else printf("MATCH: %08x == %08x\n", rdv, tblv);
594
        } tb->wb_read(QSPIFLASH+1000, 1000, rdbuf);
595
        if (tb->bombed())
596
                goto    test_failure;
597
        for(int i=0; i<1000; i++) {
598
                if ((*tb)[i+1000] != rdbuf[i]) {
599
                        printf("BOMB: READ %08x, EXPECTED %08x\n", rdv, (*tb)[i+1000]);
600
                        goto    test_failure;
601
                }
602
        } printf("VECTOR TEST PASSES! (QUAD)\n");
603
 
604
        printf("Attempting to switch to Quad mode with XIP\n");
605 16 dgisselq
        {
606
                int     nv;
607
                nv = tb->wb_read(3);
608
                printf("READ VCONF = %02x\n", nv);
609
                printf("WRITING VCONF= %02x\n", nv | 0x08);
610
                tb->wb_write(3, nv|0x08);
611
        }
612 12 dgisselq
        // tb->wb_write(0, 0x22000000);
613
 
614
        printf("Attempting to read in Quad mode, using XIP mode\n");
615
        for(int i=0; (i<1000)&&(!tb->bombed()); i++) {
616
                unsigned        tblv;
617
                tblv = (*tb)[i];
618
                rdv = tb->wb_read(QSPIFLASH+i);
619
 
620
                if(tblv != rdv) {
621
                        printf("BOMB: READ %08x, EXPECTED %08x\n", rdv, tblv);
622
                        goto test_failure;
623
                        break;
624
                } else printf("MATCH: %08x == %08x\n", rdv, tblv);
625
        }
626
 
627
        // Try a vector read
628
        tb->wb_read(QSPIFLASH+1000, 1000, rdbuf);
629
        if (tb->bombed())
630
                goto    test_failure;
631
        for(int i=0; i<1000; i++) {
632
                if ((*tb)[i+1000] != rdbuf[i]) {
633
                        printf("BOMB: READ %08x, EXPECTED %08x\n", rdv, (*tb)[i+1000]);
634
                        goto    test_failure;
635
                }
636
        } printf("VECTOR TEST PASSES! (QUAD+XIP)\n");
637
 
638
        rdbuf[0] = tb->wb_read(QSPIFLASH+1023);
639
        rdbuf[1] = tb->wb_read(QSPIFLASH+2048);
640
 
641
        printf("Turning off write-protect, calling WEL\n");
642
        tb->wb_write(0, 0x620001be);
643
        printf("Attempting to erase subsector 1\n");
644
        tb->wb_write(0, 0xf20005be);
645
 
646 16 dgisselq
        while((tb->wb_read(0)&0x01000000)&&(!tb->bombed()))
647 12 dgisselq
                ;
648 16 dgisselq
        while((tb->wb_read(0)&0x80000000)&&(!tb->bombed()))
649 12 dgisselq
                ;
650 16 dgisselq
        if (tb->bombed())
651
                goto test_failure;
652 12 dgisselq
        if (tb->wb_read(QSPIFLASH+1023) != rdbuf[0])
653
                goto test_failure;
654
        if (tb->wb_read(QSPIFLASH+2048) != rdbuf[1])
655
                goto test_failure;
656
        tb->wb_read(QSPIFLASH+1024, 1024, rdbuf);
657
        for(int i=0; i<1024; i++) {
658
                if (rdbuf[i] != 0xffffffff) {
659
                        printf("BOMB: SUBSECTOR ERASE, EXPECTED[0x%02x] = 0xffffffff != %08x\n", i, rdv);
660
                        goto test_failure;
661
                } break;
662
        }
663
 
664
        // Try to execute a single write
665
        // Check that this will work ...
666
        for(idx=4; idx<4096; idx++) {
667
                if (0 != (tb->wb_read(QSPIFLASH+idx)&(~0x11111111)))
668
                        break;
669
        }
670
        // First, turn the write-enable back on
671
        tb->wb_write(0, 0x620001be);
672
        // Now, write the value
673
        tb->wb_write(QSPIFLASH+idx, 0x11111111);
674
        while (tb->wb_read(0)&0x01000000)
675
                ;
676
        while(tb->wb_read(0)&(0x80000000))
677
                ;
678
        if (0 != (tb->wb_read(QSPIFLASH+idx)&(~0x11111111)))
679
                goto test_failure;
680
 
681
        // Try to write a complete block
682
        {
683
                FILE *fp = fopen(fname, "r"); // Open /dev/urandom
684
                if (4096 != fread(rdbuf, sizeof(unsigned), 4096, fp)) {
685
                        perror("Couldnt read /dev/urandom into buffer!");
686
                        goto test_failure;
687
                } fclose(fp);
688
        }
689
 
690
        printf("Attempting to write subsector 1\n");
691
        for(int i=0; i<1024; i+= 64) {
692
                printf("Turning off write-protect, calling WEL\n");
693
                tb->wb_write(0, 0x620001be);
694
 
695
                printf("Writing from %08x to %08x from rdbuf\n",
696
                        QSPIFLASH+1024+i, QSPIFLASH+1024+i+63);
697
                // tb->wb_write(QSPIFLASH+1024+i, 64, &rdbuf[i]);
698
                tb->wb_write_slow(QSPIFLASH+1024+i, 64, &rdbuf[i], 32);
699
                while(tb->wb_read(0)&(0x80000000))
700
                        ;
701
        }
702
 
703
        tb->wb_read(QSPIFLASH+1024, 1024, &rdbuf[1024]);
704
        for(int i=0; i<1024; i++) {
705
                if (rdbuf[i] != rdbuf[i+1024]) {
706
                        printf("BOMB: SUBSECTOR PROGRAM, EXPECTED[0x%02x] = 0x%08x != %08x\n", i, rdbuf[i], rdbuf[i+1024]);
707
                        goto test_failure;
708
                }
709
        }
710
 
711
        // -Try to write an OTP register
712
        printf("Turning off write-protect, calling WEL\n");
713
        tb->wb_write( 0, 0x620001be);
714
        printf("Writing OTP[2]\n");
715
        tb->wb_write(18, 0x620001be);
716
        while (tb->wb_read(0)&0x01000000)
717
                ;
718
        while(tb->wb_read(0)&(0x80000000))
719
                ;
720
        if (0x620001be != tb->wb_read(18))
721
                goto test_failure;
722
 
723
        // -Try to write protect all OTP register
724
        printf("Turning off write-protect, calling WEL\n");
725
        tb->wb_write( 0, 0x620001be);
726
        printf("Writing OTP[END]\n");
727
        tb->wb_write(15, 0);
728
        while (tb->wb_read(0)&0x01000000)
729
                ;
730
        while(tb->wb_read(0)&(0x80000000))
731
                ;
732
        if (0 != tb->wb_read(15))
733
                goto test_failure;
734
 
735
        // -Try to write OTP after write protecting all OTP registers
736
        printf("Turning off write-protect, calling WEL\n");
737
        tb->wb_write( 0, 0x620001be);
738
        printf("Writing OTP[7]\n");
739
        tb->wb_write(16+7, 0);
740
        while (tb->wb_read(0)&0x01000000)
741
                ;
742
        while(tb->wb_read(0)&(0x80000000))
743
                ;
744
 
745
        // -Verify OTP not written
746
        if (0 == tb->wb_read(16+7))
747
                goto test_failure;
748
 
749
 
750
        printf("SUCCESS!!\n");
751
        exit(0);
752
test_failure:
753
        printf("FAIL-HERE\n");
754
        for(int i=0; i<64; i++)
755
                tb->tick();
756
        printf("TEST FAILED\n");
757
        exit(-1);
758
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.