Line 1... |
Line 1... |
////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
//
|
//
|
// Filename: snglbrev_tb.cpp
|
// Filename: bitreverse_tb.cpp
|
//
|
//
|
// Project: A General Purpose Pipelined FFT Implementation
|
// Project: A General Purpose Pipelined FFT Implementation
|
//
|
//
|
// Purpose: A test-bench for the bitreversal stage of the pipelined
|
// Purpose: A test-bench for the bitreversal stage of the pipelined
|
// FFT. This file may be run autonomously. If so, the last line
|
// FFT. This file may be run autonomously. If so, the last line
|
Line 14... |
Line 14... |
// FFT handles one or two inputs per clock respectively.
|
// FFT handles one or two inputs per clock respectively.
|
//
|
//
|
// Creator: Dan Gisselquist, Ph.D.
|
// Creator: Dan Gisselquist, Ph.D.
|
// Gisselquist Technology, LLC
|
// Gisselquist Technology, LLC
|
//
|
//
|
///////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
//
|
//
|
// Copyright (C) 2015,2018, 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
|
Line 29... |
Line 29... |
// 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 "verilated.h"
|
#include "verilated.h"
|
#include "verilated_vcd_c.h"
|
#include "verilated_vcd_c.h"
|
|
|
#include "fftsize.h"
|
#include "fftsize.h"
|
#include "Vbitreverse.h"
|
#include "Vbitreverse.h"
|
Line 59... |
Line 59... |
#define VVAR(A) v__DOT_ ## A
|
#define VVAR(A) v__DOT_ ## A
|
#endif
|
#endif
|
|
|
typedef Vbitreverse TSTCLASS;
|
typedef Vbitreverse TSTCLASS;
|
|
|
|
#ifdef DBLCLKFFT
|
|
#define iaddr VVAR(_iaddr)
|
|
#else
|
#define iaddr VVAR(_wraddr)
|
#define iaddr VVAR(_wraddr)
|
|
#endif
|
#define in_reset VVAR(_in_reset)
|
#define in_reset VVAR(_in_reset)
|
|
|
VerilatedVcdC *trace = NULL;
|
VerilatedVcdC *trace = NULL;
|
uint64_t m_tickcount = 0;
|
uint64_t m_tickcount = 0;
|
|
|
void tick(TSTCLASS *brev) {
|
void tick(TSTCLASS *brev) {
|
m_tickcount++;
|
m_tickcount++;
|
|
|
brev->i_clk = 0;
|
brev->i_clk = 0;
|
brev->eval();
|
brev->eval();
|
if (trace) trace->dump((uint64_t)(10ul*m_tickcount-2));
|
if (trace) trace->dump((vluint64_t)(10ul*m_tickcount-2));
|
brev->i_clk = 1;
|
brev->i_clk = 1;
|
brev->eval();
|
brev->eval();
|
if (trace) trace->dump((uint64_t)(10ul*m_tickcount));
|
if (trace) trace->dump((vluint64_t)(10ul*m_tickcount));
|
brev->i_clk = 0;
|
brev->i_clk = 0;
|
brev->eval();
|
brev->eval();
|
if (trace) {
|
if (trace) {
|
trace->dump((uint64_t)(10ul*m_tickcount+5));
|
trace->dump((vluint64_t)(10ul*m_tickcount+5));
|
trace->flush();
|
trace->flush();
|
}
|
}
|
|
|
brev->i_ce = 0;
|
brev->i_ce = 0;
|
}
|
}
|
Line 115... |
Line 119... |
}
|
}
|
|
|
return r;
|
return r;
|
}
|
}
|
|
|
|
#ifdef DBLCLKFFT
|
|
#define BREVMASK (FFTMASK>>1)
|
|
#define BREVBITS (FFTBITS-1)
|
|
#else
|
|
#define BREVMASK FFTMASK
|
|
#define BREVBITS FFTBITS
|
|
#endif
|
|
|
int main(int argc, char **argv, char **envp) {
|
int main(int argc, char **argv, char **envp) {
|
Verilated::commandArgs(argc, argv);
|
Verilated::commandArgs(argc, argv);
|
Verilated::traceEverOn(true);
|
Verilated::traceEverOn(true);
|
TSTCLASS *brev = new TSTCLASS;
|
TSTCLASS *brev = new TSTCLASS;
|
int syncd = 0;
|
int syncd = 0;
|
Line 147... |
Line 159... |
brev->i_in = k;
|
brev->i_in = k;
|
datastore[(dataidx++)&(DATAMSK)] = brev->i_in;
|
datastore[(dataidx++)&(DATAMSK)] = brev->i_in;
|
#endif
|
#endif
|
tick(brev);
|
tick(brev);
|
|
|
|
#ifdef DBLCLKFFT
|
|
printf("k=%3d: IN = %6lx,%6lx OUT = %6lx,%6lx SYNC = %d\t(%2x) %d\n",
|
|
k, brev->i_in_0, brev->i_in_1,
|
|
brev->o_out_0, brev->o_out_1, brev->o_sync,
|
|
brev->iaddr, brev->in_reset);
|
|
#else
|
printf("k=%3d: IN = %6lx, OUT = %6lx, SYNC = %d\t(%2x) %d\n",
|
printf("k=%3d: IN = %6lx, OUT = %6lx, SYNC = %d\t(%2x) %d\n",
|
k, brev->i_in, brev->o_out, brev->o_sync,
|
k, brev->i_in, brev->o_out, brev->o_sync,
|
brev->iaddr, brev->in_reset);
|
brev->iaddr, brev->in_reset);
|
|
#endif
|
|
|
if ((k>BREV_OFFSET)&&((BREV_OFFSET==(k&FFTMASK))?1:0) != brev->o_sync) {
|
if ((k>BREV_OFFSET)&&((BREV_OFFSET==(k&BREVMASK))?1:0) != brev->o_sync) {
|
fprintf(stdout, "FAIL, BAD SYNC (k = %d > %d)\n", k, BREV_OFFSET);
|
fprintf(stdout, "FAIL, BAD SYNC (k = %d > %d)\n", k, BREV_OFFSET);
|
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
} else if (brev->o_sync) {
|
} else if (brev->o_sync) {
|
syncd = 1;
|
syncd = 1;
|
}
|
}
|
|
#ifdef DBLCLKFFT
|
|
if ((syncd)&&((brev->o_out_0&BREVMASK) != bitrev(FFTBITS, k+1-BREV_OFFSET))) {
|
|
fprintf(stdout, "FAIL: BITREV.0 of k (%2x) = %2lx, not %2lx\n",
|
|
k, brev->o_out_0, bitrev(FFTBITS, (k+1-BREV_OFFSET)));
|
|
// exit(EXIT_FAILURE);
|
|
}
|
|
#else
|
if ((syncd)&&((brev->o_out&FFTMASK) != bitrev(FFTBITS, k-BREV_OFFSET))) {
|
if ((syncd)&&((brev->o_out&FFTMASK) != bitrev(FFTBITS, k-BREV_OFFSET))) {
|
fprintf(stdout, "FAIL: BITREV.0 of k (%2x) = %2lx, not %2lx\n",
|
fprintf(stdout, "FAIL: BITREV.0 of k (%2x) = %2lx, not %2lx\n",
|
k, brev->o_out, bitrev(FFTBITS, (k-BREV_OFFSET)));
|
k, brev->o_out, bitrev(FFTBITS, (k-BREV_OFFSET)));
|
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
}
|
}
|
|
#endif
|
}
|
}
|
|
|
for(int k=0; k<4*(FFTSIZE); k++) {
|
for(int k=0; k<4*(FFTSIZE); k++) {
|
brev->i_ce = 1;
|
brev->i_ce = 1;
|
#ifdef DBLCLKFFT
|
#ifdef DBLCLKFFT
|