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

Subversion Repositories dblclockfft

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

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

powered by: WebSVN 2.1.0

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