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

Subversion Repositories dblclockfft

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

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

Line No. Rev Author Line
1 6 dgisselq
////////////////////////////////////////////////////////////////////////////
2
//
3
// Filename:    qtrstage_tb.cpp
4
//
5
// Project:     A Doubletime Pipelined FFT
6
//
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
//              the last line output will either read "SUCCESS" on success,
10
//              or some other failure message otherwise.
11
//
12
//              This file depends upon verilator to both compile, run, and
13
//              therefore test qtrstage.v
14
//
15
// Creator:     Dan Gisselquist, Ph.D.
16 30 dgisselq
//              Gisselquist Technology, LLC
17 6 dgisselq
//
18
///////////////////////////////////////////////////////////////////////////
19
//
20
// Copyright (C) 2015, Gisselquist Technology, LLC
21
//
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
// with this program.  (It's in the $(ROOT)/doc directory, run make with no
34
// 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
///////////////////////////////////////////////////////////////////////////
42 3 dgisselq
#include <stdio.h>
43
#include <stdint.h>
44
 
45
#include "Vqtrstage.h"
46
#include "verilated.h"
47 23 dgisselq
#include "twoc.h"
48 29 dgisselq
#include "fftsize.h"
49 3 dgisselq
 
50 29 dgisselq
#define IWIDTH  TST_QTRSTAGE_IWIDTH
51 6 dgisselq
#define OWIDTH  (IWIDTH+1)
52 29 dgisselq
#define LGWIDTH TST_QTRSTAGE_LGWIDTH
53 6 dgisselq
 
54 23 dgisselq
#define ASIZ    32
55
#define AMSK    (ASIZ-1)
56 3 dgisselq
 
57 35 dgisselq
#ifdef  NEW_VERILATOR
58
#define VVAR(A) qtrstage__DOT_ ## A
59
#else
60
#define VVAR(A) v__DOT_ ## A
61
#endif
62
 
63
#define sum_r           VVAR(_sum_r)
64
#define sum_i           VVAR(_sum_i)
65
#define diff_r          VVAR(_diff_r)
66
#define diff_i          VVAR(_diff_i)
67
#define pipeline        VVAR(_pipeline)
68
#define iaddr           VVAR(_iaddr)
69
#define imem            VVAR(_imem)
70
#define wait_for_sync   VVAR(_wait_for_sync)
71
 
