Verilog中的表达式符号
下面是一小段Verilog代码。我希望它返回三个相同的结果,都是-1的8位表示Verilog中的表达式符号,verilog,Verilog,下面是一小段Verilog代码。我希望它返回三个相同的结果,都是-1的8位表示 module trivial; reg we; reg [7:0] c; initial begin c = 8'd3; we = 1'b1; $display ("res(we) = %d", (we ? (-$signed(c)) / 8'sd2 : 8'd0)); $display ("res(1) = %
module trivial;
reg we;
reg [7:0] c;
initial
begin
c = 8'd3;
we = 1'b1;
$display ("res(we) = %d", (we ? (-$signed(c)) / 8'sd2 : 8'd0));
$display ("res(1) = %d", (1'b1 ? (-$signed(c)) / 8'sd2 : 8'd0));
$display ("res = %d", (-$signed(c)) / 8'sd2);
end
endmodule
简单地说,我的标准版本(1364-2001)在第4.1.5节中说,除法向零舍入,所以-3/2=-1。它还在第4.5节中指出,运算符符号仅取决于操作数(编辑:但仅适用于“自定表达式”;结果表明,有必要将标准符号部分与宽度部分一起阅读。因此,带除法的子表达式应该不受其使用的上下文的影响,同样,对于涉及$signed的子表达式也是如此。所以结果应该是一样的
三个不同的模拟器不适合我。他们中只有两个人彼此同意。表面原因是使用了无符号除法,而不是我所期望的有符号除法。(-3=253,253/2=126.5)
有人能告诉我模拟器是否正确,为什么?(见下文)我肯定错过了什么,但请告诉我什么?非常感谢编辑:请参见上面我缺少的内容。我现在认为Icarus中有一个bug,另外两个模拟器是正确的
注意:三元选择中未使用的值似乎没有任何区别,无论是有符号的还是无符号的编辑:这是不正确的,可能是我在用带符号的数字重试之前忘记保存修改过的测试
Modelsim的Altera版本:
$ vsim work.trivial -do 'run -all'
Reading C:/altera/12.1/modelsim_ase/tcl/vsim/pref.tcl
# 10.1b
# vsim -do {run -all} work.trivial
# Loading work.trivial
# run -all
# res(we) = 126
# res(1) = 126
# res = -1
GPL-Cver
GPLCVER_2.12a of 05/16/07 (Cygwin32).
Copyright (c) 1991-2007 Pragmatic C Software Corp.
All Rights reserved. Licensed under the GNU General Public License (GPL).
See the 'COPYING' file for details. NO WARRANTY provided.
Today is Mon Jan 21 18:49:05 2013.
Compiling source file "trivial.v"
Highest level modules:
trivial
res(we) = 126
res(1) = 126
res = -1
Icarus Verilog 0.9.6
$ iverilog.exe trivial.v && vvp a.out
res(we) = 126
res(1) = -1
res = -1
NCSIM提供:
res(we) = 126
res(1) = 126
res = -1
但是如果mux的所有输入都是有符号的,我得到:
$display ("res(we) = %d", (we ? (-$signed(c)) / 8'sd2 : 8'sd0)); //last argument now signed
$display ("res(1) = %d", (1'b1 ? (-$signed(c)) / 8'sd2 : 8'sd0));
$display ("res = %d", (-$signed(c)) / 8'sd2);
res(we) = -1
res(1) = -1
res = -1
请记住,如果我们使用无符号数进行任何算术,则该算术将作为无符号进行,使用位选择时也会发生同样的情况:
reg signed [7:0] c;
c = c[7:0] + 7'sd1; //<-- this is unsigned
reg签名[7:0]c;
c=c[7:0]+7'sd1//