always块在时序逻辑和组合逻辑都会用到。
always语法
always @ (event)
[statement]
always @ (event) begin
[multiple statements]
end
- 组合逻辑用法:
always@(*)begin
out = a&b&c&d;
end
- 时序逻辑用法:
例如一个同步复位的D触发器:
always@(posedge clk) begin
if(rst_n) begin
q <= 0;
end
else begin
q <= d;
end
end
这表示当检测到时钟上升沿时,判断是否复位有效,如果有效对输出复位,否则采样输入d值。
异步复位D触发器:
always@(posedge clk or negedge rst_n) begin
if(!rst_n) begin
q <= 0;
end
else begin
q <= d;
end
end
这表示当检测到时钟上升沿或者复位的上升沿时,都会触发always块内部的语句。
但是明显看出,复位的优先级更高,也就是说,当检测到复位的上升沿时,无论时钟边沿是否检测到都执行复位操作,否则,当检测到时钟上升沿时,采样输入值d。
敏感列表
敏感列表是指always@()括号中的触发事件,
always @ (a or b) begin //a和b都是触发列表事件,当a/b发生变化时,执行always块中的语句
[statements]
end
无敏感列表用法
在Testbench中,采用没有敏感列表的always的不断触发的特性生成时钟,
always #10 clk = ~clk;
上述表示每过10个仿真事件,clk就翻转一次。
当然,这种没有敏感列表的显示延迟,是不能综合的,只能用于仿真。
组合逻辑实例
module combo ( input a,
input b,
input c,
input d,
output reg o);
always @ (a or b or c or d) begin
o <= ~((a & b) | (c^d));
end
endmodule
时序逻辑实例
该模块接受数据输入,时钟和低电平有效复位。每当在时钟的上升沿发现d为1 时,输出就会反相。此处,该always块在clk的上升沿或rst_n的下降沿触发。
module tff (input d,
clk,
rstn,
output reg q);
always @ (posedge clk or negedge rst_n) begin
if (!rst_n)
q <= 0;
else begin
if (d)
q <= ~q;
else
q <= q;
end
end
endmodule