-
Notifications
You must be signed in to change notification settings - Fork 72
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Initial Verilator Support #3
base: master
Are you sure you want to change the base?
Changes from 4 commits
7745bbe
9ab1b8c
17e705f
c1713d2
544e3e1
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
#include <verilatedos.h> | ||
#include <stdio.h> | ||
#include <fcntl.h> | ||
#include <unistd.h> | ||
#include <string.h> | ||
#include <time.h> | ||
#include <sys/types.h> | ||
#include <signal.h> | ||
#include "verilated.h" | ||
#include "Vblinky.h" | ||
#include "testb.h" | ||
|
||
int main(int argc, char **argv) { | ||
Verilated::commandArgs(argc, argv); | ||
TESTB<Vblinky> *tb = new TESTB<Vblinky>; | ||
|
||
// 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"); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 <stdio.h> | ||
#include <stdint.h> | ||
#include <verilated_vcd_c.h> | ||
|
||
#define TBASSERT(TB,A) do { if (!(A)) { (TB).closetrace(); } assert(A); } while(0); | ||
|
||
template <class VA> 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 |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -23,11 +23,22 @@ filesets: | |
tinyfpga_bx: | ||
files: [tinyfpga_bx/pinout.pcf : {file_type : PCF}] | ||
|
||
ulx3s: | ||
files: | ||
- ulx3s/ulx3s_empty.config : {file_type : user, copyto : ulx3s_empty.config} | ||
- ulx3s/ulx3s_v20.lpf : {file_type : LPF, copyto : ulx3s_v20.lpf} | ||
|
||
upduino2: | ||
files: | ||
- 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] | ||
|
@@ -77,6 +88,15 @@ targets: | |
pnr: next | ||
toplevel : blinky | ||
|
||
ulx3s: | ||
default_tool : trellis | ||
filesets : [rtl, proginfo, ulx3s] | ||
parameters : [clk_freq_hz=25000000] | ||
tools: | ||
trellis: | ||
nextpnr_options : [--45k --basecfg ulx3s_empty.config --lpf ulx3s_v20.lpf] | ||
toplevel : blinky | ||
|
||
upduino2: | ||
default_tool : icestorm | ||
filesets : [rtl, proginfo, upduino2] | ||
|
@@ -88,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] | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I just checked that VCD generation works just fine if you create a new parameter (by adding an entry under the parameters section near the end of the core file) that looks like this
add then add the newly created vcd parameter to the list of parameters for the target (i.e. change the line above to |
||
toplevel : blinky | ||
|
||
parameters: | ||
clk_freq_hz: | ||
datatype : int | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -7,7 +7,9 @@ module blinky | |
|
||
always @(posedge clk) begin | ||
count <= count + 1; | ||
/* verilator lint_off WIDTH */ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I will add a proper fix for this |
||
if (count == clk_freq_hz-1) begin | ||
/* verilator lint_on WIDTH */ | ||
q <= !q; | ||
count <= 0; | ||
end | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be specified as
{file_type : cppSource, is_include_file : true}
so that the backend knows to include the directory of the file in the include path