Verilog 参数

17 Mar 2025 | 5 分钟阅读

在 Verilog 中,参数是常量,不属于任何其他数据类型,例如寄存器或网络数据类型。

常量表达式是指常量数字或先前定义的参数。我们无法在运行时修改参数值,但可以使用 defparam 语句修改参数值。

defparam 语句只能在编译时修改参数。可以使用带模块实例化的 # 延迟规范来修改参数值。

Verilog 中,有两种方法可以在模块实例化期间覆盖模块参数值。

  1. 使用 defparam 关键字。
  2. 以及模块实例参数值赋值。

在 defparam 关键字之后,指定参数的层次路径和参数的新值。这个新值应该是一个常量表达式。如果右侧表达式引用任何参数,则应在调用 defparam 的模块中声明它。

模块实例参数值赋值方法看起来像是将延迟分配给门实例。此方法覆盖实例化模块中的参数,因为它们出现在模块中。使用此格式,无法跳过参数。

常量表达式可以包含先前声明的参数。当检测到先前声明的参数发生更改时,所有依赖于该值的参数都会自动更新。

考虑一下,一个 4 位加法器可以被参数化为接受位数的值,并且可以在模块实例化期间传递新的参数值。因此,N 位加法器转换为 4 位、8 位或 16 位加法器。它们就像在函数调用期间传递给函数的参数。

有两种类型的参数,modulespecify,两者都接受范围规范。但是,它们被制作得与要存储它们的值一样宽,因此不需要范围规范。

模块参数

它可以用于覆盖模块内的参数定义,并使模块在编译时具有不同的参数集。可以使用 defparam 语句修改参数。通常在参数名称中使用大写字母,以便立即注意到它们。

下面的模块使用参数来指定总线宽度、数据宽度和设计中 FIFO 的深度,并且可以在实例化模块时或使用 defparam 语句来覆盖这些参数。

在 Verilog 端口声明的新 ANSI 样式中,我们可以声明诸如以下的参数

覆盖参数

可以在模块实例化期间使用新值覆盖参数。第一部分是由名称为 d0 的 design_ip 调用的模块,其中在 # ( ) 中传递新参数。

第二部分是使用一个称为 defparam 的 Verilog 构造来设置新的参数值。第一种方法通常用于在 RTL 设计中传递新参数。第二种方法用于测试平台仿真,以便快速更新设计参数,而无需重新实例化模块。

模块计数器有两个参数 NDOWN,它们被声明为具有默认值 2 和 0。

N 控制输出中的位数,从而有效地控制计数器的宽度。 默认情况下,它是一个 2 位计数器。

参数 DOWN 控制计数器是递增还是递减。 由于参数设置为 0,因此计数器将递减。

2 位向上计数器

模块计数器实例化为 N 为 2,即使这不是必需的,因为无论如何默认值是 2。

DOWN 在模块实例化期间未传递。 它采用默认值 0,使其成为向上计数器。

默认参数用于实现计数器,其中 N 等于 2,使其成为 2 位计数器,而 DOWN 等于 0,使其成为向上计数器。 来自计数器的输出在顶层保持未连接状态。

Verilog Parameters

4 位向下计数器

在这种情况下,模块计数器实例化为 N 为 4,使其成为 4 位计数器。 在模块实例化期间,DOWN 传递值为 1,因此实现了向下计数器。


Verilog Parameters

指定参数

这些参数用于提供时间和延迟值,并使用 specparam 关键字声明。允许在指定块和主模块主体中使用两者。

指定参数和模块参数之间的差异

指定参数模块参数
指定 specparam 关键字声明参数。模块参数由参数声明。
可以在特定块内或主模块内声明。只能在主模块内声明。
此参数可以分配 specparams 和参数。这可能不会分配 specparams。
SDF 可用于覆盖值。可以使用实例声明参数值或 defparam 来覆盖。

注意事项

以下是 Verilog 参数的一些重要说明,例如

  • 如果我们使用 defparam 语句,我们必须指定参数的层次路径。
  • 我们不能在 模块实例参数值赋值 中跳过参数。如果我们需要这样做,请使用未覆盖参数的初始值。
  • 当一个参数依赖于另一个参数时,如果我们更改第一个参数,则第二个参数将自动更新。

下一个主题Verilog 时序控制