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

Subversion Repositories openarty

[/] [openarty/] [trunk/] [sim/] [verilated/] [enetctrl_tb.cpp] - Blame information for rev 58

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 58 dgisselq
////////////////////////////////////////////////////////////////////////////////
2
//
3
// Filename:    enetctrl_tb.cpp
4
//
5
// Project:     OpenArty, an entirely open SoC based upon the Arty platform
6
//
7
// Purpose:     To determine whether or not the enetctrl Verilog module works.
8
//              Run this program with no arguments.  If the last line output
9
//      from it is "SUCCESS", you will know it works.  Alternatively you can
10
//      look at the return code.  If the return code is 0 (EXIT_SUCCESS), then
11
//      the test passed, ,otherrwise it failed.
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
// You should have received a copy of the GNU General Public License along
31
// with this program.  (It's in the $(ROOT)/doc directory, run make with no
32
// target there if the PDF file isn't present.)  If not, see
33
// <http://www.gnu.org/licenses/> for a copy.
34
//
35
// License:     GPL, v3, as defined and found on www.gnu.org,
36
//              http://www.gnu.org/licenses/gpl.html
37
//
38
//
39
////////////////////////////////////////////////////////////////////////////////
40
//
41
//
42
#include "verilated.h"
43
#include "verilated_vcd_c.h"
44
#include "Venetctrl.h"
45
#include "enetctrlsim.h"
46
 
47
const int       BOMBCOUNT = 2048;
48
 
