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

Subversion Repositories qspiflash

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

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 16 dgisselq
////////////////////////////////////////////////////////////////////////////////
2
//
3
// Filename:    wbflash_tb.cpp
4
//
5
// Project:     Wishbone Controlled Quad SPI Flash Controller
6
//
7
// Purpose:     To provide a fairly generic interface wrapper to a wishbone bus,
8
//              that can then be used to create a test-bench class.
9
//
10
// Creator:     Dan Gisselquist, Ph.D.
11
//              Gisselquist Technology, LLC
12
//
13
////////////////////////////////////////////////////////////////////////////////
14
//
15
// Copyright (C) 2015-2017, Gisselquist Technology, LLC
16
//
17
// This program is free software (firmware): you can redistribute it and/or
18
// modify it under the terms of  the GNU General Public License as published
19
// by the Free Software Foundation, either version 3 of the License, or (at
20
// your option) any later version.
21
//
22
// This program is distributed in the hope that it will be useful, but WITHOUT
23
// ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY or
24
// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
25
// for more details.
26
//
27
// You should have received a copy of the GNU General Public License along
28
// with this program.  (It's in the $(ROOT)/doc directory.  Run make with no
29
// target there if the PDF file isn't present.)  If not, see
30
// <http://www.gnu.org/licenses/> for a copy.
31
//
32
// License:     GPL, v3, as defined and found on www.gnu.org,
33
//              http://www.gnu.org/licenses/gpl.html
34
//
35
//
36
////////////////////////////////////////////////////////////////////////////////
37
//
38
//
39
#include <stdio.h>
40
 
41
#include <verilated.h>
42
#include <verilated_vcd_c.h>
43
#include "testb.h"
44
 
45
const int       BOMBCOUNT = 2048,
46
                LGMEMSIZE = 15;
47
 
