Quartus 24.2中$bits结合流操作符报错:需显式类型转换的原因?
$bits结合流操作符报错的原因及解决方法 问题描述
我多年来在Modelsim、Questa、Vivado、Quartus中使用$bits结合流操作符,示例代码如下:
localparam NUMS = 4; typedef struct packed { logic [31:0] val1l; } t_fields; t_fields array_rd[NUMS]; t_fields array_wr[NUMS]; scfifo #( .lpm_width ( $bits({>>{array_rd, array_wr}}) ) ) inst ( );
但Quartus 24.2不再接受该写法,合成时在$bits({>>{array_rd, array_wr}})行报错:
Error(24461): Verilog HDL error at file.sv(281): stream operands require explicit typecast to be used as argument of system task/function
疑问:报错原因是什么?对结果进行类型转换会完全失去使用$bits的意义……
报错原因
Quartus 24.2严格遵循IEEE Std 1800 SystemVerilog标准的语法规则:流操作符{>>{...}}生成的是无类型的比特序列,而系统函数$bits要求传入的参数必须是具有明确数据类型的表达式。旧版本Quartus及其他工具做了宽松兼容,自动为流操作结果隐式推断类型,但24.2版本收紧了语法检查,因此触发该错误。
兼容且不丢失$bits意义的替代写法
不需要对流操作结果做类型转换,直接换一种符合标准的方式计算总比特数即可,结果和原写法完全一致:
方案1:直接计算两个数组的比特数之和
scfifo #( .lpm_width ( $bits(array_rd) + $bits(array_wr) ) ) inst ( );
流操作{>>{array_rd, array_wr}}本质是将两个数组的比特按顺序拼接,总长度就是两个数组各自比特数的总和,这种写法所有工具都能兼容,且完全符合标准。
方案2:使用普通拼接替代流操作(长度一致)
如果需要保持类似拼接的写法,也可以用普通数组拼接,其结果具有明确的类型,$bits可直接处理:
scfifo #( .lpm_width ( $bits({array_rd, array_wr}) ) ) inst ( );
这种写法的总比特数和流操作结果完全相同,只是比特排列顺序可能有差异(流操作是按字节/比特逆序,普通拼接是顺序),但如果仅关注总宽度,两种写法效果一致。
内容的提问来源于stack exchange,提问作者無名前

