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

Subversion Repositories wbddr3

[/] [wbddr3/] [trunk/] [bench/] [cpp/] [ddrsdram_tb.cpp] - Blame information for rev 16

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

Line No. Rev Author Line
1 4 dgisselq
////////////////////////////////////////////////////////////////////////////////
2
//
3
// Filename:    ddrsdram_tb.cpp
4
//
5
// Project:     A wishbone controlled DDR3 SDRAM memory controller.
6
//
7
// Purpose:     To determine whether or not the wbddrsdram Verilog module works.
8
//              Run this program with no arguments.  If the last line output
9
//      is "SUCCESS", you will know it works.
10
//
11
// Creator:     Dan Gisselquist, Ph.D.
12
//              Gisselquist Technology, LLC
13
//
14
////////////////////////////////////////////////////////////////////////////////
15
//
16
// Copyright (C) 2015-2016, Gisselquist Technology, LLC
17
//
18
// This program is free software (firmware): you can redistribute it and/or
19
// modify it under the terms of  the GNU General Public License as published
20
// by the Free Software Foundation, either version 3 of the License, or (at
21
// your option) any later version.
22
//
23
// This program is distributed in the hope that it will be useful, but WITHOUT
24
// ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY or
25
// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
26
// for more details.
27
//
28
// You should have received a copy of the GNU General Public License along
29
// with this program.  (It's in the $(ROOT)/doc directory, run make with no
30
// target there if the PDF file isn't present.)  If not, see
31
// <http://www.gnu.org/licenses/> for a copy.
32
//
33
// License:     GPL, v3, as defined and found on www.gnu.org,
34
//              http://www.gnu.org/licenses/gpl.html
35
//
36
//
37
////////////////////////////////////////////////////////////////////////////////
38
//
39
//
40
#include <stdio.h>
41
 
42
#include "verilated.h"
43
#include "Vwbddrsdram.h"
44 16 dgisselq
#include "pddrsim.h"
45
// #include "ddrsdramsim.h"
46 4 dgisselq
 
47
const int       BOMBCOUNT = 2048,
48
                SDRAMMASK = 0x3ffffff,
49
                LGMEMSIZE = 28;
50
 
