Altifigence Academy

10 / 37 · 概念

组合 RTL 与完整赋值

用条件运算符与 always_comb 表达同一函数,找出导致锁存器的遗漏赋值。

组合电路的输出由当前输入决定

MUX多路选择器 根据选择信号,把多个输入之一连接到输出的组合电路。必须规定选择位与输入编号的对应关系。了解更多最直接的写法是 assign y = sel ? b : a;。同时计算多个输出时,可使用 always_comb。

SystemVerilog
always_comb begin
  y = a;
  if (sel) y = b;
end

先赋默认值,就定义了 sel=0 的路径。反之,若只写 if (sel) y = b;,sel=0 时必须保持过去的 y,这就不再是纯组合函数。不能忽略工具警告,也不能只相信 always_comb 这个关键字。

先将 y 默认赋为 a,仅在 sel=1 时选择 b,与下方电路具有相同的 0/1 组合功能。即使 sel=0,输出也一定有明确值。

默认赋值覆盖的两条路径

y = sel ? b : a

不要仅按软件执行顺序理解过程语法

组合块通常用阻塞赋值 = 计算临时结果。同一块中,后面的表达式读取前面已赋的结果时,这一依赖会形成组合路径。应将它与用于时序寄存器寄存器 存储多位状态的电路。本课程中的同步寄存器在时钟边沿存储指定输入。了解更多更新的非阻塞非阻塞赋值 时序 RTL 中以 <= 表示的赋值。先计算右侧,再预约更新,使同一边沿的各寄存器能够依据旧状态计算。了解更多赋值 <= 区分。

SystemVerilog
always_comb begin
  next_y = sel ? b : a;
  inverted_y = ~next_y;
end

另一个基本规则是不要让多个块驱动同一输出。模块越多,越需要在接口中追踪“这个信号唯一的驱动者是谁”。

两个数据输入位宽不同时,先对齐

若在 8 位与 12 位数据间选择,必须明确 y 的位宽和符号扩展。应在设计阶段确定输入范围,而不是靠波形偶然发现隐式扩展是否符合意图。在 0/1 模型之外,sel 为 X 时条件运算符的含义可能不同于简单 if,因此不能把本课程的两态结果推广到整个四态域。

自己试试

always_comb 中只有 if(en) y=d;。如何将它改为 enable 无效时输出 0 的组合电路?

阅读解释

在块开始处将 y 赋为 0,再在 en 有效时用 d 覆盖;或使用等价于 assign y = en ? d : 0 且位宽明确的表达式。en=0 时保持旧值,是寄存器或锁存器的另一种规格,与输出 0 的功能不同。

你的选择适用于此浏览器,可随时在页脚更改。