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

Subversion Repositories dblclockfft

[/] [dblclockfft/] [trunk/] [bench/] [cpp/] [fft_tb.cpp] - Diff between revs 35 and 36

Go to most recent revision | Only display areas with differences | Details | Blame | View Log

Rev 35 Rev 36
//
//
// Filename:    fft_tb.cpp
// Filename:    fft_tb.cpp
//
//
// Project:     A Doubletime Pipelined FFT
// Project:     A Doubletime Pipelined FFT
//
//
// Purpose:     A test-bench for the main program, fftmain.v, of the double
// Purpose:     A test-bench for the main program, fftmain.v, of the double
//              clocked FFT.  This file may be run autonomously  (when
//              clocked FFT.  This file may be run autonomously  (when
//              fully functional).  If so, the last line output will either
//      fully functional).  If so, the last line output will either read
//              read "SUCCESS" on success, or some other failure message
//      "SUCCESS" on success, or some other failure message otherwise.
//              otherwise.
 
//
//
//              This file depends upon verilator to both compile, run, and
//      This file depends upon verilator to both compile, run, and therefore
//              therefore test fftmain.v
//      test fftmain.v
//
//
// Creator:     Dan Gisselquist, Ph.D.
// Creator:     Dan Gisselquist, Ph.D.
//              Gisselquist Technology, LLC
//              Gisselquist Technology, LLC
//
//
///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
//
//
// Copyright (C) 2015, Gisselquist Technology, LLC
// Copyright (C) 2015,2018, Gisselquist Technology, LLC
//
//
// This program is free software (firmware): you can redistribute it and/or
// This program is free software (firmware): you can redistribute it and/or
// modify it under the terms of  the GNU General Public License as published
// modify it under the terms of  the GNU General Public License as published
// by the Free Software Foundation, either version 3 of the License, or (at
// by the Free Software Foundation, either version 3 of the License, or (at
// your option) any later version.
// your option) any later version.
//
//
// This program is distributed in the hope that it will be useful, but WITHOUT
// This program is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY or
// ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY or
// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
// for more details.
// for more details.
//
//
// You should have received a copy of the GNU General Public License along
// You should have received a copy of the GNU General Public License along
// with this program.  (It's in the $(ROOT)/doc directory, run make with no
// with this program.  (It's in the $(ROOT)/doc directory, run make with no
// target there if the PDF file isn't present.)  If not, see
// target there if the PDF file isn't present.)  If not, see
// <http://www.gnu.org/licenses/> for a copy.
// <http://www.gnu.org/licenses/> for a copy.
//
//
// License:     GPL, v3, as defined and found on www.gnu.org,
// License:     GPL, v3, as defined and found on www.gnu.org,
//              http://www.gnu.org/licenses/gpl.html
//              http://www.gnu.org/licenses/gpl.html
//
//
//
//
///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
#include <stdio.h>
#include <stdio.h>
 
#include <stdlib.h>
#include <math.h>
#include <math.h>
#include <fftw3.h>
#include <fftw3.h>
 
 
#include "verilated.h"
#include "verilated.h"
 
#include "verilated_vcd_c.h"
#include "Vfftmain.h"
#include "Vfftmain.h"
#include "twoc.h"
#include "twoc.h"
 
 
#include "fftsize.h"
#include "fftsize.h"
 
 
 
 
#ifdef  NEW_VERILATOR
#ifdef  NEW_VERILATOR
#define VVAR(A) fftmain__DOT_ ## A
#define VVAR(A) fftmain__DOT_ ## A
#else
#else
#define VVAR(A) v__DOT_ ## A
#define VVAR(A) v__DOT_ ## A
#endif
#endif
 
 
 
#ifdef  DBLCLKFFT
#define revstage_iaddr  VVAR(_revstage__DOT__iaddr)
#define revstage_iaddr  VVAR(_revstage__DOT__iaddr)
 
#else
 
#define revstage_iaddr  VVAR(_revstage__DOT__wraddr)
 
#endif
#define br_sync         VVAR(_br_sync)
#define br_sync         VVAR(_br_sync)
#define br_started      VVAR(_r_br_started)
#define br_started      VVAR(_r_br_started)
#define w_s2048         VVAR(_w_s2048)
#define w_s2048         VVAR(_w_s2048)
#define w_s1024         VVAR(_w_s1024)
#define w_s1024         VVAR(_w_s1024)
#define w_s512          VVAR(_w_s512)
#define w_s512          VVAR(_w_s512)
#define w_s256          VVAR(_w_s256)
#define w_s256          VVAR(_w_s256)
#define w_s128          VVAR(_w_s128)
#define w_s128          VVAR(_w_s128)
#define w_s64           VVAR(_w_s64)
#define w_s64           VVAR(_w_s64)
#define w_s32           VVAR(_w_s32)
#define w_s32           VVAR(_w_s32)
#define w_s16           VVAR(_w_s16)
#define w_s16           VVAR(_w_s16)
#define w_s8            VVAR(_w_s8)
#define w_s8            VVAR(_w_s8)
#define w_s4            VVAR(_w_s4)
#define w_s4            VVAR(_w_s4)
 
 
 
 
#define IWIDTH  FFT_IWIDTH
#define IWIDTH  FFT_IWIDTH
#define OWIDTH  FFT_OWIDTH
#define OWIDTH  FFT_OWIDTH
#define LGWIDTH FFT_LGWIDTH
#define LGWIDTH FFT_LGWIDTH
 
 
#if (IWIDTH > 16)
#if (IWIDTH > 16)
typedef unsigned long   ITYP;
typedef unsigned long   ITYP;
#else
#else
typedef unsigned int    ITYP;
typedef unsigned int    ITYP;
#endif
#endif
 
 
#if (OWIDTH > 16)
#if (OWIDTH > 16)
typedef unsigned long   OTYP;
typedef unsigned long   OTYP;
#else
#else
typedef unsigned int    OTYP;
typedef unsigned int    OTYP;
#endif
#endif
 
 
#define NFTLOG  16
#define NFTLOG  16
#define FFTLEN  (1<<LGWIDTH)
#define FFTLEN  (1<<LGWIDTH)
 
 
#ifdef  FFT_SKIPS_BIT_REVERSE
#ifdef  FFT_SKIPS_BIT_REVERSE
#define APPLY_BITREVERSE_LOCALLY
#define APPLY_BITREVERSE_LOCALLY
#endif
#endif
 
 
unsigned long bitrev(const int nbits, const unsigned long vl) {
unsigned long bitrev(const int nbits, const unsigned long vl) {
        unsigned long   r = 0;
        unsigned long   r = 0;
        unsigned long   val = vl;
        unsigned long   val = vl;
 
 
        for(int k=0; k<nbits; k++) {
        for(int k=0; k<nbits; k++) {
                r<<= 1;
                r<<= 1;
                r |= (val & 1);
                r |= (val & 1);
                val >>= 1;
                val >>= 1;
        }
        }
 
 
        return r;
        return r;
}
}
 
 
class   FFT_TB {
class   FFT_TB {
public:
public:
        Vfftmain        *m_fft;
        Vfftmain        *m_fft;
        OTYP            m_data[FFTLEN];
        OTYP            m_data[FFTLEN];
        ITYP            m_log[NFTLOG*FFTLEN];
        ITYP            m_log[NFTLOG*FFTLEN];
        int             m_iaddr, m_oaddr, m_ntest, m_logbase;
        int             m_iaddr, m_oaddr, m_ntest, m_logbase;
        FILE            *m_dumpfp;
        FILE            *m_dumpfp;
        fftw_plan       m_plan;
        fftw_plan       m_plan;
        double          *m_fft_buf;
        double          *m_fft_buf;
        bool            m_syncd;
        bool            m_syncd;
        unsigned long   m_tickcount;
        unsigned long   m_tickcount;
 
