在verilog中创建一个可变宽度的常量向量
creating a constant vector of variable width in verilog
我正在编写一些可综合的 Verilog。我需要创建一个值以用作更大表达式中的掩码。当长度存储在某个寄存器中时,该值是一个 1 的序列:
buffer & {offset{1'h1}};
其中 buffer
和 offset
都是寄存器。我期望 buffer
被 and
编辑为宽度 offset
的 11111...
。但是,编译器说这在 verilog 中是非法的,因为 offset
需要保持不变。
相反,我写了以下内容:
buffer & ~({WIDTH{1'h1}} << offset)
其中 WIDTH
是常数。这行得通。这两个表达式在值方面是等价的,但显然在将要合成的硬件方面不等价。
有什么区别?
您问题的两部分都暗示了 replication
运算符。操作员要求您使用 replication constant
来显示要复制多少次。因此,您示例的第一部分 是 非法的。 offset
必须是常量,而不是 reg.
此外,常量不是某物的宽度,而是 {1}
重复的次数。因此,示例的第二部分在句法上是正确的。
不同之处在于上下文确定表达式的规则(详见 IEEE 1800-2017 LRM 的第 11.6 和 11.8 节)要求在编译时知道表达式的所有操作数的宽度。
您的示例太简单了,无法说明问题出在哪里,但假设 buffer
是 16 位有符号变量。要执行按位与 (&
),您首先需要知道两个操作数的大小,然后扩展较小的操作数以匹配较大操作数的大小。如果我们不知道 {offset{1'h1}}
的大小是多少,我们就不知道它是否需要进行 0 扩展,或者 buffer
是否需要进行符号扩展。
当然,可以定义语言以允许这样做,但综合工具会创建很多不必要的额外硬件。如果我们开始将其应用于更复杂的表达式,则试图确定位宽传播方式将变得难以管理。
我正在编写一些可综合的 Verilog。我需要创建一个值以用作更大表达式中的掩码。当长度存储在某个寄存器中时,该值是一个 1 的序列:
buffer & {offset{1'h1}};
其中 buffer
和 offset
都是寄存器。我期望 buffer
被 and
编辑为宽度 offset
的 11111...
。但是,编译器说这在 verilog 中是非法的,因为 offset
需要保持不变。
相反,我写了以下内容:
buffer & ~({WIDTH{1'h1}} << offset)
其中 WIDTH
是常数。这行得通。这两个表达式在值方面是等价的,但显然在将要合成的硬件方面不等价。
有什么区别?
您问题的两部分都暗示了 replication
运算符。操作员要求您使用 replication constant
来显示要复制多少次。因此,您示例的第一部分 是 非法的。 offset
必须是常量,而不是 reg.
此外,常量不是某物的宽度,而是 {1}
重复的次数。因此,示例的第二部分在句法上是正确的。
不同之处在于上下文确定表达式的规则(详见 IEEE 1800-2017 LRM 的第 11.6 和 11.8 节)要求在编译时知道表达式的所有操作数的宽度。
您的示例太简单了,无法说明问题出在哪里,但假设 buffer
是 16 位有符号变量。要执行按位与 (&
),您首先需要知道两个操作数的大小,然后扩展较小的操作数以匹配较大操作数的大小。如果我们不知道 {offset{1'h1}}
的大小是多少,我们就不知道它是否需要进行 0 扩展,或者 buffer
是否需要进行符号扩展。
当然,可以定义语言以允许这样做,但综合工具会创建很多不必要的额外硬件。如果我们开始将其应用于更复杂的表达式,则试图确定位宽传播方式将变得难以管理。