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

Subversion Repositories dblclockfft

[/] [dblclockfft/] [trunk/] [bench/] [cpp/] [qtrstage_tb.cpp] - Rev 35

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

////////////////////////////////////////////////////////////////////////////
//
// Filename: 	qtrstage_tb.cpp
//
// Project:	A Doubletime Pipelined FFT
//
// Purpose:	A test-bench for the qtrstage.v subfile of the double
//		clocked FFT.  This file may be run autonomously.  If so,
//		the last line output will either read "SUCCESS" on success,
//		or some other failure message otherwise.
//
//		This file depends upon verilator to both compile, run, and
//		therefore test qtrstage.v
//
// Creator:	Dan Gisselquist, Ph.D.
//		Gisselquist Technology, LLC
//
///////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2015, Gisselquist Technology, LLC
//
// 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
// by the Free Software Foundation, either version 3 of the License, or (at
// your option) any later version.
//
// This program is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY or
// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
// for more details.
//
// 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
// target there if the PDF file isn't present.)  If not, see
// <http://www.gnu.org/licenses/> for a copy.
//
// License:	GPL, v3, as defined and found on www.gnu.org,
//		http://www.gnu.org/licenses/gpl.html
//
//
///////////////////////////////////////////////////////////////////////////
#include <stdio.h>
#include <stdint.h>
 
#include "Vqtrstage.h"
#include "verilated.h"
#include "twoc.h"
#include "fftsize.h"
 
#define	IWIDTH	TST_QTRSTAGE_IWIDTH
#define	OWIDTH	(IWIDTH+1)
#define	LGWIDTH	TST_QTRSTAGE_LGWIDTH
 
#define	ASIZ	32
#define	AMSK	(ASIZ-1)
 
#ifdef	NEW_VERILATOR
#define	VVAR(A)	qtrstage__DOT_ ## A
#else
#define	VVAR(A)	v__DOT_ ## A
#endif
 
#define	sum_r		VVAR(_sum_r)
#define	sum_i		VVAR(_sum_i)
#define	diff_r		VVAR(_diff_r)
#define	diff_i		VVAR(_diff_i)
#define	pipeline	VVAR(_pipeline)
#define	iaddr		VVAR(_iaddr)
#define	imem		VVAR(_imem)
#define	wait_for_sync	VVAR(_wait_for_sync)
 
class	QTRTEST_TB {
public:
	Vqtrstage	*m_qstage;
	unsigned long	m_data[ASIZ];
	int		m_addr, m_offset;
	bool		m_syncd;
 
	QTRTEST_TB(void) {
		m_qstage = new Vqtrstage;
		m_addr = 0; m_offset = 6; m_syncd = false;
	}
 
	void	tick(void) {
		m_qstage->i_clk = 0;
		m_qstage->eval();
		m_qstage->i_clk = 1;
		m_qstage->eval();
 
		m_qstage->i_sync = 0;
	}
 
	void	reset(void) {
		m_qstage->i_ce  = 0;
		m_qstage->i_rst = 1;
		tick();
		m_qstage->i_ce  = 0;
		m_qstage->i_rst = 0;
		tick();
 
		m_addr = 0; m_offset = 6; m_syncd = false;
	}
 