51
class   DDRSDRAM_TB {
52
        long            m_tickcount;
53
        Vwbddrsdram     *m_core;
54 16 dgisselq
        PDDRSIM         *m_sdram;
55 4 dgisselq
        bool            m_bomb;
56
public:
57
 
58
        DDRSDRAM_TB(void) {
59
                m_core = new Vwbddrsdram;
60 16 dgisselq
                m_sdram= new PDDRSIM(LGMEMSIZE);
61 4 dgisselq
        }
62
 
63 16 dgisselq
        unsigned long operator[](const int index) { return (*m_sdram)[index]; }
64
        void    set(unsigned addr, unsigned long v) {
65
                m_sdram->set(addr, v);
66 4 dgisselq
        }
67
 
68
        void    tick(void) {
69
                m_core->i_clk = 1;
70
 
71
                m_core->i_ddr_data = (*m_sdram)(
72
                        m_core->o_ddr_reset_n,
73
                        m_core->o_ddr_cke,
74
                        m_core->o_ddr_bus_oe,
75 16 dgisselq
                        m_core->o_ddr_cmd_a,
76
                        m_core->o_ddr_cmd_b,
77 4 dgisselq
                        m_core->o_ddr_data);
78
 
79 6 dgisselq
                bool    writeout = (!m_core->v__DOT__reset_override);
80 4 dgisselq
 
81 16 dgisselq
                int cmda, cmdb, cmd;
82
                cmda = (m_core->o_ddr_reset_n?0:32)
83 14 dgisselq
                        |(m_core->o_ddr_cke?0:16)
84 16 dgisselq
                        |((m_core->o_ddr_cmd_a&(1<<26))?8:0)
85
                        |((m_core->o_ddr_cmd_a&(1<<25))?4:0)
86
                        |((m_core->o_ddr_cmd_a&(1<<24))?2:0)
87
                        |((m_core->o_ddr_cmd_a&(1<<23))?1:0);
88
                cmdb = (m_core->o_ddr_reset_n?0:32)
89
                        |(m_core->o_ddr_cke?0:16)
90
                        |((m_core->o_ddr_cmd_b&(1<<26))?8:0)
91
                        |((m_core->o_ddr_cmd_b&(1<<25))?4:0)
92
                        |((m_core->o_ddr_cmd_b&(1<<24))?2:0)
93
                        |((m_core->o_ddr_cmd_b&(1<<23))?1:0);
94
                cmd = m_core->o_ddr_cmd_b;
95
                if ((cmdb&0x0f)!=DDR_NOOP)
96
                        cmd = m_core->o_ddr_cmd_a;
97
                if ((cmda&0x0f)==DDR_REFRESH)
98 14 dgisselq
                        writeout = true;
99 16 dgisselq
                if ((cmdb&0x0f)==DDR_REFRESH)
100
                        writeout = true;
101 14 dgisselq
 
102 6 dgisselq
                if (writeout) {
103 16 dgisselq
                        printf("%08lx-WB: %s/%s %s%s%s %s@0x%08x[%016lx/%016lx] -- ",
104 6 dgisselq
                                m_tickcount,
105
                                (m_core->i_wb_cyc)?"CYC":"   ",
106
                                (m_core->i_wb_stb)?"STB":"   ",
107
                                (m_core->o_wb_stall)?"STALL":"     ",
108
                                (m_core->o_wb_ack)?"ACK":"   ",
109 12 dgisselq
                                "", // (m_core->o_cmd_accepted)?"BUS":"   ",
110 6 dgisselq
                                (m_core->i_wb_we)?"W":"R",
111
                                (m_core->i_wb_addr),
112
                                (m_core->i_wb_data),
113
                                (m_core->o_wb_data));
114 4 dgisselq
 
115 16 dgisselq
                        printf("%s%s %d%d%d%d,%d%d%d%d %s%s[%x%x]%s%s B[%d,%d]@%04x %016lx %016lx",
116 6 dgisselq
                                (m_core->o_ddr_reset_n)?" ":"R",
117
                                (m_core->o_ddr_cke)?"CK":"  ",
118 16 dgisselq
                                (cmda&0x08)?1:0, (cmda&0x04)?1:0,
119
                                (cmda&0x02)?1:0, (cmda&0x01)?1:0,
120
                                (cmdb&0x08)?1:0, (cmdb&0x04)?1:0,
121
                                (cmdb&0x02)?1:0, (cmdb&0x01)?1:0,
122 6 dgisselq
                                //
123 16 dgisselq
                                ((m_core->o_ddr_cmd_a>>5)&1)?"D":"-",
124
                                ((m_core->o_ddr_cmd_b>>5)&1)?"D":"-",
125
                                ((m_core->o_ddr_cmd_a>>1)&0x0f),
126
                                ((m_core->o_ddr_cmd_b>>1)&0x0f),
127
                                (m_core->o_ddr_cmd_a&1)?"O":" ",
128 6 dgisselq
                                (m_core->o_ddr_bus_oe)?"E":" ",
129
                                //
130 16 dgisselq
                                (m_core->o_ddr_cmd_a>>(6+14))&0x07, // Get the bank address
131
                                (m_core->o_ddr_cmd_b>>(6+14))&0x07, // Get the bank address
132
                                ((cmd>>6)&0x03fff),     // The command address
133 6 dgisselq
                                (m_core->i_ddr_data),
134
                                (m_core->o_ddr_data));
135 4 dgisselq
 
136 16 dgisselq
                        printf(" FIFO[%x,%x](%s,%d,%016lx)",
137 7 dgisselq
                                m_core->v__DOT__bus_fifo_head,
138
                                m_core->v__DOT__bus_fifo_tail,
139 9 dgisselq
                                (m_core->v__DOT__bus_fifo_new[m_core->v__DOT__bus_fifo_tail])?"N":"o",
140 7 dgisselq
                                m_core->v__DOT__bus_fifo_sub[m_core->v__DOT__bus_fifo_tail],
141
                                m_core->v__DOT__bus_fifo_data[m_core->v__DOT__bus_fifo_tail]);
142
 
143 16 dgisselq
                        printf(" BUS[A%03x/R%03x/N%03x/K%03x/T%03x/%02x]",
144 7 dgisselq
                                (m_core->v__DOT__bus_active),
145
                                (m_core->v__DOT__bus_read),
146
                                (m_core->v__DOT__bus_new),
147 13 dgisselq
                                (m_core->v__DOT__bus_ack),
148 16 dgisselq
                                (m_core->v__DOT__bus_odt),
149
                                (m_core->v__DOT__bus_subaddr));
150 7 dgisselq
 
151 8 dgisselq
                        /*
152 6 dgisselq
                        // Reset logic
153 16 dgisselq
                        printf(" RST(%06x%s[%2d] - %08x->%08x)",
154 6 dgisselq
                                m_core->v__DOT__reset_timer,
155
                                (m_core->v__DOT__reset_ztimer)?"Z":" ",
156
                                (m_core->v__DOT__reset_address),
157
                                (m_core->v__DOT__reset_instruction),
158
                                (m_core->v__DOT__reset_cmd));
159 8 dgisselq
                        */
160 4 dgisselq
 
161 16 dgisselq
                        printf(" R_%s%03x[%d]%04x:%d/%02x/%016lx",
162 9 dgisselq
                                (!m_core->v__DOT__r_pending)?"_"
163
                                        :(m_core->v__DOT__r_we)?"W":"R",
164 6 dgisselq
                                (m_core->v__DOT__r_row),
165
                                (m_core->v__DOT__r_bank),
166 9 dgisselq
                                (m_core->v__DOT__r_col),
167
                                (m_core->v__DOT__r_sub),
168 16 dgisselq
                                (m_core->v__DOT__r_sel),
169 9 dgisselq
                                (m_core->v__DOT__r_data));
170
 
171 16 dgisselq
                        printf(" S_%s%03x[%d]%04x:%d/%02x/%016lx%s%s%s",
172 9 dgisselq
                                (!m_core->v__DOT__s_pending)?"_"
173
                                        :(m_core->v__DOT__s_we)?"W":"R",
174
                                (m_core->v__DOT__s_row),
175
                                (m_core->v__DOT__s_bank),
176
                                (m_core->v__DOT__s_col),
177
                                (m_core->v__DOT__s_sub),
178 16 dgisselq
                                (m_core->v__DOT__s_sel),
179 9 dgisselq
                                (m_core->v__DOT__s_data),
180 10 dgisselq
                                (m_core->v__DOT__w_s_match)?"M":" ",
181 9 dgisselq
                                (m_core->v__DOT__pipe_stall)?"P":" ",
182
                                "-"
183
                                //(m_core->v__DOT__s_stall)?"S":" "
184
                                );
185
 
186
 
187 6 dgisselq
                        printf(" %s%s%s",
188 7 dgisselq
                                "B",
189
                                // (m_core->v__DOT__all_banks_closed)?"b":"B",
190 6 dgisselq
                                (m_core->v__DOT__need_close_bank)?"C":"N",
191
                                //:(m_core->v__DOT__maybe_close_next_bank)?"c":"N",
192
                                (m_core->v__DOT__need_open_bank)?"O":"K");
193
                                // :(m_core->v__DOT__maybe_open_next_bank)?"o":"K");
194 16 dgisselq
 
195 6 dgisselq
                        for(int i=0; i<8; i++) {
196 16 dgisselq
                                printf("%s%s%s%04x|%04x@%x%s",
197 6 dgisselq
                                        (m_core->v__DOT__r_bank==i)?"R":"[",
198 14 dgisselq
                                        ((m_core->v__DOT__bank_open)&(1<<i))?"+":" ",
199
                                        ((m_core->v__DOT__bank_closed)&(1<<i))?"-":" ",
200 6 dgisselq
                                        m_core->v__DOT__bank_status[i],
201 16 dgisselq
                                        m_sdram->bank_state(i),
202 6 dgisselq
                                        m_core->v__DOT__bank_address[i],
203
                                        (m_core->v__DOT__r_nxt_bank==i)?"N":"]");
204
                        }
205
 
206 4 dgisselq
 
207 14 dgisselq
                        /*
208 6 dgisselq
                        extern int gbl_state, gbl_counts;
209
                        printf(" %2d:%08x ", gbl_state, gbl_counts);
210 14 dgisselq
                        */
211 6 dgisselq
 
212 14 dgisselq
                        printf(" %s%s%s%s%s%s%s%s%s%s%s",
213 6 dgisselq
                                (m_core->v__DOT__reset_override)?"R":" ",
214
                                (m_core->v__DOT__need_refresh)?"N":" ",
215
                                (m_core->v__DOT__need_close_bank)?"C":" ",
216
                                (m_core->v__DOT__need_open_bank)?"O":" ",
217
                                (m_core->v__DOT__valid_bank)?"V":" ",
218 14 dgisselq
                                (m_core->v__DOT__maybe_close_next_bank)?"c":" ",
219
                                (m_core->v__DOT__maybe_open_next_bank)?"o":" ",
220
                                (m_core->v__DOT__pre_valid)?"p":" ",
221
                                (m_core->v__DOT__w_r_valid)?"r":" ",
222 16 dgisselq
                                (m_core->v__DOT__w_s_valid)?"s":" ",
223
                                (m_core->v__DOT__pre_ack)?"k":" ");
224 6 dgisselq
 
225 14 dgisselq
                        // Refresh logic
226 7 dgisselq
                        printf(" F%s%05x:%x/%s",
227
                                (m_core->v__DOT__refresh_ztimer)?"Z":" ",
228
                                m_core->v__DOT__refresh_counter,
229
                                m_core->v__DOT__refresh_addr,
230
                                (m_core->v__DOT__need_refresh)?"N":" ");
231 6 dgisselq
 
232
                        if (m_core->v__DOT__reset_override)
233
                                printf(" OVERRIDE");
234
                        //if(m_core->v__DOT__last_open_bank)printf(" LST-OPEN");
235 16 dgisselq
                        switch(cmda) {
236
                        case DDR_MRSET:     printf("%13s", " MRSET"); break;
237
                        case DDR_REFRESH:   printf("%13s", " REFRESH"); break;
238
                        case DDR_PRECHARGE: printf("%9s%3s", " PRECHARGE", ((m_core->o_ddr_cmd_a>>6)&0x400)?"-ALL":""); break;
239
                        case DDR_ACTIVATE:  printf("%13s", " ACTIVATE"); break;
240
                        case DDR_WRITE:     printf("%13s", " WRITE"); break;
241
                        case DDR_READ:      printf("%13s", " READ"); break;
242
                        case DDR_ZQS:       printf("%13s", " ZQS"); break;
243
                        case DDR_NOOP:      printf("%13s", " NOOP"); break;
244
                        default: printf(" UCMD(%02x)", cmda); break;
245
                        }
246
 
247
                        switch(cmdb) {
248 6 dgisselq
                        case DDR_MRSET:     printf(" MRSET"); break;
249
                        case DDR_REFRESH:   printf(" REFRESH"); break;
250 16 dgisselq
                        case DDR_PRECHARGE: printf(" PRECHARGE%s", ((m_core->o_ddr_cmd_b>>6)&0x400)?"-ALL":""); break;
251 6 dgisselq
                        case DDR_ACTIVATE:  printf(" ACTIVATE"); break;
252
                        case DDR_WRITE:     printf(" WRITE"); break;
253
                        case DDR_READ:      printf(" READ"); break;
254
                        case DDR_ZQS:       printf(" ZQS"); break;
255
                        case DDR_NOOP:      printf(" NOOP"); break;
256 16 dgisselq
                        default: printf(" UCMD(%02x)", cmdb); break;
257 6 dgisselq
                        }
258
 
259
                        // Decode the command
260
 
261
                        printf("\n");
262
                }
263
 
264 14 dgisselq
                // A consistency check ...
265
                /*
266
                if (m_core->v__DOT__bus_fifo_head != m_core->v__DOT__bus_fifo_tail) {
267
                        fflush(stdout);
268
                        if (cmd == DDR_REFRESH)
269
                                printf("FAIL: CMD=REFRESH, but head != tail\n");
270
                        assert(cmd != DDR_REFRESH);
271
                } */
272
 
273 4 dgisselq
                m_core->eval();
274
                m_core->i_clk = 0;
275
                m_core->eval();
276
 
277
                m_tickcount++;
278
 
279
                /*
280
                if ((m_core->o_wb_ack)&&(!m_core->i_wb_cyc)) {
281
                        printf("SETTING ERR TO TRUE!!!!!  ACK w/ no CYC\n");
282
                        // m_bomb = true;
283
                }
284
                */
285
        }
286
 
287
        void reset(void) {
288
                m_core->i_reset  = 1;
289
                m_core->i_wb_cyc = 0;
290
                m_core->i_wb_stb = 0;
291
                tick();
292
                m_core->i_reset  = 0;
293
        }
294
 
295
        void wb_tick(void) {
296
                m_core->i_wb_cyc   = 0;
297
                m_core->i_wb_stb = 0;
298
                tick();
299 14 dgisselq
                assert(!m_core->o_wb_ack);
300 4 dgisselq
        }
301
 
302 16 dgisselq
        unsigned long wb_read(unsigned a) {
303 4 dgisselq
                int             errcount = 0;
304 16 dgisselq
                unsigned long   result;
305 4 dgisselq
 
306
                printf("WB-READ(%08x)\n", a);
307
 
308
                m_core->i_wb_cyc = 1;
309
                m_core->i_wb_stb = 1;
310
                m_core->i_wb_we  = 0;
311
                m_core->i_wb_addr= a & SDRAMMASK;
312
 
313
                if (m_core->o_wb_stall) {
314
                        while((errcount++ < BOMBCOUNT)&&(m_core->o_wb_stall))
315
                                tick();
316 9 dgisselq
                } tick();
317 4 dgisselq
 
318
                m_core->i_wb_stb = 0;
319
 
320
                while((errcount++ <  BOMBCOUNT)&&(!m_core->o_wb_ack))
321
                        tick();
322
 
323
 
324
                result = m_core->o_wb_data;
325 14 dgisselq
                if (result != (*this)[a]) {
326
                        printf("READ-FAIL\n");
327
                        assert(result == (*this)[a]);
328
                }
329 4 dgisselq
 
330
                // Release the bus?
331
                m_core->i_wb_cyc = 0;
332
                m_core->i_wb_stb = 0;
333
 
334
                if(errcount >= BOMBCOUNT) {
335
                        printf("SETTING ERR TO TRUE!!!!!\n");
336
                        m_bomb = true;
337
                } else if (!m_core->o_wb_ack) {
338
                        printf("SETTING ERR TO TRUE--NO ACK, NO TIMEOUT\n");
339
                        m_bomb = true;
340
                }
341
                tick();
342
 
343 14 dgisselq
                assert(m_core->v__DOT__bus_fifo_head == m_core->v__DOT__bus_fifo_tail);
344
 
345
                assert(!m_core->o_wb_ack);
346 4 dgisselq
                return result;
347
        }
348
 
349 16 dgisselq
        void    wb_read(unsigned a, int len, unsigned long *buf) {
350 4 dgisselq
                int             errcount = 0;
351
                int             THISBOMBCOUNT = BOMBCOUNT * len;
352
                int             cnt, rdidx, inc;
353
 
354
                printf("WB-READ(%08x, %d)\n", a, len);
355
 
356
                while((errcount++ < BOMBCOUNT)&&(m_core->o_wb_stall))
357
                        wb_tick();
358
 
359
                if (errcount >= BOMBCOUNT) {
360
                        m_bomb = true;
361
                        return;
362
                }
363
 
364
                errcount = 0;
365
 
366
                m_core->i_wb_cyc = 1;
367
                m_core->i_wb_stb = 1;
368
                m_core->i_wb_we  = 0;
369
                m_core->i_wb_addr= a & SDRAMMASK;
370
 
371
                rdidx =0; cnt = 0;
372
                inc = 1;
373
 
374
                do {
375
                        int     s;
376
                        s = (m_core->o_wb_stall==0)?0:1;
377
                        tick();
378
                        if (!s)
379
                                m_core->i_wb_addr += inc;
380
                        cnt += (s==0)?1:0;
381 14 dgisselq
                        if (m_core->o_wb_ack) {
382
                                buf[rdidx] = m_core->o_wb_data;
383 16 dgisselq
                                printf("WB-READ[%08x] = %016lx\n", a+rdidx,
384 14 dgisselq
                                        m_core->o_wb_data);
385
                                if (buf[rdidx] != (*this)[a+rdidx]) {
386
                                        printf("READ-FAIL\n");
387
                                        assert(buf[rdidx] == (*this)[a+rdidx]);
388
                                }
389
                                rdidx++;
390
                        }
391 4 dgisselq
                } while((cnt < len)&&(errcount++ < THISBOMBCOUNT));
392
 
393
                m_core->i_wb_stb = 0;
394
 
395
                while((rdidx < len)&&(errcount++ < THISBOMBCOUNT)) {
396
                        tick();
397 14 dgisselq
                        if (m_core->o_wb_ack) {
398
                                buf[rdidx] = m_core->o_wb_data;
399 16 dgisselq
                                printf("WB-READ[%08x] = %016lx\n", a+rdidx,
400 14 dgisselq
                                        m_core->o_wb_data);
401
                                if (buf[rdidx] != (*this)[a+rdidx]) {
402
                                        printf("READ-FAIL\n");
403
                                        assert(buf[rdidx] == (*this)[a+rdidx]);
404
                                }
405
                                rdidx++;
406
                        }
407 4 dgisselq
                }
408
 
409
                // Release the bus?
410
                m_core->i_wb_cyc = 0;
411
 
412
                if(errcount >= THISBOMBCOUNT) {
413
                        printf("SETTING ERR TO TRUE!!!!! (errcount=%08x, THISBOMBCOUNT=%08x)\n", errcount, THISBOMBCOUNT);
414
                        m_bomb = true;
415
                } else if (!m_core->o_wb_ack) {
416
                        printf("SETTING ERR TO TRUE--NO ACK, NO TIMEOUT\n");
417
                        m_bomb = true;
418
                }
419
                tick();
420 14 dgisselq
                assert(m_core->v__DOT__bus_fifo_head == m_core->v__DOT__bus_fifo_tail);
421
                assert(!m_core->o_wb_ack);
422 4 dgisselq
        }
423
 
424 16 dgisselq
        void    wb_write(unsigned a, unsigned long v) {
425 4 dgisselq
                int errcount = 0;
426
 
427 16 dgisselq
                printf("WB-WRITE(%08x) = %016lx\n", a, v);
428 4 dgisselq
                m_core->i_wb_cyc = 1;
429
                m_core->i_wb_stb = 1;
430
                m_core->i_wb_we  = 1;
431
                m_core->i_wb_addr= a & SDRAMMASK;
432 16 dgisselq
                m_core->i_wb_sel = 0x0ff;
433 4 dgisselq
                m_core->i_wb_data= v;
434
 
435
                if (m_core->o_wb_stall)
436
                        while((errcount++ < BOMBCOUNT)&&(m_core->o_wb_stall))
437
                                tick();
438
                tick();
439
 
440
                m_core->i_wb_stb = 0;
441
 
442
                while((errcount++ <  BOMBCOUNT)&&(!m_core->o_wb_ack))
443
                        tick();
444
 
445
                // Release the bus?
446
                m_core->i_wb_cyc = 0;
447
                m_core->i_wb_stb = 0;
448
 
449
                if(errcount >= BOMBCOUNT) {
450
                        printf("SETTING ERR TO TRUE!!!!!\n");
451
                        m_bomb = true;
452
                } tick();
453 14 dgisselq
                assert(m_core->v__DOT__bus_fifo_head == m_core->v__DOT__bus_fifo_tail);
454
                assert(!m_core->o_wb_ack);
455 4 dgisselq
        }
456
 
457 16 dgisselq
        void    wb_write(unsigned a, unsigned int ln, unsigned long *buf) {
458 4 dgisselq
                unsigned errcount = 0, nacks = 0;
459
 
460
                m_core->i_wb_cyc = 1;
461
                m_core->i_wb_stb = 1;
462
                for(unsigned stbcnt=0; stbcnt<ln; stbcnt++) {
463
                        m_core->i_wb_we  = 1;
464
                        m_core->i_wb_addr= (a+stbcnt) & SDRAMMASK;
465 16 dgisselq
                        m_core->i_wb_sel = 0x0ff;
466 4 dgisselq
                        m_core->i_wb_data= buf[stbcnt];
467
                        errcount = 0;
468
 
469
                        while((errcount++ < BOMBCOUNT)&&(m_core->o_wb_stall)) {
470
                                tick(); if (m_core->o_wb_ack) nacks++;
471
                        }
472
                        // Tick, now that we're not stalled.  This is the tick
473
                        // that gets accepted.
474
                        tick(); if (m_core->o_wb_ack) nacks++;
475
                }
476
 
477
                m_core->i_wb_stb = 0;
478
 
479
                errcount = 0;
480
                while((nacks < ln)&&(errcount++ < BOMBCOUNT)) {
481
                        tick();
482
                        if (m_core->o_wb_ack) {
483
                                nacks++;
484
                                errcount = 0;
485
                        }
486
                }
487
 
488
                // Release the bus
489
                m_core->i_wb_cyc = 0;
490
                m_core->i_wb_stb = 0;
491
 
492
                if(errcount >= BOMBCOUNT) {
493
                        printf("SETTING ERR TO TRUE!!!!!\n");
494
                        m_bomb = true;
495
                } tick();
496 14 dgisselq
                assert(m_core->v__DOT__bus_fifo_head == m_core->v__DOT__bus_fifo_tail);
497
                assert(!m_core->o_wb_ack);
498 4 dgisselq
        }
499
 
500
        bool    bombed(void) const { return m_bomb; }
501
 
502
};
503
 
