verilator is, well, I will just paste the wiki one-liner here
Verilator is a free and open-source software tool which converts Verilog to a cycle-accurate behavioral model in C++ or SystemC.
Similar to iverilog, It compiles verilog to a different language but verilator generates C++ not the iverilog-specific commands.
Installation Link to heading
git clone https://github.com/verilator/verilator
autoconf
./configure --prefix=`pwd`/build
make install
Or we can use the pre-built packages. Whatever easier!
Hello World Link to heading
I am using an example shipped with verilator. This is the command to build the top.v
and sim_main.cpp
and run the compiled executable.
verilator -cc --exe top.v sim_main.cpp
cd obj_dir
make -f Vtop.mk
./Vtop
And the world famous hello world!
Hello World!
- top.v:11: Verilog $finish
For top.v
, it doesn’t need much explanation here
module top;
initial begin
$display("Hello World!");
$finish;
end
endmodule
The verilator runner uses the generated C++ for top
module and calls eval()
until end of simulation.
#include <verilated.h>
#include "Vtop.h"
int main(int argc, char** argv, char** env) {
Vtop* top = new Vtop;
while (!Verilated::gotFinish()) {
top->eval();
}
top->final();
delete top;
return 0;
}
Beyond Hello world Link to heading
Now that we got hello world out of the way, Let’s dig deeper into Vtop.cpp
and Vtop.h
.
VL_MODULE(Vtop) {
public:
Vtop(const char* name="TOP");
~Vtop();
void eval();
VL_MODULE
make Vtop
inherits VerilatedModule
Which probably have common methods called in the Vtop model, I assume.
#define VL_MODULE(modname) class modname VL_NOT_FINAL : public VerilatedModule
Starting with eval
(I removed commants and debug messages to keep it short), I will go through _eval_initial_loop
because it is short and sweet and good enough to show how initial
is evaluated.
void Vtop::eval() {
VL_DEBUG_IF(VL_DBG_MSGF("+++++TOP Evaluate Vtop::eval\n"); );
Vtop__Syms* __restrict vlSymsp = this->__VlSymsp; // Setup global symbol table
Vtop* __restrict vlTOPp VL_ATTR_UNUSED = vlSymsp->TOPp;
// Initialize
if (VL_UNLIKELY(!vlSymsp->__Vm_didInit)) _eval_initial_loop(vlSymsp);
...
...
Vtop::_eval_initial
calls Vtop::_initial__TOP__1
and Vtop::_initial__TOP__1
calls methods generated to print `Hello World!'.
void Vtop::_initial__TOP__1(Vtop__Syms* __restrict vlSymsp) {
VL_DEBUG_IF(VL_DBG_MSGF("+ Vtop::_initial__TOP__1\n"); );
Vtop* __restrict vlTOPp VL_ATTR_UNUSED = vlSymsp->TOPp;
// Body
// INITIAL at top.v:9
VL_WRITEF("Hello World!\n");
VL_FINISH_MT("top.v",11,"");
}
...
...
void Vtop::_eval_initial(Vtop__Syms* __restrict vlSymsp) {
VL_DEBUG_IF(VL_DBG_MSGF("+ Vtop::_eval_initial\n"); );
Vtop* __restrict vlTOPp VL_ATTR_UNUSED = vlSymsp->TOPp;
// Body
vlTOPp->_initial__TOP__1(vlSymsp);
}