如何在 Verilog 中截断表达式位宽?

电器工程 验证日志
2022-01-19 05:41:13

考虑如下表达式:

assign x = func(A) ^ func(B);

其中 func 的输出是 32 位宽,x 是 16 位的连线。我只想分配结果异或的最低 16 位。

我知道上面的代码已经做到了,但它也会产生一个警告。“明显”的方法不起作用:

assign x = (func(A) ^ func(B))[15:0]; // error: '[' is unexpected
3个回答

您可以使用另一个变量,尽管这不是特别优雅。

wire[31:0] y;

assign y = func(A) ^ func(B);
assign x = y[15:0];

更好的方法是使用函数。

function [15:0] trunc_32_to_16(input [31:0] val32);
  trunc_32_to_16 = val32[15:0];
endfunction

assign x = trunc_32_to_16(func(A) ^ func(B));

在您的示例中,您正在隐式截断位。

明确截断通常可以消除模拟/lint/synthesis 中的警告。

在线执行此操作的一种方法是使用强制转换运算符,例如:

typedef logic [15:0] HALF_WORD;
assign x = HALF_WORD'((func(A) ^ func(B));

如果从上下文中可以明显看出所有被丢弃的位都是 0,那么这种方法可能是有意义的。

如果某些位可能不为零,那么我建议您仍然使用类似@dwikle 在先前答案中建议的中间网络,因为它更清楚地表明您实际上是在丢弃位。这里再次供大家参考。

wire[31:0] y;

assign y = func(A) ^ func(B);
assign x = y[15:0];

我认为这可能有助于减少行数。

wire [15:0] not_used ;

assign {not_used, x} = (func(A) ^ func(B));

不确定这是否对分配有效。