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

Subversion Repositories dblclockfft

[/] [dblclockfft/] [trunk/] [bench/] [cpp/] [qtrstage_tb.cpp] - Blame information for rev 41

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 41 dgisselq
////////////////////////////////////////////////////////////////////////////////
2 6 dgisselq
//
3
// Filename:    qtrstage_tb.cpp
4
//
5 41 dgisselq
// Project:     A General Purpose Pipelined FFT Implementation
6 6 dgisselq
//
7
// Purpose:     A test-bench for the qtrstage.v subfile of the double
8
//              clocked FFT.  This file may be run autonomously.  If so,
9 36 dgisselq
//      the last line output will either read "SUCCESS" on success, or some
10
//      other failure message otherwise.
11 6 dgisselq
//
12 36 dgisselq
//      This file depends upon verilator to both compile, run, and therefore
13
//      test qtrstage.v
14 6 dgisselq
//
15
// Creator:     Dan Gisselquist, Ph.D.
16 30 dgisselq
//              Gisselquist Technology, LLC
17 6 dgisselq
//
18 41 dgisselq
////////////////////////////////////////////////////////////////////////////////
19 6 dgisselq
//
20 36 dgisselq
// Copyright (C) 2015,2018, Gisselquist Technology, LLC
21 6 dgisselq
//
22
// This program is free software (firmware): you can redistribute it and/or
23
// modify it under the terms of  the GNU General Public License as published
24
// by the Free Software Foundation, either version 3 of the License, or (at
25
// your option) any later version.
26
//
27
// This program is distributed in the hope that it will be useful, but WITHOUT
28
// ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY or
29
// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
30
// for more details.
31
//
32
// You should have received a copy of the GNU General Public License along
33 41 dgisselq
// with this program.  (It's in the $(ROOT)/doc directory.  Run make with no
34 6 dgisselq
// target there if the PDF file isn't present.)  If not, see
35
// <http://www.gnu.org/licenses/> for a copy.
36
//
37
// License:     GPL, v3, as defined and found on www.gnu.org,
38
//              http://www.gnu.org/licenses/gpl.html
39
//
40
//
41 41 dgisselq
////////////////////////////////////////////////////////////////////////////////
42 3 dgisselq
#include <stdio.h>
43
#include <stdint.h>
44
 
45 36 dgisselq
#include "verilated.h"
46
#include "verilated_vcd_c.h"
47 3 dgisselq
#include "Vqtrstage.h"
48 23 dgisselq
#include "twoc.h"
49 29 dgisselq
#include "fftsize.h"
50 3 dgisselq
 
51 29 dgisselq
#define IWIDTH  TST_QTRSTAGE_IWIDTH
52 6 dgisselq
#define OWIDTH  (IWIDTH+1)
53 29 dgisselq
#define LGWIDTH TST_QTRSTAGE_LGWIDTH
54 6 dgisselq
 
55 23 dgisselq
#define ASIZ    32
56
#define AMSK    (ASIZ-1)
57 3 dgisselq
 
58 35 dgisselq
#ifdef  NEW_VERILATOR
59
#define VVAR(A) qtrstage__DOT_ ## A
60
#else
61
#define VVAR(A) v__DOT_ ## A
62
#endif
63
 
64
#define sum_r           VVAR(_sum_r)
65
#define sum_i           VVAR(_sum_i)
66
#define diff_r          VVAR(_diff_r)
67
#define diff_i          VVAR(_diff_i)
68
#define pipeline        VVAR(_pipeline)
69
#define iaddr           VVAR(_iaddr)
70
#define imem            VVAR(_imem)
71
#define wait_for_sync   VVAR(_wait_for_sync)
72
 
