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

Subversion Repositories qspiflash

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

Go to most recent revision | Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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