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

Subversion Repositories openarty

[/] [openarty/] [trunk/] [sim/] [verilated/] [enetctrl_tb.cpp] - Rev 58

Compare with Previous | Blame | View Log

////////////////////////////////////////////////////////////////////////////////
//
// Filename: 	enetctrl_tb.cpp
//
// Project:	OpenArty, an entirely open SoC based upon the Arty platform
//
// Purpose:	To determine whether or not the enetctrl Verilog module works.
//		Run this program with no arguments.  If the last line output
//	from it is "SUCCESS", you will know it works.  Alternatively you can
//	look at the return code.  If the return code is 0 (EXIT_SUCCESS), then
//	the test passed, ,otherrwise it failed.
//
// Creator:	Dan Gisselquist, Ph.D.
//		Gisselquist Technology, LLC
//
////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2015-2016, 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 "verilated.h"
#include "verilated_vcd_c.h"
#include "Venetctrl.h"
#include "enetctrlsim.h"
 
const int	BOMBCOUNT = 2048;
 
class	ENETCTRL_TB {
	unsigned long	m_tickcount;
	Venetctrl	*m_core;
	ENETCTRLSIM	*m_sim;
	bool		m_bomb;
	VerilatedVcdC	*m_trace;
 
public:
 
	ENETCTRL_TB(void) {
		m_core = new Venetctrl;
		m_sim  = new ENETCTRLSIM;
		Verilated::traceEverOn(true);
		m_trace = NULL;
		m_tickcount = 0;
	}
 
	~ENETCTRL_TB(void) {
		if (m_trace) {
			m_trace->close();
			delete	m_trace;
		}
	}
 
	int	operator[](const int index) { return (*m_sim)[index]; }
 
	void	trace(const char *fname) {
		if (!m_trace) {
			m_trace = new VerilatedVcdC;
			m_core->trace(m_trace, 99);
			m_trace->open(fname);
		}
	}
 
	void	tick(void) {
		m_core->i_mdio = (*m_sim)(0, m_core->o_mdclk,
			((m_core->o_mdwe)&(m_core->o_mdio))
				|((m_core->o_mdwe)?0:1));
 
#ifdef	DEBUGGING_OUTPUT
		printf("%08lx-WB: %s %s %s%s %s@0x%02x[%04x/%04x] -- %d[%d->(%d)->%d]",
			m_tickcount,
			(m_core->i_wb_cyc)?"CYC":"   ",
			(m_core->i_wb_stb)?"STB":"   ",
			(m_core->o_wb_stall)?"STALL":"     ",
			(m_core->o_wb_ack)?"ACK":"   ",
			(m_core->i_wb_we)?"W":"R",
			(m_core->i_wb_addr)&0x01f, (m_core->i_wb_data)&0x0ffff,
			(m_core->o_wb_data)&0x0ffff,
			(m_core->o_mdclk), (m_core->o_mdio),
			(m_core->o_mdwe), (m_core->i_mdio));
 
		printf(" [%02x,%d%d%d,%x] ",
			m_core->v__DOT__reg_pos,
			0, // m_core->v__DOT__rclk,
			m_core->v__DOT__zclk,
			m_core->v__DOT__zreg_pos,
			m_core->v__DOT__ctrl_state);
		printf(" 0x%04x/0x%04x ", m_core->v__DOT__write_reg,
				m_core->v__DOT__read_reg);
		printf(" %s%s ", 
			(m_core->v__DOT__read_pending)?"R":" ",
			(m_core->v__DOT__write_pending)?"W":" ");
 
		printf(" %s:%08x,%2d,%08x ",
			(m_sim->m_synched)?"S":" ",
			m_sim->m_datareg, m_sim->m_halfword,
			m_sim->m_outreg);
 
		printf("\n");
#endif
 
		if ((m_trace)&&(m_tickcount>0)) m_trace->dump(10*m_tickcount-2);
		m_core->eval();
		m_core->i_clk = 1;
		m_core->eval();
		if (m_trace) m_trace->dump(10*m_tickcount);
		m_core->i_clk = 0;
		m_core->eval();
		if (m_trace) m_trace->dump(10*m_tickcount+5);
 
		m_tickcount++;
 
		if ((m_core->o_wb_ack)&&(!m_core->i_wb_cyc)) {
			printf("SETTING ERR TO TRUE!!!!!  ACK w/ no CYC\n");
			// m_bomb = true;
		}
	}
 
	void wb_tick(void) {
		// printf("WB-TICK()\n");
		m_core->i_wb_cyc   = 0;
		m_core->i_wb_stb = 0;
		tick();
	}
 
	unsigned wb_read(unsigned a) {
		int		errcount = 0;
		unsigned	result;
 
		printf("WB-READ(%08x)\n", a);
 
		m_core->i_wb_cyc = 1;
		m_core->i_wb_stb = 1;
		m_core->i_wb_we  = 0;
		m_core->i_wb_addr= a & 0x01f;
 
		if (m_core->o_wb_stall)
			while((errcount++ < BOMBCOUNT)&&(m_core->o_wb_stall))
				tick();
		tick();
 
		m_core->i_wb_stb = 0;
 
		while((errcount++ <  BOMBCOUNT)&&(!m_core->o_wb_ack))
			tick();
 
 
		result = m_core->o_wb_data;
 
		// Release the bus?
		m_core->i_wb_cyc = 0;
		m_core->i_wb_stb = 0;
 
		if(errcount >= BOMBCOUNT) {
			printf("SETTING ERR TO TRUE!!!!!\n");
			m_bomb = true;
		} else if (!m_core->o_wb_ack) {
			printf("SETTING ERR TO TRUE--NO ACK, NO TIMEOUT\n");
			m_bomb = true;
		}
		tick();
 
		return result;
	}
 
