跳转到内容
新建笔记

组合与时序 RTL 写法

场景写法含义
组合过程阻塞赋值 =后续语句立即看到新值
时钟过程非阻塞赋值 <=先计算右值,在当前时间步末统一更新
简单连线assign连续驱动网络

这是一条可靠的工程约定,不是语言允许范围的完整描述。

always_comb begin
result = '0;
valid = 1'b0;
if (enable) begin
result = a + b;
valid = 1'b1;
end
end

默认值覆盖所有输出,后续分支只改变化量,可避免锁存器并减少重复代码。

always_ff @(posedge clk) begin
if (rst) begin
q <= '0;
end else if (enable) begin
q <= d;
end
end

时序块中不写最后的 else 表示寄存器保持原值,这与组合块遗漏分支不同。

非阻塞赋值的周期语义

跳转到“非阻塞赋值的周期语义”
always_ff @(posedge clk) begin
a <= in;
b <= a;
c <= b;
end

在同一个上升沿,三个右值都读取旧状态,因此这是一条三级移位流水线:in 经过 1、2、3 个周期分别到达 a、b、c。书写顺序不会把它变成单周期级联。

flowchart LR
IN["in"] --> A["a 寄存器"] --> B["b 寄存器"] --> C["c 寄存器"]
always_ff @(posedge clk) begin
if (rst) begin
count <= '0;
end else if (tick) begin
count <= count + 1'b1;
end
end
logic signal_d;
always_ff @(posedge clk) begin
signal_d <= signal_sync;
end
assign rise = signal_sync & ~signal_d;

signal_sync 必须已同步到 clk 域;该写法不能替代异步输入同步器。

将长组合逻辑拆到多个寄存器阶段,可以提高最高频率,但会增加延迟。设计接口时同时记录吞吐量和周期延迟。

  • 在同一时序块混用 = 和 <= 来制造隐含顺序。
  • 一个寄存器在多个 always_ff 中赋值。
  • 把数据本身放入 always @(posedge data) 作为“时钟”。
  • 用逻辑分频信号驱动大量寄存器;优先使用时钟使能或专用时钟资源。
  • 在组合块中读取并写回同一变量形成组合反馈。