Verilator-电路RTL仿真器使用

使用示例

南京大学电路教学项目-NVboard,可以图形化显示过程状态和数据,同时也支持verilator。

双控开关

Makefile

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
VERILATOR_FLAGS := --build -j 0 -cc --exe -x-assign fast -Wall

C_SRC := $(shell ls csrc/*.cpp)
V_SRC := $(shell ls vsrc/*.v)
OBJ_DIR := obj_dir
TARGET := obj_dir/Vtop
#TARGET_ARGS := +trace

.PHONY: run clean

ifdef TRACE
VERILATOR_FLAGS += --trace
endif

all: ${TARGET}

run: ${TARGET}
@rm -rf logs
@${TARGET} ${TARGET_ARGS}

${TARGET}: ${V_SRC} ${C_SRC}
#@verilator --build -j 0 -cc --exe -x-assign fast -Wall --trace $^
@verilator ${VERILATOR_FLAGS} $^

sim:
$(call git_commit, "sim RTL") # DO NOT REMOVE THIS LINE!!!
@echo "Write this Makefile by your self."

include ../Makefile

clean:
@rm -rf logs
@rm -rf ${OBJ_DIR}

verilog代码文件top.v

1
2
3
4
5
6
7
8
9
10
11
12
13
14
module top
(
input a,
input b,
output f
);

assign f = a ^ b;

initial begin
$display("[%0t] Model running...\n", $time);
end

endmodule

主体仿真文件sim_main.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <stdint.h>
#include <memory>
#include "Vtop.h"
#include "verilated.h"

#if VM_TRACE_VCD
#include "verilated_vcd_c.h"
#endif

int main(int argc, char** argv)
{
const std::unique_ptr<VerilatedContext> contextp{new VerilatedContext};
contextp->debug(0); // Set debug level, 0 is off, 9 is highest
contextp->randReset(2); // Randomization reset policy
contextp->commandArgs(argc, argv); // Pass arguments so Verilated code can see them

// "TOP" will be hierarchical name of the module.
const std::unique_ptr<Vtop> top{new Vtop{contextp.get(), "TOP"}};

#if VM_TRACE_VCD
Verilated::mkdir("logs");
contextp->traceEverOn(true); // Verilator must compute traced signals
const std::unique_ptr<VerilatedVcdC>tfp{new VerilatedVcdC};
top->trace(tfp.get(), 99); // Trace 99 levels of hierarchy (or see below)
tfp->open("logs/simu_top.vcd");
printf("Start trace ...\n");
#endif

uint64_t sim_time = 10000;
while(contextp->time()<sim_time && !contextp->gotFinish())
{
contextp->timeInc(1);

int a = rand() & 1;
int b = rand() & 1;
top->a = a;
top->b = b;
top->eval();
// printf("a = %d, b = %d, f = %d, time = %lu\n", a, b, top->f, contextp->time());
assert(top->f == (a ^ b));

#if VM_TRACE_VCD
tfp->dump(contextp->time());
#endif
}

top->final();

// Coverage analysis
#if VM_COVERAGE
Verilated::mkdir("logs");
contextp->converagep()->write("logs/coverage.dat");
#endif

// Final simulation summary
contextp->statsPrintSummary();

return 0;
}