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

Subversion Repositories dblclockfft

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

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

Line No. Rev Author Line
1 7 dgisselq
//
2 9 dgisselq
// Filename:    fft_tb.cpp
3 7 dgisselq
//
4
// Project:     A Doubletime Pipelined FFT
5
//
6 14 dgisselq
// Purpose:     A test-bench for the main program, fftmain.v, of the double
7 9 dgisselq
//              clocked FFT.  This file may be run autonomously  (when
8
//              fully functional).  If so, the last line output will either
9
//              read "SUCCESS" on success, or some other failure message
10
//              otherwise.
11 7 dgisselq
//
12
//              This file depends upon verilator to both compile, run, and
13 9 dgisselq
//              therefore test fftmain.v
14 7 dgisselq
//
15
// Creator:     Dan Gisselquist, Ph.D.
16 30 dgisselq
//              Gisselquist Technology, LLC
17 7 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
#include <stdio.h>
43 9 dgisselq
#include <math.h>
44
#include <fftw3.h>
45 7 dgisselq
 
46
#include "verilated.h"
47
#include "Vfftmain.h"
48 23 dgisselq
#include "twoc.h"
49 7 dgisselq
 
50 28 dgisselq
#include "fftsize.h"
51 7 dgisselq
 
52 28 dgisselq
#define IWIDTH  FFT_IWIDTH
53
#define OWIDTH  FFT_OWIDTH
54
#define LGWIDTH FFT_LGWIDTH
55
 
56
#if (IWIDTH > 16)
57
typedef unsigned long   ITYP;
58
#else
59
typedef unsigned int    ITYP;
60
#endif
61
 
62
#if (OWIDTH > 16)
63
typedef unsigned long   OTYP;
64
#else
65
typedef unsigned int    OTYP;
66
#endif
67
 
68
#define NFTLOG  16
69 7 dgisselq
#define FFTLEN  (1<<LGWIDTH)
70
 
71 28 dgisselq
#ifdef  FFT_SKIPS_BIT_REVERSE
72
#define APPLY_BITREVERSE_LOCALLY
73
#endif
74
 
75 26 dgisselq
unsigned long bitrev(const int nbits, const unsigned long vl) {
76
        unsigned long   r = 0;
77
        unsigned long   val = vl;
78
 
79
        for(int k=0; k<nbits; k++) {
80
                r<<= 1;
81
                r |= (val & 1);
82
                val >>= 1;
83
        }
84
 
85
        return r;
86
}
87
 
