【问题标题】:Verilog shift extending result?Verilog移位扩展结果?
【发布时间】:2014-04-28 05:26:25
【问题描述】:
我们有以下代码行,我们知道regF 是 16 位长,regD 是 8 位长,regE 是 8 位长,regC 是 3 位长并且假定为无符号:
regF <= regF + ( ( regD << regC ) & { 16{ regE [ regC ]} }) ;
我的问题是:移位regD << regC 会假设结果是 8 位,还是会因为按位 & 与 16 位向量而扩展到 16 位?
【问题讨论】:
标签:
verilog
hdl
synthesis
flip-flop
【解决方案1】:
移位子表达式本身的宽度为8位;移位的位宽始终是左操作数的位宽(参见 2005 LRM 中的表 5-22)。
但是,在那之后事情变得更加复杂。 shift 子表达式显示为& 运算符的操作数。 & 表达式的位长是 2 个操作数中最大的位长;在本例中为 16 位。
这个子表达式现在显示为+ 表达式的操作数;这个表达式的结果宽度又是+的两个操作数的最大宽度,又是16。
我们现在有一个任务。这在技术上不是操作数,但使用相同的规则;在这种情况下,LHS 也是 16 位,因此 RHS 的大小不受影响。
我们现在知道整体表达式大小为 16 位;除了“自行确定”的操作数外,这个大小会向下传播到操作数。这里唯一的自定操作数是移位表达式的 RHS (regC),它没有被扩展。
现在已确定表达式的符号。传播以同样的方式发生。由于我们至少有一个无符号操作数,这里的整体效果是表达式是无符号的,并且所有操作数都被强制为无符号。因此,在实际执行任何操作之前,所有(非自行确定的)操作数都被强制转换为无符号 16 位。
因此,换句话说,移位子表达式实际上以 16 位移位结束,尽管乍一看它似乎是 8 位。请注意,它不是 16 位,因为& 的 RHS 是 16 位,但是因为整个大小调整过程 - 表达式的宽度传播 - 出现了答案为 16。如果您分配给 18 位 reg,而不是 16 位 regF,那么您的移位将扩展到 18 位。
这一切都非常复杂且不直观,至少如果您对主流语言有任何经验的话。在 2005 LRM 的 5.4 和 5.5 部分(或多或少)解释了这一点。如果你想要任何建议,那么永远不要写这样的表达式。防御性写作 - 将所有内容分解为单独的子表达式,然后组合子表达式。