        VerilatedVcdC*  m_trace;
 
 
        FFT_TB(void) {
        FFT_TB(void) {
                m_fft = new Vfftmain;
                m_fft = new Vfftmain;
 
                Verilated::traceEverOn(true);
                m_iaddr = m_oaddr = 0;
                m_iaddr = m_oaddr = 0;
                m_dumpfp = NULL;
                m_dumpfp = NULL;
 
 
                m_fft_buf = (double *)fftw_malloc(sizeof(fftw_complex)*(FFTLEN));
                m_fft_buf = (double *)fftw_malloc(sizeof(fftw_complex)*(FFTLEN));
                m_plan = fftw_plan_dft_1d(FFTLEN, (fftw_complex *)m_fft_buf,
                m_plan = fftw_plan_dft_1d(FFTLEN, (fftw_complex *)m_fft_buf,
                                (fftw_complex *)m_fft_buf,
                                (fftw_complex *)m_fft_buf,
                                FFTW_FORWARD, FFTW_MEASURE);
                                FFTW_FORWARD, FFTW_MEASURE);
                m_syncd = false;
                m_syncd = false;
                m_ntest = 0;
                m_ntest = 0;
 
        }
 
 
                m_tickcount = 0l;
        ~FFT_TB(void) {
 
                closetrace();
 
                delete m_fft;
 
                m_fft = NULL;
 
        }
 
 
 
        virtual void opentrace(const char *vcdname) {
 
                if (!m_trace) {
 
                        m_trace = new VerilatedVcdC;
 
                        m_fft->trace(m_trace, 99);
 
                        m_trace->open(vcdname);
 
                }
 
        }
 
 
 
        virtual void closetrace(void) {
 
                if (m_trace) {
 
                        m_trace->close();
 
                        delete m_trace;
 
                        m_trace = NULL;
 
                }
        }
        }
 
 
        void    tick(void) {
        void    tick(void) {
                if ((!m_fft->i_ce)||(m_fft->i_rst))
                m_tickcount++;
 
                if (m_fft->i_reset)
                        printf("TICK(%s,%s)\n",
                        printf("TICK(%s,%s)\n",
                                (m_fft->i_rst)?"RST":"   ",
                                (m_fft->i_reset)?"RST":"   ",
                                (m_fft->i_ce)?"CE":"  ");
                                (m_fft->i_ce)?"CE":"  ");
 
 
                m_fft->i_clk = 0;
                m_fft->i_clk = 0;
                m_fft->eval();
                m_fft->eval();
 
                if (m_trace)
 
                        m_trace->dump((vluint64_t)(10*m_tickcount-2));
                m_fft->i_clk = 1;
                m_fft->i_clk = 1;
                m_fft->eval();
                m_fft->eval();
 
                if (m_trace)
 
                        m_trace->dump((vluint64_t)(10*m_tickcount));
 
                m_fft->i_clk = 0;
 
                m_fft->eval();
 
                if (m_trace) {
 
                        m_trace->dump((vluint64_t)(10*m_tickcount+5));
 
                        m_trace->flush();
 
                }
 
        }
 
 
                m_tickcount++;
        void    cetick(void) {
 
                int     ce = m_fft->i_ce, nkce;
 
                tick();
 
 
                /*
                nkce = (rand()&1);
                int nrpt = (rand()&0x01f) + 1;
#ifdef  FFT_CKPCE
                m_fft->i_ce = 0;
                nkce += FFT_CKPCE;
                for(int i=0; i<nrpt; i++) {
#endif
                        m_fft->i_clk = 0;
                if ((ce)&&(nkce>0)) {
                        m_fft->eval();
                        m_fft->i_ce = 0;
                        m_fft->i_clk = 1;
                        for(int kce=1; kce < nkce; kce++)
                        m_fft->eval();
                                tick();
                }
                }
                */
 
 
                m_fft->i_ce = ce;
        }
        }
 
 
        void    reset(void) {
        void    reset(void) {
                m_fft->i_ce  = 0;
                m_fft->i_ce  = 0;
                m_fft->i_rst = 1;
                m_fft->i_reset = 1;
                tick();
                tick();
                m_fft->i_rst = 0;
                m_fft->i_reset = 0;
                tick();
                tick();
 
 
                m_iaddr = m_oaddr = m_logbase = 0;
                m_iaddr = m_oaddr = m_logbase = 0;
                m_syncd = false;
                m_syncd = false;
                m_tickcount = 0l;
                m_tickcount = 0l;
        }
        }
 
 
        long    twos_complement(const long val, const int bits) {
        long    twos_complement(const long val, const int bits) {
                return sbits(val, bits);
                return sbits(val, bits);
        }
        }
 
 
        void    checkresults(void) {
        void    checkresults(void) {
                double  *dp, *sp; // Complex array
                double  *dp, *sp; // Complex array
                double  vout[FFTLEN*2];
                double  vout[FFTLEN*2];
                double  isq=0.0, osq = 0.0;
                double  isq=0.0, osq = 0.0;
                ITYP    *lp;
                ITYP    *lp;
 
 
                // Fill up our test array from the log array
                // Fill up our test array from the log array
                printf("%3d : CHECK: %8d %5x m_log[-%x=%x]\n", m_ntest, m_iaddr, m_iaddr,
                printf("%3d : CHECK: %8d %5x m_log[-%x=%x]\n", m_ntest, m_iaddr, m_iaddr,
                        m_logbase, (m_iaddr-m_logbase)&((NFTLOG*FFTLEN-1)&(-FFTLEN)));
                        m_logbase, (m_iaddr-m_logbase)&((NFTLOG*FFTLEN-1)&(-FFTLEN)));
 
 
                // Convert our logged data into doubles, in an FFT buffer
                // Convert our logged data into doubles, in an FFT buffer
                dp = m_fft_buf; lp = &m_log[(m_iaddr-m_logbase)&((NFTLOG*FFTLEN-1)&(-FFTLEN))];
                dp = m_fft_buf; lp = &m_log[(m_iaddr-m_logbase)&((NFTLOG*FFTLEN-1)&(-FFTLEN))];
                for(int i=0; i<FFTLEN; i++) {
                for(int i=0; i<FFTLEN; i++) {
                        ITYP    tv = *lp++;
                        ITYP    tv = *lp++;
 
 
                        dp[0] = sbits((long)tv >> IWIDTH, IWIDTH);
                        dp[0] = sbits((long)tv >> IWIDTH, IWIDTH);
                        dp[1] = sbits((long)tv, IWIDTH);
                        dp[1] = sbits((long)tv, IWIDTH);
 
 
                        // printf("IN[%4d = %4x] = %9.1f %9.1f\n",
                        // printf("IN[%4d = %4x] = %9.1f %9.1f\n",
                                // i+((m_iaddr-FFTLEN*3)&((4*FFTLEN-1)&(-FFTLEN))),
                                // i+((m_iaddr-FFTLEN*3)&((4*FFTLEN-1)&(-FFTLEN))),
                                // i+((m_iaddr-FFTLEN*3)&((4*FFTLEN-1)&(-FFTLEN))),
                                // i+((m_iaddr-FFTLEN*3)&((4*FFTLEN-1)&(-FFTLEN))),
                                // dp[0], dp[1]);
                                // dp[0], dp[1]);
                        dp += 2;
                        dp += 2;
                }
                }
 
 
                // Let's measure ... are we the zero vector?  If not, how close?
                // Let's measure ... are we the zero vector?  If not, how close?
                dp = m_fft_buf;
                dp = m_fft_buf;
                for(int i=0; i<FFTLEN*2; i++) {
                for(int i=0; i<FFTLEN*2; i++) {
                        isq += (*dp) * (*dp); dp++;
                        isq += (*dp) * (*dp); dp++;
                }
                }
 
 
                fftw_execute(m_plan);
                fftw_execute(m_plan);
 
 
                // Let's load up the output we received into double valued
                // Let's load up the output we received into double valued
                // array vout
                // array vout
                dp = vout;
                dp = vout;
                for(int i=0; i<FFTLEN; i++) {
                for(int i=0; i<FFTLEN; i++) {
                        *dp = rdata(i);
                        *dp = rdata(i);
                        osq += (*dp) * (*dp); dp++;
                        osq += (*dp) * (*dp); dp++;
                        *dp = idata(i);
                        *dp = idata(i);
                        osq += (*dp) * (*dp); dp++;
                        osq += (*dp) * (*dp); dp++;
                }
                }
 
 
 
 
                // Let's figure out if there's a scale factor difference ...
                // Let's figure out if there's a scale factor difference ...
                double  scale = 0.0, wt = 0.0;
                double  scale = 0.0, wt = 0.0;
                sp = m_fft_buf;  dp = vout;
                sp = m_fft_buf;  dp = vout;
                for(int i=0; i<FFTLEN*2; i++) {
                for(int i=0; i<FFTLEN*2; i++) {
                        scale += (*sp) * (*dp++);
                        scale += (*sp) * (*dp++);
                        wt += (*sp) * (*sp); sp++;
                        wt += (*sp) * (*sp); sp++;
                } scale = scale / wt;
                } scale = scale / wt;
 
 
                if (fabs(scale) <= 1./4./FFTLEN)
                if (fabs(scale) <= 1./4./FFTLEN)
                        scale = 2./(FFTLEN);
                        scale = 2./(FFTLEN);
                else if (wt == 0.0) scale = 1.0;
                else if (wt == 0.0) scale = 1.0;
 
 
                double xisq = 0.0;
                double xisq = 0.0;
                sp = m_fft_buf;  dp = vout;
                sp = m_fft_buf;  dp = vout;
 
 
                if ((true)&&(m_dumpfp)) {
                if ((true)&&(m_dumpfp)) {
                        double  tmp[FFTLEN*2], nscl;
                        double  tmp[FFTLEN*2], nscl;
 
 
                        if (fabs(scale) < 1e-4)
                        if (fabs(scale) < 1e-4)
                                nscl = 1.0;
                                nscl = 1.0;
                        else
                        else
                                nscl = scale;
                                nscl = scale;
                        for(int i=0; i<FFTLEN*2; i++)
                        for(int i=0; i<FFTLEN*2; i++)
                                tmp[i] = m_fft_buf[i] * nscl;
                                tmp[i] = m_fft_buf[i] * nscl;
                        fwrite(tmp, sizeof(double), FFTLEN*2, m_dumpfp);
                        fwrite(tmp, sizeof(double), FFTLEN*2, m_dumpfp);
                }
                }
 
 
                for(int i=0; i<FFTLEN*2; i++) {
                for(int i=0; i<FFTLEN*2; i++) {
                        double vl = (*sp++) * scale - (*dp++);
                        double vl = (*sp++) * scale - (*dp++);
                        xisq += vl * vl;
                        xisq += vl * vl;
                }
                }
 
 
                printf("%3d : SCALE = %12.6f, WT = %18.1f, ISQ = %15.1f, ",
                printf("%3d : SCALE = %12.6f, WT = %18.1f, ISQ = %15.1f, ",
                        m_ntest, scale, wt, isq);
                        m_ntest, scale, wt, isq);
                printf("OSQ = %18.1f, ", osq);
                printf("OSQ = %18.1f, ", osq);
                printf("XISQ = %18.1f\n", xisq);
                printf("XISQ = %18.1f, sqrt = %9.2f\n", xisq, sqrt(xisq));
                if (xisq > 1.4 * FFTLEN/2) {
                if (xisq > 1.4 * FFTLEN/2) {
                        printf("TEST FAIL!!  Result is out of bounds from ");
                        printf("TEST FAIL!!  Result is out of bounds from ");
                        printf("expected result with FFTW3.\n");
                        printf("expected result with FFTW3.\n");
                        // exit(-2);
                        // exit(EXIT_FAILURE);
                }
                }
                m_ntest++;
                m_ntest++;
        }
        }
 
 
 
#ifdef  DBLCLKFFT
        bool    test(ITYP lft, ITYP rht) {
        bool    test(ITYP lft, ITYP rht) {
                m_fft->i_ce    = 1;
                m_fft->i_ce    = 1;
                m_fft->i_rst   = 0;
                m_fft->i_reset = 0;
                m_fft->i_left  = lft;
                m_fft->i_left  = lft;
                m_fft->i_right = rht;
                m_fft->i_right = rht;
 
 
                m_log[(m_iaddr++)&(NFTLOG*FFTLEN-1)] = lft;
                m_log[(m_iaddr++)&(NFTLOG*FFTLEN-1)] = lft;
                m_log[(m_iaddr++)&(NFTLOG*FFTLEN-1)] = rht;
                m_log[(m_iaddr++)&(NFTLOG*FFTLEN-1)] = rht;
 
 
                tick();
                cetick();
 
 
                if (m_fft->o_sync) {
                if (m_fft->o_sync) {
                        if (!m_syncd) {
                        if (!m_syncd) {
                                m_syncd = true;
                                m_syncd = true;
                                printf("ORIGINAL SYNC AT 0x%lx, m_oaddr set to 0x%x\n", m_tickcount, m_oaddr);
                                printf("ORIGINAL SYNC AT 0x%lx, m_oaddr set to 0x%x\n", m_tickcount, m_oaddr);
                                m_logbase = m_iaddr;
                                m_logbase = m_iaddr;
                        } else printf("RESYNC AT %lx\n", m_tickcount);
                        } else printf("RESYNC AT %lx\n", m_tickcount);
                        m_oaddr &= (-1<<LGWIDTH);
                        m_oaddr &= (-1<<LGWIDTH);
                } else m_oaddr += 2;
                } else m_oaddr += 2;
 
 
                printf("%8x,%5d: %08x,%08x -> %011lx,%011lx\t",
                printf("%8x,%5d: %08x,%08x -> %011lx,%011lx\t",
                        m_iaddr, m_oaddr,
                        m_iaddr, m_oaddr,
                        lft, rht, m_fft->o_left, m_fft->o_right);
                        lft, rht, m_fft->o_left, m_fft->o_right);
 
 
#ifndef APPLY_BITREVERSE_LOCALLY
#ifndef APPLY_BITREVERSE_LOCALLY
                printf(" [%3x]%s", m_fft->revstage_iaddr,
                printf(" [%3x]%s", m_fft->revstage_iaddr,
                        (m_fft->br_sync)?"S"
                        (m_fft->br_sync)?"S"
                                :((m_fft->br_started)?".":"x"));
                                :((m_fft->br_started)?".":"x"));
#endif
#endif
 
 
                printf(" ");
                printf(" ");
#if (FFT_SIZE>=2048)
#if (FFT_SIZE>=2048)
                printf("%s", (m_fft->w_s2048)?"S":"-");
                printf("%s", (m_fft->w_s2048)?"S":"-");
#endif
#endif
#if (FFT_SIZE>1024)
#if (FFT_SIZE>1024)
                printf("%s", (m_fft->w_s1024)?"S":"-");
                printf("%s", (m_fft->w_s1024)?"S":"-");
#endif
#endif
#if (FFT_SIZE>512)
#if (FFT_SIZE>512)
                printf("%s", (m_fft->w_s512)?"S":"-");
                printf("%s", (m_fft->w_s512)?"S":"-");
#endif
#endif
#if (FFT_SIZE>256)
#if (FFT_SIZE>256)
                printf("%s", (m_fft->w_s256)?"S":"-");
                printf("%s", (m_fft->w_s256)?"S":"-");
#endif
#endif
#if (FFT_SIZE>128)
#if (FFT_SIZE>128)
                printf("%s", (m_fft->w_s128)?"S":"-");
                printf("%s", (m_fft->w_s128)?"S":"-");
#endif
#endif
#if (FFT_SIZE>64)
#if (FFT_SIZE>64)
                printf("%s", (m_fft->w_s64)?"S":"-");
                printf("%s", (m_fft->w_s64)?"S":"-");
#endif
#endif
#if (FFT_SIZE>32)
#if (FFT_SIZE>32)
                printf("%s", (m_fft->w_s32)?"S":"-");
                printf("%s", (m_fft->w_s32)?"S":"-");
#endif
#endif
#if (FFT_SIZE>16)
#if (FFT_SIZE>16)
                printf("%s", (m_fft->w_s16)?"S":"-");
                printf("%s", (m_fft->w_s16)?"S":"-");
#endif
#endif
#if (FFT_SIZE>8)
#if (FFT_SIZE>8)
                printf("%s", (m_fft->w_s8)?"S":"-");
                printf("%s", (m_fft->w_s8)?"S":"-");
#endif
#endif
#if (FFT_SIZE>4)
#if (FFT_SIZE>4)
                printf("%s", (m_fft->w_s4)?"S":"-");
                printf("%s", (m_fft->w_s4)?"S":"-");
#endif
#endif
 
 
                printf(" %s%s\n",
                printf(" %s%s\n",
                        (m_fft->o_sync)?"\t(SYNC!)":"",
                        (m_fft->o_sync)?"\t(SYNC!)":"",
                        (m_fft->o_left | m_fft->o_right)?"  (NZ)":"");
                        (m_fft->o_left | m_fft->o_right)?"  (NZ)":"");
 
 
                m_data[(m_oaddr  )&(FFTLEN-1)] = m_fft->o_left;
                m_data[(m_oaddr  )&(FFTLEN-1)] = m_fft->o_left;
                m_data[(m_oaddr+1)&(FFTLEN-1)] = m_fft->o_right;
                m_data[(m_oaddr+1)&(FFTLEN-1)] = m_fft->o_right;
 
 
                if ((m_syncd)&&((m_oaddr&(FFTLEN-1)) == FFTLEN-2)) {
                if ((m_syncd)&&((m_oaddr&(FFTLEN-1)) == FFTLEN-2)) {
                        dumpwrite();
                        dumpwrite();
                        checkresults();
                        checkresults();
                }
                }
 
 
                return (m_fft->o_sync);
                return (m_fft->o_sync);
        }
        }
 
#else
 
