为什么out1与out2有任何不同
module diff_outputs(in,out1,out2);
input in;
output out1,out2,out3;
wire [8:0] in, out1, out2;
wire [8:0] interm;
assign out1 = in>>>4 + in[3];
assign interm = in>>>4;
assign out2 = interm + in[3];
endmodule
out1和out2对于正输入是相同的。但对于负输入,out1为正,而out2为负(因此out1中的移位运算符实际上正在执行逻辑移位)
答案 0 :(得分:2)
差异是由Verilog处理无符号和有符号算术的方式引起的。 Verilog非常自由,但正因为如此,你需要熟悉它的工作原理。 3与此案相关的详细信息如下:
部分选择总是无符号
和
非基础整数文字是签名
和
如果混合有符号和无符号值,则无符号算术完成
所以,使用这个表达式
assign out1 = (in>>>4) + in[3];
in[3]
是部分选择,因此是无符号的。因此,无符号算术用于整个表达式,因此使用逻辑移位。 (使用逻辑右移,从左侧添加零。)但是,如果将其拆分为两个表达式:
assign interm = in>>>4;
assign out2 = interm + in[3];
然后签名算法用于第一个表达式(因为in
和4
都已签名),因此使用算术移位 。 (右移算术,左侧位是_sign_extended_,所以在这种情况下,从左侧添加。)第二个表达式是带符号(interm
)和无符号(in[3]
)的混合,所以使用无符号算术(如前所述)。
所以,当你做的每件事都是一个表达式时,有一个无符号和有符号的混合,所以使用了无符号算术,因此完成了逻辑右移。但是,当使用两个表达式时,shift的表达式是纯符号的,因此使用了带符号的算术,因此算术右移完成。
你会找到这个
assign out3 = $signed(in>>>4) + in[3];
的行为与双表达式的情况相同,因为$signed()
系统函数强制执行算术移位。