88 7 dgisselq
class   FFT_TB {
89
public:
90
        Vfftmain        *m_fft;
91 28 dgisselq
        OTYP            m_data[FFTLEN];
92
        ITYP            m_log[NFTLOG*FFTLEN];
93 26 dgisselq
        int             m_iaddr, m_oaddr, m_ntest, m_logbase;
94 7 dgisselq
        FILE            *m_dumpfp;
95 9 dgisselq
        fftw_plan       m_plan;
96
        double          *m_fft_buf;
97
        bool            m_syncd;
98 28 dgisselq
        unsigned long   m_tickcount;
99 7 dgisselq
 
100
        FFT_TB(void) {
101
                m_fft = new Vfftmain;
102 9 dgisselq
                m_iaddr = m_oaddr = 0;
103 7 dgisselq
                m_dumpfp = NULL;
104 9 dgisselq
 
105
                m_fft_buf = (double *)fftw_malloc(sizeof(fftw_complex)*(FFTLEN));
106
                m_plan = fftw_plan_dft_1d(FFTLEN, (fftw_complex *)m_fft_buf,
107
                                (fftw_complex *)m_fft_buf,
108
                                FFTW_FORWARD, FFTW_MEASURE);
109
                m_syncd = false;
110
                m_ntest = 0;
111 28 dgisselq
 
112
                m_tickcount = 0l;
113 7 dgisselq
        }
114
 
115
        void    tick(void) {
116 28 dgisselq
                if ((!m_fft->i_ce)||(m_fft->i_rst))
117
                        printf("TICK(%s,%s)\n",
118
                                (m_fft->i_rst)?"RST":"   ",
119
                                (m_fft->i_ce)?"CE":"  ");
120 7 dgisselq
                m_fft->i_clk = 0;
121
                m_fft->eval();
122
                m_fft->i_clk = 1;
123
                m_fft->eval();
124 26 dgisselq
 
125 28 dgisselq
                m_tickcount++;
126
 
127 26 dgisselq
                /*
128
                int nrpt = (rand()&0x01f) + 1;
129
                m_fft->i_ce = 0;
130
                for(int i=0; i<nrpt; i++) {
131
                        m_fft->i_clk = 0;
132
                        m_fft->eval();
133
                        m_fft->i_clk = 1;
134
                        m_fft->eval();
135
                }
136
                */
137 7 dgisselq
        }
138
 
139
        void    reset(void) {
140
                m_fft->i_ce  = 0;
141
                m_fft->i_rst = 1;
142
                tick();
143
                m_fft->i_rst = 0;
144
                tick();
145 9 dgisselq
 
146 26 dgisselq
                m_iaddr = m_oaddr = m_logbase = 0;
147 9 dgisselq
                m_syncd = false;
148 28 dgisselq
                m_tickcount = 0l;
149 7 dgisselq
        }
150
 
151 9 dgisselq
        long    twos_complement(const long val, const int bits) {
152 23 dgisselq
                return sbits(val, bits);
153 9 dgisselq
        }
154
 
155
        void    checkresults(void) {
156
                double  *dp, *sp; // Complex array
157
                double  vout[FFTLEN*2];
158
                double  isq=0.0, osq = 0.0;
159 28 dgisselq
                ITYP    *lp;
160 9 dgisselq
 
161
                // Fill up our test array from the log array
162 26 dgisselq
                printf("%3d : CHECK: %8d %5x m_log[-%x=%x]\n", m_ntest, m_iaddr, m_iaddr,
163
                        m_logbase, (m_iaddr-m_logbase)&((NFTLOG*FFTLEN-1)&(-FFTLEN)));
164 28 dgisselq
 
165
                // Convert our logged data into doubles, in an FFT buffer
166 26 dgisselq
                dp = m_fft_buf; lp = &m_log[(m_iaddr-m_logbase)&((NFTLOG*FFTLEN-1)&(-FFTLEN))];
167 9 dgisselq
                for(int i=0; i<FFTLEN; i++) {
168 28 dgisselq
                        ITYP    tv = *lp++;
169 9 dgisselq
 
170 28 dgisselq
                        dp[0] = sbits((long)tv >> IWIDTH, IWIDTH);
171
                        dp[1] = sbits((long)tv, IWIDTH);
172 9 dgisselq
 
173 16 dgisselq
                        // printf("IN[%4d = %4x] = %9.1f %9.1f\n",
174
                                // i+((m_iaddr-FFTLEN*3)&((4*FFTLEN-1)&(-FFTLEN))),
175
                                // i+((m_iaddr-FFTLEN*3)&((4*FFTLEN-1)&(-FFTLEN))),
176
                                // dp[0], dp[1]);
177 9 dgisselq
                        dp += 2;
178
                }
179
 
180
                // Let's measure ... are we the zero vector?  If not, how close?
181
                dp = m_fft_buf;
182 26 dgisselq
                for(int i=0; i<FFTLEN*2; i++) {
183
                        isq += (*dp) * (*dp); dp++;
184
                }
185 9 dgisselq
 
186
                fftw_execute(m_plan);
187
 
188 28 dgisselq
                // Let's load up the output we received into double valued
189
                // array vout
190 9 dgisselq
                dp = vout;
191
                for(int i=0; i<FFTLEN; i++) {
192 26 dgisselq
                        *dp = rdata(i);
193 9 dgisselq
                        osq += (*dp) * (*dp); dp++;
194 26 dgisselq
                        *dp = idata(i);
195 9 dgisselq
                        osq += (*dp) * (*dp); dp++;
196
                }
197
 
198
 
199
                // Let's figure out if there's a scale factor difference ...
200
                double  scale = 0.0, wt = 0.0;
201
                sp = m_fft_buf;  dp = vout;
202
                for(int i=0; i<FFTLEN*2; i++) {
203
                        scale += (*sp) * (*dp++);
204
                        wt += (*sp) * (*sp); sp++;
205
                } scale = scale / wt;
206
 
207 28 dgisselq
                if (fabs(scale) <= 1./4./FFTLEN)
208
                        scale = 2./(FFTLEN);
209
                else if (wt == 0.0) scale = 1.0;
210 9 dgisselq
 
211
                double xisq = 0.0;
212
                sp = m_fft_buf;  dp = vout;
213 26 dgisselq
 
214
                if ((true)&&(m_dumpfp)) {
215
                        double  tmp[FFTLEN*2], nscl;
216
 
217
                        if (fabs(scale) < 1e-4)
218
                                nscl = 1.0;
219
                        else
220
                                nscl = scale;
221
                        for(int i=0; i<FFTLEN*2; i++)
222
                                tmp[i] = m_fft_buf[i] * nscl;
223
                        fwrite(tmp, sizeof(double), FFTLEN*2, m_dumpfp);
224
                }
225
 
226 9 dgisselq
                for(int i=0; i<FFTLEN*2; i++) {
227
                        double vl = (*sp++) * scale - (*dp++);
228
                        xisq += vl * vl;
229
                }
230
 
231
                printf("%3d : SCALE = %12.6f, WT = %18.1f, ISQ = %15.1f, ",
232
                        m_ntest, scale, wt, isq);
233
                printf("OSQ = %18.1f, ", osq);
234
                printf("XISQ = %18.1f\n", xisq);
235 19 dgisselq
                if (xisq > 1.4 * FFTLEN/2) {
236 16 dgisselq
                        printf("TEST FAIL!!  Result is out of bounds from ");
237
                        printf("expected result with FFTW3.\n");
238 23 dgisselq
                        // exit(-2);
239 16 dgisselq
                }
240 9 dgisselq
                m_ntest++;
241
        }
242
 
243 28 dgisselq
        bool    test(ITYP lft, ITYP rht) {
244 7 dgisselq
                m_fft->i_ce    = 1;
245
                m_fft->i_rst   = 0;
246
                m_fft->i_left  = lft;
247
                m_fft->i_right = rht;
248
 
249 28 dgisselq
                m_log[(m_iaddr++)&(NFTLOG*FFTLEN-1)] = lft;
250
                m_log[(m_iaddr++)&(NFTLOG*FFTLEN-1)] = rht;
251 9 dgisselq
 
252 7 dgisselq
                tick();
253
 
254
                if (m_fft->o_sync) {
255 26 dgisselq
                        if (!m_syncd) {
256 28 dgisselq
                                m_syncd = true;
257
                                printf("ORIGINAL SYNC AT 0x%lx, m_oaddr set to 0x%x\n", m_tickcount, m_oaddr);
258 26 dgisselq
                                m_logbase = m_iaddr;
259 28 dgisselq
                        } else printf("RESYNC AT %lx\n", m_tickcount);
260 9 dgisselq
                        m_oaddr &= (-1<<LGWIDTH);
261
                } else m_oaddr += 2;
262 7 dgisselq
 
263 28 dgisselq
                printf("%8x,%5d: %08x,%08x -> %011lx,%011lx\t",
264 26 dgisselq
                        m_iaddr, m_oaddr,
265
                        lft, rht, m_fft->o_left, m_fft->o_right);
266 28 dgisselq
 
267
        /*
268
                printf(" %011lx,%011lx", m_fft->v__DOT__w_e2048,
269
                        m_fft->v__DOT__w_o2048);
270
 
271
                printf(" BF(%d,%11x,%11x,%11lx -> %d,%03x,%8x,%8x)", // %d,%11x,%11x)",
272
                        m_fft->v__DOT__stage_o2048__DOT__ib_sync,
273
                        m_fft->v__DOT__stage_o2048__DOT__ib_a,
274
                        m_fft->v__DOT__stage_o2048__DOT__ib_b,
275
                        m_fft->v__DOT__stage_o2048__DOT__ib_c,
276
                        m_fft->v__DOT__stage_o2048__DOT__ob_sync,
277
                        m_fft->v__DOT__stage_o2048__DOT__oB,
278
                        m_fft->v__DOT__stage_o2048__DOT__bfly__DOT__rnd_left_r,
279
                        m_fft->v__DOT__stage_o2048__DOT__bfly__DOT__rnd_right_r);
280
        */
281
 
282
#ifndef APPLY_BITREVERSE_LOCALLY
283
                printf(" [%3x]%s", m_fft->v__DOT__revstage__DOT__iaddr,
284
                        (m_fft->v__DOT__br_sync)?"S"
285
                                :((m_fft->v__DOT__r_br_started)?".":"x"));
286
#endif
287
 
288
                printf(" ");
289
#if (FFT_SIZE>=2048)
290
                printf("%s", (m_fft->v__DOT__w_s2048)?"S":"-");
291
#endif
292
#if (FFT_SIZE>1024)
293
                printf("%s", (m_fft->v__DOT__w_s1024)?"S":"-");
294
#endif
295
#if (FFT_SIZE>512)
296
                printf("%s", (m_fft->v__DOT__w_s512)?"S":"-");
297
#endif
298
#if (FFT_SIZE>256)
299
                printf("%s", (m_fft->v__DOT__w_s256)?"S":"-");
300
#endif
301
#if (FFT_SIZE>128)
302
                printf("%s", (m_fft->v__DOT__w_s128)?"S":"-");
303
#endif
304
#if (FFT_SIZE>64)
305
                printf("%s", (m_fft->v__DOT__w_s64)?"S":"-");
306
#endif
307
#if (FFT_SIZE>32)
308
                printf("%s", (m_fft->v__DOT__w_s32)?"S":"-");
309
#endif
310
#if (FFT_SIZE>16)
311
                printf("%s", (m_fft->v__DOT__w_s16)?"S":"-");
312
#endif
313
#if (FFT_SIZE>8)
314
                printf("%s", (m_fft->v__DOT__w_s8)?"S":"-");
315
#endif
316
#if (FFT_SIZE>4)
317
                printf("%s", (m_fft->v__DOT__w_s4)?"S":"-");
318
#endif
319
 
320
                printf(" %s%s\n",
321 9 dgisselq
                        (m_fft->o_sync)?"\t(SYNC!)":"",
322
                        (m_fft->o_left | m_fft->o_right)?"  (NZ)":"");
323 7 dgisselq
 
324 9 dgisselq
                m_data[(m_oaddr  )&(FFTLEN-1)] = m_fft->o_left;
325
                m_data[(m_oaddr+1)&(FFTLEN-1)] = m_fft->o_right;
326 7 dgisselq
 
327 9 dgisselq
                if ((m_syncd)&&((m_oaddr&(FFTLEN-1)) == FFTLEN-2)) {
328 7 dgisselq
                        dumpwrite();
329 9 dgisselq
                        checkresults();
330
                }
331 7 dgisselq
 
332
                return (m_fft->o_sync);
333
        }
334
 
335
        bool    test(double lft_r, double lft_i, double rht_r, double rht_i) {
336 28 dgisselq
                ITYP    ilft, irht, ilft_r, ilft_i, irht_r, irht_i;
337 7 dgisselq
 
338 28 dgisselq
                ilft_r = (ITYP)(lft_r) & ((1<<IWIDTH)-1);
339
                ilft_i = (ITYP)(lft_i) & ((1<<IWIDTH)-1);
340
                irht_r = (ITYP)(rht_r) & ((1<<IWIDTH)-1);
341
                irht_i = (ITYP)(rht_i) & ((1<<IWIDTH)-1);
342 7 dgisselq
 
343
                ilft = (ilft_r << IWIDTH) | ilft_i;
344
                irht = (irht_r << IWIDTH) | irht_i;
345
 
346
                return test(ilft, irht);
347
        }
348
 
349
        double  rdata(int addr) {
350 26 dgisselq
                int     index = addr & (FFTLEN-1);
351
 
352 28 dgisselq
#ifdef  APPLY_BITREVERSE_LOCALLY
353
                index = bitrev(LGWIDTH, index);
354
#endif
355 26 dgisselq
                return (double)sbits(m_data[index]>>OWIDTH, OWIDTH);
356 7 dgisselq
        }
357
 
358
        double  idata(int addr) {
359 26 dgisselq
                int     index = addr & (FFTLEN-1);
360
 
361 28 dgisselq
#ifdef  APPLY_BITREVERSE_LOCALLY
362
                index = bitrev(LGWIDTH, index);
363
#endif
364 26 dgisselq
                return (double)sbits(m_data[index], OWIDTH);
365 7 dgisselq
        }
366
 
367
        void    dump(FILE *fp) {
368
                m_dumpfp = fp;
369
        }
370
 
371
        void    dumpwrite(void) {
372
                if (!m_dumpfp)
373
                        return;
374
 
375
                double  *buf;
376
 
377
                buf = new double[FFTLEN * 2];
378
                for(int i=0; i<FFTLEN; i++) {
379
                        buf[i*2] = rdata(i);
380
                        buf[i*2+1] = idata(i);
381
                }
382
 
383
                fwrite(buf, sizeof(double), FFTLEN*2, m_dumpfp);
384
                delete[] buf;
385
        }
386
};
387
 
