Previous journal: | Next journal: |
---|---|
0049-2020-08-02.md | 0051-2020-08-04.md |
Let's built event-driven simulation models, in C++, from Verilog, using Verilator!
The goal: Use vgasim to display a simulation of my VGA controller. Optionally see if we can sneak in actual user interaction that generates signals ad-hoc.
This might depend on Linux?
- vgasim is designed for GTK+.
- Other screen-based rendering is designed for SDL2.
nand2tetris might also be worth another look.
There is actually another project called "VgaSim" which apparently is an alpha that displays a screen based on a raw text file of signal inputs. Might be good enough for me, for now. Looks like it's available for Windows and maybe Linux? https://sourceforge.net/projects/vgasim/files/1.0.0%20alpha/ - I had a look at the source, and it's pretty primitive, but easy to understand.
I will try installing Verilator for macOS first. There is a Homebrew package for it, apparently:
brew info verilator
verilator: stable 4.038 (bottled), HEAD
Verilog simulator
https://www.veripool.org/wiki/verilator
Not installed
From: https://github.com/Homebrew/homebrew-core/blob/HEAD/Formula/verilator.rb
License: LGPL-3.0
==> Options
--HEAD
Install HEAD version
4.038 seems to be the latest version at the time of writing, released 2020-07-11.
Doing brew install verilator
seemed to work fine and now I have:
$ verilator --version
Verilator 4.038 2020-07-11 rev v4.036-114-g0cd4a57ad
Tutorial time: See Gisselquist Technology's "Taking a New Look at Verilator" article.
There is a very clear example of how to get started – Example C++ Execution – and I followed it:
- Create
our.v
-- the module under test. - Create
sim_main.cpp
-- test bench, utilising Verilator to drive the simulation. - Run:
verilator -Wall --cc our.v --exe --build sim_main.cpp
- This seems to have run Clang to produce a bunch of output files in
obj_dir
. The nature of these files is described here. Main thing is that it creates our executable:obj_dir/Vour
- Run
obj_dir/Vour
:$ obj_dir/Vour Hello World - our.v:2: Verilog $finish
- Can build again at any time by doing:
cd obj_dir; make -f Vour.mk ; cd ..
- Test bench can manipulate/use signals exposed by the module under test. For example, this test bench (testing a module called
module
, henceVmodule
) toggles thei_clk
input signal:#include <stdlib.h> #include "Vmodule.h" #include "verilated.h" int main(int argc, char **argv) { // Initialize Verilators variables Verilated::commandArgs(argc, argv); // Create an instance of our module under test Vmodule *tb = new Vmodule; // Tick the clock until we are done while(!Verilated::gotFinish()) { tb->i_clk = 1; tb->eval(); tb->i_clk = 0; tb->eval(); } exit(EXIT_SUCCESS); }
- Verilator will stop simulation when it encounters
$finish
or when you hit CTRL+C.