49
class   ENETCTRL_TB {
50
        unsigned long   m_tickcount;
51
        Venetctrl       *m_core;
52
        ENETCTRLSIM     *m_sim;
53
        bool            m_bomb;
54
        VerilatedVcdC   *m_trace;
55
 
56
public:
57
 
58
        ENETCTRL_TB(void) {
59
                m_core = new Venetctrl;
60
                m_sim  = new ENETCTRLSIM;
61
                Verilated::traceEverOn(true);
62
                m_trace = NULL;
63
                m_tickcount = 0;
64
        }
65
 
66
        ~ENETCTRL_TB(void) {
67
                if (m_trace) {
68
                        m_trace->close();
69
                        delete  m_trace;
70
                }
71
        }
72
 
73
        int     operator[](const int index) { return (*m_sim)[index]; }
74
 
75
        void    trace(const char *fname) {
76
                if (!m_trace) {
77
                        m_trace = new VerilatedVcdC;
78
                        m_core->trace(m_trace, 99);
79
                        m_trace->open(fname);
80
                }
81
        }
82
 
83
        void    tick(void) {
84
                m_core->i_mdio = (*m_sim)(0, m_core->o_mdclk,
85
                        ((m_core->o_mdwe)&(m_core->o_mdio))
86
                                |((m_core->o_mdwe)?0:1));
87
 
88
#ifdef  DEBUGGING_OUTPUT
89
                printf("%08lx-WB: %s %s %s%s %s@0x%02x[%04x/%04x] -- %d[%d->(%d)->%d]",
90
                        m_tickcount,
91
                        (m_core->i_wb_cyc)?"CYC":"   ",
92
                        (m_core->i_wb_stb)?"STB":"   ",
93
                        (m_core->o_wb_stall)?"STALL":"     ",
94
                        (m_core->o_wb_ack)?"ACK":"   ",
95
                        (m_core->i_wb_we)?"W":"R",
96
                        (m_core->i_wb_addr)&0x01f, (m_core->i_wb_data)&0x0ffff,
97
                        (m_core->o_wb_data)&0x0ffff,
98
                        (m_core->o_mdclk), (m_core->o_mdio),
99
                        (m_core->o_mdwe), (m_core->i_mdio));
100
 
101
                printf(" [%02x,%d%d%d,%x] ",
102
                        m_core->v__DOT__reg_pos,
103
                        0, // m_core->v__DOT__rclk,
104
                        m_core->v__DOT__zclk,
105
                        m_core->v__DOT__zreg_pos,
106
                        m_core->v__DOT__ctrl_state);
107
                printf(" 0x%04x/0x%04x ", m_core->v__DOT__write_reg,
108
                                m_core->v__DOT__read_reg);
109
                printf(" %s%s ",
110
                        (m_core->v__DOT__read_pending)?"R":" ",
111
                        (m_core->v__DOT__write_pending)?"W":" ");
112
 
113
                printf(" %s:%08x,%2d,%08x ",
114
                        (m_sim->m_synched)?"S":" ",
115
                        m_sim->m_datareg, m_sim->m_halfword,
116
                        m_sim->m_outreg);
117
 
118
                printf("\n");
119
#endif
120
 
121
                if ((m_trace)&&(m_tickcount>0)) m_trace->dump(10*m_tickcount-2);
122
                m_core->eval();
123
                m_core->i_clk = 1;
124
                m_core->eval();
125
                if (m_trace) m_trace->dump(10*m_tickcount);
126
                m_core->i_clk = 0;
127
                m_core->eval();
128
                if (m_trace) m_trace->dump(10*m_tickcount+5);
129
 
130
                m_tickcount++;
131
 
132
                if ((m_core->o_wb_ack)&&(!m_core->i_wb_cyc)) {
133
                        printf("SETTING ERR TO TRUE!!!!!  ACK w/ no CYC\n");
134
                        // m_bomb = true;
135
                }
136
        }
137
 
138
        void wb_tick(void) {
139
                // printf("WB-TICK()\n");
140
                m_core->i_wb_cyc   = 0;
141
                m_core->i_wb_stb = 0;
142
                tick();
143
        }
144
 
145
        unsigned wb_read(unsigned a) {
146
                int             errcount = 0;
147
                unsigned        result;
148
 
149
                printf("WB-READ(%08x)\n", a);
150
 
151
                m_core->i_wb_cyc = 1;
152
                m_core->i_wb_stb = 1;
153
                m_core->i_wb_we  = 0;
154
                m_core->i_wb_addr= a & 0x01f;
155
 
156
                if (m_core->o_wb_stall)
157
                        while((errcount++ < BOMBCOUNT)&&(m_core->o_wb_stall))
158
                                tick();
159
                tick();
160
 
161
                m_core->i_wb_stb = 0;
162
 
163
                while((errcount++ <  BOMBCOUNT)&&(!m_core->o_wb_ack))
164
                        tick();
165
 
166
 
167
                result = m_core->o_wb_data;
168
 
169
                // Release the bus?
170
                m_core->i_wb_cyc = 0;
171
                m_core->i_wb_stb = 0;
172
 
173
                if(errcount >= BOMBCOUNT) {
174
                        printf("SETTING ERR TO TRUE!!!!!\n");
175
                        m_bomb = true;
176
                } else if (!m_core->o_wb_ack) {
177
                        printf("SETTING ERR TO TRUE--NO ACK, NO TIMEOUT\n");
178
                        m_bomb = true;
179
                }
180
                tick();
181
 
182
                return result;
183
        }
184
 
185
        void    wb_read(unsigned a, int len, unsigned *buf) {
186
                int             errcount = 0;
187
                int             THISBOMBCOUNT = BOMBCOUNT * len;
188
                int             cnt, rdidx;
189
 
190
                printf("WB-READ(%08x, %d)\n", a, len);
191
 
192
                while((errcount++ < BOMBCOUNT)&&(m_core->o_wb_stall))
193
                        wb_tick();
194
 
195
                if (errcount >= BOMBCOUNT) {
196
                        m_bomb = true;
197
                        return;
198
                }
199
 
200
                errcount = 0;
201
 
202
                m_core->i_wb_cyc = 1;
203
                m_core->i_wb_stb = 1;
204
                m_core->i_wb_we  = 0;
205
                m_core->i_wb_addr= a & 0x01f;
206
 
207
                rdidx =0; cnt = 0;
208
 
209
                do {
210
                        int     s;
211
                        s = (m_core->o_wb_stall==0)?0:1;
212
                        tick();
213
                        if (!s)
214
                                m_core->i_wb_addr = (m_core->i_wb_addr+1)&0x1f;
215
                        cnt += (s==0)?1:0;
216
                        if (m_core->o_wb_ack)
217
                                buf[rdidx++] = m_core->o_wb_data;
218
                } while((cnt < len)&&(errcount++ < THISBOMBCOUNT));
219
 
220
                m_core->i_wb_stb = 0;
221
 
222
                while((rdidx < len)&&(errcount++ < THISBOMBCOUNT)) {
223
                        tick();
224
                        if (m_core->o_wb_ack)
225
                                buf[rdidx++] = m_core->o_wb_data;
226
                }
227
 
228
                // Release the bus?
229
                m_core->i_wb_cyc = 0;
230
 
231
                if(errcount >= THISBOMBCOUNT) {
232
                        printf("SETTING ERR TO TRUE!!!!! (errcount=%08x, THISBOMBCOUNT=%08x)\n", errcount, THISBOMBCOUNT);
233
                        m_bomb = true;
234
                } else if (!m_core->o_wb_ack) {
235
                        printf("SETTING ERR TO TRUE--NO ACK, NO TIMEOUT\n");
236
                        m_bomb = true;
237
                }
238
                tick();
239
        }
240
 
241
        void    wb_write(unsigned a, unsigned int v) {
242
                int errcount = 0;
243
 
244
                printf("WB-WRITE(%08x) = %08x\n", a, v);
245
                m_core->i_wb_cyc = 1;
246
                m_core->i_wb_stb = 1;
247
                m_core->i_wb_we  = 1;
248
                m_core->i_wb_addr= a & 0x01f;
249
                m_core->i_wb_data= v;
250
 
251
                if (m_core->o_wb_stall)
252
                        while((errcount++ < BOMBCOUNT)&&(m_core->o_wb_stall))
253
                                tick();
254
                tick();
255
 
256
                m_core->i_wb_stb = 0;
257
 
258
                while((errcount++ <  BOMBCOUNT)&&(!m_core->o_wb_ack))
259
                        tick();
260
 
261
                // Release the bus?
262
                m_core->i_wb_cyc = 0;
263
                m_core->i_wb_stb = 0;
264
 
265
                if(errcount >= BOMBCOUNT) {
266
                        printf("SETTING ERR TO TRUE!!!!!\n");
267
                        m_bomb = true;
268
                } tick();
269
        }
270
 
271
        void    wb_write(unsigned a, unsigned int ln, unsigned int *buf) {
272
                unsigned errcount = 0, nacks = 0;
273
 
274
                m_core->i_wb_cyc = 1;
275
                for(unsigned stbcnt=0; stbcnt<ln; stbcnt++) {
276
                        m_core->i_wb_stb = 1;
277
                        m_core->i_wb_we  = 1;
278
                        m_core->i_wb_addr= (a+stbcnt) & 0x01f;
279
                        m_core->i_wb_data= buf[stbcnt];
280
                        errcount = 0;
281
 
282
                        do {
283
                                tick(); if (m_core->o_wb_ack) nacks++;
284
                        } while((errcount++ < BOMBCOUNT)&&(m_core->o_wb_stall));
285
                }
286
 
287
                m_core->i_wb_stb = 0;
288
 
289
                errcount = 0;
290
                while((nacks < ln)&&(errcount++ < BOMBCOUNT)) {
291
                        tick();
292
                        if (m_core->o_wb_ack) {
293
                                nacks++;
294
                                errcount = 0;
295
                        }
296
                }
297
 
298
                // Release the bus
299
                m_core->i_wb_cyc = 0;
300
                m_core->i_wb_stb = 0;
301
 
302
                if(errcount >= BOMBCOUNT) {
303
                        printf("SETTING ERR TO TRUE!!!!!\n");
304
                        m_bomb = true;
305
                } tick();
306
        }
307
 
308
        bool    bombed(void) const { return m_bomb; }
309
 
310
};
311
 
