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

Subversion Repositories dblclockfft

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

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 23 dgisselq
class   QTRTEST_TB {
58
public:
59
        Vqtrstage       *m_qstage;
60
        unsigned long   m_data[ASIZ];
61
        int             m_addr, m_offset;
62
        bool            m_syncd;
63 3 dgisselq
 
64 23 dgisselq
        QTRTEST_TB(void) {
65
                m_qstage = new Vqtrstage;
66
                m_addr = 0; m_offset = 6; m_syncd = false;
67
        }
68 3 dgisselq
 
69 23 dgisselq
        void    tick(void) {
70
                m_qstage->i_clk = 0;
71
                m_qstage->eval();
72
                m_qstage->i_clk = 1;
73
                m_qstage->eval();
74
 
75
                m_qstage->i_sync = 0;
76 15 dgisselq
        }
77
 
78 23 dgisselq
        void    reset(void) {
79
                m_qstage->i_ce  = 0;
80
                m_qstage->i_rst = 1;
81
                tick();
82
                m_qstage->i_ce  = 0;
83
                m_qstage->i_rst = 0;
84
                tick();
85 3 dgisselq
 
86 23 dgisselq
                m_addr = 0; m_offset = 6; m_syncd = false;
87
        }
88 3 dgisselq
 
89 23 dgisselq
        void    check_results(void) {
90
                int     ir0, ii0, ir1, ii1, ir2, ii2;
91
                int     sumr, sumi, difr, difi, or0, oi0;
92
                bool    fail = false;
93 3 dgisselq
 
94 23 dgisselq
                if ((!m_syncd)&&(m_qstage->o_sync)) {
95
                        m_syncd = true;
96
                        m_offset = m_addr;
97
                }
98 3 dgisselq
 
99 23 dgisselq
                if (!m_syncd)
100
                        return;
101 3 dgisselq
 
102 23 dgisselq
                ir0 = sbits(m_data[(m_addr-m_offset-1)&AMSK]>>IWIDTH, IWIDTH);
103
                ii0 = sbits(m_data[(m_addr-m_offset-1)&AMSK], IWIDTH);
104
                ir1 = sbits(m_data[(m_addr-m_offset  )&AMSK]>>IWIDTH, IWIDTH);
105
                ii1 = sbits(m_data[(m_addr-m_offset  )&AMSK], IWIDTH);
106
                ir2 = sbits(m_data[(m_addr-m_offset+1)&AMSK]>>IWIDTH, IWIDTH);
107
                ii2 = sbits(m_data[(m_addr-m_offset+1)&AMSK], IWIDTH);
108 3 dgisselq
 
109 23 dgisselq
                sumr = ir1 + ir2;
110
                sumi = ii1 + ii2;
111
                difr = ir0 - ir1;
112
                difi = ii0 - ii1;
113
 
114
                or0 = sbits(m_qstage->o_data >> OWIDTH, OWIDTH);
115
                oi0 = sbits(m_qstage->o_data, OWIDTH);
116
 
117
                if (0==((m_addr-m_offset)&1)) {
118
                        if (or0 != sumr)        {
119
                                printf("FAIL 1: or0 != sumr (%x(exp) != %x(sut))\n", sumr, or0); fail = true;}
120
                        if (oi0 != sumi)        {
121
                                printf("FAIL 2: oi0 != sumi (%x(exp) != %x(sut))\n", sumi, oi0); fail = true;}
122
                } else if (1==((m_addr-m_offset)&1)) {
123
                        if (or0 != difr)        {
124
                                printf("FAIL 3: or0 != difr (%x(exp) != %x(sut))\n", difr, or0); fail = true;}
125
                        if (oi0 != difi)        {
126
                                printf("FAIL 4: oi0 != difi (%x(exp) != %x(sut))\n", difi, oi0); fail = true;}
127 3 dgisselq
                }
128
 
129 23 dgisselq
                if (m_qstage->o_sync != ((((m_addr-m_offset)&127) == 0)?1:0)) {
130
                        printf("BAD O-SYNC, m_addr = %d, m_offset = %d\n", m_addr, m_offset); fail = true;
131
                }
132 3 dgisselq
 
133 23 dgisselq
                if (fail)
134
                        exit(-1);
135
        }
136 3 dgisselq
 
137 23 dgisselq
        void    sync(void) {
138
                m_qstage->i_sync = 1;
139
                m_addr = 0;
140
        }
141 3 dgisselq
 
142 23 dgisselq
        void    test(unsigned int data) {
143
                int     isync = m_qstage->i_sync;
144
                m_qstage->i_ce = 1;
145
                m_qstage->i_data = data;
146
                // m_qstage->i_sync = (((m_addr&127)==2)?1:0);
147
                m_data[ (m_addr++)&AMSK] = data;
148
                tick();
149 3 dgisselq
 
150 23 dgisselq
                printf("k=%4d: ISYNC=%d, IN = %08x, OUT =%09lx, SYNC=%d\t%5x,%5x,%5x,%5x\t%x %4x %8x %d\n",
151
                        (m_addr-m_offset), isync, m_qstage->i_data,
152
                        m_qstage->o_data, m_qstage->o_sync,
153
                        m_qstage->v__DOT__sum_r,
154
                        m_qstage->v__DOT__sum_i,
155
                        m_qstage->v__DOT__diff_r,
156
                        m_qstage->v__DOT__diff_i,
157
                        m_qstage->v__DOT__pipeline,
158
                        m_qstage->v__DOT__iaddr,
159
                        m_qstage->v__DOT__imem,
160
                        m_qstage->v__DOT__wait_for_sync);
161
 
162
                check_results();
163 3 dgisselq
        }
164
 
165 23 dgisselq
        void    test(int ir0, int ii0) {
166
                unsigned int    data;
167 3 dgisselq
 
168 23 dgisselq
                data = (((ir0&((1<<IWIDTH)-1)) << IWIDTH) | (ii0 & ((1<<IWIDTH)-1)));
169
                // printf("%d,%d -> %8x\n", ir0, ii0, data);
170
                test(data);
171
        }
172
 
173
        void    random_test(void) {
174
                int     ir0, ii0;
175
 
176
                // Let's pick some random values
177
                ir0 = rand(); if (ir0&4) ir0 = -ir0;
178
                ii0 = rand(); if (ii0&2) ii0 = -ii0;
179
                test(ir0, ii0);
180
        }
181
};
182
 
183
int     main(int argc, char **argv, char **envp) {
184
        Verilated::commandArgs(argc, argv);
185
        QTRTEST_TB      *tb = new QTRTEST_TB;
186
        int16_t         ir0, ii0, ir1, ii1, ir2, ii2;
187
        int32_t         sumr, sumi, difr, difi;
188
 
189
        tb->reset();
190
 
191
        tb->test( 16, 0);
192
        tb->test( 16, 0);
193
        tb->sync();
194
        tb->test(  0, 16);
195
        tb->test(  0, 16);
196
        tb->test( 16,  0);
197
        tb->test(-16,  0);
198
        tb->test(  0, 16);
199
        tb->test(  0,-16);
200
 
201
        for(int k=0; k<1060; k++) {
202
                tb->random_test();
203
        }
204
 
205
        delete  tb;
206
 
207 4 dgisselq
        printf("SUCCESS!\n");
208 3 dgisselq
        exit(0);
209
}
210 23 dgisselq
 
211
 
212
 
213
 
214
 

powered by: WebSVN 2.1.0

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