代码
learning.v
module learning(input wire iflag,input wire[7:0]i1,i2,output wire[7:0]out);
add ADD(.flag(iflag),.a(i1),.b(i2),.c(out));
endmodule
module add(input flag,input[7:0]a,b,output reg[7:0]c);
always @(flag,a,b)
begin
if(flag == 1) c = a + b;
else c = a * b;
end
endmodule
注意事项
- 需要有一个和文件名同名的模块作为顶层module,有点类似于c++中的main函数;
- 在调用模块时,别忘了实例化(ADD);
- 传参时,wire给reg或者reg给wire都不影响;
learning.vt
`timescale 1 ps/ 1 ps
module learning_vlg_tst();
reg [7:0] i1;
reg [7:0] i2;
reg iflag;
wire [7:0] out;
reg clk;
learning inp (
.i1(i1),
.i2(i2),
.iflag(iflag),
.out(out)
);
always begin
#1000 clk = ~clk;
end
always@(posedge clk)
begin
i1 <= i2;
i2 <= i1;
iflag = ~iflag;
$display("i1=%d,i2=%d,flag=%d",i1,i2,iflag);
end
initial
begin
$display("Running testbench");
clk = 0;
i1 = 2;
i2 = 3;
iflag = 1;
end
endmodule
注意事项
- 需要把module实例化,实例化的名字可以随意改动,不一定用系统给的。
- 注意仿真锁死问题。
生成测试文件vt
Quartus II中 Assignment-Start-Start EDA Netlist Writer
仿真
Assignment-Settings- EDA Tool Setting- Simulation- Test Benches
导入vt文件;
编译;
仿真。
关于reg和wire的设定
在以下两种情况下,务必把数据定义为wire:
- 输出(每一个模块的输出都是这样,在顶层文件都要定义为wire);
- assign的赋值对象。
在以下两种情况,务必把数据定义为:
- always的赋值对象;
- initial中的赋值对象。
对于其他而言,比如输入,通常是定义为wire的。
.