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

在verilog中创建可变宽度的常量向量,verilog,Verilog,我正在写一些可合成的Verilog。我需要创建一个值,在更大的表达式中用作掩码。当长度存储在某个寄存器中时,该值为1的序列: buffer & {offset{1'h1}}; 其中缓冲区和偏移量都是寄存器。我所期望的是缓冲区与11111进行AND运算。。。宽度偏移。然而,编译器说这在verilog中是非法的,因为偏移量必须是常量 相反,我写了以下内容: buffer & ~({WIDTH{1'h1}} << offset) 其中宽度为常数。这很有效。这两个表达式

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

buffer & {offset{1'h1}}; 
其中缓冲区和偏移量都是寄存器。我所期望的是缓冲区与11111进行AND运算。。。宽度偏移。然而,编译器说这在verilog中是非法的,因为偏移量必须是常量

相反,我写了以下内容:

buffer & ~({WIDTH{1'h1}} << offset)
其中宽度为常数。这很有效。这两个表达式在值方面是等价的,但在将被合成的硬件方面显然不是


有什么区别吗?

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


同样,常数不是某个东西的宽度,而是{1}重复的次数。因此,示例的第二部分在语法上是正确的

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

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


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

从语义上讲,请注意,在第二部分中,缓冲区与移位的否定进行And运算。如果从1111开始左移,我得到,比如说,11100,然后是否定-,00011,这是我需要的-,一系列的。我想我的问题的答案是因为语言标准这么说。但是我正在为这样一个决定寻找更深层次的工程原因。对不起,我错过了否定部分。