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


11

考虑如下表达式:

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

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

我知道上面的代码已经做到了,但是它也会产生警告。“显而易见”的方法行不通:

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

Answers:


8

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

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));

我希望会有比这更好的东西...哦,好了,我将创建大量的截断函数。
user23106 2013年

5

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

明确表示截断通常可以消除模拟/皮棉/综合中的警告。

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

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];

1
我认为那只会在SystemVerilog中起作用。很有意思。
汤姆·卡彭特

@TomCarpenter,是否要限制自己使用IEEE Std 1364-2005中可用的Verilog子集,而不是使用更新的统一IEEE Std 1800修订版中可用的全套可综合Verilog?您可能要说Verilog-2005或需要澄清的东西,因为Verilog标准在2009
。– mattgately '16

3

我认为这可能有助于减少生产线数量。

wire [15:0] not_used ;

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

虽然不确定这是否与分配有效。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.