73 23 dgisselq
class   QTRTEST_TB {
74
public:
75
        Vqtrstage       *m_qstage;
76 36 dgisselq
        VerilatedVcdC   *m_trace;
77
        unsigned long   m_data[ASIZ], m_tickcount;
78 23 dgisselq
        int             m_addr, m_offset;
79
        bool            m_syncd;
80 3 dgisselq
 
81 23 dgisselq
        QTRTEST_TB(void) {
82 36 dgisselq
                Verilated::traceEverOn(true);
83
                m_trace = NULL;
84 23 dgisselq
                m_qstage = new Vqtrstage;
85 36 dgisselq
                m_addr = 0;
86
                m_offset = 6;
87
                m_syncd = false;
88
                m_tickcount = 0;
89 23 dgisselq
        }
90 3 dgisselq
 
91 36 dgisselq
        void    opentrace(const char *vcdname) {
92
                if (!m_trace) {
93
                        m_trace = new VerilatedVcdC;
94
                        m_qstage->trace(m_trace, 99);
95
                        m_trace->open(vcdname);
96
                }
97
        }
98
 
99
        void    closetrace(void) {
100
                if (m_trace) {
101
                        m_trace->close();
102
                        delete  m_trace;
103
                        m_trace = NULL;
104
                }
105
        }
106
 
107 23 dgisselq
        void    tick(void) {
108 36 dgisselq
                m_tickcount++;
109
 
110 23 dgisselq
                m_qstage->i_clk = 0;
111
                m_qstage->eval();
112 41 dgisselq
                if (m_trace)    m_trace->dump((vluint64_t)(10ul*m_tickcount-2));
113 23 dgisselq
                m_qstage->i_clk = 1;
114
                m_qstage->eval();
115 41 dgisselq
                if (m_trace)    m_trace->dump((vluint64_t)(10ul*m_tickcount));
116 36 dgisselq
                m_qstage->i_clk = 0;
117
                m_qstage->eval();
118
                if (m_trace) {
119 41 dgisselq
                        m_trace->dump((vluint64_t)(10ul*m_tickcount+5));
120 36 dgisselq
                        m_trace->flush();
121
                }
122 23 dgisselq
 
123
                m_qstage->i_sync = 0;
124 15 dgisselq
        }
125
 
126 36 dgisselq
        void    cetick(void) {
127
                int     nkce;
128
 
129
                tick();
130
                nkce = (rand()&1);
131
#ifdef  FFT_CKPCE
132
                nkce += FFT_CKPCE;
133
#endif
134
                if ((m_qstage->i_ce)&&(nkce>0)) {
135
                        m_qstage->i_ce = 0;
136
                        for(int kce = 1; kce < nkce; kce++)
137
                                tick();
138
                        m_qstage->i_ce = 1;
139
                }
140
        }
141
 
142 23 dgisselq
        void    reset(void) {
143
                m_qstage->i_ce  = 0;
144 36 dgisselq
                m_qstage->i_reset = 1;
145 23 dgisselq
                tick();
146
                m_qstage->i_ce  = 0;
147 36 dgisselq
                m_qstage->i_reset = 0;
148 23 dgisselq
                tick();
149 3 dgisselq
 
150 23 dgisselq
                m_addr = 0; m_offset = 6; m_syncd = false;
151
        }
152 3 dgisselq
 
153 23 dgisselq
        void    check_results(void) {
154
                int     sumr, sumi, difr, difi, or0, oi0;
155
                bool    fail = false;
156 3 dgisselq
 
157 23 dgisselq
                if ((!m_syncd)&&(m_qstage->o_sync)) {
158
                        m_syncd = true;
159 36 dgisselq
                        assert(m_addr == m_offset);
160 23 dgisselq
                        m_offset = m_addr;
161 36 dgisselq
                        printf("VALID-SYNC!!\n");
162 23 dgisselq
                }
163 3 dgisselq
 
164 23 dgisselq
                if (!m_syncd)
165
                        return;
166 3 dgisselq
 
167 36 dgisselq
#ifdef  DBLCLKFFT
168
                int     ir0, ii0, ir1, ii1, ir2, ii2;
169
 
170 23 dgisselq
                ir0 = sbits(m_data[(m_addr-m_offset-1)&AMSK]>>IWIDTH, IWIDTH);
171
                ii0 = sbits(m_data[(m_addr-m_offset-1)&AMSK], IWIDTH);
172
                ir1 = sbits(m_data[(m_addr-m_offset  )&AMSK]>>IWIDTH, IWIDTH);
173
                ii1 = sbits(m_data[(m_addr-m_offset  )&AMSK], IWIDTH);
174
                ir2 = sbits(m_data[(m_addr-m_offset+1)&AMSK]>>IWIDTH, IWIDTH);
175
                ii2 = sbits(m_data[(m_addr-m_offset+1)&AMSK], IWIDTH);
176 3 dgisselq
 
177 23 dgisselq
                sumr = ir1 + ir2;
178
                sumi = ii1 + ii2;
179
                difr = ir0 - ir1;
180
                difi = ii0 - ii1;
181
 
182
                or0 = sbits(m_qstage->o_data >> OWIDTH, OWIDTH);
183
                oi0 = sbits(m_qstage->o_data, OWIDTH);
184
 
185
                if (0==((m_addr-m_offset)&1)) {
186
                        if (or0 != sumr)        {
187
                                printf("FAIL 1: or0 != sumr (%x(exp) != %x(sut))\n", sumr, or0); fail = true;}
188
                        if (oi0 != sumi)        {
189
                                printf("FAIL 2: oi0 != sumi (%x(exp) != %x(sut))\n", sumi, oi0); fail = true;}
190
                } else if (1==((m_addr-m_offset)&1)) {
191
                        if (or0 != difr)        {
192
                                printf("FAIL 3: or0 != difr (%x(exp) != %x(sut))\n", difr, or0); fail = true;}
193
                        if (oi0 != difi)        {
194
                                printf("FAIL 4: oi0 != difi (%x(exp) != %x(sut))\n", difi, oi0); fail = true;}
195 3 dgisselq
                }
196 36 dgisselq
#else
197
                int     locn = (m_addr-m_offset)&AMSK;
198
                int     ir1, ii1, ir3, ii3, ir5, ii5;
199 3 dgisselq
 
200 36 dgisselq
                ir5 = sbits(m_data[(m_addr-m_offset-2)&AMSK]>>IWIDTH, IWIDTH);
201
                ii5 = sbits(m_data[(m_addr-m_offset-2)&AMSK], IWIDTH);
202
                ir3 = sbits(m_data[(m_addr-m_offset  )&AMSK]>>IWIDTH, IWIDTH);
203
                ii3 = sbits(m_data[(m_addr-m_offset  )&AMSK], IWIDTH);
204
                ir1 = sbits(m_data[(m_addr-m_offset+2)&AMSK]>>IWIDTH, IWIDTH);
205
                ii1 = sbits(m_data[(m_addr-m_offset+2)&AMSK], IWIDTH);
206
 
207
                sumr = ir3 + ir1;
208
                sumi = ii3 + ii1;
209
                difr = ir5 - ir3;
210
                difi = ii5 - ii3;
211
 
212
                or0 = sbits(m_qstage->o_data >> OWIDTH, OWIDTH);
213
                oi0 = sbits(m_qstage->o_data, OWIDTH);
214
 
215
                if (0==((locn)&2)) {
216
                        if (or0 != sumr)        {
217
                                printf("FAIL 1: or0 != sumr (%x(exp) != %x(sut))\n", sumr, or0); fail = true;
218
                        }
219
                        if (oi0 != sumi)        {
220
                                printf("FAIL 2: oi0 != sumi (%x(exp) != %x(sut))\n", sumi, oi0); fail = true;}
221
                } else if (2==((m_addr-m_offset)&3)) {
222
                        if (or0 != difr)        {
223
                                printf("FAIL 3: or0 != difr (%x(exp) != %x(sut))\n", difr, or0); fail = true;}
224
                        if (oi0 != difi)        {
225
                                printf("FAIL 4: oi0 != difi (%x(exp) != %x(sut))\n", difi, oi0); fail = true;}
226
                } else if (3==((m_addr-m_offset)&3)) {
227
                        if (or0 != difi)        {
228
                                printf("FAIL 3: or0 != difr (%x(exp) != %x(sut))\n", difr, or0); fail = true;}
229
                        if (oi0 != -difr)       {
230
                                printf("FAIL 4: oi0 != difi (%x(exp) != %x(sut))\n", difi, oi0); fail = true;}
231 23 dgisselq
                }
232 3 dgisselq
 
233 36 dgisselq
//              if (m_qstage->o_sync != ((((m_addr-m_offset)&127) == 0)?1:0)) {
234
//                      printf("BAD O-SYNC, m_addr = %d, m_offset = %d\n", m_addr, m_offset); fail = true;
235
//              }
236
#endif
237
 
238
 
239 23 dgisselq
                if (fail)
240
                        exit(-1);
241
        }
242 3 dgisselq
 
243 23 dgisselq
        void    sync(void) {
244
                m_qstage->i_sync = 1;
245
                m_addr = 0;
246
        }
247 3 dgisselq
 
248 23 dgisselq
        void    test(unsigned int data) {
249
                int     isync = m_qstage->i_sync;
250
                m_qstage->i_ce = 1;
251
                m_qstage->i_data = data;
252
                // m_qstage->i_sync = (((m_addr&127)==2)?1:0);
253 36 dgisselq
                // printf("DATA[%08x] = %08x ... ", m_addr, data);
254 23 dgisselq
                m_data[ (m_addr++)&AMSK] = data;
255
                tick();
256 3 dgisselq
 
257 23 dgisselq
                printf("k=%4d: ISYNC=%d, IN = %08x, OUT =%09lx, SYNC=%d\t%5x,%5x,%5x,%5x\t%x %4x %8x %d\n",
258
                        (m_addr-m_offset), isync, m_qstage->i_data,
259
                        m_qstage->o_data, m_qstage->o_sync,
260
 
261 35 dgisselq
                        m_qstage->sum_r,
262
                        m_qstage->sum_i,
263
                        m_qstage->diff_r,
264
                        m_qstage->diff_i,
265
                        m_qstage->pipeline,
266
                        m_qstage->iaddr,
267 36 dgisselq
#ifdef  DBLCLKFFT
268 35 dgisselq
                        m_qstage->imem,
269 36 dgisselq
#else
270
                        m_qstage->imem[1],
271
#endif
272 35 dgisselq
                        m_qstage->wait_for_sync);
273
 
274 23 dgisselq
                check_results();
275 3 dgisselq
        }
276
 
277 23 dgisselq
        void    test(int ir0, int ii0) {
278
                unsigned int    data;
279 3 dgisselq
 
280 23 dgisselq
                data = (((ir0&((1<<IWIDTH)-1)) << IWIDTH) | (ii0 & ((1<<IWIDTH)-1)));
281
                // printf("%d,%d -> %8x\n", ir0, ii0, data);
282
                test(data);
283
        }
284
 
285
        void    random_test(void) {
286
                int     ir0, ii0;
287
 
288
                // Let's pick some random values
289
                ir0 = rand(); if (ir0&4) ir0 = -ir0;
290
                ii0 = rand(); if (ii0&2) ii0 = -ii0;
291
                test(ir0, ii0);
292
        }
293
};
294
 