504 16 dgisselq
void    uload(unsigned len, unsigned long *buf) {
505 4 dgisselq
        FILE    *fp = fopen("/dev/urandom", "r");
506
 
507 16 dgisselq
        if ((NULL == fp)||(len != fread(buf, sizeof(unsigned long), len, fp))) {
508 4 dgisselq
                for(int i=0; i<(int)len; i++)
509 16 dgisselq
                        buf[i] = (((unsigned long)rand())<<32)
510
                                |(((unsigned long)rand())&(-1l<<32));
511 4 dgisselq
        } if (NULL == fp)
512
                fclose(fp);
513
}
514
 
515
int main(int  argc, char **argv) {
516
        Verilated::commandArgs(argc, argv);
517
        DDRSDRAM_TB     *tb = new DDRSDRAM_TB;
518 16 dgisselq
        unsigned long   *rdbuf, *mbuf;
519
        unsigned        mlen = (1<<(LGMEMSIZE-3));
520 4 dgisselq
 
521
        printf("Giving the core 140k cycles to start up\n");
522
        // Before testing, let's give the unit time enough to warm up
523
        tb->reset();
524 7 dgisselq
        for(int i=0; i<141195; i++)
525 4 dgisselq
                tb->wb_tick();
526
 
527 8 dgisselq
        // Let's short circuit the test, and only test *some* of the memory
528
        // space.  It'll probably be good enough, and it'll finish while I'm
529
        // waiting ...
530
        mlen = 1<<16;
531
 
532 4 dgisselq
        printf("Getting some memory ...\n");
533 16 dgisselq
        rdbuf = new unsigned long[mlen];
534
        mbuf  = new unsigned long[mlen]; // Match buffer
535 4 dgisselq
        printf("Charging my memory with random values\n");
536
        uload(mlen, rdbuf);
537
 
538 12 dgisselq
#define CASE_TESTS
539 9 dgisselq
#define SINGULAR_WRITE
540
#define SINGULAR_READ
541
#define BIGPIPELINE_WRITE
542
#define BIGPIPELINE_READ
543
#define PRIMEVEC_WRITE
544
#define PRIMEVEC_READ
545
#define SKIP_WRITE
546
#define SKIP_READ
547
 
548 12 dgisselq
#ifdef  CASE_TESTS
549
        {
550 16 dgisselq
                unsigned long v;
551 12 dgisselq
                for(int i=0; i<8; i++) {
552
                        tb->wb_write(i, rdbuf[i]);
553
                        if ((v=tb->wb_read(i)) != rdbuf[i]) {
554 16 dgisselq
                                printf("CASE-1, %16lx -> MEM[%08x] -> %16lx FAILED (R/W not equal)\n", rdbuf[i], i, v);
555 12 dgisselq
                                goto test_failure;
556 16 dgisselq
                        } else printf("MATCH[%d] = %16lx\n", i, rdbuf[i]);
557 12 dgisselq
                }
558
        }
559
 
560
        // Now repeat, hitting a different bank with each command
561
        {
562 16 dgisselq
                unsigned a;
563
                unsigned long v;
564 12 dgisselq
                for(int i=0; i<8; i++) {
565
                        a = 1087 + i*1031;
566
                        tb->wb_write(a, rdbuf[a]);
567
                        if ((v=tb->wb_read(a)) != rdbuf[a]) {
568 16 dgisselq
                                printf("CASE-2, %016lx -> MEM[%08x] -> %016lx FAILED (R/W not equal)\n", rdbuf[a], a, v);
569 12 dgisselq
                                goto test_failure;
570
                        }
571
                }
572
        }
573
 
574
        // And again, hitting the same bank with each command
575
        {
576 16 dgisselq
                unsigned a;
577
                unsigned long v;
578 12 dgisselq
                for(int i=0; i<8; i++) {
579
                        a = 1109 + i*1024;
580
                        tb->wb_write(a, rdbuf[a]);
581
                        if ((v=tb->wb_read(a)) != rdbuf[a]) {
582 16 dgisselq
                                printf("CASE-3, %016lx -> MEM[%08x] -> %016lx FAILED (R/W not equal)\n", rdbuf[a], a, v);
583 12 dgisselq
                                goto test_failure;
584
                        }
585
                }
586
        }
587 13 dgisselq
 
588
        // Same thing, but writing all first before reading
589
        {
590 16 dgisselq
                unsigned a;
591
                unsigned long v;
592 13 dgisselq
                for(int i=0; i<8; i++) {
593
                        a = 1109 + i*1024;
594
                        tb->wb_write(a, rdbuf[a]);
595 14 dgisselq
                } for(int i=0; i<8; i++) {
596
                        a = 1109 + i*1024;
597 13 dgisselq
                        if ((v=tb->wb_read(a)) != rdbuf[a]) {
598 16 dgisselq
                                printf("CASE-4, %016lx -> MEM[%08x] -> %016lx FAILED (R/W not equal)\n", rdbuf[a], a, v);
599 13 dgisselq
                                goto test_failure;
600
                        }
601
                }
602
        }
603 14 dgisselq
 
604
        // And a quick pipeline test
605
        {
606 16 dgisselq
                unsigned long   v, mbuf[8];
607
                unsigned        a = 379;
608 14 dgisselq
                tb->wb_write(0, 8, &rdbuf[379]);
609
                for(int i=0; i<8; i++) {
610
                        a = 379+i;
611
                        if ((v=(*tb)[i]) != rdbuf[a]) {
612 16 dgisselq
                                printf("CASE-5, %016lx -> MEM[%08x] -> %016lx FAILED (R/W not equal)\n", rdbuf[a], i, v);
613 14 dgisselq
                                goto test_failure;
614
                        }
615
                } tb->wb_read(0, 8, mbuf);
616
                for(int i=0; i<8; i++) {
617
                        a = 379+i;
618
                        if (mbuf[i] != rdbuf[a]) {
619 16 dgisselq
                                printf("CASE-6, %016lx -> MEM[%08x] -> %016lx FAILED (R/W not equal)\n", rdbuf[a], i, mbuf[i]);
620 14 dgisselq
                                goto test_failure;
621
                        }
622
                }
623
        }
624 12 dgisselq
#endif
625
 
626 9 dgisselq
#ifdef  SINGULAR_WRITE
627 4 dgisselq
        // First test: singular reads through the memory, followed by
628
        // singular  writes
629
        printf("Starting the single-read test\n");
630
        for(int i=0; i<(int)mlen; i++) {
631
                tb->wb_write(i, rdbuf[i]);
632
                tb->wb_tick();
633
                if ((*tb)[i] != rdbuf[i]) {
634 16 dgisselq
                        printf("WRITE[%06x] = %016lx (Expecting %016lx) FAILED\n",
635 4 dgisselq
                                i, (*tb)[i], rdbuf[i]);
636
                        goto test_failure;
637
                } if (tb->bombed())
638
                        goto test_failure;
639
 
640 9 dgisselq
        }
641
#else
642
#ifdef  SINGULAR_READ
643
        // If we aren't doing the write test, we still need to charge
644
        // the memory for the read test.  Here we do it manually.
645
        for(int i=0; i<(int)mlen; i++)
646 16 dgisselq
                tb->set(i, rdbuf[i]);
647 9 dgisselq
#endif // !SINGULAR_WRITE && SINGULAR_READ
648
#endif // SINGULAR_WRITE
649
#ifdef  SINGULAR_READ
650
        for(int i=0; i<(int)mlen; i++) {
651 16 dgisselq
                unsigned long   v;
652 4 dgisselq
                if (rdbuf[i] != (v=tb->wb_read(i))) {
653 16 dgisselq
                        printf("READ[%06x] = %016lx (Expecting %016lx)\n",
654 4 dgisselq
                                i, v, rdbuf[i]);
655
                        goto test_failure;
656
                } if (tb->bombed())
657
                        goto test_failure;
658
                tb->wb_tick();
659
        }
660 9 dgisselq
#endif
661 4 dgisselq
 
662 9 dgisselq
#ifdef  BIGPIPELINE_WRITE
663 4 dgisselq
        // Second test: Vector writes going through all memory, followed a
664
        // massive vector read
665 14 dgisselq
        printf("Starting the big-pipeline write test\n");
666 4 dgisselq
        uload(mlen, rdbuf); // Get some new values
667
        tb->wb_write(0, mlen, rdbuf);
668
        if (tb->bombed())
669
                goto test_failure;
670
        for(int i=0; i<(int)mlen; i++) {
671 16 dgisselq
                unsigned long   v;
672 4 dgisselq
                if (rdbuf[i] != (v=(*tb)[i])) {
673 16 dgisselq
                        printf("V-WRITE[%06x] = %016lx (Expecting %016lx)\n",
674 4 dgisselq
                                i, v, rdbuf[i]);
675
                        goto test_failure;
676
                }
677
        }
678 9 dgisselq
#else
679
#ifdef  BIGPIPELINE_READ
680
        uload(mlen, rdbuf); // Get some new values
681
        // If we aren't doing the write test, we still need to charge
682
        // the memory for the read test.  Here we do it manually.
683
        for(int i=0; i<(int)mlen; i++)
684
                (*tb)[i] = rdbuf[i];
685
#endif // BIGPIPELINE_WRITE && BIGPIPELINE_READ
686
#endif
687
#ifdef  BIGPIPELINE_READ
688 14 dgisselq
        printf("Starting the big-pipeline read test\n");
689 4 dgisselq
        tb->wb_read( 0, mlen, mbuf);
690
        if (tb->bombed())
691
                goto test_failure;
692
        for(int i=0; i<(int)mlen; i++) {
693
                if (rdbuf[i] != mbuf[i]) {
694 16 dgisselq
                        printf("V-READ[%06x] = %016lx (Expecting %016lx)\n",
695 4 dgisselq
                                i, mbuf[i], rdbuf[i]);
696
                        goto test_failure;
697
                }
698
        }
699 9 dgisselq
#endif
700 4 dgisselq
 
701 9 dgisselq
#ifdef  PRIMEVEC_WRITE
702 14 dgisselq
        printf("Starting the prime-vector write test\n");
703 8 dgisselq
        // Third test: Vector writes going through all memory, in prime numbers
704 4 dgisselq
        // of values at a time, followed by reads via a different prime number
705 8 dgisselq
        uload(mlen, rdbuf); // Get some new values
706 9 dgisselq
        {
707
                int     nw = 3;
708
                for(int i=0; i<(int)mlen; i+=nw) {
709
                        int     ln = ((int)mlen-i>nw)?nw:mlen-i;
710
                        tb->wb_write(i, nw, &rdbuf[i]);
711
                        for(int j=0; j<ln; j++) {
712
                                if ((*tb)[i+j] != rdbuf[i+j]) {
713 16 dgisselq
                                        printf("P-WRITE[%06x] = %016lx (Expecting %016lx) FAILED\n",
714 9 dgisselq
                                                i, (*tb)[i], rdbuf[i]);
715
                                        goto test_failure;
716
                                }
717
                        } if (tb->bombed())
718 4 dgisselq
                                goto test_failure;
719 9 dgisselq
                }
720
        }
721
#else
722
#ifdef  PRIMEVEC_READ
723
        uload(mlen, rdbuf); // Get some new values
724
        // If we aren't doing the write test, we still need to charge
725
        // the memory for the read test.  Here we do it manually.
726
        for(int i=0; i<(int)mlen; i++)
727 16 dgisselq
                tb->set(i, rdbuf[i]);
728 9 dgisselq
#endif
729
#endif
730
#ifdef  PRIMEVEC_READ
731 16 dgisselq
        printf("Starting the prime-vector read test\n");
732 9 dgisselq
        {
733
                int     nr = 13;
734
                for(int i=0; i<(int)mlen; i+=nr) {
735
                        int     ln = ((int)mlen-i>nr)?nr:mlen-i;
736
                        tb->wb_read(i, nr, &mbuf[i]);
737
                        for(int j=0; j<ln; j++) {
738
                                if (mbuf[i+j] != rdbuf[i+j]) {
739 16 dgisselq
                                        printf("P-READ[%06x] = %016lx (Expecting %016lx) FAILED\n",
740 9 dgisselq
                                                i, mbuf[i], rdbuf[i]);
741
                                        goto test_failure;
742
                                }
743
                        } if (tb->bombed())
744 4 dgisselq
                                goto test_failure;
745 9 dgisselq
                }
746 4 dgisselq
        }
747 9 dgisselq
#endif
748 4 dgisselq
 
749 9 dgisselq
#ifdef  SKIP_WRITE
750 8 dgisselq
        // Fourth test: Singular writes though all of memory, skipping by some
751
        // prime address increment each time, followed by reads via a different
752
        // prime numbered increment.
753
        uload(mlen, rdbuf); // Get some new values
754
        for(int i=0; i<(int)mlen; i++) {
755 9 dgisselq
                int     loc = (i*3889)&(mlen-1);
756 8 dgisselq
                tb->wb_write(loc, rdbuf[loc]);
757
                if ((*tb)[loc] != rdbuf[loc]) {
758 16 dgisselq
                        printf("R-WRITE[%06x] = %016lx (Expecting %016lx) FAILED\n",
759 8 dgisselq
                                i, (*tb)[loc], rdbuf[loc]);
760
                        goto test_failure;
761
                } if (tb->bombed())
762
                        goto test_failure;
763 9 dgisselq
        }
764
#else
765
#ifdef  SKIP_READ
766
        uload(mlen, rdbuf); // Get some new values
767
        for(int i=0; i<(int)mlen; i++)
768 16 dgisselq
                tb->set(i, rdbuf[i]);
769 9 dgisselq
#endif // !SKIP_WRITE && SKIP_READ
770
#endif
771
#ifdef  SKIP_READ
772
        for(int i=0; i<(int)mlen; i++) {
773
                int     loc = (i*7477)&(mlen-1);
774 8 dgisselq
                mbuf[loc] = tb->wb_read(loc);
775
                if (mbuf[loc] != rdbuf[loc]) {
776 16 dgisselq
                        printf("R-READ[%06x] = %016lx (Expecting %016lx) FAILED\n",
777 8 dgisselq
                                loc, mbuf[loc], rdbuf[loc]);
778
                        goto test_failure;
779
                } if (tb->bombed())
780
                        goto test_failure;
781
        }
782 9 dgisselq
#endif
783 4 dgisselq
 
784 8 dgisselq
 
785 4 dgisselq
        printf("SUCCESS!!\n");
786
        exit(0);
787
test_failure:
788
        printf("FAIL-HERE\n");
789
        for(int i=0; i<64; i++)
790
                tb->tick();
791
        printf("TEST FAILED\n");
792
        exit(-1);
793
}

powered by: WebSVN 2.1.0

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