diff --git a/README.md b/README.md index 0a98bb0..06fa988 100644 --- a/README.md +++ b/README.md @@ -62,3 +62,7 @@ https://www.avnet.com/shop/us/products/avnet-engineering-services/aes-s6mb-lx9-g ### Upduino 2 http://www.gnarlygrey.com/ + +### ULX3S + +https://github.com/emard/ulx3s diff --git a/bench/blinky_tb.cpp b/bench/blinky_tb.cpp new file mode 100644 index 0000000..0fdfff2 --- /dev/null +++ b/bench/blinky_tb.cpp @@ -0,0 +1,40 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include "verilated.h" +#include "Vblinky.h" +#include "testb.h" + +int main(int argc, char **argv) { + Verilated::commandArgs(argc, argv); + TESTB *tb = new TESTB; + + // See if we have a +vcd=something command-line option. + // If so, create the trace.vcd file + const char *vcd = Verilated::commandArgsPlusMatch("vcd="); + if (vcd[0]) { + printf("Creating trace.vcd\n"); + tb->opentrace("trace.vcd"); + } + + // Run the simulation for 100_000 ticks + int old_q=0; + for (int i=0; i < 100000; i++) { + tb->tick(); + + // Print out if the q output has changed + if (tb->m_core->q != old_q) { + printf("LED: %d\n", tb->m_core->q); + + // and save the old q value for later comparison + old_q= tb->m_core->q; + } + } + + printf("Simulation complete\n"); +} diff --git a/bench/testb.h b/bench/testb.h new file mode 100644 index 0000000..ae542f5 --- /dev/null +++ b/bench/testb.h @@ -0,0 +1,99 @@ +//////////////////////////////////////////////////////////////////////////////// +// +// Filename: testb.h +// +// Project: Verilog Tutorial Example file +// +// Purpose: A wrapper providing a common interface to a clocked FPGA core +// being exercised by Verilator. +// +// Creator: Dan Gisselquist, Ph.D. +// Gisselquist Technology, LLC +// +//////////////////////////////////////////////////////////////////////////////// +// +// Written and distributed by Gisselquist Technology, LLC +// +// This program is hereby granted to the public domain. +// +// 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. +// +//////////////////////////////////////////////////////////////////////////////// +// +// +#ifndef TESTB_H +#define TESTB_H + +#include +#include +#include + +#define TBASSERT(TB,A) do { if (!(A)) { (TB).closetrace(); } assert(A); } while(0); + +template class TESTB { +public: + VA *m_core; + VerilatedVcdC* m_trace; + uint64_t m_tickcount; + + TESTB(void) : m_trace(NULL), m_tickcount(0l) { + m_core = new VA; + Verilated::traceEverOn(true); + m_core->clk = 0; + eval(); // Get our initial values set properly. + } + virtual ~TESTB(void) { + closetrace(); + delete m_core; + m_core = NULL; + } + + virtual void opentrace(const char *vcdname) { + if (!m_trace) { + m_trace = new VerilatedVcdC; + m_core->trace(m_trace, 99); + m_trace->open(vcdname); + } + } + + virtual void closetrace(void) { + if (m_trace) { + m_trace->close(); + delete m_trace; + m_trace = NULL; + } + } + + virtual void eval(void) { + m_core->eval(); + } + + virtual void tick(void) { + m_tickcount++; + + // Make sure we have our evaluations straight before the top + // of the clock. This is necessary since some of the + // connection modules may have made changes, for which some + // logic depends. This forces that logic to be recalculated + // before the top of the clock. + eval(); + if (m_trace) m_trace->dump((vluint64_t)(10*m_tickcount-2)); + m_core->clk = 1; + eval(); + if (m_trace) m_trace->dump((vluint64_t)(10*m_tickcount)); + m_core->clk = 0; + eval(); + if (m_trace) { + m_trace->dump((vluint64_t)(10*m_tickcount+5)); + m_trace->flush(); + } + } + + unsigned long tickcount(void) { + return m_tickcount; + } +}; + +#endif diff --git a/blinky.core b/blinky.core index 8779d6d..dc3f06e 100644 --- a/blinky.core +++ b/blinky.core @@ -33,6 +33,12 @@ filesets: - upduino2/blinky_upduino2.v : {file_type : verilogSource} - upduino2/pinout.pcf : {file_type : PCF} + verilator_tb: + files: + - bench/blinky_tb.cpp : {file_type : cppSource} + - bench/testb.h : {file_type : user} + + targets: default: filesets : [rtl] @@ -102,6 +108,15 @@ targets: pnr: next toplevel : blinky_upduino2 + verilator: + default_tool: verilator + filesets : [rtl, verilator_tb] + tools: + verilator: + verilator_options : [--trace] + parameters : [clk_freq_hz=10000] + toplevel : blinky + parameters: clk_freq_hz: datatype : int diff --git a/blinky.v b/blinky.v index 2a1c67d..96bb5f0 100644 --- a/blinky.v +++ b/blinky.v @@ -7,7 +7,9 @@ module blinky always @(posedge clk) begin count <= count + 1; +/* verilator lint_off WIDTH */ if (count == clk_freq_hz-1) begin +/* verilator lint_on WIDTH */ q <= !q; count <= 0; end