always 块
本课属于 Coddy Verilog 学习旅程的“基础知识”单元。第 46 课,共 90 课。
过程块是一段代码,其中的语句会像 C 或 Python 等软件编程语言中那样,按照顺序依次执行。Verilog 有两种过程块:initial(运行一次)和 always(持续运行)。我们先从 always 块开始。
always 块会持续运行。仿真开始后,它会永远重复执行。它用于描述需要持续运行的硬件,例如触发器、计数器和组合逻辑。
基本语法:
always @(sensitivity_list) begin
// 反复运行的代码
end@(sensitivity_list) 会告诉代码块何时执行。如果没有它(并且块内没有像 #5 这样的延迟),代码块就会无限循环,导致仿真卡住。
always 块示例:计数器
下面是一个使用 always 块创建计数器的示例。
module counter (
input clk,
output reg [3:0] count
);
always @(posedge clk) count <= count + 1;
endmodule这段代码的工作原理
| 部分 | 含义 |
|---|---|
always | 反复运行这段代码,永不停止 |
@(posedge clk) | 等待时钟从 0 变为 1(上升沿) |
count <= count + 1 | 取出 count 的当前值,加上 1,再存回去 |
每当时钟出现上升沿时,这个代码块就会运行。每次运行时,count 都会加 1。
敏感列表 @(posedge clk) 告诉它只在时钟边沿执行,而不是持续执行。没有它,循环就会一直运行,没有延迟。
带多个信号的 always 块
你可以列出特定信号:
always @(a or b) begin
out = a & b;
enda 或 b 发生变化时,这段代码会运行。
挑战
添加缺失的 always 块,让这个模块正常工作。
工作原理:
- 每次时钟上升沿到来时,
out1都会在 0 和 1 之间切换 out2跟随out1(与out1的值相同)
操作步骤:
- 添加一个
always @(posedge clk)块 - 在块内,让
out1切换(使用out1 = ~out1) - 让
out2等于out1
亲手试试
module toggler (
input clk,
output reg out1,
output reg out2
);
initial begin
out1 = 0;
out2 = 0;
end
// TODO:添加一个使用 posedge clk 的 always 块
// out1 在每个时钟周期切换一次
// out2 跟随 out1
endmodule这节课包含一个小测验。开始学习即可作答,并记录你的进度。
基础知识中的所有课
自己练习: Verilog 在线编译器