首先,您使用的构造实际上称为复制运算符。这可能会在您以后的搜索中帮助您,例如在 the SystemVerilog LRM 中。
其次,您在最后一个代码块中使用了数组连接,而不是数组赋值(注意缺少的撇号')。 LRM 在第 10.10.1 节(未打包的数组连接与数组分配模式的比较)中给出了以下(简单)示例来解释差异:
int A3[1:3];
A3 = {1, 2, 3}; // unpacked array concatenation
A3 = '{1, 2, 3}; // array assignment pattern
LRM 在同一节中说
...未打包的数组连接禁止复制、默认和
显式类型,但它们提供了额外的灵活性
由任意混合的元素和数组组成一个数组值。
int A9[1:9];
A9 = {9{1}}; // illegal, no replication in unpacked array concatenation
让我们也看看替代方案:数组赋值。在同一部分,LRM 提到
...分配模式中的项目可以使用语法复制,例如'{ n{element} },并且可以默认使用default: 语法。但是,数组赋值模式中的每个元素项都必须与目标数组的元素类型相同。
如果将其转换为数组赋值(通过添加撇号),您的代码实际上会转换为:
AAA = '{'{1,1,1,1}, '{2,2,2}, '{3,3}, 4};
这意味着 SystemVerilog 解释器只会看到 4 个元素,并且会抱怨分配中的元素太少。
在第 10.9.1 节(数组分配模式)中,LRM 对此进行了如下说明:
连接大括号用于构造和解构简单的位向量。类似的语法用于支持数组的构造和解构。 表达式应逐个元素匹配,大括号应与数组尺寸匹配。每个表达式项应在分配给数组中相应元素类型的上下文中进行评估。
[...]
类似于复制的语法(参见 11.4.12.1)也可以用于数组分配模式。 每个复制应代表一个完整的单一维度。
为了帮助解释上面引用中的粗体文本,LRM 给出了以下示例:
int n[1:2][1:3] = '{2{'{3{y}}}}; // same as '{'{y,y,y},'{y,y,y}}