7月初,毕业离校就开始自学IC验证,某乎上面建议学习verilog、systemverilog、UVM。
花了三天时间看完了一本verilog语法,知道一些规则,就结合FPGA实战项目(状态机、交通灯等),学习了数字电路、Verilog,熟悉语法点、看的懂部分代码,通过quartus II进行了仿真(功能仿真、后仿真);
后来又去某乎,别人建议参考绿皮书、红宝书、白皮书学习systemverilog、UVM,这有颜色的书是什么呀?于是乎,就去各大辅导机构招生群里咨询,最终确认:
接下来就去啃这三本书,看路桑的V2视频,学完SystemVerilog、UVM,会简单使用Questasim,只做了几个简单的练习,但是抛过课程,自己连个interface都不会写,别说自己写出testbench,发现这和FPGA的项目完全不一样。后来就去练习Synopsys公司的一个的SV实验,但实验教程上面使用的VCS逻辑仿真工具,我用Questasim会出错,于是就去找VCS。结果呢?
好吧,结果电脑BIOS进不去,虚拟化没办法打开,虚拟机没办法安装,申请了免费的服务器,被迫学习linux、shell、gvim。然后发现服务器上安装不了图形化界面。好吧,人生中真正属于自己的电脑该有了,把去年攒的奖学金全部拿出来,刚好入手战神Z7-CT7NA(i7-9750H、GTX1660Ti)。
//flop.v
module flop(data,clock,clear,q,qb);
input data,clock,clear;
output q,qb;
nand #10 nd1(a,data,clock,clear), // 注意结束时用逗号,最后才用分号
nd2(b,ndata,clock), // 表示nd1 到nd8 都是nand(与非门)
nd4(d,c,b,clear),
nd5(e,c,nclock),
nd6(f,d,nclock),
nd8(qb,q,f,clear);
nand #9 nd3(c,a,d),
nd7(q,e,qb);
not #10 iv1(ndata,data),
iv2(nclock,clock);
endmodule
由已经设计成的模块来构成更高一层的模块
引用上面的模块flop,构成一个四位寄存器,代码如下:
//hardreg.v
//` include " flop.v"
module hardreg(d,clk,clrb,q);
input clk,clrb;
input[3:0] d;
output[3:0] q;
flop f1(d[0],clk,clrb,q[0],), // 注意结束时用逗号,最后才用分号
f2(d[1],clk,clrb,q[1],), // 表示f1 到f4 都是flop
f3(d[2],clk,clrb,q[2],),
f4(d[3],clk,clrb,q[3],);
endmodule
既然四位寄存器的verilog已经出炉了,我最关心的部分已经来了。
testbench代码如下。
//hardreg_top.v
//`include "flop.v"
//`include " hardreg.v" //仿真时需要包含文件"hardreg.v" 和 "flop.v"
/***如果仿真环境可以把有关的文件安排在一个项目中,只要底层模块经过编译,并记录在编译的库中,可以不用包含文件。**/
module hardreg_top; //顶层模块,没有输入和输出的端口
reg clock, clearb; //为产生测试用的时钟和清零信号需要寄存器
reg [3:0] data; //为产生测试用数据需要用寄存器
wire [3:0] qout; //为观察输出信号需要从模块实例端口中引出线
`define stim #100 data=4'b //宏定义 stim,可使源程序简洁
event end_first_pass; //定义事件end_first_pass
hardreg reg_4bit (.d(data), .clk(clock), .clrb(clearb), .q(qout));
/************************************************************************
把本模块中产生的测试信号data、clock、clearb输入实例reg_4bit以观察输出信号qout。
实例reg_4bit实际上是已经设计好的模块hardreg。
实例引用的hardreg模块,根据包含文件的不同, 可以是表示行为的模块也可以是表示结构的模块。
***********************************************************************/
initial
begin
clock = 0;
clearb = 1;
end
always #50 clock = ~clock;
always @(end_first_pass)
clearb = ~clearb;
always @(posedge clock)
$display("at time %0d clearb= %b data= %d qout= %d",
$time, clearb, data, qout);
/*****************************************************
类似于C语言的 printf 语句,可打印不同时刻的信号值
******************************************************/
initial
begin
repeat(4) //重复四次产生下面的data变化
begin
data=4'b0000;
`stim 0001;
/***************************************************************
宏定义stim引用,等同于 #100 data=4'b0001;。注意引用时要用 `符号。
******************************************************/
`stim 0010;
`stim 0011;
`stim 0100;
`stim 0101;
`stim 0110;
`stim 0111;
`stim 1000;
`stim 1001;
`stim 1010;
`stim 1011;
`stim 1100;
`stim 1101;
`stim 1110;
`stim 1111;
#200 -> end_first_pass;
end
/***********************************************
延迟200个单位时间,触发事件end_first_pass
************************************************/
$finish; //结束仿真
end
endmodule
运行上面的命令,产生的效果如下(是不是多了两个文件):
好吧,我暂且认为是自己的testbench中没有加$vcdpluson()造成的。
1、编译
要想有波形文件,必须在testbench中加入$vcdpluson类似的的语句,最简单的格式如下:
initial begin
$vcdpluson;
end
编译的时候,必须加上“+vcd+vcdpluson”开关,在仿真时才能产生波形文件,使用如下命令编译:
vcs *.v -l readme.log +v2k -debug_all +vcd+vcdpluson
vcs *.v 就是编译的主要命令
-l readme.log 就是把编译过程记录在文件readme.log中,以备后面查看
+v2k 好像是遵守verilog 2005 标准编译吧
-debug_all 就是打开所有的debug开关,还有-debug_pp、-debug
+vcd+vcdpluson 在仿真时才能产生波形文件
2.仿真
命令如下:
./simv -l run.log
./simv 就可以生成波形文件vcdpluson.vpd
-l run.log 把仿真的过程记录在文件run.log中,以备后面查看
3.看波形
dve –vpd vcdpluson.vpd
结果又报错了,尽管打开了dve,但是打不开波形文件
修改文件名,继续!结果不知道为什么是这样!就这样吧
我现在真的不知道该怎么学习验证了。昨天问学长,他怎么学的verilog,他说就简单看了一下verilog语法,也没练习。我该怎么做呀!有点难搞,炸裂,裂开。