48
template <class VA>     class   WBFLASH_TB : public TESTB<VA> {
49
        bool    m_ack_expected;
50
public:
51
        bool    m_bomb;
52
 
53
        WBFLASH_TB(void) {
54
                m_bomb = false;
55
                m_ack_expected = false;
56
                TESTB<VA>::m_core->i_wb_cyc = 0;
57
                TESTB<VA>::m_core->i_wb_data_stb = 0;
58
                TESTB<VA>::m_core->i_wb_ctrl_stb = 0;
59
        }
60
 
61
#define TICK    tick
62
        virtual void    tick(void) {
63
                // printf("WB-TICK\n");
64
                TESTB<VA>::tick();
65
                assert((TESTB<VA>::m_core->i_wb_cyc)
66
                        ||(!TESTB<VA>::m_core->o_wb_ack));
67
        }
68
 
69
        unsigned wb_ctrl_read(unsigned a) {
70
                int             errcount = 0;
71
                unsigned        result;
72
 
73
                // printf("WB-READM(%08x)\n", a);
74
 
75
                TESTB<VA>::m_core->i_wb_cyc = 1;
76
                TESTB<VA>::m_core->i_wb_data_stb = 0;
77
                TESTB<VA>::m_core->i_wb_ctrl_stb = 1;
78
                TESTB<VA>::m_core->i_wb_we  = 0;
79
                TESTB<VA>::m_core->i_wb_addr= (a>>2);
80
 
81
                if (TESTB<VA>::m_core->o_wb_stall) {
82
                        while((errcount++ < BOMBCOUNT)&&(TESTB<VA>::m_core->o_wb_stall)) {
83
                                TICK();
84
                        }
85
                } TICK();
86
 
87
                TESTB<VA>::m_core->i_wb_data_stb = 0;
88
                TESTB<VA>::m_core->i_wb_ctrl_stb = 0;
89
 
90
                while((errcount++ <  BOMBCOUNT)&&(!TESTB<VA>::m_core->o_wb_ack)) {
91
                        TICK();
92
                }
93
 
94
 
95
                result = TESTB<VA>::m_core->o_wb_data;
96
                m_ack_expected = false;
97
 
98
                // Release the bus
99
                TESTB<VA>::m_core->i_wb_cyc = 0;
100
                TESTB<VA>::m_core->i_wb_data_stb = 0;
101
                TESTB<VA>::m_core->i_wb_ctrl_stb = 0;
102
 
103
                if(errcount >= BOMBCOUNT) {
104
                        printf("WB/SR-BOMB: NO RESPONSE AFTER %d CLOCKS\n", errcount);
105
                        m_bomb = true;
106
                } else if (!TESTB<VA>::m_core->o_wb_ack) {
107
                        printf("WB/SR-BOMB: NO ACK, NO TIMEOUT\n");
108
                        m_bomb = true;
109
                }
110
                TICK();
111
 
112
                assert(!TESTB<VA>::m_core->o_wb_ack);
113
 
114
                while(TESTB<VA>::m_core->o_wb_stall)
115
                        TICK();
116
                // assert(!TESTB<VA>::m_core->o_wb_stall);
117
 
118
                return result;
119
        }
120
 
121
        unsigned wb_read(unsigned a) {
122
                int             errcount = 0;
123
                unsigned        result;
124
 
125
                // printf("WB-READM(%08x)\n", a);
126
 
127
                TESTB<VA>::m_core->i_wb_cyc = 1;
128
                TESTB<VA>::m_core->i_wb_data_stb = 1;
129
                TESTB<VA>::m_core->i_wb_ctrl_stb = 0;
130
                TESTB<VA>::m_core->i_wb_we  = 0;
131
                TESTB<VA>::m_core->i_wb_addr= (a>>2);
132
 
133
                if (TESTB<VA>::m_core->o_wb_stall) {
134
                        while((errcount++ < BOMBCOUNT)&&(TESTB<VA>::m_core->o_wb_stall)) {
135
                                TICK();
136
                        }
137
                } TICK();
138
 
139
                TESTB<VA>::m_core->i_wb_data_stb = 0;
140
                TESTB<VA>::m_core->i_wb_ctrl_stb = 0;
141
 
142
                while((errcount++ <  BOMBCOUNT)&&(!TESTB<VA>::m_core->o_wb_ack)) {
143
                        TICK();
144
                }
145
 
146
 
147
                result = TESTB<VA>::m_core->o_wb_data;
148
                m_ack_expected = false;
149
 
150
                // Release the bus
151
                TESTB<VA>::m_core->i_wb_cyc = 0;
152
                TESTB<VA>::m_core->i_wb_data_stb = 0;
153
                TESTB<VA>::m_core->i_wb_ctrl_stb = 0;
154
 
155
                if(errcount >= BOMBCOUNT) {
156
                        printf("WB/SR-BOMB: NO RESPONSE AFTER %d CLOCKS\n", errcount);
157
                        m_bomb = true;
158
                } else if (!TESTB<VA>::m_core->o_wb_ack) {
159
                        printf("WB/SR-BOMB: NO ACK, NO TIMEOUT\n");
160
                        m_bomb = true;
161
                }
162
                TICK();
163
 
164
                assert(!TESTB<VA>::m_core->o_wb_ack);
165
//
166
// #warning     Core should not assert stall post-ack"
167
// But ... the QSPI flash driver ... does .. ???
168
                // assert(!TESTB<VA>::m_core->o_wb_stall);
169
                while(TESTB<VA>::m_core->o_wb_stall)
170
                        TICK();
171
 
172
                return result;
173
        }
174
 
175
        void    wb_read(unsigned a, int len, unsigned *buf, const int inc=1) {
176
                int             errcount = 0;
177
                int             THISBOMBCOUNT = BOMBCOUNT * len;
178
                int             cnt, rdidx;
179
 
180
                printf("WB-READM(%08x, %d)\n", a, len);
181
                TESTB<VA>::m_core->i_wb_cyc  = 0;
182
                TESTB<VA>::m_core->i_wb_data_stb = 1;
183
                TESTB<VA>::m_core->i_wb_ctrl_stb = 0;
184
 
185
                while((errcount++ < BOMBCOUNT)&&(TESTB<VA>::m_core->o_wb_stall))
186
                        TICK();
187
 
188
                if (errcount >= BOMBCOUNT) {
189
                        printf("WB-READ(%d): Setting bomb to true (errcount = %d)\n", __LINE__, errcount);
190
                        m_bomb = true;
191
                        return;
192
                }
193
 
194
                errcount = 0;
195
 
196
                TESTB<VA>::m_core->i_wb_cyc  = 1;
197
                TESTB<VA>::m_core->i_wb_data_stb = 1;
198
                TESTB<VA>::m_core->i_wb_ctrl_stb = 0;
199
                TESTB<VA>::m_core->i_wb_we   = 0;
200
                TESTB<VA>::m_core->i_wb_addr = (a>>2);
201
 
202
                rdidx =0; cnt = 0;
203
 
204
                do {
205
                        int     s;
206
                        s = (TESTB<VA>::m_core->o_wb_stall==0)?0:1;
207
                        TICK();
208
                        TESTB<VA>::m_core->i_wb_addr += inc&(s^1);
209
                        cnt += (s^1);
210
                        if (TESTB<VA>::m_core->o_wb_ack)
211
                                buf[rdidx++] = TESTB<VA>::m_core->o_wb_data;
212
                } while((cnt < len)&&(errcount++ < THISBOMBCOUNT));
213
 
214
                TESTB<VA>::m_core->i_wb_data_stb = 0;
215
                TESTB<VA>::m_core->i_wb_ctrl_stb = 0;
216
 
217
                while((rdidx < len)&&(errcount++ < THISBOMBCOUNT)) {
218
                        TICK();
219
                        if (TESTB<VA>::m_core->o_wb_ack)
220
                                buf[rdidx++] = TESTB<VA>::m_core->o_wb_data;
221
                }
222
 
223
                // Release the bus
224
                TESTB<VA>::m_core->i_wb_cyc = 0;
225
                m_ack_expected = false;
226
 
227
                if(errcount >= THISBOMBCOUNT) {
228
                        printf("WB/PR-BOMB: NO RESPONSE AFTER %d CLOCKS\n", errcount);
229
                        m_bomb = true;
230
                } else if (!TESTB<VA>::m_core->o_wb_ack) {
231
                        printf("WB/PR-BOMB: NO ACK, NO TIMEOUT\n");
232
                        m_bomb = true;
233
                }
234
                TICK();
235
                assert(!TESTB<VA>::m_core->o_wb_ack);
236
        }
237
 
238
        void    wb_ctrl_write(unsigned a, unsigned v) {
239
                int errcount = 0;
240
 
241
                printf("WB-WRITEM(%08x) <= %08x\n", a, v);
242
                TESTB<VA>::m_core->i_wb_cyc = 1;
243
                TESTB<VA>::m_core->i_wb_data_stb = 0;
244
                TESTB<VA>::m_core->i_wb_ctrl_stb = 1;
245
                TESTB<VA>::m_core->i_wb_we  = 1;
246
                TESTB<VA>::m_core->i_wb_addr= (a>>2);
247
                TESTB<VA>::m_core->i_wb_data= v;
248
                // TESTB<VA>::m_core->i_wb_sel = 0x0f;
249
 
250
                if (TESTB<VA>::m_core->o_wb_stall)
251
                        while((errcount++ < BOMBCOUNT)&&(TESTB<VA>::m_core->o_wb_stall)) {
252
                                printf("Stalled, so waiting, errcount=%d\n", errcount);
253
                                TICK();
254
                        }
255
                TICK();
256
 
257
                TESTB<VA>::m_core->i_wb_ctrl_stb = 0;
258
 
259
                while((errcount++ <  BOMBCOUNT)&&(!TESTB<VA>::m_core->o_wb_ack))
260
                        TICK();
261
                TICK();
262
 
263
                // Release the bus?
264
                TESTB<VA>::m_core->i_wb_cyc = 0;
265
                TESTB<VA>::m_core->i_wb_ctrl_stb = 0;
266
                TESTB<VA>::m_core->i_wb_data_stb = 0;
267
                m_ack_expected = false;
268
 
269
                if(errcount >= BOMBCOUNT) {
270
                        printf("WB/SW-BOMB: NO RESPONSE AFTER %d CLOCKS (LINE=%d)\n",errcount, __LINE__);
271
                        m_bomb = true;
272
                } TICK();
273
                assert(!TESTB<VA>::m_core->o_wb_ack);
274
                // assert(!TESTB<VA>::m_core->o_wb_stall);
275
 
276
                while(TESTB<VA>::m_core->o_wb_stall)
277
                        TICK();
278
        }
279
 
280
        void    wb_write(unsigned a, unsigned v) {
281
                int errcount = 0;
282
 
283
                printf("WB-WRITEM(%08x) <= %08x\n", a, v);
284
                TESTB<VA>::m_core->i_wb_cyc = 1;
285
                TESTB<VA>::m_core->i_wb_data_stb = 1;
286
                TESTB<VA>::m_core->i_wb_ctrl_stb = 0;
287
                TESTB<VA>::m_core->i_wb_we  = 1;
288
                TESTB<VA>::m_core->i_wb_addr= (a>>2);
289
                TESTB<VA>::m_core->i_wb_data= v;
290
                // TESTB<VA>::m_core->i_wb_sel = 0x0f;
291
 
292
                if (TESTB<VA>::m_core->o_wb_stall)
293
                        while((errcount++ < BOMBCOUNT)&&(TESTB<VA>::m_core->o_wb_stall)) {
294
                                printf("Stalled, so waiting, errcount=%d\n", errcount);
295
                                TICK();
296
                        }
297
                TICK();
298
 
299
                TESTB<VA>::m_core->i_wb_data_stb = 0;
300
                TESTB<VA>::m_core->i_wb_ctrl_stb = 0;
301
 
302
                while((errcount++ <  BOMBCOUNT)&&(!TESTB<VA>::m_core->o_wb_ack))
303
                        TICK();
304
                TICK();
305
 
306
                // Release the bus?
307
                TESTB<VA>::m_core->i_wb_cyc = 0;
308
                TESTB<VA>::m_core->i_wb_data_stb = 0;
309
                TESTB<VA>::m_core->i_wb_ctrl_stb = 0;
310
                m_ack_expected = false;
311
 
312
                if(errcount >= BOMBCOUNT) {
313
                        printf("WB/SW-BOMB: NO RESPONSE AFTER %d CLOCKS (LINE=%d)\n",errcount, __LINE__);
314
                        m_bomb = true;
315
                } TICK();
316
                assert(!TESTB<VA>::m_core->o_wb_ack);
317
 
318
                while(TESTB<VA>::m_core->o_wb_stall)
319
                        TICK();
320
                assert(!TESTB<VA>::m_core->o_wb_stall);
321
        }
322
 
323
        void    wb_write(unsigned a, unsigned int ln, unsigned *buf, const int inc=1) {
324
                unsigned errcount = 0, nacks = 0;
325
 
326
                printf("WB-WRITEM(%08x, %d, ...)\n", a, ln);
327
                TESTB<VA>::m_core->i_wb_cyc = 1;
328
                TESTB<VA>::m_core->i_wb_data_stb = 1;
329
                TESTB<VA>::m_core->i_wb_ctrl_stb = 0;
330
                TESTB<VA>::m_core->i_wb_we  = 1;
331
                TESTB<VA>::m_core->i_wb_addr= (a>>2);
332
                // TESTB<VA>::m_core->i_wb_sel = 0x0f;
333
                for(unsigned stbcnt=0; stbcnt<ln; stbcnt++) {
334
                        // m_core->i_wb_addr= a+stbcnt;
335
                        TESTB<VA>::m_core->i_wb_data= buf[stbcnt];
336
                        errcount = 0;
337
 
338
                        while((errcount++ < BOMBCOUNT)&&(TESTB<VA>::m_core->o_wb_stall)) {
339
                                TICK();
340
                                if (TESTB<VA>::m_core->o_wb_ack)
341
                                        nacks++;
342
                        }
343
                        // Tick, now that we're not stalled.  This is the tick
344
                        // that gets accepted.
345
                        TICK();
346
                        if (TESTB<VA>::m_core->o_wb_ack) nacks++;
347
 
348
                        // Now update the address
349
                        TESTB<VA>::m_core->i_wb_addr += inc;
350
                }
351
 
352
                TESTB<VA>::m_core->i_wb_data_stb = 1;
353
                TESTB<VA>::m_core->i_wb_ctrl_stb = 0;
354
 
355
                errcount = 0;
356
                while((nacks < ln)&&(errcount++ < BOMBCOUNT)) {
357
                        TICK();
358
                        if (TESTB<VA>::m_core->o_wb_ack) {
359
                                nacks++;
360
                                errcount = 0;
361
                        }
362
                }
363
 
364
                // Release the bus
365
                TESTB<VA>::m_core->i_wb_cyc = 0;
366
                TESTB<VA>::m_core->i_wb_data_stb = 0;
367
                TESTB<VA>::m_core->i_wb_ctrl_stb = 0;
368
                m_ack_expected = false;
369
 
370
                if(errcount >= BOMBCOUNT) {
371
                        printf("WB/PW-BOMB: NO RESPONSE AFTER %d CLOCKS (LINE=%d)\n",errcount,__LINE__);
372
                        m_bomb = true;
373
                }
374
                TICK();
375
                assert(!TESTB<VA>::m_core->o_wb_ack);
376
                // assert(!TESTB<VA>::m_core->o_wb_stall);
377
                while(TESTB<VA>::m_core->o_wb_stall)
378
                        TICK();
379
        }
380
 
381
        bool    bombed(void) const { return m_bomb; }
382
};
383
 

powered by: WebSVN 2.1.0

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