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

Subversion Repositories zipcpu

[/] [zipcpu/] [trunk/] [sim/] [verilator/] [zipmmu_tb.cpp] - Blame information for rev 204

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

Line No. Rev Author Line
1 204 dgisselq
////////////////////////////////////////////////////////////////////////////////
2
//
3
// Filename:    zipmmu_tb.cpp
4
//
5
// Project:     Zip CPU -- a small, lightweight, RISC CPU soft core
6
//
7
// Purpose:     A quick test bench to determine if the zipmmu module works.
8
//              This test bench does nothing to determine whether or not it
9
//      is connected properly, but only tests whether or not the zipmmu works
10
//      as it is supposed to.
11
//
12
//
13
// Creator:     Dan Gisselquist, Ph.D.
14
//              Gisselquist Technology, LLC
15
//
16
////////////////////////////////////////////////////////////////////////////////
17
//
18
// Copyright (C) 2015-2016, Gisselquist Technology, LLC
19
//
20
// This program is free software (firmware): you can redistribute it and/or
21
// modify it under the terms of  the GNU General Public License as published
22
// by the Free Software Foundation, either version 3 of the License, or (at
23
// your option) any later version.
24
//
25
// This program is distributed in the hope that it will be useful, but WITHOUT
26
// ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY or
27
// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
28
// for more details.
29
//
30
// License:     GPL, v3, as defined and found on www.gnu.org,
31
//              http://www.gnu.org/licenses/gpl.html
32
//
33
//
34
////////////////////////////////////////////////////////////////////////////////
35
//
36
//
37
#include <stdio.h>
38
 
39
#include <verilated.h>
40
#include <verilated_vcd_c.h>
41
#include "testb.h"
42
#include "Vzipmmu_tb.h"
43
 
44
#define MMUFLAG_RONW    8 // Read only (not writeable)
45
#define MMUFLAG_ACCS    4 // Accessed
46
#define MMUFLAG_CCHE    2 // Cachable
47
#define MMUFLAG_THSP    1 // Page has this context
48
 
49
const int       BOMBCOUNT = 32,
50
                LGMEMSIZE = 15;
51
 
