Verilog 用户自定义原语

17 Mar 2025 | 6 分钟阅读

一种建模技术,用户可以通过设计和指定称为用户自定义原语 (UDP) 的新原语元素来虚拟地扩展预定义的门原语。 这些原语是独立的,不会实例化其他原语或模块。

Verilog 提供了一组标准原语,例如 AND、NAND、 NOT、 ORNOR,作为语言的一部分。 这些也称为内置原语。

这些新 UDP 的实例可以像门原语一样使用,以表示正在建模的电路。 这种技术可以减少内存量并提高仿真性能。 Verilog-XL 算法加速了这些 UDP 的评估。

然而,设计人员有时希望在开发设计时使用他们定制构建的原语。

每个 UDP 只有一个输出,该输出可以处于以下状态之一:0、1 或 x。 不支持三态值 z。 任何具有值 Z 的输入都将被视为 X。

以下两种类型的行为可以在用户自定义原语中表示:

  1. 组合 UDP
  2. 时序 UDP

时序 UDP 使用其输入的价值和其输出的当前价值来确定输出的下一个价值。

时序 UDP 提供了一种有效且简单的方法来对时序电路(例如锁存器和触发器)进行建模。

时序 UDP 可以对电平敏感和边沿敏感的行为进行建模。 组合 UDP 的最大输入数为 10。 时序 UDP 的最大输入数限制为 9,因为内部状态算作一个输入。

语法

UDP 以保留字 primitive 开头,以 endprimitive 结尾。 原语的端口/端子应遵循。 UDP 应在 moduleendmodule 之外定义。

UDP 规则

  • UDP 仅采用标量输入端子(1 位)。
  • UDP 只能有一个标量输出。 输出端子必须始终出现在端子列表中的第一位。
  • 时序 UDP 中的状态使用初始语句进行初始化。
  • 状态表条目可以包含 0、1 或 X 的值。传递给 UDP 的 Z 值被视为 X 值。
  • UDP 的定义级别与模块相同。
  • UDP 的实例化方式与门原语完全相同。
  • UDP 不支持 inout 端口。

Verilog UDP 符号

Verilog 用户自定义原语可以写在与模块定义相同的级别,但绝不能写在 moduleendmodule 之间。 它们可以有多个输入端口,但始终只有一个输出端口,并且双向端口无效。 所有端口信号都必须是标量,这意味着它们必须是 1 位宽。

硬件行为被描述为一个原语状态表,该表列出了 tableendtable 中输入的不同可能组合及其相应的输出。 输入和输出信号的值使用以下符号表示。

符号注释
0逻辑 0
1逻辑 1
x未知,可以是逻辑 0 或 1。 它可以用作时序 UDP 的输入/输出或当前状态
?逻辑 0、1 或 x。 它不能是任何 UDP 的输出
-无变化,仅允许在 UDP 的输出中
ab值从 a 到 b 的变化,其中 a 或 b 是 0、1 或 x
*与 ?? 相同,表示输入值的任何变化
r与 01 -> 输入上的上升沿相同
f与 10 -> 输入上的下降沿相同
p输入上的潜在正沿; 0->1、0->x 或 x->1
n输入上的潜在下降沿; 1->0、x->0、1->x

组合 UDP

在组合 UDP 中,输出状态仅由当前输入状态的函数决定。 每当输入改变状态时,UDP 都会被评估,并且会匹配状态表中的一行。 输出状态设置为该行指示的值。 组合 UDP 的最大输入数为 10。

考虑以下示例,该示例定义了一个多路复用器,该多路复用器有两个数据输入和一个控制输入。 但是只能有一个输出。

?表示该信号可以是 0、1 或 x,并且在决定最终输出时无关紧要。

示例

下面是一个测试平台模块,该模块实例化 UDP 并向其应用输入激励。

时序 UDP

时序 UDP 允许在同一描述中混合使用电平敏感和边沿敏感的构造。 输出端口也应在 UDP 定义中声明为 reg 类型,并且可以选择在 initial 语句中进行初始化。

时序 UDP 采用其输入的价值和其输出的当前价值来确定其输出的下一个价值。 输出的价值也是 UDP 的内部状态。

时序 UDP 在输入和输出字段之间有一个附加字段,该字段由一个 ":" 分隔,表示当前状态。

时序 UDP 提供了一种简单有效的方法来对时序电路(例如锁存器和触发器)进行建模。 时序 UDP 的最大输入数限制为 9,因为内部状态算作一个输入。 有两种时序 UDP。

1. 电平敏感 UDP

电平敏感时序行为的表示方式与组合行为相同,不同之处在于输出被声明为 reg 类型,并且每个表条目中都有一个附加字段。

这个新字段表示 UDP 的当前状态。 时序 UDP 中的输出字段表示下一个状态。

在上面的代码中,表最后一行上的连字符 "-" 表示 q+ 的值没有变化。

2. 边沿敏感 UDP

在电平敏感行为中,输入和当前状态的值足以确定输出值。

边沿敏感行为的不同之处在于,输出的变化是由输入的特定转换触发的。

在下面的示例中,D 触发器被建模为 Verilog 用户自定义原语。 请注意,时钟的上升沿由 01 或 0? 指定。

UDP 在随机数量的时钟之后在测试平台中实例化,并以随机 d 输入值驱动。

输出 q 在 1 个时钟延迟后跟随输入 d,这是 D 触发器的期望行为。


下一个主题Verilog 仿真基础