与大多数编程语言一样,我们应该尝试使尽可能多的代码可重用。这使我们能够减少未来项目的开发时间,因为我们可以更轻松地将代码从一个设计移植到另一个设计。 我们在verilog中有两个可用的结构,可以帮助我们编写可重用的代码 - 参数化和generate语句。这两种结构都允许我们创建更通用的代码,当我们实例化组件时,我们可以轻松修改这些代码以满足我们的需求。
Verilog参数化
在verilog中,参数是常量的局部形式,可以在我们实例化模块时为其赋值。由于参数的范围有限,我们可以多次调用同一个verilog模块,并为参数分配不同的值。这使我们能够动态配置模块的行为。
下面的verilog代码片段显示了在模块中声明参数的方法。当我们在这样的verilog模块中声明一个参数时,我们称之为参数化模块。
上面verilog代码中的 <parameter_name> 字段用于为我们的参数提供标识符。我们使用此标识符在代码中调用参数值,就像使用普通变量一样。我们还可以使用上面示例中的 字段为参数分配默认值。这很有用,因为它允许我们实例化组件,而无需专门为参数赋值。
当我们 verilog设计单元中实例化模块时,我们可以使用命名关联或位置关联为参数分配一个值。这与将信号分配给模块上的输入或输出完全相同。但是,当我们编写使用 verilog 1995 标准的代码时,我们只能使用位置关联为参数赋值。
下面的 verilog 代码片段显示了我们在实例化模块时用于为参数赋值的方法。
1 |
// Example of named association |
3 |
// If the module uses parameters they are connected here |
10 |
// Example of positional association |
Verilog 参数化模块示例
为了更好地理解我们如何在verilog中使用参数,让我们考虑一个基本的例子。对于此示例,让我们考虑一个需要两个同步计数器的设计。其中一个计数器宽 8 位,另一个宽 12 位。 为了实现这个电路,我们可以编写两个具有不同宽度的不同计数器模块。
然而,这是一种对电路进行编码的低效方法。相反,我们将编写单个计数器电路并使用参数来更改输出中的位数。 由于理解我们如何使用参数化模块并不重要,因此我们将排除此示例中的功能代码。相反,我们将只研究如何在 verilog中声明和实例参数化模块。
下面的 verilog 代码片段显示了我们如何为参数化计数器模块编写接口。
7 |
outputreg[BITS-1:0] count |
在这个例子中,我们看到了如何使用参数来调整verilog中信号的大小。我们不是使用固定数字来声明端口宽度,而是将参数值替换为端口声明。这是 verilog 中参数最常见的用例之一。 在上面的 verilog 代码中,我们将 BITS 参数的默认值定义为 8。因此,当我们想要一个不是 8 位的输出时,我们只需要为参数分配一个值。 下面的代码片段显示了当我们想要 12 位输出时如何实例化这个模块。在这种情况下,我们必须在实例化 verilog 模块时覆盖参数的默认值。
虽然我们在上面的示例中使用命名关联,但我们也可以使用位置关联为 verilog 中的参数赋值。
下面的代码片段显示了我们将如何使用位置关联将值 12 分配给 BITS 参数。
1 |
counter # (12) count_12 (clock, reset, count_out); |
审核编辑:刘清
评论