在verilog中,我有一个二进制值数组。如何取减去值的绝对值?
Verilog代码:
module aaa(clk);
input clk;
reg [7:0] a [1:9];
reg [7:0] s [1:9];
always@(posedge clk)
begin
s[1] = a[1] - a[2];
s[2] = a[2] - a[3];
s[3] = a[1] + a[3];
end
endmodule
我希望我的s[1]
和s[2]
值永远是正的。我怎样才能在合成的verilog中做到这一点呢?
我尝试过使用signed reg
,但它显示了一个错误。
发布于 2013-10-22 07:20:00
无论该数字是否为signed
,仍然使用两个补码,在位级正确执行加法和减法。
如果要将一个数字解释为签名,则可以使用MSB来判断它是正(0)还是负(1)。
对于绝对数字,只需根据MSB逆序:
reg [31:0] ans ; // Something else drives this value
reg [31:0] abs_ans; // Absolute version of ans
// invert (absolute value)
always @* begin
if (ans[31] == 1'b1) begin
abs_ans = -ans;
end
else begin
abs_ans = ans;
end
end
注意:使用=
是因为它是一个组合块,如果使用触发器(边缘触发器),就像@TzachiNoy提到的那样使用<=
。
发布于 2013-10-18 08:32:09
这应该能完成以下工作:
s[1] <= (a[1]>a[2])?(a[1]-a[2]):(a[2]-a[1]);
注意:您应该始终在时钟始终块中使用“<=”。
发布于 2016-03-31 23:08:58
按照@Morgan的回答,并且由于我的系统中已经有一个模块执行了这个操作,下面是我的贡献:
module Mod(
input signed [11:0] i,
output signed [11:0] o
);
assign o = i[11] ? -i : i; // This does all the magic
endmodule
下面是一个测试台:
module tb;
reg signed [11:0] i;
wire signed [11:0] o;
Mod M(i,o);
integer t;
initial begin
for (t = -10; t < 10; t = t + 1) begin
#1
i <= t;
$display("i = %d, o = %d", i, o);
end
end
endmodule
产出如下:
i = x, o = x
i = -10, o = 10
i = -9, o = 9
i = -8, o = 8
i = -7, o = 7
i = -6, o = 6
i = -5, o = 5
i = -4, o = 4
i = -3, o = 3
i = -2, o = 2
i = -1, o = 1
i = 0, o = 0
i = 1, o = 1
i = 2, o = 2
i = 3, o = 3
i = 4, o = 4
i = 5, o = 5
i = 6, o = 6
i = 7, o = 7
i = 8, o = 8
https://stackoverflow.com/questions/19423792
复制相似问题