52
class   ZIPMMU_TB : public TESTB<Vzipmmu_tb> {
53
        long            m_tickcount;
54
        bool            m_bomb, m_miss, m_err, m_debug;
55
        int             m_last_tlb_index;
56
public:
57
 
58
        ZIPMMU_TB(void) {
59
                m_debug = true;
60
                m_last_tlb_index = 0;
61
        }
62
 
63
#define v__DOT__mem_stb v__DOT__mut__DOT__r_valid
64
        void    tick(void) {
65
 
66
                TESTB<Vzipmmu_tb>::tick();
67
 
68
                bool    writeout = true;
69
 
70
                if ((m_debug)&&(writeout)) {
71
                        printf("%08lx-MMU: ", m_tickcount);
72
                        printf("(%s%s%s%s) %08x (%s%s%s)%08x%s %s %08x/%08x %s%s%s%s%s",
73
                                (m_core->i_ctrl_cyc_stb)?"CT":"  ",
74
                                (m_core->i_wbm_cyc)?"CYC":"   ",
75
                                (m_core->i_wbm_stb)?"STB":"   ",
76
                                (m_core->i_wb_we)?"WE":"  ",
77
                                (m_core->i_wb_addr),
78
                                (m_core->v__DOT__mem_cyc)?"CYC":"   ",
79
                                (m_core->v__DOT__mem_stb)?"STB":"   ",
80
#define v__DOT__mem_we  v__DOT__mut__DOT__r_we
81
                                (m_core->v__DOT__mem_we)?"WE":"  ",
82
                                (m_core->v__DOT__mem_addr),
83
                                (m_core->v__DOT__mem_err)?"ER":"  ",
84
                                (m_core->i_wb_we)?"<-":"->",
85
                                (m_core->i_wb_we)?m_core->i_wb_data:m_core->o_rtn_data,
86
                                (m_core->v__DOT__mem_we)?m_core->v__DOT__mut__DOT__r_data:m_core->v__DOT__mem_odata,
87
                                (m_core->o_rtn_stall)?"STALL":"     ",
88
                                (m_core->v__DOT__mut__DOT__setup_ack)?"S":" ",
89
                                (m_core->o_rtn_ack )?"ACK":"   ",
90
                                (m_core->o_rtn_miss)?"MISS":"    ",
91
                                (m_core->o_rtn_err )?"ERR":"   ");
92
 
93
                        printf("[%d,%d]",
94
                                m_core->v__DOT__mut__DOT__wr_vtable,
95
                                m_core->v__DOT__mut__DOT__wr_ptable);
96
                        printf("[%d,%d,%04x]",
97
                                m_core->v__DOT__mut__DOT__wr_control,
98
                                m_core->v__DOT__mut__DOT__z_context,
99
                                m_core->v__DOT__mut__DOT__r_context_word);
100
                        /*
101
                        printf("[%08x,%08x-%08x]",
102
                                m_core->v__DOT__mut__DOT__w_vtable_reg,
103
                                m_core->v__DOT__mut__DOT__w_ptable_reg,
104
                                m_core->v__DOT__mut__DOT__setup_data);
105
                        */
106
                        printf(" %s[%s%s@%08x,%08x]",
107
                                (m_core->v__DOT__mut__DOT__r_pending)?"R":" ",
108
                                (m_core->v__DOT__mut__DOT__r_we)?"W":" ",
109
                                (m_core->v__DOT__mut__DOT__r_valid)?"V":" ",
110
                                (m_core->v__DOT__mut__DOT__r_addr),
111
                                (m_core->v__DOT__mut__DOT__r_data));
112
                        printf("@%2x[%s%s%s][%s%s%s%s]",
113
                                (m_core->v__DOT__mut__DOT__s_tlb_addr),
114
                                (m_core->v__DOT__mut__DOT__s_pending)?"P":" ",
115
                                (m_core->v__DOT__mut__DOT__s_tlb_hit)?"HT":"  ",
116
                                (m_core->v__DOT__mut__DOT__s_tlb_miss)?"MS":"  ",
117
                                (m_core->v__DOT__mut__DOT__ro_flag)?"RO":"  ",
118
                                (m_core->v__DOT__mut__DOT__simple_miss)?"SM":"  ",
119
                                (m_core->v__DOT__mut__DOT__ro_miss)?"RM":"  ",
120
                                (m_core->v__DOT__mut__DOT__table_err)?"TE":"  ");
121
                                //(m_core->v__DOT__mut__DOT__cachable)?"CH":"  ");
122
                        /*
123
                        printf(" M[%016lx]",
124
                                m_core->v__DOT__mut__DOT__r_tlb_match);
125
                        printf(" P[%3d] = 0x%08x, V=0x%08x, C=0x%08x, CTXT=%04x",
126
                                m_last_tlb_index,
127
                                m_core->v__DOT__mut__DOT__tlb_pdata[m_last_tlb_index],
128
                                m_core->v__DOT__mut__DOT__tlb_vdata[m_last_tlb_index],
129
                                m_core->v__DOT__mut__DOT__tlb_cdata[m_last_tlb_index],
130
                                m_core->v__DOT__mut__DOT__r_context_word);
131
                        */
132
                        printf("\n");
133
                }
134
        }
135
 
136
        void reset(void) {
137
                m_core->i_rst    = 1;
138
                m_core->i_ctrl_cyc_stb = 0;
139
                m_core->i_wbm_cyc  = 0;
140
                m_core->i_wbm_stb  = 0;
141
                tick();
142
                m_core->i_rst  = 0;
143
        }
144
 
145
        void wb_tick(void) {
146
                m_core->i_rst  = 0;
147
                m_core->i_ctrl_cyc_stb = 0;
148
                m_core->i_wbm_cyc  = 0;
149
                m_core->i_wbm_stb  = 0;
150
                tick();
151
                assert(!m_core->o_rtn_ack);
152
                assert(!m_core->o_rtn_err);
153
        }
154
 
155
        unsigned operator[](unsigned a) {
156
                a &= ((1<<LGMEMSIZE)-1);
157
                return m_core->v__DOT__ram__DOT__mem[a];
158
        }
159
 
160
        unsigned setup_read(unsigned a) {
161
                int             errcount = 0;
162
                unsigned        result;
163
                m_miss = false; m_err = false;
164
 
165
                printf("WB-READS(%08x)\n", a);
166
 
167
                m_core->i_ctrl_cyc_stb = 1;
168
                m_core->i_wbm_cyc = 0;
169
                m_core->i_wbm_stb = 0;
170
                m_core->i_wb_we  = 0;
171
                m_core->i_wb_addr= a;
172
 
173
                if (m_core->o_rtn_stall) {
174
                        while((errcount++ < BOMBCOUNT)&&(m_core->o_rtn_stall))
175
                                tick();
176
                } tick();
177
 
178
                m_core->i_ctrl_cyc_stb = 0;
179
 
180
                while((errcount++ <  BOMBCOUNT)&&(!m_core->o_rtn_ack)) {
181
                        tick();
182
                }
183
 
184
 
185
                result = m_core->o_rtn_data;
186
                assert(!m_core->o_rtn_err);
187
                assert(!m_core->o_rtn_miss);
188
 
189
                if(errcount >= BOMBCOUNT) {
190
                        printf("SETTING ERR TO TRUE!!!!! (BOMB)\n");
191
                        m_bomb = true;
192
                } else if (!m_core->o_rtn_ack) {
193
                        printf("SETTING ERR TO TRUE--NO ACK, NO TIMEOUT\n");
194
                        m_bomb = true;
195
                }
196
                tick();
197
 
198
                assert(!m_core->o_rtn_ack);
199
                assert(!m_core->o_rtn_miss);
200
                assert(!m_core->o_rtn_err);
201
                assert(!m_core->o_rtn_stall);
202
 
203
                return result;
204
        }
205
 
206
        void setup_write(unsigned a, unsigned v) {
207
                int             errcount = 0;
208
                m_miss = false; m_err = false;
209
 
210
                printf("WB-WRITES(%08x,%08x)\n", a,v);
211
 
212
                m_core->i_ctrl_cyc_stb = 1;
213
                m_core->i_wbm_cyc = 0;
214
                m_core->i_wbm_stb = 0;
215
                m_core->i_wb_we  = 1;
216
                m_core->i_wb_addr= a;
217
                m_core->i_wb_data= v;
218
 
219
                if (a & 0x080)
220
                        m_last_tlb_index = (a>>1)&0x3f;
221
 
222
                if (m_core->o_rtn_stall) {
223
                        while((errcount++ < BOMBCOUNT)&&(m_core->o_rtn_stall))
224
                                tick();
225
                } tick();
226
 
227
                m_core->i_ctrl_cyc_stb = 0;
228
 
229
                while((errcount++ <  BOMBCOUNT)&&(!m_core->o_rtn_ack)) {
230
                        tick();
231
                }
232
 
233
 
234
                assert(!m_core->o_rtn_err);
235
                assert(!m_core->o_rtn_miss);
236
 
237
                if(errcount >= BOMBCOUNT) {
238
                        printf("SETTING ERR TO TRUE!!!!! (BOMB)\n");
239
                        m_bomb = true;
240
                } else if (!m_core->o_rtn_ack) {
241
                        printf("SETTING ERR TO TRUE--NO ACK, NO TIMEOUT\n");
242
                        m_bomb = true;
243
                }
244
                tick();
245
 
246
                assert(!m_core->o_rtn_ack);
247
                assert(!m_core->o_rtn_miss);
248
                assert(!m_core->o_rtn_err);
249
                assert(!m_core->o_rtn_stall);
250
        }
251
 
252
        unsigned wb_read(unsigned a, bool *err) {
253
                int             errcount = 0;
254
                unsigned        result;
255
                if (err)        *err = false;
256
 
257
                printf("WB-READM(%08x)\n", a);
258
 
259
                m_core->i_ctrl_cyc_stb = 0;
260
                m_core->i_wbm_cyc = 1;
261
                m_core->i_wbm_stb = 1;
262
                m_core->i_wb_we  = 0;
263
                m_core->i_wb_addr= a;
264
 
265
                if (m_core->o_rtn_stall) {
266
                        while((errcount++ < BOMBCOUNT)&&(m_core->o_rtn_stall)) {
267
                                tick();
268
                                if ((err)&&((m_core->o_rtn_err)||(m_core->o_rtn_miss))) {
269
                                        if (!*err) {
270
                                                m_miss = (m_core->o_rtn_miss);
271
                                                m_err  = (m_core->o_rtn_err);
272
                                        } *err = true;
273
                                        m_core->i_ctrl_cyc_stb = 0;
274
                                        m_core->i_wbm_cyc = 0;
275
                                        m_core->i_wbm_stb = 0;
276
                                        tick();
277
                                        return 0;
278
                                }
279
                        }
280
                } tick();
281
 
282
                m_core->i_wbm_stb = 0;
283
 
284
                while((errcount++ <  BOMBCOUNT)&&(!m_core->o_rtn_ack)) {
285
                        tick();
286
                        if ((err)&&((m_core->o_rtn_err)||(m_core->o_rtn_miss))) {
287
                                if (!*err) {
288
                                        m_miss = (m_core->o_rtn_miss);
289
                                        m_err  = (m_core->o_rtn_err);
290
                                } *err = true;
291
                                m_core->i_ctrl_cyc_stb = 0;
292
                                m_core->i_wbm_cyc = 0;
293
                                        m_core->i_wbm_stb = 0;
294
                                tick();
295
                                return 0;
296
                        }
297
                }
298
 
299
 
300
                result = m_core->o_rtn_data;
301
                assert(!m_core->o_rtn_err);
302
                assert(!m_core->o_rtn_miss);
303
 
304
                // Release the bus?
305
                m_core->i_wbm_cyc = 0;
306
                m_core->i_wbm_stb = 0;
307
 
308
                if(errcount >= BOMBCOUNT) {
309
                        printf("SETTING ERR TO TRUE!!!!! (BOMB)\n");
310
                        m_bomb = true;
311
                } else if (!m_core->o_rtn_ack) {
312
                        printf("SETTING ERR TO TRUE--NO ACK, NO TIMEOUT\n");
313
                        m_bomb = true;
314
                }
315
                tick();
316
 
317
                assert(!m_core->o_rtn_ack);
318
                assert(!m_core->o_rtn_miss);
319
                assert(!m_core->o_rtn_err);
320
                assert(!m_core->o_rtn_stall);
321
 
322
                return result;
323
        }
324
 
325
        void    wb_read(unsigned a, int len, unsigned *buf, bool *err) {
326
                int             errcount = 0;
327
                int             THISBOMBCOUNT = BOMBCOUNT * len;
328
                int             cnt, rdidx, inc;
329
 
330
                if (err)        *err = false;
331
                printf("WB-READM(%08x, %d)\n", a, len);
332
 
333
                while((errcount++ < BOMBCOUNT)&&(m_core->o_rtn_stall))
334
                        wb_tick();
335
 
336
                if (errcount >= BOMBCOUNT) {
337
                        printf("WB-READ(%d): Setting bomb to true (errcount = %d)\n", __LINE__, errcount);
338
                        m_bomb = true;
339
                        return;
340
                }
341
 
342
                errcount = 0;
343
 
344
                m_core->i_ctrl_cyc_stb = 0;
345
                m_core->i_wbm_cyc = 1;
346
                m_core->i_wbm_stb = 1;
347
                m_core->i_wb_we   = 0;
348
                m_core->i_wb_addr = a;
349
 
350
                rdidx =0; cnt = 0;
351
                inc = 1;
352
 
353
                do {
354
                        int     s;
355
                        s = (m_core->o_rtn_stall==0)?0:1;
356
                        tick();
357
                        if (!s)
358
                                m_core->i_wb_addr += inc;
359
                        cnt += (s==0)?1:0;
360
                        if (m_core->o_rtn_ack)
361
                                buf[rdidx++] = m_core->o_rtn_data;
362
                        if ((err)&&((m_core->o_rtn_err)||(m_core->o_rtn_miss))) {
363
                                if (!*err) {
364
                                        m_miss = (m_core->o_rtn_miss);
365
                                        m_err  = (m_core->o_rtn_err);
366
                                } *err = true;
367
                                m_core->i_ctrl_cyc_stb = 0;
368
                                m_core->i_wbm_cyc = 0;
369
                                        m_core->i_wbm_stb = 0;
370
                                tick();
371
                                return;
372
                        }
373
                } while((cnt < len)&&(errcount++ < THISBOMBCOUNT));
374
 
375
                m_core->i_wbm_stb = 0;
376
 
377
                while((rdidx < len)&&(errcount++ < THISBOMBCOUNT)) {
378
                        tick();
379
                        if ((err)&&((m_core->o_rtn_err)||(m_core->o_rtn_miss))) {
380
                                if (!*err) {
381
                                        m_miss = (m_core->o_rtn_miss);
382
                                        m_err  = (m_core->o_rtn_err);
383
                                } *err = true;
384
                                m_core->i_ctrl_cyc_stb = 0;
385
                                m_core->i_wbm_cyc = 0;
386
                                        m_core->i_wbm_stb = 0;
387
                                tick();
388
                                return;
389
                        }
390
                        if (m_core->o_rtn_ack)
391
                                buf[rdidx++] = m_core->o_rtn_data;
392
                }
393
 
394
                // Release the bus?
395
                m_core->i_wbm_cyc = 0;
396
 
397
                if(errcount >= THISBOMBCOUNT) {
398
                        printf("SETTING ERR TO TRUE!!!!! (errcount=%08x, THISBOMBCOUNT=%08x)\n", errcount, THISBOMBCOUNT);
399
                        m_bomb = true;
400
                } else if (!m_core->o_rtn_ack) {
401
                        printf("SETTING ERR TO TRUE--NO ACK, NO TIMEOUT\n");
402
                        m_bomb = true;
403
                }
404
                tick();
405
                assert(!m_core->o_rtn_ack);
406
                assert(!m_core->o_rtn_miss);
407
                assert(!m_core->o_rtn_err);
408
                assert(!m_core->o_rtn_stall);
409
        }
410
 
411
        void    wb_write(unsigned a, unsigned v, bool *err) {
412
                int errcount = 0;
413
 
414
                if (err)        *err = false;
415
                printf("WB-WRITEM(%08x) <= %08x\n", a, v);
416
                m_core->i_ctrl_cyc_stb = 0;
417
                m_core->i_wbm_cyc = 1;
418
                m_core->i_wbm_stb = 1;
419
                m_core->i_wb_we  = 1;
420
                m_core->i_wb_addr= a;
421
                m_core->i_wb_data= v;
422
 
423
                if (m_core->o_rtn_stall)
424
                        while((errcount++ < BOMBCOUNT)&&(m_core->o_rtn_stall)) {
425
                                printf("Stalled, so waiting, errcount=%d\n", errcount);
426
                                tick();
427
                                if ((err)&&((m_core->o_rtn_miss)||(m_core->o_rtn_err))) {
428
                                        if (!*err) {
429
                                                m_miss = (m_core->o_rtn_miss);
430
                                                m_err  = (m_core->o_rtn_err);
431
                                        } *err = true;
432
                                        m_core->i_wbm_cyc = 0;
433
                                        m_core->i_wbm_stb = 0;
434
                                        tick();
435
                                        return;
436
                                }
437
                        }
438
                tick();
439
                if ((err)&&((m_core->o_rtn_miss)||(m_core->o_rtn_err))) {
440
                        if (!*err) {
441
                                m_miss = (m_core->o_rtn_miss);
442
                                m_err  = (m_core->o_rtn_err);
443
                        } *err = true;
444
                        m_core->i_wbm_cyc = 0;
445
                        m_core->i_wbm_stb = 0;
446
                        tick();
447
                        return;
448
                }
449
 
450
                m_core->i_wbm_stb = 0;
451
 
452
                while((errcount++ <  BOMBCOUNT)&&(!m_core->o_rtn_ack)) {
453
                        tick();
454
                        if ((err)&&((m_core->o_rtn_miss)||(m_core->o_rtn_err))) {
455
                                if (!*err) {
456
                                        m_miss = (m_core->o_rtn_miss);
457
                                        m_err  = (m_core->o_rtn_err);
458
                                } *err = true;
459
                                m_core->i_wbm_cyc = 0;
460
                                m_core->i_wbm_stb = 0;
461
                                tick();
462
                                return;
463
                        }
464
                } tick();
465
                if ((err)&&((m_core->o_rtn_miss)||(m_core->o_rtn_err))) {
466
                        if (!*err) {
467
                                m_miss = (m_core->o_rtn_miss);
468
                                m_err  = (m_core->o_rtn_err);
469
                        } *err = true;
470
                        m_core->i_wbm_cyc = 0;
471
                        m_core->i_wbm_stb = 0;
472
                        tick();
473
                        return;
474
                }
475
 
476
                // Release the bus?
477
                m_core->i_ctrl_cyc_stb = 0;
478
                m_core->i_wbm_cyc = 0;
479
                m_core->i_wbm_stb = 0;
480
 
481
                if(errcount >= BOMBCOUNT) {
482
                        printf("SETTING ERR TO TRUE!!!!! (BOMB) (LINE=%d, count=%d)\n",__LINE__, errcount);
483
                        m_bomb = true;
484
                } tick();
485
                assert(!m_core->o_rtn_ack);
486
                assert(!m_core->o_rtn_miss);
487
                assert(!m_core->o_rtn_err);
488
                assert(!m_core->o_rtn_stall);
489
        }
490
 
491
        void    wb_write(unsigned a, unsigned int ln, unsigned *buf, bool *err) {
492
                unsigned errcount = 0, nacks = 0;
493
                if (err)        *err = false;
494
 
495
                printf("WB-WRITEM(%08x, %d, ...)\n", a, ln);
496
                m_core->i_ctrl_cyc_stb = 0;
497
                m_core->i_wbm_cyc = 1;
498
                m_core->i_wbm_stb = 1;
499
                m_core->i_wb_we  = 1;
500
                for(unsigned stbcnt=0; stbcnt<ln; stbcnt++) {
501
                        m_core->i_wb_addr= a+stbcnt;
502
                        m_core->i_wb_data= buf[stbcnt];
503
                        errcount = 0;
504
 
505
                        while((errcount++ < BOMBCOUNT)&&(m_core->o_rtn_stall)) {
506
                                tick();
507
                                if ((err)&&((m_core->o_rtn_miss)||(m_core->o_rtn_err))) {
508
                                        if (!*err) {
509
                                                m_miss = (m_core->o_rtn_miss);
510
                                                m_err  = (m_core->o_rtn_err);
511
                                        } *err = true;
512
                                        m_core->i_wbm_cyc = 0;
513
                                        m_core->i_wbm_stb = 0;
514
                                        tick();
515
                                        return;
516
                                }
517
                                if (m_core->o_rtn_ack) nacks++;
518
                        }
519
                        // Tick, now that we're not stalled.  This is the tick
520
                        // that gets accepted.
521
                        tick(); if (m_core->o_rtn_ack) nacks++;
522
                        if ((err)&&((m_core->o_rtn_miss)||(m_core->o_rtn_err))) {
523
                                if (!*err) {
524
                                        m_miss = (m_core->o_rtn_miss);
525
                                        m_err  = (m_core->o_rtn_err);
526
                                } *err = true;
527
                                m_core->i_wbm_cyc = 0;
528
                                m_core->i_wbm_stb = 0;
529
                                tick();
530
                                return;
531
                        }
532
                }
533
 
534
                m_core->i_wbm_stb = 0;
535
 
536
                errcount = 0;
537
                while((nacks < ln)&&(errcount++ < BOMBCOUNT)) {
538
                        tick();
539
                        if (m_core->o_rtn_ack) {
540
                                nacks++;
541
                                errcount = 0;
542
                        }
543
                        if ((err)&&((m_core->o_rtn_miss)||(m_core->o_rtn_err))) {
544
                                if (!*err) {
545
                                        m_miss = (m_core->o_rtn_miss);
546
                                        m_err  = (m_core->o_rtn_err);
547
                                } *err = true;
548
                                m_core->i_wbm_cyc = 0;
549
                                m_core->i_wbm_stb = 0;
550
                                tick();
551
                                return;
552
                        }
553
                }
554
 
555
                // Release the bus
556
                m_core->i_wbm_cyc = 0;
557
                m_core->i_wbm_stb = 0;
558
 
559
                if(errcount >= BOMBCOUNT) {
560
                        printf("SETTING ERR TO TRUE!!!!! (BOMB)\n");
561
                        m_bomb = true;
562
                } tick();
563
                assert(!m_core->o_rtn_ack);
564
                assert(!m_core->o_rtn_miss);
565
                assert(!m_core->o_rtn_err);
566
                assert(!m_core->o_rtn_stall);
567
        }
568
 
569
        bool    miss(void) {
570
                return m_miss;
571
        } bool  err(void) {
572
                return m_err;
573
        }
574
 
575
        bool    bombed(void) const { return m_bomb; }
576
 
577
        bool    debug(void) const { return m_debug; }
578
        bool    debug(bool nxtv) { return m_debug = nxtv; }
579
};
580
 
