在Verilog中创建可变宽度的常量向量



我正在编写一些可合成的Verilog。我需要创建一个值以在更大的表达式中用作掩码。当长度存储在某个寄存器中时,此值是 1 的序列:

buffer & {offset{1'h1}}; 

其中bufferoffset都是寄存器。我期望的是bufferand宽度offset11111...。但是,编译器在 verilog 中说这是非法的,因为offset需要恒定。

相反,我写了以下内容:

buffer & ~({WIDTH{1'h1}} << offset)

其中WIDTH是一个常量。这行得通。这两个表达式在值方面是等效的,但显然不是在要合成的硬件方面。

有什么区别?

区别在于上下文确定表达式的规则(在 IEEE 1800-2017 LRM 的第 11.6 和 11.8 节中详细介绍(要求在编译时知道表达式的所有操作数的宽度。

您的示例太简单,无法显示复杂性出现的位置,但假设buffer是 16 位有符号变量。要执行按位和(&(,首先需要知道两个操作数的大小,然后扩展较小的操作数以匹配较大操作数的大小。如果我们不知道{offset{1'h1}}的大小是多少,我们就不知道它是否需要 0 扩展,或者buffer需要符号扩展。

当然,可以定义语言以允许这样做,以便它工作,但合成工具将创建许多不必要的额外硬件。如果我们开始将其应用于更复杂的表达式,那么试图确定位宽如何传播将变得难以管理。

您问题的两部分都暗示了replication运算符。操作员要求您使用replication constant来显示要复制的次数。因此,示例的第一部分非法的。offset必须是常量,而不是 reg。

此外,常量不是某物的宽度,而是重复{1}多次。因此,示例的第二部分在语法上是正确的。

最新更新