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

Subversion Repositories dblclockfft

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

Go to most recent revision | Show entire file | Details | Blame | View Log

Rev 35 Rev 36
Line 1... Line 1...
////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
//
//
// Filename:    butterfly_tb.cpp
// Filename:    hwbfly_tb.cpp
//
//
// Project:     A Doubletime Pipelined FFT
// Project:     A Doubletime Pipelined FFT
//
//
// Purpose:     A test-bench for the butterfly.v subfile of the double
// Purpose:     A test-bench for the hardware butterfly subfile of the generic
//              clocked FFT.  This file may be run autonomously.  If so,
//              pipelined FFT.  This file may be run autonomously.  If so,
//              the last line output will either read "SUCCESS" on success,
//      the last line output will either read "SUCCESS" on success, or some
//              or some other failure message otherwise.
//      other failure message otherwise.
//
//
//              This file depends upon verilator to both compile, run, and
//      This file depends upon verilator to both compile, run, and therefore
//              therefore test butterfly.v
//      test hwbfly.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.
Line 40... Line 40...
//
//
///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
#include <stdio.h>
#include <stdio.h>
#include <stdint.h>
#include <stdint.h>
 
 
#include "Vhwbfly.h"
 
#include "verilated.h"
#include "verilated.h"
 
#include "verilated_vcd_c.h"
 
#include "Vhwbfly.h"
#include "twoc.h"
#include "twoc.h"
 
#include "fftsize.h"
 
 
#ifdef  NEW_VERILATOR
#ifdef  NEW_VERILATOR
#define VVAR(A) hwbfly__DOT_ ## A
#define VVAR(A) hwbfly__DOT_ ## A
#else
#else
#define VVAR(A) v__DOT_ ## A
#define VVAR(A) v__DOT_ ## A
#endif
#endif
 
 
 
#define IWIDTH  TST_BUTTERFLY_IWIDTH
 
#define CWIDTH  TST_BUTTERFLY_CWIDTH
 
#define OWIDTH  TST_BUTTERFLY_OWIDTH
 
 
class   BFLY_TB {
class   HWBFLY_TB {
public:
public:
        Vhwbfly         *m_bfly;
        Vhwbfly         *m_bfly;
 
        VerilatedVcdC   *m_trace;
        unsigned long   m_left[64], m_right[64];
        unsigned long   m_left[64], m_right[64];
        bool            m_aux[64];
        bool            m_aux[64];
        int             m_addr, m_lastaux, m_offset;
        int             m_addr, m_lastaux, m_offset;
        bool            m_syncd;
        bool            m_syncd;
 
        uint64_t        m_tickcount;
 
 
        BFLY_TB(void) {
        HWBFLY_TB(void) {
 
                Verilated::traceEverOn(true);
 
                m_trace = NULL;
                m_bfly = new Vhwbfly;
                m_bfly = new Vhwbfly;
                m_addr = 0;
                m_addr = 0;
                m_syncd = 0;
                m_syncd = 0;
 
                m_tickcount = 0;
 
                m_bfly->i_reset = 1;
 
                m_bfly->i_clk = 0;
 
                m_bfly->eval();
 
                m_bfly->i_reset = 0;
 
        }
 
 
 
        void    opentrace(const char *vcdname) {
 
                if (!m_trace) {
 
                        m_trace = new VerilatedVcdC;
 
                        m_bfly->trace(m_trace, 99);
 
                        m_trace->open(vcdname);
 
                }
 
        }
 
 
 
        void    closetrace(void) {
 
                if (m_trace) {
 
                        m_trace->close();
 
                        delete  m_trace;
 
                        m_trace = NULL;
 
                }
        }
        }
 
 
        void    tick(void) {
        void    tick(void) {
 
                m_tickcount++;
 
 
                m_lastaux = m_bfly->o_aux;
                m_lastaux = m_bfly->o_aux;
                m_bfly->i_clk = 0;
                m_bfly->i_clk = 0;
                m_bfly->eval();
                m_bfly->eval();
 
                if (m_trace) m_trace->dump((uint64_t)(10ul*m_tickcount-2));
                m_bfly->i_clk = 1;
                m_bfly->i_clk = 1;
                m_bfly->eval();
                m_bfly->eval();
 
                if (m_trace) m_trace->dump((uint64_t)(10ul*m_tickcount));
 
                m_bfly->i_clk = 0;
 
                m_bfly->eval();
 
                if (m_trace) {
 
                        m_trace->dump((uint64_t)(10ul*m_tickcount+5));
 
                        m_trace->flush();
 
                }
 
 
                if ((!m_syncd)&&(m_bfly->o_aux))
                if ((!m_syncd)&&(m_bfly->o_aux))
                        m_offset = m_addr;
                        m_offset = m_addr;
                m_syncd = (m_syncd) || (m_bfly->o_aux);
                m_syncd = (m_syncd) || (m_bfly->o_aux);
        }
        }
 
 
 