581
void    uload(unsigned len, unsigned *buf) {
582
        FILE    *fp = fopen("/dev/urandom", "r");
583
 
584
        if ((NULL == fp)||(len != fread(buf, sizeof(unsigned), len, fp))) {
585
                for(int i=0; i<(int)len; i++)
586
                        buf[i] = ((unsigned)rand());
587
        } if (NULL == fp)
588
                fclose(fp);
589
}
590
 
591
void    install_page(ZIPMMU_TB *tb, int idx, unsigned va, unsigned pa, int flags) {
592
        int     LGTBL, LGPGSZ, LGCTXT;
593
        int     c;
594
        unsigned base;
595
        bool    hdebug = tb->debug();
596
 
597
        tb->debug(false);
598
        c=tb->setup_read(0);
599
        printf("CONTEXT-REG = %08x\n", c);
600
        LGTBL  = ((c>>24)&15);
601
        LGPGSZ= (((c>>20)&15)+8)&31;
602
        LGCTXT= (((c>>16)&15)+1)&31;
603
        c &= ((1<<LGCTXT)-1);
604
        base  = (2<<LGTBL)+(idx<<1);
605
        va &= -(1<<LGPGSZ);
606
        pa &= -(1<<LGPGSZ);
607
 
608
        printf("INSTALL[%2d] %04x:%08xV -> %08xP %s%s\n",
609
                idx, c, va, pa,
610
                (flags&MMUFLAG_RONW)?"RO":"  ",
611
                (flags&MMUFLAG_CCHE)?"Cachable":"");
612
        tb->setup_write(base  , va|(( c    &0x0ff)<<4)|flags);
613
        tb->setup_write(base+1, pa|(((c>>8)&0x0ff)<<4)|flags);
614
        tb->debug(hdebug);
615
}
616
 
