Previous journal: | Next journal: |
---|---|
0051-2020-08-04.md | 0053-2020-08-06.md |
Created t01c
. It's mostly the same as t01b
but has an internal overflow
register. This gets set when it counts from 255 to 0, but otherwise is unused. We get a warning to that effect:
$ verilator -Wall --cc counter.v --exe --build sim_main.cpp
%Warning-UNUSED: counter.v:7:5: Signal is not used: 'overflow'
: ... In instance counter
7 | reg overflow;
| ^~~~~~~~
... Use "/* verilator lint_off UNUSED */" and lint_on around source to disable this message.
%Error: Exiting due to 1 warning(s)
With -Wall
specified, it stops the build right there.
In conflict with what this said in 2017, internal module signals are not exactly accessed using the v__DOT__...
pattern. Specifically, this is what I found:
- Internal signals are not exposed by default, or so it seems. When I ran
verilator
using the command-line above, the resulting source code files inobj_dir
have no mention ofoverflow
in them. Eitheroverflow
was "optimised out" (because it has no effect and is not an output) or Verilator is choosing not to expose them in any accessible way. - You can use the
--public
switch with Verilator, and this then does expose a member variable with the namecounter__DOT__overflow
. Note that the doco for--public
says that it "is only for historical debug use". It warns about effects it might have on simulation of generated clocks. - It might be better to use
--public-flat-rw
. I'm not really sure what the difference is between the two.
Anyway, I did this:
verilator --public-flat-rw --cc counter.v --exe --build sim_main.cpp
...and was then able to access m_core->counter__DOT__overflow
in the code. Thus, I could run:
$ obj_dir/Vcounter +verilator+rand+reset+0
Cold start...
[00000000] counter.q=0 counter.(overflow)=0
Counted 0
[00000001] counter.q=1 counter.(overflow)=0
[00000002] counter.q=2 counter.(overflow)=0
[00000003] counter.q=3 counter.(overflow)=0
[00000004] counter.q=4 counter.(overflow)=0
[00000005] counter.q=5 counter.(overflow)=0
Synchronous reset...
[00000006] counter.q=0 counter.(overflow)=0
Main loop...
Counted 0
[00000007] counter.q=1 counter.(overflow)=0
[00000008] counter.q=2 counter.(overflow)=0
[00000009] counter.q=3 counter.(overflow)=0
[00000010] counter.q=4 counter.(overflow)=0
[00000011] counter.q=5 counter.(overflow)=0
[00000012] counter.q=6 counter.(overflow)=0
[00000013] counter.q=7 counter.(overflow)=0
[00000014] counter.q=8 counter.(overflow)=0
...
[00000103] counter.q=97 counter.(overflow)=0
[00000104] counter.q=98 counter.(overflow)=0
[00000105] counter.q=99 counter.(overflow)=0
[00000106] counter.q=100 counter.(overflow)=0
Counted 100
[00000107] counter.q=101 counter.(overflow)=0
[00000108] counter.q=102 counter.(overflow)=0
...
[00000115] counter.q=109 counter.(overflow)=0
[00000116] counter.q=110 counter.(overflow)=0
- counter.v:19: Verilog $finish
[00000117] counter.q=111 counter.(overflow)=0
...and:
$ obj_dir/Vcounter +verilator+rand+reset+1
Cold start...
[00000000] counter.q=255 counter.(overflow)=1
Counted 255
[00000001] counter.q=0 counter.(overflow)=0
Counted 0
[00000002] counter.q=0 counter.(overflow)=0
Counted 0
[00000003] counter.q=0 counter.(overflow)=0
Counted 0
[00000004] counter.q=0 counter.(overflow)=0
Counted 0
[00000005] counter.q=0 counter.(overflow)=0
Synchronous reset...
Counted 0
[00000006] counter.q=0 counter.(overflow)=0
Main loop...
Counted 0
[00000007] counter.q=1 counter.(overflow)=0
[00000008] counter.q=2 counter.(overflow)=0
[00000009] counter.q=3 counter.(overflow)=0
...
(the rest is the same as above)
Note above that we see reset
held on, for those initial ticks.
Don't forget that the initial reset()
call does a clock tick. In the output above we see the result of q <= 0
after reset
has been asserted, and then we see this:
[00000007] counter.q=1 counter.(overflow)=0
...which is the result after tick()
has completed.
My dev VM is a bit old:
$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description: Ubuntu 16.04.3 LTS
Release: 16.04
Codename: xenial
That's from 2016, and while it has Verilator, it is a bit old (pre-dating 4.x) so I will build from source:
sudo apt-get install git make autoconf g++ flex bison
# The following two are for Ubuntu, but neither were required for my system.
# In fact, the first one gave an (ignorable) error.
sudo apt-get install libfl2
sudo apt-get install libfl-dev
cd ~/projects
git clone https://github.com/verilator/verilator
unset VERILATOR_ROOT
cd verilator
git pull
git checkout stable
autoconf
./configure
make
sudo make install
OK, it's in the $PATH
now:
$ which verilator
/usr/local/bin/verilator
$ verilator --version
Verilator 4.038 2020-07-11 rev v4.038-8-gdd03d0f
No need to set $VERILATOR_ROOT
, I think, because evidently it is a "Compiled in default if not in environment
".
I tried running verilator
against my t01c
example, but it failed: obj_dir/Vcounter.mk
referred to the platform-specific VERILATOR_ROOT
of my Mac which differs from that in my Ubuntu VM. I guess the answer is that obj_dir
could probably be excluded from the git repo. I ended up deleting it, and then could built a binary that was compatible with my Linux VM:
cd ~/shared_projects/sandpit/fpga/verilator/test01/t01c
rm -rf obj_dir
verilator --public-flat-rw --cc counter.v --exe --build sim_main.cpp
obj_dir/Vcounter
# Cold start...
# [00000000] counter.q=0 counter.(overflow)=0
# Counted 0
# [00000001] counter.q=1 counter.(overflow)=0
# [00000002] counter.q=2 counter.(overflow)=0
# [00000003] counter.q=3 counter.(overflow)=0
# [00000004] counter.q=4 counter.(overflow)=0
# [00000005] counter.q=5 counter.(overflow)=0
# Synchronous reset...
# [00000006] counter.q=0 counter.(overflow)=0
# Main loop...
# Counted 0
# [00000007] counter.q=1 counter.(overflow)=0
# [00000008] counter.q=2 counter.(overflow)=0
# [00000009] counter.q=3 counter.(overflow)=0
# ...
NOTE: Even though I don't have a desktop environment in my Ubuntu VM, I could still use Verilator to generate a raw data file for something like Eric Eastwood's VGA Simulator.
- Read more about VPI
- Read more about generated clocks, starting maybe with this bit.
- Online tool for rendering frames from VCD-like simple text data representing the state of VGA signals at various timecodes: Eric Eastwood's VGA Simulator
- higan-verilog is some sort of interesting blend of a SNES emulator with a Verilog hook for selectively modifying reads/writes. See also: GitHub repo
- Why not have a look at the VGAtonic that fits in an XC95144XL?
- Icarus Verilog