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

Subversion Repositories dblclockfft

[/] [dblclockfft/] [trunk/] [bench/] [cpp/] [fft_tb.cpp] - Blame information for rev 7

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

Line No. Rev Author Line
1 7 dgisselq
////////////////////////////////////////////////////////////////////////////
2
//
3
// Filename:    butterfly_tb.cpp
4
//
5
// Project:     A Doubletime Pipelined FFT
6
//
7
// Purpose:     A test-bench for the butterfly.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 butterfly.v
14
//
15
// Creator:     Dan Gisselquist, Ph.D.
16
//              Gisselquist Tecnology, LLC
17
//
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
#include <stdio.h>
43
 
44
#include "verilated.h"
45
#include "Vfftmain.h"
46
 
47
#define LGWIDTH 11
48
#define IWIDTH  16
49
#define OWIDTH  22
50
 
51
#define FFTLEN  (1<<LGWIDTH)
52
 
53
class   FFT_TB {
54
public:
55
        Vfftmain        *m_fft;
56
        long            m_data[FFTLEN];
57
        int             m_addr;
58
        FILE            *m_dumpfp;
59
 
60
        FFT_TB(void) {
61
                m_fft = new Vfftmain;
62
                m_addr = 0;
63
                m_dumpfp = NULL;
64
        }
65
 
66
        void    tick(void) {
67
                m_fft->i_clk = 0;
68
                m_fft->eval();
69
                m_fft->i_clk = 1;
70
                m_fft->eval();
71
        }
72
 
73
        void    reset(void) {
74
                m_fft->i_ce  = 0;
75
                m_fft->i_rst = 1;
76
                tick();
77
                m_fft->i_rst = 0;
78
                tick();
79
        }
80
 
81
 
82
        bool    test(int lft, int rht) {
83
                m_fft->i_ce    = 1;
84
                m_fft->i_rst   = 0;
85
                m_fft->i_left  = lft;
86
                m_fft->i_right = rht;
87
 
88
                tick();
89
 
90
                if (m_fft->o_sync) {
91
                        m_addr = 0;
92
                } else m_addr += 2;
93
 
94
                printf("%5d: %08x,%08x -> %09lx,%09lx\t%s%s%s%s%s%s%s%s%s%s %s\n",
95
                        m_addr,
96
                        lft, rht, m_fft->o_left, m_fft->o_right,
97
                        (m_fft->v__DOT__w_s2048)?"S":"-",
98
                        (m_fft->v__DOT__w_s1024)?"S":"-",
99
                        (m_fft->v__DOT__w_s512)?"S":"-",
100
                        (m_fft->v__DOT__w_s256)?"S":"-",
101
                        (m_fft->v__DOT__w_s128)?"S":"-",
102
                        (m_fft->v__DOT__w_s64)?"S":"-",
103
                        (m_fft->v__DOT__w_s32)?"S":"-",
104
                        (m_fft->v__DOT__w_s16)?"S":"-", // This works
105
                        (m_fft->v__DOT__w_s8)?"S":"-",
106
                        (m_fft->v__DOT__w_s4)?"S":"-", // This doesn.t
107
                        (m_fft->o_sync)?"\t(SYNC!)":"");
108
 
109
                m_data[(m_addr  )&(FFTLEN-1)] = m_fft->o_left;
110
                m_data[(m_addr+1)&(FFTLEN-1)] = m_fft->o_right;
111
 
112
                if (m_addr == FFTLEN-2)
113
                        dumpwrite();
114
 
115
                return (m_fft->o_sync);
116
        }
117
 
118
        bool    test(double lft_r, double lft_i, double rht_r, double rht_i) {
119
                int     ilft, irht, ilft_r, ilft_i, irht_r, irht_i;
120
 
121
                ilft_r = (int)(lft_r + 0.5) & ((1<<IWIDTH)-1);
122
                ilft_i = (int)(lft_i + 0.5) & ((1<<IWIDTH)-1);
123
                irht_r = (int)(rht_r + 0.5) & ((1<<IWIDTH)-1);
124
                irht_i = (int)(rht_i + 0.5) & ((1<<IWIDTH)-1);
125
 
126
                ilft = (ilft_r << IWIDTH) | ilft_i;
127
                irht = (irht_r << IWIDTH) | irht_i;
128
 
129
                return test(ilft, irht);
130
        }
131
 
132
        double  rdata(int addr) {
133
                long    ivl = m_data[addr & (FFTLEN-1)];
134
 
135
                ivl = ivl >> 17;
136
                ivl &= ((1<<OWIDTH)-1);
137
                if (1 & (ivl>>(OWIDTH-1)))
138
                        ivl |= (-1l << OWIDTH);
139
                return (double)ivl;
140
        }
141
 
142
        double  idata(int addr) {
143
                long    ivl = m_data[addr & (FFTLEN-1)];
144
 
145
                ivl = ivl;
146
                ivl &= ((1<<OWIDTH)-1);
147
                if (1 & (ivl>>(OWIDTH-1)))
148
                        ivl |= (-1l << OWIDTH);
149
                return (double)ivl;
150
        }
151
 
152
        void    dump(FILE *fp) {
153
                m_dumpfp = fp;
154
        }
155
 
156
        void    dumpwrite(void) {
157
                if (!m_dumpfp)
158
                        return;
159
 
160
                double  *buf;
161
 
162
                buf = new double[FFTLEN * 2];
163
                for(int i=0; i<FFTLEN; i++) {
164
                        buf[i*2] = rdata(i);
165
                        buf[i*2+1] = idata(i);
166
                }
167
 
168
                fwrite(buf, sizeof(double), FFTLEN*2, m_dumpfp);
169
                delete[] buf;
170
        }
171
};
172
 
