我不明白。出于某种原因,<
运算符返回0,即使a
明显小于0.该函数仅在我使用a[15]
检查符号位时才有效。
N = 16;
wire signed [15:0] a;
assign a = -100;
function [N-1:0] abs (input signed [N-1:0] a);
abs = (a < {N{1'b0}}) ? -a : a;
endfunction
答案 0 :(得分:4)
问题是{N{1'b0}}
是无符号值。当verilog比较无符号和有符号值时,它会将这两个值视为无符号。
以下引用存在于IEE1364-2005(Verilog)§5.1.7和IEEE1800-2012(SystemVerilog)&amp;第11.4.4节。几乎相同的引用在IEEE1364-2001(Verilog)§4.1.7:
中当关系表达式的一个或两个操作数无符号时,表达式应解释为无符号值之间的比较。如果操作数的位长度不相等,则较小的操作数应该零扩展到较大操作数的大小。
当两个操作数都被签名时,表达式应被解释为有符号值之间的比较。如果操作数的位长不相等,则较小的操作数应符号扩展为较大操作数的大小。
你需要将unsinged转换为signed,即$signed({N{1'b0}})
。或者,您可以查看a
的MSB以了解它是否为负数。
parameter N = 16;
wire signed [N-1:0] a;
assign a = -100;
function [N-1:0] abs_old (input signed [N-1:0] a);
abs_old = (a < {N{1'b0}}) ? -a : a; // unsigned compare
endfunction
function [N-1:0] abs_new (input signed [N-1:0] a);
abs_new = (a < $signed({N{1'b0}})) ? -a : a; // signed compare
endfunction
function [N-1:0] abs_msb (input signed [N-1:0] a);
abs_msb = (a[N-1]) ? -a : a; // MSB check
endfunction
initial begin
$strobe("a:%0d abs(old):%0d", a, abs_old(a)); // a:-100 abs(old):65436
$strobe("a:%0d abs(new):%0d", a, abs_new(a)); // a:-100 abs(new):100
$strobe("a:%0d abs(msb):%0d", a, abs_msb(a)); // a:-100 abs(msb):100
end
答案 1 :(得分:2)
试试这个:
N = 16;
reg signed [15:0] a;
assign a = -100;
function [N-1:0] abs (input signed [N-1:0] a);
abs = (a < 0) ? -a : a;
endfunction
我将变量'a'更改为reg,当你在函数中进行比较时,我会与'0'进行比较而不是向量,并且事情按预期工作。