1.Verilog的运行方式
一阴一阳之谓道 《易经》
0 介绍
Verilog的功能有两个:
- 模拟硬件
- 测试的模拟的硬件
1.0 verilog模型框架
Verilog是一门可以来描述硬件的语言。
硬件有几个层面:
- 物理 - 材料的模型,如半导体,化学等等
- 电路 - 场效管/晶体管/mosfet的模型
- 逻辑门 - 与/或/异或门的模型
- 行为 - 数学公式的模型
Verilog可以模拟2-4,同常用的是在3-4的层面。
物理的模拟就得用其它的工具了,如hspice。这里就不赘述了。
以下会有一些列子。它们都是为了描述一个非门。
1.1 电路模型
module fei_dianlu(input jia, output yi);
nmos(yi, 0, jia);
pmos(yi, 1, jia);
endmodule;
1.2 逻辑门模型
module fei_men(input jia, output yi)
NOT(yi, jia);
endmodule;
1.3 行为模型
module fei_xingwei(input jia, output yi);
assign yi = ~jia;
endmodule
此三个模块都有同样的效果。不同任务就需要用不一样的模型编写方式。
2.0 verilog仿真框架
Verilog不仅可以描述硬件,也可以直接的测试它。
当然,也有一些工具如verilator 可以将verilog变成C++,然后用C++来测试。为了方便和容易上手,这里只会用verilog原生的测试框架来进行测试。
就是说,verilog可以用来,
- 模拟硬件
- 写测试的代码
前者已经讨论了,后者就在以下来讨论一下。
2.1 测试框架
测试框架如同C/Java的入口函数。
module main;
initial begin
//测试代码
end
endmodule
比如说,
module main;
initial begin
$display("nihao! hello world!");
$finish;
end
endmodule
3.0 合并模型和测试框架
有了模型和测试框架两者,就可以运行了。
如以下的文件fei.v,
//模型
module fei_xingwei(input jia, output yi);
assign yi = ~jia;
endmodule
//测试
module main;
initial begin
$display("nihao! hello world!");
$finish;
end
endmodule
3.1 连接
有了此两个模块,该如何连接呢?加三行就可以了
//模型
module fei_xingwei(input jia, output yi);
assign yi = ~jia;
endmodule
//测试
module main;
reg a;//新
wire b;//新
fei_xingwei dut(a, b);//新
//fei_xingwei dut(.jia(a), .yi(b));//也可以这样写
initial begin
$display("nihao! hello world!");
$finish;
end
endmodule
3.2 测试数据
有了连接,现在该如何来测试了?这个可以这样做,
//模型
module fei_xingwei(input jia, output yi);
assign yi = ~jia;
endmodule
//测试
module main;
reg a;
wire b;
fei_xingwei dut(.jia(a), .yi(b));
initial begin
a = 0; //新
#1;
$display("a = %b, b = %b", a, b);//改
a = 1; //新
#1;
$display("a = %b, b = %b", a, b);//改
$finish;
end
endmodule
运行就可以了!
4. 注意的点
4.1 input, output
verilog 的模块的参数需要input,output(或inout)的修实。不加的话会有一下的错误
liu2333hui@liu2333hui-PC:~/verilog/nihao$ epicsim fei.v
fei.v:1: error: Port jia (1) of module fei has no direction declaration.
fei.v:1: error: Port yi (2) of module fei has no direction declaration.
fei.v:1: error: signal jia in module main.dut is not a port.
fei.v:1: : Are you missing an input/output/inout declaration?
fei.v:1: error: signal yi in module main.dut is not a port.
fei.v:1: : Are you missing an input/output/inout declaration?
4 error(s) during elaboration.
4.2 reg/wire
reg/wire在模拟和测试的用法有一点小的区别。先不讨论模拟的用法因为会比较复杂。
测试的时候,reg对应的是input (可控), wire 对应的是output(被控的). 如果弄反了会导致有错误。
如把wire(output)连接input会有,
...
wire a; // 问题
wire b;
fei dut(.jia(a), .yi(b));
...
liu2333hui@liu2333hui-PC:~/verilog/nihao$ epicsim fei.v
fei.v:18: error: a is not a valid l-value in main.
fei.v:10: : a is declared here as wire.
1 error(s) during elaboration.
如把reg(input)连接output会有,
...
reg a;
reg b; // 问题
fei dut(.jia(a), .yi(b));
...
liu2333hui@liu2333hui-PC:~/verilog/nihao$ epicsim fei.v
fei.v:13: error: reg b; cannot be driven by primitives or continuous assignment.
fei.v:13: error: Output port expression must support continuous assignment.
fei.v:13: : Port 2 (yi) of fei is connected to b
2 error(s) during elaboration.
改错就可以通过了
...
reg a;
wire b;
fei dut(.jia(a), .yi(b));
...
liu2333hui@liu2333hui-PC:~/verilog/nihao$ epicsim fei.v
a = 0, b = 1
4.3 ;和begin/end
注意,verilog的语句里没有{}
,要用 begin
和end
还有,语句后都要加一个;
4.4 时序#
为了让电路的输出信号变的稳定,就得给电路足够的时间。
用#
就可以了,它代表时间的延迟。如#10
代表十个拍子,#1
一个。
如果不加的话会有信号不稳定的情况。
如,
liu2333hui@liu2333hui-PC:~/verilog/nihao$ epicsim test.v
a = 0, b = x
a = 1, b = x
4.5 $display
display就如同C的printf, python的print。
这里%b
代表二进制的数据。