1.进行verilog代码的编写
module example(
input a,
input b,
output f
);
assign f=a^b ;
endmodule
2.紧接着进行验证代码的编写
#include <verilated.h>
#include <verilated_vcd_c.h>
#include "Vexample.h"
#define MAX_SIM_TIME 300
vluint64_t sim_time = 0;
int main(int argc, char** argv, char** env) {
Verilated::commandArgs(argc, argv);
Vexample *dut = new Vexample;
Verilated::traceEverOn(true);
VerilatedVcdC *m_trace = new VerilatedVcdC;
dut->trace(m_trace, 5);
m_trace->open("waveform.vcd");
while (sim_time < MAX_SIM_TIME) //主函数
{
int a = rand() % 2; //随机产生但比特信号
int b = rand() % 2; //随机产生但比特信号
dut->a =a ; //对dut中的信号a赋值
dut->b =b ; //对dut中的信号b赋值
dut->eval(); //通过 `eval()`函数更新电路的状态
if (dut->f != (a^b)) //查看结果是否与预期相符合
{
std::cout<<"ERROR: f mismatch, "<< "exp: "
<< (int)(a^b) <<"simtime: "
<<sim_time<<std::endl;
}
m_trace->dump(sim_time); //将对应的时间dump进去
sim_time++ ; //循环结束前,把时间加1 .
}
m_trace->close();
delete dut;
exit(EXIT_SUCCESS);
}
3.Makefile脚本编写
MODULE=example //文件名**
.PHONY:sim
sim: waveform.vcd
.PHONY:verilate
verilate: .stamp.verilate
PHONY:build
build: obj_dir/Vexample
.PHONY:waves
waves: waveform.vcd
waves: waveform.vcd
@echo
@echo "### WAVES ###"
gtkwave waveform.vcd
waveform.vcd: ./obj_dir/V$(MODULE)
@echo
@echo "### SIMULATING ###"
./obj_dir/V$(MODULE) +verilator+rand+reset+2
./obj_dir/V$(MODULE): .stamp.verilate
@echo
@echo "### BUILDING SIM ###"
make -C obj_dir -f V$(MODULE).mk V$(MODULE)
.stamp.verilate: $(MODULE).v tb_$(MODULE).cpp
@echo
@echo "### VERILATING ###"
verilator -Wall --trace --x-assign unique --x-initial unique -cc $(MODULE).v --exe tb_$(MODULE).cpp
@touch .stamp.verilate
.PHONY:lint
lint: $(MODULE).v
verilator --lint-only $(MODULE).v
.PHONY: clean
clean:
rm -rf .stamp.*;
rm -rf ./obj_dir
rm -rf waveform.vcd
4.结果展示:
make sim //使用makefile进行仿真,得到waveform.vcd文件
gtkwave waveform.vcd //打开波形文件
如果将dut中的逻辑更改之后,会产生报错信息
由此可见,添加:std::cout<<"ERROR: f mismatch, "<< "exp: " << (int)(a^b) <<"simtime: "<<sim_time<<std::endl;
这条语句是十分有帮助的,对于检查错误