295
int     main(int argc, char **argv, char **envp) {
296
        Verilated::commandArgs(argc, argv);
297
        QTRTEST_TB      *tb = new QTRTEST_TB;
298
        int16_t         ir0, ii0, ir1, ii1, ir2, ii2;
299
        int32_t         sumr, sumi, difr, difi;
300
 
301 41 dgisselq
        // tb->opentrace("qtrstage.vcd");
302 23 dgisselq
        tb->reset();
303
 
304
        tb->test( 16, 0);
305
        tb->test( 16, 0);
306
        tb->sync();
307 36 dgisselq
 
308
        tb->test(  8,  0);
309
        tb->test(  0,  0);
310
        tb->test(  0,  0);
311
        tb->test(  0,  0);
312
 
313
        tb->test(  0, 4);
314
        tb->test(  0,  0);
315
        tb->test(  0,  0);
316
        tb->test(  0,  0);
317
 
318
        tb->test(  0,  0);
319
        tb->test( 32,  0);
320
        tb->test(  0,  0);
321
        tb->test(  0,  0);
322
 
323
        tb->test(  0,  0);
324
        tb->test(  0, 64);
325
        tb->test(  0,  0);
326
        tb->test(  0,  0);
327
 
328
        tb->test(  0,  0);
329
        tb->test(  0,  0);
330
        tb->test(128,  0);
331
        tb->test(  0,  0);
332
 
333
        tb->test(  0,  0);
334
        tb->test(  0,  0);
335
        tb->test(  0,256);
336
        tb->test(  0,  0);
337
 
338
        tb->test(  0,  0);
339
        tb->test(  0,  0);
340
        tb->test(  0,  0);
341
        tb->test(  2,  0);
342
 
343
        tb->test(  0,  0);
344
        tb->test(  0,  0);
345
        tb->test(  0,  0);
346
        tb->test(  0,  1);
347
 
348 23 dgisselq
        tb->test(  0, 16);
349
        tb->test(  0, 16);
350
        tb->test( 16,  0);
351
        tb->test(-16,  0);
352
 
353
        for(int k=0; k<1060; k++) {
354
                tb->random_test();
355
        }
356
 
357
        delete  tb;
358
 
359 4 dgisselq
        printf("SUCCESS!\n");
360 3 dgisselq
        exit(0);
361
}
362 23 dgisselq
 
363
 
364
 
365
 
366
 

powered by: WebSVN 2.1.0

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