617
int main(int  argc, char **argv) {
618
        Verilated::commandArgs(argc, argv);
619
        ZIPMMU_TB       *tb = new ZIPMMU_TB;
620
        unsigned        *rdbuf; // *mbuf;
621
        unsigned        mlen = (1<<LGMEMSIZE), c, blen;
622
 
623
        tb->opentrace("zipmmu_tb.vcd");
624
        printf("Giving the core 2 cycles to start up\n");
625
        // Before testing, let's give the unit time enough to warm up
626
        tb->reset();
627
        for(int i=0; i<2; i++)
628
                tb->wb_tick();
629
 
630
        mlen = 1<<16;
631
 
632
        printf("Getting some memory ...\n");
633
        rdbuf = new unsigned[mlen];
634
        // mbuf  = new unsigned[mlen]; // Match buffer
635
        printf("Charging my memory with random values\n");
636
        uload(mlen, rdbuf);
637
 
638
 
639
        int     LGADR, LGTBL, LGPGSZ, LGCTXT, sr;
640
 
641
        c=tb->setup_read(0);
642
        printf("CONTROL-REG = %08x\n = %2d\n", c, c);
643
        sr = tb->setup_read(1);
644
        printf("STATUS-REG  = %08x = %2d\n", sr, sr);
645
        LGADR = (((c>>28)&15)+17)&31;
646
        LGTBL = ((c>>24)&15);
647
        LGPGSZ= (((c>>20)&15)+8)&31;
648
        LGCTXT= (((c>>16)&15)+1)&31;
649
        printf("LGADR       = %08x = %2d\n", LGADR, LGADR);
650
        printf("LGTBL       = %08x = %2d\n", LGTBL, LGTBL);
651
        printf("LGPGSZ      = %08x = %2d\n", LGPGSZ, LGPGSZ);
652
        printf("LGCTXT      = %08x = %2d\n", LGCTXT, LGCTXT);
653
 
654
        // First, let's make sure we can read/write the context
655
        printf("\n\nTest: Can we read/write the context register?\n");
656
        tb->setup_write(0,0x01fec);
657
        c=tb->setup_read(0);
658
        printf("CONTEXT     = %08x (0x1fec?)\n", c&0x0ffff);
659
        if ((c&0x0ffff) != 0x01fec)
660
                goto test_failure;
661
 
662
        // Load the table with TLB misses
663
        printf("\n\nTest: Can we load the table with TLB misses? (%d entries)\n", (1<<LGTBL));
664
        for(int i=0; i<(1<<LGTBL); i++) {
665
                c = 0x0f70; // Context: 0xfef7
666
                tb->setup_write((2<<LGTBL)+(i<<1)  , c+(((1<<LGTBL)-1-i)<<LGPGSZ));
667
                c = 0x0fe2; // CCHE flag only
668
                tb->setup_write((2<<LGTBL)+(i<<1)+1, c+(((1<<LGTBL)-1-i)<<LGPGSZ));
669
        }
670
 
671
        // Dump the table, make sure we got it right
672
        for(int i=0; i<(1<<LGTBL); i++) {
673
                unsigned v, p;
674
                v=tb->setup_read((2<<LGTBL)+(i<<1)  );
675
                p=tb->setup_read((2<<LGTBL)+(i<<1)+1);
676
 
677
                printf("TBL[%2d] = %08x -> %08x\n", i, v, p);
678
                if (v != (unsigned)(0x00f72+(((1<<LGTBL)-1-i)<<LGPGSZ)))
679
                        goto test_failure;
680
                if (p != (unsigned)(0x00fe2+(((1<<LGTBL)-1-i)<<LGPGSZ)))
681
                        goto test_failure;
682
        }
683
 
684
        // Now, let's create a fictitious process, context 1, with no pages.
685
        // See what happens when we try to access his stack at 0xffffffff
686
        bool    tberr;
687
        printf("\n\nTest: Do we get a TLB miss when attempting to find a non-existent page?\n");
688
        tberr = false;
689
        tb->wb_write(0xffffffff, 0x0fe, &tberr);
690
        if ((!tberr)||(!tb->miss())||(tb->err())) {
691
                printf("TBERR = %s\nMISS  = %s\nERR   = %s\n",
692
                        (tberr)?"true":"false", (tb->miss())?"true":"false",
693
                        (tb->err())?"true":"false");
694
                goto test_failure;
695
        }
696
 
697
        tberr = false;
698
        install_page(tb, 0, 0x0ffffffff, (1<<LGMEMSIZE)+0*(1<<LGPGSZ),
699
                        MMUFLAG_RONW);
700
        printf("\n\nTest: Do we get a TLB miss when attempting to write a RO page?\n");
701
        tb->wb_write(0xffffffff, 0x0fe, &tberr);
702
        if ((!tberr)||(!tb->miss())||(tb->err())) {
703
                printf("TBERR = %s\nMISS  = %s\nERR   = %s\n",
704
                        (tberr)?"true":"false", (tb->miss())?"true":"false",
705
                        (tb->err())?"true":"false");
706
                goto test_failure;
707
        }
708
 
709
        tberr = false;
710
        printf("\n\nTest: What if we make this into a writeable page?\n");
711
        install_page(tb, 0, 0xffffffff, (1<<LGMEMSIZE)+0*(1<<LGPGSZ), 0);
712
        tb->wb_write(0xffffffff, 0x0fe, &tberr);
713
        if (tberr) {
714
                printf("TBERR = %s\nMISS  = %s\nERR   = %s\n",
715
                        (tberr)?"true":"false", (tb->miss())?"true":"false",
716
                        (tb->err())?"true":"false");
717
                goto test_failure;
718
        }
719
        printf("\n\nTest: Is the next access done w/in a single clock?\n");
720
        tb->wb_write(0xfffffff7, 0xdeadbeef, &tberr);
721
        if (tberr) {
722
                printf("TBERR = %s\nMISS  = %s\nERR   = %s\n",
723
                        (tberr)?"true":"false", (tb->miss())?"true":"false",
724
                        (tb->err())?"true":"false");
725
                goto test_failure;
726
        }
727
 
728
 
729
        tberr = false;
730
        printf("\n\nTest: What if we make this into a writeable page?\n");
731
        install_page(tb, 0, 0xffffffff, (1<<LGMEMSIZE)+0*(1<<LGPGSZ), 0);
732
        tb->wb_write(0xffffffff, 0x0fe, &tberr);
733
        if ((tberr)||((*tb)[0x0fff]!=0x0fe)) {
734
                unsigned v;
735
                v = ((*tb)[0x0fff]!=0x0fe);
736
                printf("V     = 0x%08x (!= 0x0fe?)\nTBERR = %s\nMISS  = %s\nERR   = %s\n",
737
                        v, (tberr)?"true":"false", (tb->miss())?"true":"false",
738
                        (tb->err())?"true":"false");
739
                goto test_failure;
740
        }
741
 
742
        tberr = false;
743
        printf("\n\nTest: How about a read from the same location?\n");
744
        {
745
                unsigned        v;
746
                v = tb->wb_read(0xffffffff, &tberr);
747
                if ((tberr)||(v != 0x0fe)) {
748
                        printf("V     = 0x%08x (!= 0x0fe?)\nTBERR = %s\nMISS  = %s\nERR   = %s\n",
749
                                v,
750
                                (tberr)?"true":"false", (tb->miss())?"true":"false",
751
                                (tb->err())?"true":"false");
752
                        goto test_failure;
753
                }
754
        }
755
 
756
        printf("Test: Burst write, within page\n");
757
        tb->setup_write(0, 0x0dad);
758
        install_page(tb, 0, ((0x0ffffffffl)&(-(1l<<LGPGSZ)))-2*(1<<LGPGSZ), (1<<LGMEMSIZE)+0*(1<<LGPGSZ), 0);
759
        install_page(tb, 1, ((0x0ffffffffl)&(-(1l<<LGPGSZ)))-1*(1<<LGPGSZ), (1<<LGMEMSIZE)+1*(1<<LGPGSZ), 0);
760
        install_page(tb, 2, ((0x0ffffffffl)&(-(1l<<LGPGSZ)))+0*(1<<LGPGSZ), (1<<LGMEMSIZE)+2*(1<<LGPGSZ), 0);
761
 
762
        tberr = false;
763
        blen = (1<<(LGPGSZ-2));
764
        tb->wb_write(((0xffffffff)&(-(1l<<LGPGSZ)))-2*(1<<LGPGSZ), blen, rdbuf, &tberr);
765
        if (tberr) {
766
                printf("TBERR = %s\nMISS  = %s\nERR   = %s\n",
767
                        (tberr)?"true":"false", (tb->miss())?"true":"false",
768
                        (tb->err())?"true":"false");
769
                printf("STATUS= %08x\n", tb->setup_read(1));
770
                goto test_failure;
771
        } for(unsigned i=0; i<blen; i++) {
772
                if ((*tb)[i] != rdbuf[i]) {
773
                        printf("MEM[%04x] = %08x (!= %08x as expected)\n",
774
                                i, (*tb)[i], rdbuf[i]);
775
                        goto test_failure;
776
                }
777
        }
778
 
779
        printf("Test: Burst read\n");
780
        // Try somewhere within that last page
781
        tberr = false;
782
        tb->wb_read(((0xffffffff)&(-(1<<LGPGSZ)))-2*(1<<LGPGSZ)+18, blen, rdbuf, &tberr);
783
        if (tberr) {
784
                printf("TBERR = %s\nMISS  = %s\nERR   = %s\n",
785
                        (tberr)?"true":"false", (tb->miss())?"true":"false",
786
                        (tb->err())?"true":"false");
787
                printf("STATUS= %08x\n", tb->setup_read(1));
788
                goto test_failure;
789
        } for(unsigned i=0; i<blen; i++) {
790
                if ((*tb)[i+18] != rdbuf[i]) {
791
                        printf("MEM[%04x] = %08x (!= %08x as expected)\n",
792
                                i+18, (*tb)[i+18], rdbuf[i]);
793
                        goto test_failure;
794
                }
795
        }
796
 
797
 
798
        printf("Tests not (yet) implemented\n");
799
        printf("Test: Burst read crossing pages, second page valid\n");
800
        printf("Test: Burst read crossing pages, second page invalid\n");
801
 
802
        printf("SUCCESS!!\n");
803
        exit(0);
804
test_failure:
805
        printf("FAIL-HERE\n");
806
        for(int i=0; i<4; i++)
807
                tb->tick();
808
        printf("TEST FAILED\n");
809
        exit(-1);
810
}

powered by: WebSVN 2.1.0

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