文章目录
- 前言
- 一、实现方式
-
- 1.always_ff
- [2. always](#2. always)
- 二、比较
前言
如何在当前时刻采样上一拍的值?采用always_ff
和 always
一、实现方式
1.always_ff
bash
module example_always_ff (
input logic clk,
input logic rstn,
input logic a,
output logic q
);
always_ff @(posedge clk or negedge rstn) begin
if (!rstn) begin
q <= 0; // 使用非阻塞赋值
end else begin
q <= a; // 使用非阻塞赋值
end
end
endmodule
- 敏感列表:明确要求只能在时钟边沿或复位信号变化时触发。
- 赋值方式:只允许使用非阻塞赋值 (<=),确保在时钟边沿时更新信号的行为符合时序逻辑的预期。一般推荐在时序逻辑中使用非阻塞赋值(<=)
2. always
bash
module example_always (
input logic clk,
input logic rstn,
input logic a,
output logic q
);
always @(posedge clk or negedge rstn) begin
if (!rstn) begin
q = 0; // 使用阻塞赋值
end else begin
q = a; // 使用阻塞赋值
end
end
endmodule
- 敏感列表:指定时钟和复位信号。
- 赋值方式:使用了阻塞赋值 (=),这可能导致在同一时钟周期内出现时序问题
二、比较
通常建议使用 always_ff
,原因如下:
-
语义清晰:
always_ff
明确表示这是一个时序逻辑块,适合描述寄存器或触发器的行为。这种清晰的语义使得代码更易于理解和维护。
always
可以用于组合和时序逻辑,可能导致混淆,尤其是在复杂设计中。 -
敏感列表管理:
always_ff
自动管理敏感列表,只允许时钟边沿和复位信号,减少了设计错误的机会。
always
需要手动指定敏感列表,容易出现遗漏或错误。 -
赋值方式:
always_ff
只 允许使用非阻塞赋值 (<=),这有助于确保时序逻辑的正确性,避免潜在的时序问题。
always
可以使用阻塞赋值(=),在时序逻辑中可能导致意外的行为。
总的来说,推荐使用 always_ff
来实现时序逻辑,因为它提供了更好的可读性、可维护性和设计安全性。在设计复杂的数字电路时,使用 always_ff
可以减少错误并提高代码的质量。如果你的设计环境支持 SystemVerilog
,尽量利用这些新特性。
always
:适用于组合逻辑和时序逻辑,但需要手动管理敏感列表和赋值方式。
always_ff
:专门用于时序逻辑,强制使用非阻塞赋值,减少设计错误。
always_comb
: SystemVerilog
的组合逻辑描述方式,自动管理敏感列表。