	void	check_results(void) {
		int	ir0, ii0, ir1, ii1, ir2, ii2;
		int	sumr, sumi, difr, difi, or0, oi0;
		bool	fail = false;
 
		if ((!m_syncd)&&(m_qstage->o_sync)) {
			m_syncd = true;
			m_offset = m_addr;
		}
 
		if (!m_syncd)
			return;
 
		ir0 = sbits(m_data[(m_addr-m_offset-1)&AMSK]>>IWIDTH, IWIDTH);
		ii0 = sbits(m_data[(m_addr-m_offset-1)&AMSK], IWIDTH);
		ir1 = sbits(m_data[(m_addr-m_offset  )&AMSK]>>IWIDTH, IWIDTH);
		ii1 = sbits(m_data[(m_addr-m_offset  )&AMSK], IWIDTH);
		ir2 = sbits(m_data[(m_addr-m_offset+1)&AMSK]>>IWIDTH, IWIDTH);
		ii2 = sbits(m_data[(m_addr-m_offset+1)&AMSK], IWIDTH);
 
		sumr = ir1 + ir2;
		sumi = ii1 + ii2;
		difr = ir0 - ir1;
		difi = ii0 - ii1;
 
		or0 = sbits(m_qstage->o_data >> OWIDTH, OWIDTH);
		oi0 = sbits(m_qstage->o_data, OWIDTH);
 
		if (0==((m_addr-m_offset)&1)) {
			if (or0 != sumr)	{
				printf("FAIL 1: or0 != sumr (%x(exp) != %x(sut))\n", sumr, or0); fail = true;}
			if (oi0 != sumi)	{
				printf("FAIL 2: oi0 != sumi (%x(exp) != %x(sut))\n", sumi, oi0); fail = true;}
		} else if (1==((m_addr-m_offset)&1)) {
			if (or0 != difr)	{
				printf("FAIL 3: or0 != difr (%x(exp) != %x(sut))\n", difr, or0); fail = true;}
			if (oi0 != difi)	{
				printf("FAIL 4: oi0 != difi (%x(exp) != %x(sut))\n", difi, oi0); fail = true;}
		}
 
		if (m_qstage->o_sync != ((((m_addr-m_offset)&127) == 0)?1:0)) {
			printf("BAD O-SYNC, m_addr = %d, m_offset = %d\n", m_addr, m_offset); fail = true;
		}
 
		if (fail)
			exit(-1);
	}
 
	void	sync(void) {
		m_qstage->i_sync = 1;
		m_addr = 0;
	}
 
	void	test(unsigned int data) {
		int	isync = m_qstage->i_sync;
		m_qstage->i_ce = 1;
		m_qstage->i_data = data;
		// m_qstage->i_sync = (((m_addr&127)==2)?1:0);
		m_data[ (m_addr++)&AMSK] = data;
		tick();
 
		printf("k=%4d: ISYNC=%d, IN = %08x, OUT =%09lx, SYNC=%d\t%5x,%5x,%5x,%5x\t%x %4x %8x %d\n",
			(m_addr-m_offset), isync, m_qstage->i_data,
			m_qstage->o_data, m_qstage->o_sync,
 
			m_qstage->sum_r,
			m_qstage->sum_i,
			m_qstage->diff_r,
			m_qstage->diff_i,
			m_qstage->pipeline,
			m_qstage->iaddr,
			m_qstage->imem,
			m_qstage->wait_for_sync);
 
		check_results();
	}
 
	void	test(int ir0, int ii0) {
		unsigned int	data;
 
		data = (((ir0&((1<<IWIDTH)-1)) << IWIDTH) | (ii0 & ((1<<IWIDTH)-1)));
		// printf("%d,%d -> %8x\n", ir0, ii0, data);
		test(data);
	}
 
	void	random_test(void) {
		int	ir0, ii0;
 
		// Let's pick some random values
		ir0 = rand(); if (ir0&4) ir0 = -ir0;
		ii0 = rand(); if (ii0&2) ii0 = -ii0;
		test(ir0, ii0);
	}
};
 
int	main(int argc, char **argv, char **envp) {
	Verilated::commandArgs(argc, argv);
	QTRTEST_TB	*tb = new QTRTEST_TB;
	int16_t		ir0, ii0, ir1, ii1, ir2, ii2;
	int32_t		sumr, sumi, difr, difi;
 
	tb->reset();
 
	tb->test( 16, 0);
	tb->test( 16, 0);
	tb->sync();
	tb->test(  0, 16);
	tb->test(  0, 16);
	tb->test( 16,  0);
	tb->test(-16,  0);
	tb->test(  0, 16);
	tb->test(  0,-16);
 
	for(int k=0; k<1060; k++) {
		tb->random_test();
	}
 
	delete	tb;
 
	printf("SUCCESS!\n");
	exit(0);
}
 
 
 
 
 
 

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

powered by: WebSVN 2.1.0

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