312
int main(int  argc, char **argv) {
313
        Verilated::commandArgs(argc, argv);
314
        ENETCTRL_TB     *tb = new ENETCTRL_TB;
315
        unsigned        v;
316
        // unsigned     *rdbuf;
317
 
318
        tb->trace("enetctrl.vcd");
319
 
320
        tb->wb_tick();
321
        tb->wb_write(0, 0x7f82);
322
        if ((*tb)[0] != 0x7f82) {
323
                printf("Somehow wrote a %04x, rather than 0x7f82\n", (*tb)[0]);
324
                goto test_failure;
325
        }
326
 
327
        tb->wb_tick();
328
        if ((v=tb->wb_read(0))!=0x7f82) {
329
                printf("READ A %08x FROM THE CORE, NOT 0x7f82\n", v);
330
                goto test_failure;
331
        }
332
 
333
        // 
334
        tb->wb_tick();
335
        tb->wb_write(14, 0x5234);
336
 
337
        tb->wb_tick();
338
        if (tb->wb_read(14)!=0x5234)
339
                goto test_failure;
340
 
341
        printf("SUCCESS!!\n");
342
        exit(EXIT_SUCCESS);
343
test_failure:
344
        printf("FAIL-HERE\n");
345
        for(int i=0; i<64; i++)
346
                tb->tick();
347
        printf("TEST FAILED\n");
348
        exit(EXIT_FAILURE);
349
}

powered by: WebSVN 2.1.0

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