72 23 dgisselq
class   QTRTEST_TB {
73
public:
74
        Vqtrstage       *m_qstage;
75
        unsigned long   m_data[ASIZ];
76
        int             m_addr, m_offset;
77
        bool            m_syncd;
78 3 dgisselq
 
79 23 dgisselq
        QTRTEST_TB(void) {
80
                m_qstage = new Vqtrstage;
81
                m_addr = 0; m_offset = 6; m_syncd = false;
82
        }
83 3 dgisselq
 
84 23 dgisselq
        void    tick(void) {
85
                m_qstage->i_clk = 0;
86
                m_qstage->eval();
87
                m_qstage->i_clk = 1;
88
                m_qstage->eval();
89
 
90
                m_qstage->i_sync = 0;
91 15 dgisselq
        }
92
 
93 23 dgisselq
        void    reset(void) {
94
                m_qstage->i_ce  = 0;
95
                m_qstage->i_rst = 1;
96
                tick();
97
                m_qstage->i_ce  = 0;
98
                m_qstage->i_rst = 0;
99
                tick();
100 3 dgisselq
 
101 23 dgisselq
                m_addr = 0; m_offset = 6; m_syncd = false;
102
        }
103 3 dgisselq
 
104 23 dgisselq
        void    check_results(void) {
105
                int     ir0, ii0, ir1, ii1, ir2, ii2;
106
                int     sumr, sumi, difr, difi, or0, oi0;
107
                bool    fail = false;
108 3 dgisselq
 
109 23 dgisselq
                if ((!m_syncd)&&(m_qstage->o_sync)) {
110
                        m_syncd = true;
111
                        m_offset = m_addr;
112
                }
113 3 dgisselq
 
114 23 dgisselq
                if (!m_syncd)
115
                        return;
116 3 dgisselq
 
117 23 dgisselq
                ir0 = sbits(m_data[(m_addr-m_offset-1)&AMSK]>>IWIDTH, IWIDTH);
118
                ii0 = sbits(m_data[(m_addr-m_offset-1)&AMSK], IWIDTH);
119
                ir1 = sbits(m_data[(m_addr-m_offset  )&AMSK]>>IWIDTH, IWIDTH);
120
                ii1 = sbits(m_data[(m_addr-m_offset  )&AMSK], IWIDTH);
121
                ir2 = sbits(m_data[(m_addr-m_offset+1)&AMSK]>>IWIDTH, IWIDTH);
122
                ii2 = sbits(m_data[(m_addr-m_offset+1)&AMSK], IWIDTH);
123 3 dgisselq
 
124 23 dgisselq
                sumr = ir1 + ir2;
125
                sumi = ii1 + ii2;
126
                difr = ir0 - ir1;
127
                difi = ii0 - ii1;
128
 
129
                or0 = sbits(m_qstage->o_data >> OWIDTH, OWIDTH);
130
                oi0 = sbits(m_qstage->o_data, OWIDTH);
131
 
132
                if (0==((m_addr-m_offset)&1)) {
133
                        if (or0 != sumr)        {
134
                                printf("FAIL 1: or0 != sumr (%x(exp) != %x(sut))\n", sumr, or0); fail = true;}
135
                        if (oi0 != sumi)        {
136
                                printf("FAIL 2: oi0 != sumi (%x(exp) != %x(sut))\n", sumi, oi0); fail = true;}
137
                } else if (1==((m_addr-m_offset)&1)) {
138
                        if (or0 != difr)        {
139
                                printf("FAIL 3: or0 != difr (%x(exp) != %x(sut))\n", difr, or0); fail = true;}
140
                        if (oi0 != difi)        {
141
                                printf("FAIL 4: oi0 != difi (%x(exp) != %x(sut))\n", difi, oi0); fail = true;}
142 3 dgisselq
                }
143
 
144 23 dgisselq
                if (m_qstage->o_sync != ((((m_addr-m_offset)&127) == 0)?1:0)) {
145
                        printf("BAD O-SYNC, m_addr = %d, m_offset = %d\n", m_addr, m_offset); fail = true;
146
                }
147 3 dgisselq
 
148 23 dgisselq
                if (fail)
149
                        exit(-1);
150
        }
151 3 dgisselq
 
152 23 dgisselq
        void    sync(void) {
153
                m_qstage->i_sync = 1;
154
                m_addr = 0;
155
        }
156 3 dgisselq
 
157 23 dgisselq
        void    test(unsigned int data) {
158
                int     isync = m_qstage->i_sync;
159
                m_qstage->i_ce = 1;
160
                m_qstage->i_data = data;
161
                // m_qstage->i_sync = (((m_addr&127)==2)?1:0);
162
                m_data[ (m_addr++)&AMSK] = data;
163
                tick();
164 3 dgisselq
 
165 23 dgisselq
                printf("k=%4d: ISYNC=%d, IN = %08x, OUT =%09lx, SYNC=%d\t%5x,%5x,%5x,%5x\t%x %4x %8x %d\n",
166
                        (m_addr-m_offset), isync, m_qstage->i_data,
167
                        m_qstage->o_data, m_qstage->o_sync,
168
 
169 35 dgisselq
                        m_qstage->sum_r,
170
                        m_qstage->sum_i,
171
                        m_qstage->diff_r,
172
                        m_qstage->diff_i,
173
                        m_qstage->pipeline,
174
                        m_qstage->iaddr,
175
                        m_qstage->imem,
176
                        m_qstage->wait_for_sync);
177
 
178 23 dgisselq
                check_results();
179 3 dgisselq
        }
180
 
181 23 dgisselq
        void    test(int ir0, int ii0) {
182
                unsigned int    data;
183 3 dgisselq
 
184 23 dgisselq
                data = (((ir0&((1<<IWIDTH)-1)) << IWIDTH) | (ii0 & ((1<<IWIDTH)-1)));
185
                // printf("%d,%d -> %8x\n", ir0, ii0, data);
186
                test(data);
187
        }
188
 
189
        void    random_test(void) {
190
                int     ir0, ii0;
191
 
192
                // Let's pick some random values
193
                ir0 = rand(); if (ir0&4) ir0 = -ir0;
194
                ii0 = rand(); if (ii0&2) ii0 = -ii0;
195
                test(ir0, ii0);
196
        }
197
};
198
 
199
int     main(int argc, char **argv, char **envp) {
200
        Verilated::commandArgs(argc, argv);
201
        QTRTEST_TB      *tb = new QTRTEST_TB;
202
        int16_t         ir0, ii0, ir1, ii1, ir2, ii2;
203
        int32_t         sumr, sumi, difr, difi;
204
 
205
        tb->reset();
206
 
207
        tb->test( 16, 0);
208
        tb->test( 16, 0);
209
        tb->sync();
210
        tb->test(  0, 16);
211
        tb->test(  0, 16);
212
        tb->test( 16,  0);
213
        tb->test(-16,  0);
214
        tb->test(  0, 16);
215
        tb->test(  0,-16);
216
 
217
        for(int k=0; k<1060; k++) {
218
                tb->random_test();
219
        }
220
 
221
        delete  tb;
222
 
223 4 dgisselq
        printf("SUCCESS!\n");
224 3 dgisselq
        exit(0);
225
}
226 23 dgisselq
 
227
 
228
 
229
 
230
 

powered by: WebSVN 2.1.0

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