        bool    test(ITYP data) {
 
                m_fft->i_ce    = 1;
 
                m_fft->i_reset = 0;
 
                m_fft->i_sample  = data;
 
 
 
                m_log[(m_iaddr++)&(NFTLOG*FFTLEN-1)] = data;
 
 
 
                cetick();
 
 
 
                if (m_fft->o_sync) {
 
                        if (!m_syncd) {
 
                                m_syncd = true;
 
                                printf("ORIGINAL SYNC AT 0x%lx, m_oaddr set to 0x%x\n", m_tickcount, m_oaddr);
 
                                m_logbase = m_iaddr;
 
                        } else printf("RESYNC AT %lx\n", m_tickcount);
 
                        m_oaddr &= (-1<<LGWIDTH);
 
                } else m_oaddr += 1;
 
 
 
                printf("%8x,%5d: %08x -> %011lx\t",
 
                        m_iaddr, m_oaddr, data, m_fft->o_result);
 
 
 
#ifndef APPLY_BITREVERSE_LOCALLY
 
                printf(" [%3x]%s", m_fft->revstage_iaddr,
 
                        (m_fft->br_sync)?"S"
 
                                :((m_fft->br_started)?".":"x"));
 
#endif
 
 
 
                printf(" ");
 
#if (FFT_SIZE>=2048)
 
                printf("%s", (m_fft->w_s2048)?"S":"-");
 
#endif
 
#if (FFT_SIZE>1024)
 
                printf("%s", (m_fft->w_s1024)?"S":"-");
 
#endif
 
#if (FFT_SIZE>512)
 
                printf("%s", (m_fft->w_s512)?"S":"-");
 
#endif
 
#if (FFT_SIZE>256)
 
                printf("%s", (m_fft->w_s256)?"S":"-");
 
#endif
 
#if (FFT_SIZE>128)
 
                printf("%s", (m_fft->w_s128)?"S":"-");
 
#endif
 
#if (FFT_SIZE>64)
 
                printf("%s", (m_fft->w_s64)?"S":"-");
 
#endif
 
#if (FFT_SIZE>32)
 
                printf("%s", (m_fft->w_s32)?"S":"-");
 
#endif
 
#if (FFT_SIZE>16)
 
                printf("%s", (m_fft->w_s16)?"S":"-");
 
#endif
 
#if (FFT_SIZE>8)
 
                printf("%s", (m_fft->w_s8)?"S":"-");
 
#endif
 
#if (FFT_SIZE>4)
 
                printf("%s", (m_fft->w_s4)?"S":"-");
 
#endif
 
 
 
                printf(" %s%s\n",
 
                        (m_fft->o_sync)?"\t(SYNC!)":"",
 
                        (m_fft->o_result)?"  (NZ)":"");
 
 
 
                m_data[(m_oaddr  )&(FFTLEN-1)] = m_fft->o_result;
 
 
 
                if ((m_syncd)&&((m_oaddr&(FFTLEN-1)) == FFTLEN-1)) {
 
                        dumpwrite();
 
                        checkresults();
 
                }
 
 
 
                return (m_fft->o_sync);
 
        }
 
#endif
 
 
        bool    test(double lft_r, double lft_i, double rht_r, double rht_i) {
        bool    test(double lft_r, double lft_i, double rht_r, double rht_i) {
                ITYP    ilft, irht, ilft_r, ilft_i, irht_r, irht_i;
                ITYP    ilft, irht, ilft_r, ilft_i, irht_r, irht_i;
 
 
                ilft_r = (ITYP)(lft_r) & ((1<<IWIDTH)-1);
                ilft_r = (ITYP)(lft_r) & ((1<<IWIDTH)-1);
                ilft_i = (ITYP)(lft_i) & ((1<<IWIDTH)-1);
                ilft_i = (ITYP)(lft_i) & ((1<<IWIDTH)-1);
                irht_r = (ITYP)(rht_r) & ((1<<IWIDTH)-1);
                irht_r = (ITYP)(rht_r) & ((1<<IWIDTH)-1);
                irht_i = (ITYP)(rht_i) & ((1<<IWIDTH)-1);
                irht_i = (ITYP)(rht_i) & ((1<<IWIDTH)-1);
 
 
                ilft = (ilft_r << IWIDTH) | ilft_i;
                ilft = (ilft_r << IWIDTH) | ilft_i;
                irht = (irht_r << IWIDTH) | irht_i;
                irht = (irht_r << IWIDTH) | irht_i;
 
 
 
#ifdef  DBLCLKFFT
                return test(ilft, irht);
                return test(ilft, irht);
 
#else
 
                test(ilft);
 
                return test(irht);
 
#endif
        }
        }
 
 
        double  rdata(int addr) {
        double  rdata(int addr) {
                int     index = addr & (FFTLEN-1);
                int     index = addr & (FFTLEN-1);
 
 
#ifdef  APPLY_BITREVERSE_LOCALLY
#ifdef  APPLY_BITREVERSE_LOCALLY
                index = bitrev(LGWIDTH, index);
                index = bitrev(LGWIDTH, index);
#endif
#endif
                return (double)sbits(m_data[index]>>OWIDTH, OWIDTH);
                return (double)sbits(m_data[index]>>OWIDTH, OWIDTH);
        }
        }
 
 
        double  idata(int addr) {
        double  idata(int addr) {
                int     index = addr & (FFTLEN-1);
                int     index = addr & (FFTLEN-1);
 
 
#ifdef  APPLY_BITREVERSE_LOCALLY
#ifdef  APPLY_BITREVERSE_LOCALLY
                index = bitrev(LGWIDTH, index);
                index = bitrev(LGWIDTH, index);
#endif
#endif
                return (double)sbits(m_data[index], OWIDTH);
                return (double)sbits(m_data[index], OWIDTH);
        }
        }
 
 
        void    dump(FILE *fp) {
        void    dump(FILE *fp) {
                m_dumpfp = fp;
                m_dumpfp = fp;
        }
        }
 
 
        void    dumpwrite(void) {
        void    dumpwrite(void) {
                if (!m_dumpfp)
                if (!m_dumpfp)
                        return;
                        return;
 
 
                double  *buf;
                double  *buf;
 
 
                buf = new double[FFTLEN * 2];
                buf = new double[FFTLEN * 2];
                for(int i=0; i<FFTLEN; i++) {
                for(int i=0; i<FFTLEN; i++) {
                        buf[i*2] = rdata(i);
                        buf[i*2] = rdata(i);
                        buf[i*2+1] = idata(i);
                        buf[i*2+1] = idata(i);
                }
                }
 
 
                fwrite(buf, sizeof(double), FFTLEN*2, m_dumpfp);
                fwrite(buf, sizeof(double), FFTLEN*2, m_dumpfp);
                delete[] buf;
                delete[] buf;
        }
        }
};
};
 
 
 
 
int     main(int argc, char **argv, char **envp) {
int     main(int argc, char **argv, char **envp) {
        Verilated::commandArgs(argc, argv);
        Verilated::commandArgs(argc, argv);
        FFT_TB *fft = new FFT_TB;
        FFT_TB *fft = new FFT_TB;
        FILE    *fpout;
        FILE    *fpout;
 
 
        fpout = fopen("fft_tb.dbl", "w");
        fpout = fopen("fft_tb.dbl", "w");
        if (NULL == fpout) {
        if (NULL == fpout) {
                fprintf(stderr, "Cannot write output file, fft_tb.dbl\n");
                fprintf(stderr, "Cannot write output file, fft_tb.dbl\n");
                exit(-1);
                exit(-1);
        }
        }
 
 
 
        fft->opentrace("fft.vcd");
        fft->reset();
        fft->reset();
 
 
        {
        {
                int     ftlen = FFTLEN;
                int     ftlen = FFTLEN;
                fwrite(&ftlen, 1, sizeof(int), fpout);
                fwrite(&ftlen, 1, sizeof(int), fpout);
        }
        }
        fft->dump(fpout);
        fft->dump(fpout);
 
 
        // 1.
        // 1.
        fft->test(0.0, 0.0, 32767.0, 0.0);
        double  maxv = ((1l<<(IWIDTH-1))-1l);
 
        fft->test(0.0, 0.0, maxv, 0.0);
        for(int k=0; k<FFTLEN/2-1; k++)
        for(int k=0; k<FFTLEN/2-1; k++)
                fft->test(0.0,0.0,0.0,0.0);
                fft->test(0.0,0.0,0.0,0.0);
 
 
        // 2. Try placing a pulse at the very end location
        // 2. Try placing a pulse at the very end location
        for(int k=0; k<FFTLEN/2; k++) {
        for(int k=0; k<FFTLEN/2; k++) {
                double cl, cr, sl, sr, W;
                double cl, cr, sl, sr, W;
                W = - 2.0 * M_PI / FFTLEN * (1);
                W = - 2.0 * M_PI / FFTLEN * (1);
                cl = cos(W * (2*k  )) * 16383.0;
                cl = cos(W * (2*k  )) * (double)((1l<<(IWIDTH-2))-1l);
                sl = sin(W * (2*k  )) * 16383.0;
                sl = sin(W * (2*k  )) * (double)((1l<<(IWIDTH-2))-1l);
                cr = cos(W * (2*k+1)) * 16383.0;
                cr = cos(W * (2*k+1)) * (double)((1l<<(IWIDTH-2))-1l);
                sr = sin(W * (2*k+1)) * 16383.0;
                sr = sin(W * (2*k+1)) * (double)((1l<<(IWIDTH-2))-1l);
                fft->test(cl, sl, cr, sr);
                fft->test(cl, sl, cr, sr);
        }
        }
 
 
        // 2. 
        // 2. 
        fft->test(32767.0, 0.0, 32767.0, 0.0);
        fft->test(maxv, 0.0, maxv, 0.0);
        for(int k=0; k<FFTLEN/2-1; k++)
        for(int k=0; k<FFTLEN/2-1; k++)
                fft->test(0.0,0.0,0.0,0.0);
                fft->test(0.0,0.0,0.0,0.0);
 
 
        // 3. 
        // 3. 
        fft->test(0.0,0.0,0.0,0.0);
        fft->test(0.0,0.0,0.0,0.0);
        fft->test(32767.0, 0.0, 0.0, 0.0);
        fft->test(maxv, 0.0, 0.0, 0.0);
        for(int k=0; k<FFTLEN/2-1; k++)
        for(int k=0; k<FFTLEN/2-1; k++)
                fft->test(0.0,0.0,0.0,0.0);
                fft->test(0.0,0.0,0.0,0.0);
 
 
        // 4.
        // 4.
        for(int k=0; k<8; k++)
        for(int k=0; k<8; k++)
                fft->test(32767.0, 0.0, 32767.0, 0.0);
                fft->test(maxv, 0.0, maxv, 0.0);
        for(int k=8; k<FFTLEN/2; k++)
        for(int k=8; k<FFTLEN/2; k++)
                fft->test(0.0,0.0,0.0,0.0);
                fft->test(0.0,0.0,0.0,0.0);
 
 
        // 5.
        // 5.
        if (FFTLEN/2 >= 16) {
        if (FFTLEN/2 >= 16) {
                for(int k=0; k<16; k++)
                for(int k=0; k<16; k++)
                        fft->test(32767.0, 0.0, 32767.0, 0.0);
                        fft->test(maxv, 0.0, maxv, 0.0);
                for(int k=16; k<FFTLEN/2; k++)
                for(int k=16; k<FFTLEN/2; k++)
                        fft->test(0.0,0.0,0.0,0.0);
                        fft->test(0.0,0.0,0.0,0.0);
        }
        }
 
 
        // 6.
        // 6.
        if (FFTLEN/2 >= 32) {
        if (FFTLEN/2 >= 32) {
                for(int k=0; k<32; k++)
                for(int k=0; k<32; k++)
                        fft->test(32767.0, 0.0, 32767.0, 0.0);
                        fft->test(maxv, 0.0, maxv, 0.0);
                for(int k=32; k<FFTLEN/2; k++)
                for(int k=32; k<FFTLEN/2; k++)
                        fft->test(0.0,0.0,0.0,0.0);
                        fft->test(0.0,0.0,0.0,0.0);
        }
        }
 
 
        // 7.
        // 7.
        if (FFTLEN/2 >= 64) {
        if (FFTLEN/2 >= 64) {
                for(int k=0; k<64; k++)
                for(int k=0; k<64; k++)
                        fft->test(32767.0, 0.0, 32767.0, 0.0);
                        fft->test(maxv, 0.0, maxv, 0.0);
                for(int k=64; k<FFTLEN/2; k++)
                for(int k=64; k<FFTLEN/2; k++)
                        fft->test(0.0,0.0,0.0,0.0);
                        fft->test(0.0,0.0,0.0,0.0);
        }
        }
 
 
        if (FFTLEN/2 >= 128) {
        if (FFTLEN/2 >= 128) {
                for(int k=0; k<128; k++)
                for(int k=0; k<128; k++)
                        fft->test(32767.0, 0.0, 32767.0, 0.0);
                        fft->test(maxv, 0.0, maxv, 0.0);
                for(int k=128; k<FFTLEN/2; k++)
                for(int k=128; k<FFTLEN/2; k++)
                        fft->test(0.0,0.0,0.0,0.0);
                        fft->test(0.0,0.0,0.0,0.0);
        }
        }
 
 
        if (FFTLEN/2 >= 256) {
        if (FFTLEN/2 >= 256) {
                for(int k=0; k<256; k++)
                for(int k=0; k<256; k++)
                        fft->test(32767.0, 0.0, 32767.0, 0.0);
                        fft->test(maxv, 0.0, maxv, 0.0);
                for(int k=256; k<FFTLEN/2; k++)
                for(int k=256; k<FFTLEN/2; k++)
                        fft->test(0.0,0.0,0.0,0.0);
                        fft->test(0.0,0.0,0.0,0.0);
        }
        }
 
 
        if (FFTLEN/2 >= 512) {
        if (FFTLEN/2 >= 512) {
                for(int k=0; k<256+128; k++)
                for(int k=0; k<256+128; k++)
                        fft->test(32767.0, 0.0, 32767.0, 0.0);
                        fft->test(maxv, 0.0, maxv, 0.0);
                for(int k=256+128; k<FFTLEN/2; k++)
                for(int k=256+128; k<FFTLEN/2; k++)
                        fft->test(0.0,0.0,0.0,0.0);
                        fft->test(0.0,0.0,0.0,0.0);
        }
        }
 
 
        /*
        /*
        for(int k=0; k<FFTLEN/2; k++)
        for(int k=0; k<FFTLEN/2; k++)
                fft->test(0.0,0.0,0.0,0.0);
                fft->test(0.0,0.0,0.0,0.0);
 
 
        for(int k=0; k<FFTLEN/2; k++)
        for(int k=0; k<FFTLEN/2; k++)
                fft->test(0.0,0.0,0.0,0.0);
                fft->test(0.0,0.0,0.0,0.0);
 
 
        for(int k=0; k<FFTLEN/2; k++)
        for(int k=0; k<FFTLEN/2; k++)
                fft->test(0.0,0.0,0.0,0.0);
                fft->test(0.0,0.0,0.0,0.0);
 
 
        for(int k=0; k<FFTLEN/2; k++)
        for(int k=0; k<FFTLEN/2; k++)
                fft->test(0.0,0.0,0.0,0.0);
                fft->test(0.0,0.0,0.0,0.0);
 
 
        for(int k=0; k<FFTLEN/2; k++)
        for(int k=0; k<FFTLEN/2; k++)
                fft->test(0.0,0.0,0.0,0.0);
                fft->test(0.0,0.0,0.0,0.0);
 
 
        for(int k=0; k<FFTLEN/2; k++)
        for(int k=0; k<FFTLEN/2; k++)
                fft->test(0.0,0.0,0.0,0.0);
                fft->test(0.0,0.0,0.0,0.0);
        */
        */
 
 
#ifndef NO_JUNK
#ifndef NO_JUNK
        // 7.
        // 7.
 
 
        //     1 -> 0x0001 
        //     1 -> 0x0001 
        //     2 -> 0x0002 
        //     2 -> 0x0002 
        //     4 -> 0x0004 
        //     4 -> 0x0004 
        //     8 -> 0x0008 
        //     8 -> 0x0008 
        //    16 -> 0x0010 
        //    16 -> 0x0010 
        //    32 -> 0x0020 
        //    32 -> 0x0020 
        //    64 -> 0x0040 
        //    64 -> 0x0040 
        //   128 -> 0x0080 
        //   128 -> 0x0080 
        //   256 -> 0x0100 
        //   256 -> 0x0100 
        //   512 -> 0x0200 
        //   512 -> 0x0200 
        //  1024 -> 0x0400 
        //  1024 -> 0x0400 
        //  2048 -> 0x0800
        //  2048 -> 0x0800
        //  4096 -> 0x1000
        //  4096 -> 0x1000
        //  8192 -> 0x2000
        //  8192 -> 0x2000
        // 16384 -> 0x4000
        // 16384 -> 0x4000
        for(int v=1; v<32768; v<<=1) for(int k=0; k<FFTLEN/2; k++)
        for(int v=1; v<32768; v<<=1) for(int k=0; k<FFTLEN/2; k++)
                fft->test((double)v,0.0,(double)v,0.0);
                fft->test((double)v,0.0,(double)v,0.0);
        //     1 -> 0xffff      
        //     1 -> 0xffff      
        //     2 -> 0xfffe
        //     2 -> 0xfffe
        //     4 -> 0xfffc
        //     4 -> 0xfffc
        //     8 -> 0xfff8
        //     8 -> 0xfff8
        //    16 -> 0xfff0
        //    16 -> 0xfff0
        //    32 -> 0xffe0
        //    32 -> 0xffe0
        //    64 -> 0xffc0
        //    64 -> 0xffc0
        //   128 -> 0xff80
        //   128 -> 0xff80
        //   256 -> 0xff00
        //   256 -> 0xff00
        //   512 -> 0xfe00
        //   512 -> 0xfe00
        //  1024 -> 0xfc00
        //  1024 -> 0xfc00
        //  2048 -> 0xf800
        //  2048 -> 0xf800
        //  4096 -> 0xf000
        //  4096 -> 0xf000
        //  8192 -> 0xe000
        //  8192 -> 0xe000
        // 16384 -> 0xc000
        // 16384 -> 0xc000
        // 32768 -> 0x8000
        // 32768 -> 0x8000
        fft->test(0.0,0.0,16384.0,0.0);
        fft->test(0.0,0.0,16384.0,0.0);
        for(int k=0; k<FFTLEN/2-1; k++)
        for(int k=0; k<FFTLEN/2-1; k++)
                fft->test(0.0,0.0,0.0,0.0);
                fft->test(0.0,0.0,0.0,0.0);
 
 
        for(int v=1; v<=32768; v<<=1) for(int k=0; k<FFTLEN/2; k++)
        for(int v=1; v<=32768; v<<=1) for(int k=0; k<FFTLEN/2; k++)
                fft->test(-(double)v,0.0,-(double)v,0.0);
                fft->test(-(double)v,0.0,-(double)v,0.0);
        //     1 -> 0x000040    CORRECT!!
        //     1 -> 0x000040    CORRECT!!
        //     2 -> 0x000080 
        //     2 -> 0x000080 
        //     4 -> 0x000100 
        //     4 -> 0x000100 
        //     8 -> 0x000200
        //     8 -> 0x000200
        //    16 -> 0x000400
        //    16 -> 0x000400
        //    32 -> 0x000800
        //    32 -> 0x000800
        //    64 -> 0x001000
        //    64 -> 0x001000
        //   128 -> 0x002000
        //   128 -> 0x002000
        //   256 -> 0x004000
        //   256 -> 0x004000
        //   512 -> 0x008000
        //   512 -> 0x008000
        //  1024 -> 0x010000
        //  1024 -> 0x010000
        //  2048 -> 0x020000
        //  2048 -> 0x020000
        //  4096 -> 0x040000
        //  4096 -> 0x040000
        //  8192 -> 0x080000
        //  8192 -> 0x080000
        // 16384 -> 0x100000
        // 16384 -> 0x100000
        for(int v=1; v<32768; v<<=1) for(int k=0; k<FFTLEN/2; k++)
        for(int v=1; v<32768; v<<=1) for(int k=0; k<FFTLEN/2; k++)
                fft->test(0.0,(double)v,0.0,(double)v);
                fft->test(0.0,(double)v,0.0,(double)v);
        //     1 -> 0x3fffc0
        //     1 -> 0x3fffc0
        //     2 -> 0x3fff80
        //     2 -> 0x3fff80
        //     4 -> 0x3fff00
        //     4 -> 0x3fff00
        //     8 -> 0x3ffe00
        //     8 -> 0x3ffe00
        //    16 -> 0x3ffc00
        //    16 -> 0x3ffc00
        //    32 -> 0x3ff800
        //    32 -> 0x3ff800
        //    64 -> 0x3ff000
        //    64 -> 0x3ff000
        //   128 -> 0x3fe000
        //   128 -> 0x3fe000
        //   256 -> 0x3fc000
        //   256 -> 0x3fc000
        //   512 -> 0x3f8000
        //   512 -> 0x3f8000
        //  1024 -> 0x3f0000
        //  1024 -> 0x3f0000
        //  2048 -> 0x3e0000
        //  2048 -> 0x3e0000
        //  4096 -> 0x3c0000
        //  4096 -> 0x3c0000
        //  8192 -> 0x380000
        //  8192 -> 0x380000
        // 16384 -> 0x300000
        // 16384 -> 0x300000
        for(int v=1; v<32768; v<<=1) for(int k=0; k<FFTLEN/2; k++)
        for(int v=1; v<32768; v<<=1) for(int k=0; k<FFTLEN/2; k++)
                fft->test(0.0,-(double)v,0.0,-(double)v);
                fft->test(0.0,-(double)v,0.0,-(double)v);
 
 
        // 61. Now, how about the smallest alternating real signal
        // 61. Now, how about the smallest alternating real signal
        for(int k=0; k<FFTLEN/2; k++)
        for(int k=0; k<FFTLEN/2; k++)
                fft->test(2.0,0.0,0.0,0.0); // Don't forget to expect a bias!
                fft->test(2.0,0.0,0.0,0.0); // Don't forget to expect a bias!
        // 62. Now, how about the smallest alternating imaginary signal
        // 62. Now, how about the smallest alternating imaginary signal
        for(int k=0; k<FFTLEN/2; k++)
        for(int k=0; k<FFTLEN/2; k++)
                fft->test(0.0,2.0,0.0,0.0); // Don't forget to expect a bias!
                fft->test(0.0,2.0,0.0,0.0); // Don't forget to expect a bias!
        // 63. Now, how about the smallest alternating real signal,2nd phase
        // 63. Now, how about the smallest alternating real signal,2nd phase
        for(int k=0; k<FFTLEN/2; k++)
        for(int k=0; k<FFTLEN/2; k++)
                fft->test(0.0,0.0,2.0,0.0); // Don't forget to expect a bias!
                fft->test(0.0,0.0,2.0,0.0); // Don't forget to expect a bias!
        // 64.Now, how about the smallest alternating imaginary signal,2nd phase
        // 64.Now, how about the smallest alternating imaginary signal,2nd phase
        for(int k=0; k<FFTLEN/2; k++)
        for(int k=0; k<FFTLEN/2; k++)
                fft->test(0.0,0.0,0.0,2.0); // Don't forget to expect a bias!
                fft->test(0.0,0.0,0.0,2.0); // Don't forget to expect a bias!
 
 
        // 65.
        // 65.
        for(int k=0; k<FFTLEN/2; k++)
        for(int k=0; k<FFTLEN/2; k++)
                fft->test(32767.0,0.0,-32767.0,0.0);
                fft->test(maxv,0.0,-maxv,0.0);
        // 66.
        // 66.
        for(int k=0; k<FFTLEN/2; k++)
        for(int k=0; k<FFTLEN/2; k++)
                fft->test(0.0,-32767.0,0.0,32767.0);
                fft->test(0.0,-maxv,0.0,maxv);
        // 67.
        // 67.
        for(int k=0; k<FFTLEN/2; k++)
        for(int k=0; k<FFTLEN/2; k++)
                fft->test(-32768.0,-32768.0,-32768.0,-32768.0);
                fft->test(-maxv,-maxv,-maxv,-maxv);
        // 68.
        // 68.
        for(int k=0; k<FFTLEN/2; k++)
        for(int k=0; k<FFTLEN/2; k++)
                fft->test(0.0,-32767.0,0.0,32767.0);
                fft->test(0.0,-maxv,0.0,maxv);
        // 69.
        // 69.
        for(int k=0; k<FFTLEN/2; k++)
        for(int k=0; k<FFTLEN/2; k++)
                fft->test(0.0,32767.0,0.0,-32767.0);
                fft->test(0.0,maxv,0.0,-maxv);
        // 70. 
        // 70. 
        for(int k=0; k<FFTLEN/2; k++)
        for(int k=0; k<FFTLEN/2; k++)
                fft->test(-32768.0,-32768.0,-32768.0,-32768.0);
                fft->test(-maxv,-maxv,-maxv,-maxv);
 
 
        // 71. Now let's go for an impulse (SUCCESS)
        // 71. Now let's go for an impulse (SUCCESS)
        fft->test(16384.0, 0.0, 0.0, 0.0);
        fft->test(16384.0, 0.0, 0.0, 0.0);
        for(int k=0; k<FFTLEN/2-1; k++)
        for(int k=0; k<FFTLEN/2-1; k++)
                fft->test(0.0,0.0,0.0,0.0);
                fft->test(0.0,0.0,0.0,0.0);
 
 
        // 72. And another one on the next clock (FAILS, ugly)
        // 72. And another one on the next clock (FAILS, ugly)
        fft->test(0.0, 0.0, 16384.0, 0.0);
        fft->test(0.0, 0.0, 16384.0, 0.0);
        for(int k=0; k<FFTLEN/2-1; k++)
        for(int k=0; k<FFTLEN/2-1; k++)
                fft->test(0.0,0.0,0.0,0.0);
                fft->test(0.0,0.0,0.0,0.0);
 
 
        // 72. And another one on the next clock (FAILS, ugly)
        // 72. And another one on the next clock (FAILS, ugly)
        fft->test(0.0, 0.0,  8192.0, 0.0);
        fft->test(0.0, 0.0,  8192.0, 0.0);
        for(int k=0; k<FFTLEN/2-1; k++)
        for(int k=0; k<FFTLEN/2-1; k++)
                fft->test(0.0,0.0,0.0,0.0);
                fft->test(0.0,0.0,0.0,0.0);
 
 
        // 72. And another one on the next clock (FAILS, ugly)
        // 72. And another one on the next clock (FAILS, ugly)
        fft->test(0.0, 0.0,   512.0, 0.0);
        fft->test(0.0, 0.0,   512.0, 0.0);
        for(int k=0; k<FFTLEN/2-1; k++)
        for(int k=0; k<FFTLEN/2-1; k++)
                fft->test(0.0,0.0,0.0,0.0);
                fft->test(0.0,0.0,0.0,0.0);
 
 
        // 73. And an imaginary one on the second clock
        // 73. And an imaginary one on the second clock
        fft->test(0.0, 0.0, 0.0, 16384.0);
        fft->test(0.0, 0.0, 0.0, 16384.0);
        for(int k=0; k<FFTLEN/2-1; k++)
        for(int k=0; k<FFTLEN/2-1; k++)
                fft->test(0.0,0.0,0.0,0.0);
                fft->test(0.0,0.0,0.0,0.0);
 
 
        // 74. Likewise the next clock
        // 74. Likewise the next clock
        fft->test(0.0,0.0,0.0,0.0);
        fft->test(0.0,0.0,0.0,0.0);
        fft->test(16384.0, 0.0, 0.0, 0.0);
        fft->test(16384.0, 0.0, 0.0, 0.0);
        for(int k=0; k<FFTLEN/2-2; k++)
        for(int k=0; k<FFTLEN/2-2; k++)
                fft->test(0.0,0.0,0.0,0.0);
                fft->test(0.0,0.0,0.0,0.0);
 
 
        // 75. And it's imaginary counterpart
        // 75. And it's imaginary counterpart
        fft->test(0.0,0.0,0.0,0.0);
        fft->test(0.0,0.0,0.0,0.0);
        fft->test(0.0, 16384.0, 0.0, 0.0);
        fft->test(0.0, 16384.0, 0.0, 0.0);
        for(int k=0; k<FFTLEN/2-2; k++)
        for(int k=0; k<FFTLEN/2-2; k++)
                fft->test(0.0,0.0,0.0,0.0);
                fft->test(0.0,0.0,0.0,0.0);
 
 
        // 76. Likewise the next clock
        // 76. Likewise the next clock
        fft->test(0.0,0.0,0.0,0.0);
        fft->test(0.0,0.0,0.0,0.0);
        fft->test(0.0, 0.0, 16384.0, 0.0);
        fft->test(0.0, 0.0, 16384.0, 0.0);
        for(int k=0; k<FFTLEN/2-2; k++)
        for(int k=0; k<FFTLEN/2-2; k++)
                fft->test(0.0,0.0,0.0,0.0);
                fft->test(0.0,0.0,0.0,0.0);
 
 
        // 77. And it's imaginary counterpart
        // 77. And it's imaginary counterpart
        fft->test(0.0,0.0,0.0,0.0);
        fft->test(0.0,0.0,0.0,0.0);
        fft->test(0.0, 0.0, 0.0, 16384.0);
        fft->test(0.0, 0.0, 0.0, 16384.0);
        for(int k=0; k<FFTLEN/2-2; k++)
        for(int k=0; k<FFTLEN/2-2; k++)
                fft->test(0.0,0.0,0.0,0.0);
                fft->test(0.0,0.0,0.0,0.0);
 
 
 
 
        // 78. Now let's try some exponentials
        // 78. Now let's try some exponentials
        for(int k=0; k<FFTLEN/2; k++) {
        for(int k=0; k<FFTLEN/2; k++) {
                double cl, cr, sl, sr, W;
                double cl, cr, sl, sr, W;
                W = - 2.0 * M_PI / FFTLEN;
                W = - 2.0 * M_PI / FFTLEN;
                cl = cos(W * (2*k  )) * 16383.0;
                cl = cos(W * (2*k  )) * 16383.0;
                sl = sin(W * (2*k  )) * 16383.0;
                sl = sin(W * (2*k  )) * 16383.0;
                cr = cos(W * (2*k+1)) * 16383.0;
                cr = cos(W * (2*k+1)) * 16383.0;
                sr = sin(W * (2*k+1)) * 16383.0;
                sr = sin(W * (2*k+1)) * 16383.0;
                fft->test(cl, sl, cr, sr);
                fft->test(cl, sl, cr, sr);
        }
        }
 
 
        // 72.
        // 72.
        for(int k=0; k<FFTLEN/2; k++) {
        for(int k=0; k<FFTLEN/2; k++) {
                double cl, cr, sl, sr, W;
                double cl, cr, sl, sr, W;
                W = - 2.0 * M_PI / FFTLEN * 5;
                W = - 2.0 * M_PI / FFTLEN * 5;
                cl = cos(W * (2*k  )) * 16383.0;
                cl = cos(W * (2*k  )) * 16383.0;
                sl = sin(W * (2*k  )) * 16383.0;
                sl = sin(W * (2*k  )) * 16383.0;
                cr = cos(W * (2*k+1)) * 16383.0;
                cr = cos(W * (2*k+1)) * 16383.0;
                sr = sin(W * (2*k+1)) * 16383.0;
                sr = sin(W * (2*k+1)) * 16383.0;
                fft->test(cl, sl, cr, sr);
                fft->test(cl, sl, cr, sr);
        }
        }
 
 
        // 73.
        // 73.
        for(int k=0; k<FFTLEN/2; k++) {
        for(int k=0; k<FFTLEN/2; k++) {
                double cl, cr, sl, sr, W;
                double cl, cr, sl, sr, W;
                W = - 2.0 * M_PI / FFTLEN * 8;
                W = - 2.0 * M_PI / FFTLEN * 8;
                cl = cos(W * (2*k  )) * 8190.0;
                cl = cos(W * (2*k  )) * 8190.0;
                sl = sin(W * (2*k  )) * 8190.0;
                sl = sin(W * (2*k  )) * 8190.0;
                cr = cos(W * (2*k+1)) * 8190.0;
                cr = cos(W * (2*k+1)) * 8190.0;
                sr = sin(W * (2*k+1)) * 8190.0;
                sr = sin(W * (2*k+1)) * 8190.0;
                fft->test(cl, sl, cr, sr);
                fft->test(cl, sl, cr, sr);
        }
        }
 
 
        // 74.
        // 74.
        for(int k=0; k<FFTLEN/2; k++) {
        for(int k=0; k<FFTLEN/2; k++) {
                double cl, cr, sl, sr, W;
                double cl, cr, sl, sr, W;
                W = - 2.0 * M_PI / FFTLEN * 25;
                W = - 2.0 * M_PI / FFTLEN * 25;
                cl = cos(W * (2*k  )) * 4.0;
                cl = cos(W * (2*k  )) * 4.0;
                sl = sin(W * (2*k  )) * 4.0;
                sl = sin(W * (2*k  )) * 4.0;
                cr = cos(W * (2*k+1)) * 4.0;
                cr = cos(W * (2*k+1)) * 4.0;
                sr = sin(W * (2*k+1)) * 4.0;
                sr = sin(W * (2*k+1)) * 4.0;
                fft->test(cl, sl, cr, sr);
                fft->test(cl, sl, cr, sr);
        }
        }
#endif
#endif
        // 19.--24. And finally, let's clear out our results / buffer
        // 19.--24. And finally, let's clear out our results / buffer
        for(int k=0; k<(FFTLEN/2) * 5; k++)
        for(int k=0; k<(FFTLEN/2) * 5; k++)
                fft->test(0.0,0.0,0.0,0.0);
                fft->test(0.0,0.0,0.0,0.0);
 
 
 
 
 
 
        fclose(fpout);
        fclose(fpout);
 
 
 
        if (!fft->m_syncd) {
 
                printf("FAIL -- NO SYNC\n");
 
                goto test_failure;
 
        }
 
 
        printf("SUCCESS!!\n");
        printf("SUCCESS!!\n");
        exit(0);
        exit(0);
 
test_failure:
 
        printf("TEST FAILED!!\n");
 
        exit(0);
}
}
 
 
 
 
 
 

powered by: WebSVN 2.1.0

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