173
int     main(int argc, char **argv, char **envp) {
174
        Verilated::commandArgs(argc, argv);
175
        FFT_TB *fft = new FFT_TB;
176
        FILE    *fpout;
177
 
178
        fpout = fopen("fft_tb.dbl", "w");
179
        if (NULL == fpout) {
180
                fprintf(stderr, "Cannot write output file, fft_tb.dbl\n");
181
                exit(-1);
182
        }
183
 
184
        fft->reset();
185
        fft->dump(fpout);
186
 
187
        // Let's start by just testing our limits ...
188
        // First, the smallest real number
189
        for(int k=0; k<FFTLEN/2; k++)
190
                fft->test(1.0,0.0,1.0,0.0);
191
        // Then the smallest imaginary number
192
        for(int k=0; k<FFTLEN/2; k++)
193
                fft->test(0.0,1.0,0.0,1.0);
194
        // First, the smallest real number
195
        for(int k=0; k<FFTLEN/2; k++)
196
                fft->test(-1.0,0.0,-1.0,0.0);
197
        // Then the smallest imaginary number
198
        for(int k=0; k<FFTLEN/2; k++)
199
                fft->test(0.0,-1.0,0.0,-1.0);
200
        // Now, how about the smallest alternating real signal
201
        for(int k=0; k<FFTLEN/2; k++)
202
                fft->test(1.0,0.0,0.0,0.0); // Don't forget to expect a bias!
203
        // Now, how about the smallest alternating imaginary signal
204
        for(int k=0; k<FFTLEN/2; k++)
205
                fft->test(0.0,1.0,0.0,0.0); // Don't forget to expect a bias!
206
        // Now, how about the smallest alternating real signal,2nd phase
207
        for(int k=0; k<FFTLEN/2; k++)
208
                fft->test(0.0,0.0,1.0,0.0); // Don't forget to expect a bias!
209
        // Now, how about the smallest alternating imaginary signal,2nd phase
210
        for(int k=0; k<FFTLEN/2; k++)
211
                fft->test(0.0,0.0,0.0,1.0); // Don't forget to expect a bias!
212
 
213
        // Now let's go for the largest value
214
        for(int k=0; k<FFTLEN/2; k++)
215
                fft->test(-32768.0,-32768.0,-32768.0,-32768.0);
216
 
217
        // And finally, let's clear out our results / buffer
218
        for(int k=0; k<(FFTLEN/2) * 3; k++)
219
                fft->test(0.0,0.0,0.0,0.0);
220
 
221
        // Now let's try some exponentials
222
        // for(int k=0; k<FFTLEN/2; k++)
223
                // fft->test(-32768.0,-32768.0,-32768.0,-32768.0);
224
 
225
 
226
 
227
        fclose(fpout);
228
}
229
 
230
// 564, 874, 1058, 1178, 1300, 1422, 1546, 1666, 1788, 1798 --> SYNC @ 3852
231
// 2612, 2922, 3106, 3226, 3348, 3470, 3594, 3714, 3836, 3846
232
// 808, 1118, 1302, 1422, 1544, 1666, 1790, 1910, 2032, 2042 --> SYNC @ 2848
233
// 8756 .. ??

powered by: WebSVN 2.1.0

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