388 9 dgisselq
 
389 7 dgisselq
int     main(int argc, char **argv, char **envp) {
390
        Verilated::commandArgs(argc, argv);
391
        FFT_TB *fft = new FFT_TB;
392
        FILE    *fpout;
393
 
394
        fpout = fopen("fft_tb.dbl", "w");
395
        if (NULL == fpout) {
396
                fprintf(stderr, "Cannot write output file, fft_tb.dbl\n");
397
                exit(-1);
398
        }
399
 
400
        fft->reset();
401 28 dgisselq
 
402
        {
403
                int     ftlen = FFTLEN;
404
                fwrite(&ftlen, 1, sizeof(int), fpout);
405
        }
406 7 dgisselq
        fft->dump(fpout);
407
 
408 26 dgisselq
        // 1.
409
        fft->test(0.0, 0.0, 32767.0, 0.0);
410
        for(int k=0; k<FFTLEN/2-1; k++)
411
                fft->test(0.0,0.0,0.0,0.0);
412
 
413 28 dgisselq
        // 2. Try placing a pulse at the very end location
414
        for(int k=0; k<FFTLEN/2; k++) {
415
                double cl, cr, sl, sr, W;
416
                W = - 2.0 * M_PI / FFTLEN * (1);
417
                cl = cos(W * (2*k  )) * 16383.0;
418
                sl = sin(W * (2*k  )) * 16383.0;
419
                cr = cos(W * (2*k+1)) * 16383.0;
420
                sr = sin(W * (2*k+1)) * 16383.0;
421
                fft->test(cl, sl, cr, sr);
422
        }
423
 
424 26 dgisselq
        // 2. 
425
        fft->test(32767.0, 0.0, 32767.0, 0.0);
426
        for(int k=0; k<FFTLEN/2-1; k++)
427
                fft->test(0.0,0.0,0.0,0.0);
428
 
429
        // 3. 
430
        fft->test(0.0,0.0,0.0,0.0);
431
        fft->test(32767.0, 0.0, 0.0, 0.0);
432
        for(int k=0; k<FFTLEN/2-1; k++)
433
                fft->test(0.0,0.0,0.0,0.0);
434
 
435
        // 4.
436
        for(int k=0; k<8; k++)
437
                fft->test(32767.0, 0.0, 32767.0, 0.0);
438
        for(int k=8; k<FFTLEN/2; k++)
439
                fft->test(0.0,0.0,0.0,0.0);
440
 
441
        // 5.
442
        if (FFTLEN/2 >= 16) {
443
                for(int k=0; k<16; k++)
444
                        fft->test(32767.0, 0.0, 32767.0, 0.0);
445
                for(int k=16; k<FFTLEN/2; k++)
446
                        fft->test(0.0,0.0,0.0,0.0);
447
        }
448
 
449
        // 6.
450
        if (FFTLEN/2 >= 32) {
451
                for(int k=0; k<32; k++)
452
                        fft->test(32767.0, 0.0, 32767.0, 0.0);
453
                for(int k=32; k<FFTLEN/2; k++)
454
                        fft->test(0.0,0.0,0.0,0.0);
455
        }
456
 
457
        // 7.
458
        if (FFTLEN/2 >= 64) {
459
                for(int k=0; k<64; k++)
460
                        fft->test(32767.0, 0.0, 32767.0, 0.0);
461
                for(int k=64; k<FFTLEN/2; k++)
462
                        fft->test(0.0,0.0,0.0,0.0);
463
        }
464
 
465
        if (FFTLEN/2 >= 128) {
466
                for(int k=0; k<128; k++)
467
                        fft->test(32767.0, 0.0, 32767.0, 0.0);
468
                for(int k=128; k<FFTLEN/2; k++)
469
                        fft->test(0.0,0.0,0.0,0.0);
470
        }
471
 
472
        if (FFTLEN/2 >= 256) {
473
                for(int k=0; k<256; k++)
474
                        fft->test(32767.0, 0.0, 32767.0, 0.0);
475
                for(int k=256; k<FFTLEN/2; k++)
476
                        fft->test(0.0,0.0,0.0,0.0);
477
        }
478
 
479
        if (FFTLEN/2 >= 512) {
480
                for(int k=0; k<256+128; k++)
481
                        fft->test(32767.0, 0.0, 32767.0, 0.0);
482
                for(int k=256+128; k<FFTLEN/2; k++)
483
                        fft->test(0.0,0.0,0.0,0.0);
484
        }
485
 
486
        /*
487
        for(int k=0; k<FFTLEN/2; k++)
488
                fft->test(0.0,0.0,0.0,0.0);
489
 
490
        for(int k=0; k<FFTLEN/2; k++)
491
                fft->test(0.0,0.0,0.0,0.0);
492
 
493
        for(int k=0; k<FFTLEN/2; k++)
494
                fft->test(0.0,0.0,0.0,0.0);
495
 
496
        for(int k=0; k<FFTLEN/2; k++)
497
                fft->test(0.0,0.0,0.0,0.0);
498
 
499
        for(int k=0; k<FFTLEN/2; k++)
500
                fft->test(0.0,0.0,0.0,0.0);
501
 
502
        for(int k=0; k<FFTLEN/2; k++)
503
                fft->test(0.0,0.0,0.0,0.0);
504
        */
505
 
506
#ifndef NO_JUNK
507
        // 7.
508
 
509 9 dgisselq
        //     1 -> 0x0001 
510
        //     2 -> 0x0002 
511
        //     4 -> 0x0004 
512
        //     8 -> 0x0008 
513
        //    16 -> 0x0010 
514
        //    32 -> 0x0020 
515
        //    64 -> 0x0040 
516
        //   128 -> 0x0080 
517
        //   256 -> 0x0100 
518
        //   512 -> 0x0200 
519
        //  1024 -> 0x0400 
520
        //  2048 -> 0x0800
521
        //  4096 -> 0x1000
522
        //  8192 -> 0x2000
523
        // 16384 -> 0x4000
524
        for(int v=1; v<32768; v<<=1) for(int k=0; k<FFTLEN/2; k++)
525
                fft->test((double)v,0.0,(double)v,0.0);
526
        //     1 -> 0xffff      
527
        //     2 -> 0xfffe
528
        //     4 -> 0xfffc
529
        //     8 -> 0xfff8
530
        //    16 -> 0xfff0
531
        //    32 -> 0xffe0
532
        //    64 -> 0xffc0
533
        //   128 -> 0xff80
534
        //   256 -> 0xff00
535
        //   512 -> 0xfe00
536
        //  1024 -> 0xfc00
537
        //  2048 -> 0xf800
538
        //  4096 -> 0xf000
539
        //  8192 -> 0xe000
540
        // 16384 -> 0xc000
541
        // 32768 -> 0x8000
542 26 dgisselq
        fft->test(0.0,0.0,16384.0,0.0);
543
        for(int k=0; k<FFTLEN/2-1; k++)
544
                fft->test(0.0,0.0,0.0,0.0);
545
 
546 9 dgisselq
        for(int v=1; v<=32768; v<<=1) for(int k=0; k<FFTLEN/2; k++)
547
                fft->test(-(double)v,0.0,-(double)v,0.0);
548
        //     1 -> 0x000040    CORRECT!!
549
        //     2 -> 0x000080 
550
        //     4 -> 0x000100 
551
        //     8 -> 0x000200
552
        //    16 -> 0x000400
553
        //    32 -> 0x000800
554
        //    64 -> 0x001000
555
        //   128 -> 0x002000
556
        //   256 -> 0x004000
557
        //   512 -> 0x008000
558
        //  1024 -> 0x010000
559
        //  2048 -> 0x020000
560
        //  4096 -> 0x040000
561
        //  8192 -> 0x080000
562
        // 16384 -> 0x100000
563
        for(int v=1; v<32768; v<<=1) for(int k=0; k<FFTLEN/2; k++)
564
                fft->test(0.0,(double)v,0.0,(double)v);
565
        //     1 -> 0x3fffc0
566
        //     2 -> 0x3fff80
567
        //     4 -> 0x3fff00
568
        //     8 -> 0x3ffe00
569
        //    16 -> 0x3ffc00
570
        //    32 -> 0x3ff800
571
        //    64 -> 0x3ff000
572
        //   128 -> 0x3fe000
573
        //   256 -> 0x3fc000
574
        //   512 -> 0x3f8000
575
        //  1024 -> 0x3f0000
576
        //  2048 -> 0x3e0000
577
        //  4096 -> 0x3c0000
578
        //  8192 -> 0x380000
579
        // 16384 -> 0x300000
580
        for(int v=1; v<32768; v<<=1) for(int k=0; k<FFTLEN/2; k++)
581
                fft->test(0.0,-(double)v,0.0,-(double)v);
582
 
583
        // 61. Now, how about the smallest alternating real signal
584 7 dgisselq
        for(int k=0; k<FFTLEN/2; k++)
585 9 dgisselq
                fft->test(2.0,0.0,0.0,0.0); // Don't forget to expect a bias!
586
        // 62. Now, how about the smallest alternating imaginary signal
587 7 dgisselq
        for(int k=0; k<FFTLEN/2; k++)
588 9 dgisselq
                fft->test(0.0,2.0,0.0,0.0); // Don't forget to expect a bias!
589
        // 63. Now, how about the smallest alternating real signal,2nd phase
590 7 dgisselq
        for(int k=0; k<FFTLEN/2; k++)
591 9 dgisselq
                fft->test(0.0,0.0,2.0,0.0); // Don't forget to expect a bias!
592
        // 64.Now, how about the smallest alternating imaginary signal,2nd phase
593 7 dgisselq
        for(int k=0; k<FFTLEN/2; k++)
594 9 dgisselq
                fft->test(0.0,0.0,0.0,2.0); // Don't forget to expect a bias!
595
 
596
        // 65.
597 7 dgisselq
        for(int k=0; k<FFTLEN/2; k++)
598 9 dgisselq
                fft->test(32767.0,0.0,-32767.0,0.0);
599
        // 66.
600 7 dgisselq
        for(int k=0; k<FFTLEN/2; k++)
601 9 dgisselq
                fft->test(0.0,-32767.0,0.0,32767.0);
602
        // 67.
603 7 dgisselq
        for(int k=0; k<FFTLEN/2; k++)
604 9 dgisselq
                fft->test(-32768.0,-32768.0,-32768.0,-32768.0);
605
        // 68.
606 7 dgisselq
        for(int k=0; k<FFTLEN/2; k++)
607 9 dgisselq
                fft->test(0.0,-32767.0,0.0,32767.0);
608
        // 69.
609 7 dgisselq
        for(int k=0; k<FFTLEN/2; k++)
610 9 dgisselq
                fft->test(0.0,32767.0,0.0,-32767.0);
611
        // 70. 
612
        for(int k=0; k<FFTLEN/2; k++)
613 7 dgisselq
                fft->test(-32768.0,-32768.0,-32768.0,-32768.0);
614
 
615 9 dgisselq
        // 71. Now let's go for an impulse (SUCCESS)
616
        fft->test(16384.0, 0.0, 0.0, 0.0);
617
        for(int k=0; k<FFTLEN/2-1; k++)
618 7 dgisselq
                fft->test(0.0,0.0,0.0,0.0);
619
 
620 9 dgisselq
        // 72. And another one on the next clock (FAILS, ugly)
621
        fft->test(0.0, 0.0, 16384.0, 0.0);
622
        for(int k=0; k<FFTLEN/2-1; k++)
623
                fft->test(0.0,0.0,0.0,0.0);
624 7 dgisselq
 
625 26 dgisselq
        // 72. And another one on the next clock (FAILS, ugly)
626
        fft->test(0.0, 0.0,  8192.0, 0.0);
627
        for(int k=0; k<FFTLEN/2-1; k++)
628
                fft->test(0.0,0.0,0.0,0.0);
629
 
630
        // 72. And another one on the next clock (FAILS, ugly)
631
        fft->test(0.0, 0.0,   512.0, 0.0);
632
        for(int k=0; k<FFTLEN/2-1; k++)
633
                fft->test(0.0,0.0,0.0,0.0);
634
 
635 9 dgisselq
        // 73. And an imaginary one on the second clock
636
        fft->test(0.0, 0.0, 0.0, 16384.0);
637
        for(int k=0; k<FFTLEN/2-1; k++)
638
                fft->test(0.0,0.0,0.0,0.0);
639 7 dgisselq
 
640 9 dgisselq
        // 74. Likewise the next clock
641
        fft->test(0.0,0.0,0.0,0.0);
642
        fft->test(16384.0, 0.0, 0.0, 0.0);
643
        for(int k=0; k<FFTLEN/2-2; k++)
644
                fft->test(0.0,0.0,0.0,0.0);
645 7 dgisselq
 
646 9 dgisselq
        // 75. And it's imaginary counterpart
647
        fft->test(0.0,0.0,0.0,0.0);
648
        fft->test(0.0, 16384.0, 0.0, 0.0);
649
        for(int k=0; k<FFTLEN/2-2; k++)
650
                fft->test(0.0,0.0,0.0,0.0);
651
 
652
        // 76. Likewise the next clock
653
        fft->test(0.0,0.0,0.0,0.0);
654
        fft->test(0.0, 0.0, 16384.0, 0.0);
655
        for(int k=0; k<FFTLEN/2-2; k++)
656
                fft->test(0.0,0.0,0.0,0.0);
657
 
658
        // 77. And it's imaginary counterpart
659
        fft->test(0.0,0.0,0.0,0.0);
660
        fft->test(0.0, 0.0, 0.0, 16384.0);
661
        for(int k=0; k<FFTLEN/2-2; k++)
662
                fft->test(0.0,0.0,0.0,0.0);
663
 
664
 
665
        // 78. Now let's try some exponentials
666
        for(int k=0; k<FFTLEN/2; k++) {
667
                double cl, cr, sl, sr, W;
668
                W = - 2.0 * M_PI / FFTLEN;
669
                cl = cos(W * (2*k  )) * 16383.0;
670
                sl = sin(W * (2*k  )) * 16383.0;
671
                cr = cos(W * (2*k+1)) * 16383.0;
672
                sr = sin(W * (2*k+1)) * 16383.0;
673
                fft->test(cl, sl, cr, sr);
674
        }
675
 
676
        // 72.
677
        for(int k=0; k<FFTLEN/2; k++) {
678
                double cl, cr, sl, sr, W;
679
                W = - 2.0 * M_PI / FFTLEN * 5;
680
                cl = cos(W * (2*k  )) * 16383.0;
681
                sl = sin(W * (2*k  )) * 16383.0;
682
                cr = cos(W * (2*k+1)) * 16383.0;
683
                sr = sin(W * (2*k+1)) * 16383.0;
684
                fft->test(cl, sl, cr, sr);
685
        }
686
 
687
        // 73.
688
        for(int k=0; k<FFTLEN/2; k++) {
689
                double cl, cr, sl, sr, W;
690
                W = - 2.0 * M_PI / FFTLEN * 8;
691
                cl = cos(W * (2*k  )) * 8190.0;
692
                sl = sin(W * (2*k  )) * 8190.0;
693
                cr = cos(W * (2*k+1)) * 8190.0;
694
                sr = sin(W * (2*k+1)) * 8190.0;
695
                fft->test(cl, sl, cr, sr);
696
        }
697
 
698
        // 74.
699
        for(int k=0; k<FFTLEN/2; k++) {
700
                double cl, cr, sl, sr, W;
701
                W = - 2.0 * M_PI / FFTLEN * 25;
702
                cl = cos(W * (2*k  )) * 4.0;
703
                sl = sin(W * (2*k  )) * 4.0;
704
                cr = cos(W * (2*k+1)) * 4.0;
705
                sr = sin(W * (2*k+1)) * 4.0;
706
                fft->test(cl, sl, cr, sr);
707
        }
708 26 dgisselq
#endif
709 9 dgisselq
        // 19.--24. And finally, let's clear out our results / buffer
710
        for(int k=0; k<(FFTLEN/2) * 5; k++)
711
                fft->test(0.0,0.0,0.0,0.0);
712
 
713
 
714
 
715 7 dgisselq
        fclose(fpout);
716 16 dgisselq
 
717
        printf("SUCCESS!!\n");
718
        exit(0);
719 7 dgisselq
}
720
 
721 9 dgisselq
 

powered by: WebSVN 2.1.0

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