	void	wb_read(unsigned a, int len, unsigned *buf) {
		int		errcount = 0;
		int		THISBOMBCOUNT = BOMBCOUNT * len;
		int		cnt, rdidx;
 
		printf("WB-READ(%08x, %d)\n", a, len);
 
		while((errcount++ < BOMBCOUNT)&&(m_core->o_wb_stall))
			wb_tick();
 
		if (errcount >= BOMBCOUNT) {
			m_bomb = true;
			return;
		}
 
		errcount = 0;
 
		m_core->i_wb_cyc = 1;
		m_core->i_wb_stb = 1;
		m_core->i_wb_we  = 0;
		m_core->i_wb_addr= a & 0x01f;
 
		rdidx =0; cnt = 0;
 
		do {
			int	s;
			s = (m_core->o_wb_stall==0)?0:1;
			tick();
			if (!s)
				m_core->i_wb_addr = (m_core->i_wb_addr+1)&0x1f;
			cnt += (s==0)?1:0;
			if (m_core->o_wb_ack)
				buf[rdidx++] = m_core->o_wb_data;
		} while((cnt < len)&&(errcount++ < THISBOMBCOUNT));
 
		m_core->i_wb_stb = 0;
 
		while((rdidx < len)&&(errcount++ < THISBOMBCOUNT)) {
			tick();
			if (m_core->o_wb_ack)
				buf[rdidx++] = m_core->o_wb_data;
		}
 
		// Release the bus?
		m_core->i_wb_cyc = 0;
 
		if(errcount >= THISBOMBCOUNT) {
			printf("SETTING ERR TO TRUE!!!!! (errcount=%08x, THISBOMBCOUNT=%08x)\n", errcount, THISBOMBCOUNT);
			m_bomb = true;
		} else if (!m_core->o_wb_ack) {
			printf("SETTING ERR TO TRUE--NO ACK, NO TIMEOUT\n");
			m_bomb = true;
		}
		tick();
	}
 
	void	wb_write(unsigned a, unsigned int v) {
		int errcount = 0;
 
		printf("WB-WRITE(%08x) = %08x\n", a, v);
		m_core->i_wb_cyc = 1;
		m_core->i_wb_stb = 1;
		m_core->i_wb_we  = 1;
		m_core->i_wb_addr= a & 0x01f;
		m_core->i_wb_data= v;
 
		if (m_core->o_wb_stall)
			while((errcount++ < BOMBCOUNT)&&(m_core->o_wb_stall))
				tick();
		tick();
 
		m_core->i_wb_stb = 0;
 
		while((errcount++ <  BOMBCOUNT)&&(!m_core->o_wb_ack))
			tick();
 
		// Release the bus?
		m_core->i_wb_cyc = 0;
		m_core->i_wb_stb = 0;
 
		if(errcount >= BOMBCOUNT) {
			printf("SETTING ERR TO TRUE!!!!!\n");
			m_bomb = true;
		} tick();
	}
 
	void	wb_write(unsigned a, unsigned int ln, unsigned int *buf) {
		unsigned errcount = 0, nacks = 0;
 
		m_core->i_wb_cyc = 1;
		for(unsigned stbcnt=0; stbcnt<ln; stbcnt++) {
			m_core->i_wb_stb = 1;
			m_core->i_wb_we  = 1;
			m_core->i_wb_addr= (a+stbcnt) & 0x01f;
			m_core->i_wb_data= buf[stbcnt];
			errcount = 0;
 
			do {
				tick(); if (m_core->o_wb_ack) nacks++;
			} while((errcount++ < BOMBCOUNT)&&(m_core->o_wb_stall));
		}
 
		m_core->i_wb_stb = 0;
 
		errcount = 0;
		while((nacks < ln)&&(errcount++ < BOMBCOUNT)) {
			tick();
			if (m_core->o_wb_ack) {
				nacks++;
				errcount = 0;
			}
		}
 
		// Release the bus
		m_core->i_wb_cyc = 0;
		m_core->i_wb_stb = 0;
 
		if(errcount >= BOMBCOUNT) {
			printf("SETTING ERR TO TRUE!!!!!\n");
			m_bomb = true;
		} tick();
	}
 
	bool	bombed(void) const { return m_bomb; }
 
};
 
int main(int  argc, char **argv) {
	Verilated::commandArgs(argc, argv);
	ENETCTRL_TB	*tb = new ENETCTRL_TB;
	unsigned	v;
	// unsigned	*rdbuf;
 
	tb->trace("enetctrl.vcd");
 
	tb->wb_tick();
	tb->wb_write(0, 0x7f82);
	if ((*tb)[0] != 0x7f82) {
		printf("Somehow wrote a %04x, rather than 0x7f82\n", (*tb)[0]);
		goto test_failure;
	}
 
	tb->wb_tick();
	if ((v=tb->wb_read(0))!=0x7f82) {
		printf("READ A %08x FROM THE CORE, NOT 0x7f82\n", v);
		goto test_failure;
	}
 
	// 
	tb->wb_tick();
	tb->wb_write(14, 0x5234);
 
	tb->wb_tick();
	if (tb->wb_read(14)!=0x5234)
		goto test_failure;
 
	printf("SUCCESS!!\n");
	exit(EXIT_SUCCESS);
test_failure:
	printf("FAIL-HERE\n");
	for(int i=0; i<64; i++)
		tb->tick();
	printf("TEST FAILED\n");
	exit(EXIT_FAILURE);
}
 

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.