        void    cetick(void) {
 
                int     ce = m_bfly->i_ce, nkce;
 
 
 
                tick();
 
 
 
                nkce = (rand()&1);
 
#ifdef  FFT_CKPCE
 
                nkce += FFT_CKPCE;
 
#endif
 
 
 
                if ((ce)&&(nkce > 0)) {
 
                        m_bfly->i_ce = 0;
 
                        for(int kce=0; kce<nkce-1; kce++)
 
                                tick();
 
                }
 
 
 
                m_bfly->i_ce = ce;
 
        }
 
 
        void    reset(void) {
        void    reset(void) {
                m_bfly->i_ce    = 0;
                m_bfly->i_ce    = 0;
                m_bfly->i_rst   = 1;
                m_bfly->i_reset = 1;
                m_bfly->i_coef  = 0l;
                m_bfly->i_coef  = 0l;
                m_bfly->i_left  = 0;
                m_bfly->i_left  = 0;
                m_bfly->i_right = 0;
                m_bfly->i_right = 0;
                tick();
                tick();
                m_bfly->i_rst = 0;
                m_bfly->i_reset = 0;
                m_bfly->i_ce  = 1;
                m_bfly->i_ce  = 1;
                //
                //
                // Let's run a RESET test here, forcing the whole butterfly
                // Let's run a RESET test here, forcing the whole butterfly
                // to be filled with aux=1.  If the reset works right,
                // to be filled with aux=1.  If the reset works right,
                // we'll never get an aux=1 output.
                // we'll never get an aux=1 output.
                //
                //
                m_bfly->i_rst = 1;
                m_bfly->i_reset = 1;
                m_bfly->i_ce  = 1;
 
                m_bfly->i_aux = 1;
                m_bfly->i_aux = 1;
 
                m_bfly->i_ce  = 1;
                for(int i=0; i<200; i++)
                for(int i=0; i<200; i++)
                        tick();
                        cetick();
 
 
                // Now here's the RESET line, so let's see what the test does
                // Now here's the RESET line, so let's see what the test does
                m_bfly->i_rst = 1;
                m_bfly->i_reset = 1;
                m_bfly->i_ce  = 1;
                m_bfly->i_ce  = 1;
                m_bfly->i_aux = 1;
                m_bfly->i_aux = 1;
                tick();
                cetick();
                m_bfly->i_rst = 0;
                m_bfly->i_reset = 0;
                m_syncd = 0;
                m_syncd = 0;
        }
        }
 
 
        void    test(const int n, const int k, const unsigned long cof,
        void    test(const int n, const int k, const unsigned long cof,
                        const unsigned lft, const unsigned rht, const int aux) {
                        const unsigned lft, const unsigned rht, const int aux) {
 
 
                m_bfly->i_coef  = cof & (~(-1l << 40));
                m_bfly->i_coef  = ubits(cof, 2*TST_BUTTERFLY_CWIDTH);
                m_bfly->i_left  = lft;
                m_bfly->i_left  = ubits(lft, 2*TST_BUTTERFLY_IWIDTH);
                m_bfly->i_right = rht;
                m_bfly->i_right = ubits(rht, 2*TST_BUTTERFLY_IWIDTH);
                m_bfly->i_aux   = aux & 1;
                m_bfly->i_aux   = aux & 1;
 
 
                m_bfly->i_ce = 1;
                m_bfly->i_ce = 1;
                tick();
                cetick();
 
 
                if ((m_bfly->o_aux)&&(!m_lastaux))
                if ((m_bfly->o_aux)&&(!m_lastaux))
                        printf("\n");
                        printf("\n");
                printf("n,k=%d,%3d: COEF=%010lx, LFT=%08x, RHT=%08x, A=%d, OLFT =%09lx, ORHT=%09lx, AUX=%d",
                printf("n,k=%d,%3d: COEF=%010lx, LFT=%08x, RHT=%08x, A=%d, OLFT =%09lx, ORHT=%09lx, AUX=%d",
                        n,k,
                        n,k,
Line 128... Line 187...
                        m_bfly->i_right,
                        m_bfly->i_right,
                        m_bfly->i_aux,
                        m_bfly->i_aux,
                        m_bfly->o_left,
                        m_bfly->o_left,
                        m_bfly->o_right,
                        m_bfly->o_right,
                        m_bfly->o_aux);
                        m_bfly->o_aux);
 
#if (FFT_CKPCE == 1)
 
                printf(", p1 = 0x%08lx p2 = 0x%08lx, p3 = 0x%08lx",
 
#define rp_one          VVAR(_CKPCE_ONE__DOT__rp_one)
 
#define rp_two          VVAR(_CKPCE_ONE__DOT__rp_two)
 
#define rp_three        VVAR(_CKPCE_ONE__DOT__rp_three)
 
                        m_bfly->rp_one,
 
                        m_bfly->rp_two,
 
                        m_bfly->rp_three);
 
#elif (FFT_CKPCE == 2)
 
#define rp_one          VVAR(_genblk1__DOT__CKPCE_TWO__DOT__rp2_one)
 
#define rp_two          VVAR(_genblk1__DOT__CKPCE_TWO__DOT__rp_two)
 
#define rp_three        VVAR(_genblk1__DOT__CKPCE_TWO__DOT__rp_three)
 
                printf(", p1 = 0x%08lx p2 = 0x%08lx, p3 = 0x%08lx",
 
                        m_bfly->rp_one,
 
                        m_bfly->rp_two,
 
                        m_bfly->rp_three);
 
#else
 
                printf("CKPCE = %d\n", FFT_CKPCE);
 
#endif
 
 
                printf("\n");
                printf("\n");
 
 
                if ((m_syncd)&&(m_left[(m_addr-m_offset)&(64-1)] != m_bfly->o_left)) {
                if ((m_syncd)&&(m_left[(m_addr-m_offset)&(64-1)] != m_bfly->o_left)) {
                        fprintf(stderr, "WRONG O_LEFT! (%lx(exp) != %lx(sut)\n",
                        printf("WRONG O_LEFT! (%lx(exp) != %lx(sut)\n",
                                m_left[(m_addr-m_offset)&(64-1)],
                                m_left[(m_addr-m_offset)&(64-1)],
                                m_bfly->o_left);
                                m_bfly->o_left);
                        exit(-1);
                        exit(EXIT_FAILURE);
                }
                }
 
 
                if ((m_syncd)&&(m_right[(m_addr-m_offset)&(64-1)] != m_bfly->o_right)) {
                if ((m_syncd)&&(m_right[(m_addr-m_offset)&(64-1)] != m_bfly->o_right)) {
                        fprintf(stderr, "WRONG O_RIGHT! (%lx(exp) != %lx(sut))\n",
                        printf("WRONG O_RIGHT! (%lx(exp) != %lx(sut))\n",
                                m_right[(m_addr-m_offset)&(64-1)],
                                m_right[(m_addr-m_offset)&(64-1)], m_bfly->o_right);
                                m_bfly->o_right);
                        exit(EXIT_FAILURE);
                        exit(-1);
 
                }
                }
 
 
                if ((m_syncd)&&(m_aux[(m_addr-m_offset)&(64-1)] != m_bfly->o_aux)) {
                if ((m_syncd)&&(m_aux[(m_addr-m_offset)&(64-1)] != m_bfly->o_aux)) {
                        fprintf(stderr, "FAILED AUX CHANNEL TEST (i.e. the SYNC)\n");
                        printf("FAILED AUX CHANNEL TEST (i.e. the SYNC)\n");
                        exit(-1);
                        exit(EXIT_FAILURE);
                }
                }
 
 
                if ((m_addr > 22)&&(!m_syncd)) {
                if ((m_addr > 22)&&(!m_syncd)) {
                        fprintf(stderr, "NO SYNC PULSE!\n");
                        printf("NO SYNC PULSE!\n");
                        exit(-1);
                        exit(EXIT_FAILURE);
                }
                }
 
 
                // Now, let's calculate an "expected" result ...
                // Now, let's calculate an "expected" result ...
                long    rlft, ilft;
                long    rlft, ilft;
 
 
                // Extract left and right values ...
                // Extract left and right values ...
                rlft = sbits(m_bfly->i_left >> 16, 16);
                rlft = sbits(m_bfly->i_left >> IWIDTH, IWIDTH);
                ilft = sbits(m_bfly->i_left      , 16);
                ilft = sbits(m_bfly->i_left          , IWIDTH);
 
 
                // Now repeat for the right hand value ...
                // Now repeat for the right hand value ...
                long    rrht, irht;
                long    rrht, irht;
                // Extract left and right values ...
                // Extract left and right values ...
                rrht = sbits(m_bfly->i_right >> 16, 16);
                rrht = sbits(m_bfly->i_right >> IWIDTH, IWIDTH);
                irht = sbits(m_bfly->i_right      , 16);
                irht = sbits(m_bfly->i_right          , IWIDTH);
 
 
                // and again for the coefficients
                // and again for the coefficients
                long    rcof, icof;
                long    rcof, icof;
                // Extract left and right values ...
                // Extract left and right values ...
                rcof = sbits(m_bfly->i_coef >> 20, 20);
                rcof = sbits(m_bfly->i_coef >> CWIDTH, CWIDTH);
                icof = sbits(m_bfly->i_coef      , 20);
                icof = sbits(m_bfly->i_coef          , CWIDTH);
 
 
                // Now, let's do the butterfly ourselves ...
                // Now, let's do the butterfly ourselves ...
                long sumi, sumr, difi, difr;
                long sumi, sumr, difi, difr;
                sumr = rlft + rrht;
                sumr = rlft + rrht;
                sumi = ilft + irht;
                sumi = ilft + irht;
Line 196... Line 274...
                long p1, p2, p3, mpyr, mpyi;
                long p1, p2, p3, mpyr, mpyi;
                p1 = difr * rcof;
                p1 = difr * rcof;
                p2 = difi * icof;
                p2 = difi * icof;
                p3 = (difr + difi) * (rcof + icof);
                p3 = (difr + difi) * (rcof + icof);
 
 
                mpyr = p1-p2 + (1<<17);
                mpyr = p1-p2;
                mpyi = p3-p1-p2 + (1<<17);
                mpyi = p3-p1-p2;
 
 
 
                mpyr = rndbits(mpyr, (IWIDTH+2)+(CWIDTH+1), OWIDTH+4);
 
                mpyi = rndbits(mpyi, (IWIDTH+2)+(CWIDTH+1), OWIDTH+4);
 
 
        /*
        /*
                printf("RC=%lx, IC=%lx, ", rcof, icof);
                printf("RC=%lx, IC=%lx, ", rcof, icof);
                printf("P1=%lx,P2=%lx,P3=%lx, ", p1,p2,p3);
                printf("P1=%lx,P2=%lx,P3=%lx, ", p1,p2,p3);
                printf("MPYr = %lx, ", mpyr);
                printf("MPYr = %lx, ", mpyr);
Line 209... Line 290...
        */
        */
 
 
                long    o_left_r, o_left_i, o_right_r, o_right_i;
                long    o_left_r, o_left_i, o_right_r, o_right_i;
                unsigned long   o_left, o_right;
                unsigned long   o_left, o_right;
 
 
                o_left_r = sumr & 0x01ffff; o_left_i = sumi & 0x01ffff;
                o_left_r = rndbits(sumr<<(CWIDTH-2), CWIDTH+IWIDTH+3, OWIDTH+4);
                o_left = (o_left_r << 17) | (o_left_i);
                        o_left_r = ubits(o_left_r, OWIDTH);
 
                o_left_i = rndbits(sumi<<(CWIDTH-2), CWIDTH+IWIDTH+3, OWIDTH+4);
                o_right_r = (mpyr>>18) & 0x01ffff;
                        o_left_i = ubits(o_left_i, OWIDTH);
                o_right_i = (mpyi>>18) & 0x01ffff;
                o_left = (o_left_r << OWIDTH) | (o_left_i);
                o_right = (o_right_r << 17) | (o_right_i);
 
 
                o_right_r = ubits(mpyr, OWIDTH);
 
                o_right_i = ubits(mpyi, OWIDTH);
 
                o_right = (o_right_r << OWIDTH) | (o_right_i);
        /*
        /*
                printf("oR_r = %lx, ", o_right_r);
                printf("oR_r = %lx, ", o_right_r);
                printf("oR_i = %lx\n", o_right_i);
                printf("oR_i = %lx\n", o_right_i);
        */
        */
 
 
Line 230... Line 314...
        }
        }
};
};
 
 
int     main(int argc, char **argv, char **envp) {
int     main(int argc, char **argv, char **envp) {
        Verilated::commandArgs(argc, argv);
        Verilated::commandArgs(argc, argv);
        BFLY_TB *bfly = new BFLY_TB;
        HWBFLY_TB       *bfly = new HWBFLY_TB;
        int16_t         ir0, ii0, lstr, lsti;
        int16_t         ir0, ii0, lstr, lsti;
        int32_t         sumr, sumi, difr, difi;
        int32_t         sumr, sumi, difr, difi;
        int32_t         smr, smi, dfr, dfi;
        int32_t         smr, smi, dfr, dfi;
        int             rnd = 0;
        int             rnd = 0;
 
 
        const int       TESTSZ = 256;
        const int       TESTSZ = 256;
 
 
 
        bfly->opentrace("hwbfly.vcd");
 
 
        bfly->reset();
        bfly->reset();
 
 
        bfly->test(9,0,0x4000000000l,0x7fff0000,0x7fff0000, 1);
        bfly->test(9,0,0x4000000000l,0x7fff0000,0x7fff0000, 1);
        bfly->test(9,1,0x4000000000l,0x7fff0000,0x80010000, 0);
        bfly->test(9,1,0x4000000000l,0x7fff0000,0x80010000, 0);
        bfly->test(9,2,0x4000000000l,0x00007fff,0x00008001, 0);
        bfly->test(9,2,0x4000000000l,0x00007fff,0x00008001, 0);

powered by: WebSVN 2.1.0

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