Verilog - 简而言之
所有的行为代码都写在module
里面 和 endmodule
.因此,无论您打算创建什么数字设计,它都会进入 module
堵塞。它可能有也可能没有定义端口 - 允许信号以 input
的形式进入模块 或将块转义为 output
.
模块
下例中的空模块称为 testbench .你可以随意命名,但它应该是字母数字,并且可以包含'_'。
<无脚本>
module testbench;
endmodule
让我们看看另一个模块。它有几个信号(d, clk, rstb ) 声明为输入和 q 声明为输出。
<无脚本>
module dff (input d,
clk,
rstb,
output q);
endmodule
数据类型
现在我们已经了解了模块的外观,让我们再次查看 testbench 模块,看看可以在模块中放入什么。 verilog 中主要有两种类型的数据类型:
- 注册
- 电线
reg
数据类型用于保存变量之类的值,而 wire
就像电线一样,必须连续驱动。所以通常 wire
用于连接多个模块之间,以及其他信号。
module testbench;
reg d;
reg rst_b;
reg clk;
wire q;
endmodule
作业
Verilog 有三个基本块:
always @ (条件 ) | 条件满足时执行 |
initial | 在模拟开始时只执行一次 |
assign [左轴] =[右轴] | 只要 RHS 发生变化,LHS 的值就会更新 |
编写 Verilog 时需要牢记一些规则:
reg
只能在initial
中分配 和always
块wire
只能通过assign
赋值 声明- 如果 initial/always 中有多个语句 块,它们应该被包裹在
begin .. end
module testbench;
reg d;
reg rst_b;
reg clk;
wire q;
initial begin
d = 0;
rst_b = 0;
clk = 0;
#100 $finish;
end
always begin
#10 clk = ~clk;
end
endmodule
注意 上图示例如下:
- 由于
initial
有多行 阻止,开始 和结束 被使用 - 信号 d、rst_b 和 clk 在初始块内分配,因为它们的类型为
reg
- 初始块内的代码将在 0ns 即仿真开始时执行
- 由于
always
没有条件 块,它将像 C 中的无限循环一样运行 - # 用于表示时间延迟。 #10 告诉模拟器将模拟时间提前 10 个单位。
clk = ~clk;
将切换时钟的值,因为 #10 放在语句之前,时钟将在每 10 个时间单位后切换一次。$finish
是结束模拟的方法。在这种情况下,它将运行 100 个时间单位并退出。
Verilog