【发布时间】:2018-01-28 00:00:28
【问题描述】:
我正在研究一个 Verilog 定点加法器,我也将使用它来做减法。当我做减法时,我并不总是得到正确的结果。
例如,1-1=0,但我得到 -0。
请查看下面提到的代码:
`timescale 1ns/1ps
module adder #(
//Parameterized values
parameter Q = 27,
parameter N = 32
)
(
input [N-1:0] a,
input [N-1:0] b,
output [N-1:0] c
);
reg [N-1:0] res;
assign c = res;
always @(a,b) begin
// both negative or both positive
if(a[N-1] == b[N-1]) begin //Since they have the same sign, absolute magnitude increases
res[N-2:0] = a[N-2:0] + b[N-2:0]; //So just the two numbers are added
res[N-1] = a[N-1]; //and the sign is set appropriately...
end
// one of them is negative...
else if(a[N-1] == 0 && b[N-1] == 1) begin // subtracts a-b
if( a[N-2:0] > b[N-2:0] ) begin // if a is greater than b,
res[N-2:0] = a[N-2:0] - b[N-2:0];
res[N-1] = 0; // manually the sign is set to positive
end
else begin // if a is less than b,
res[N-2:0] = b[N-2:0] - a[N-2:0]; // subtracting a from b to avoid a 2's complement answer
if (res[N-2:0] == 0)
res[N-1] = 0; // To remove negative zero....
else
res[N-1] = 1; // and manually the sign is set to negative
end
end
else begin // subtract b-a (a negative, b positive)
if( a[N-2:0] > b[N-2:0] ) begin // if a is greater than b,
res[N-2:0] = a[N-2:0] - b[N-2:0]; // subtracting b from a to avoid a 2's complement answer
if (res[N-2:0] == 0)
res[N-1] = 0;
else
res[N-1] = 1; // and manually the sign is set to negative
end
else begin // if a is less than b,
res[N-2:0] = b[N-2:0] - a[N-2:0];
res[N-1] = 0;
end
end
end
endmodule
加法器的测试平台如下:
`timescale 1ns/1ps
module tb_adder (
);
reg clk;
reg [ 31 : 0 ] a;
reg [ 31 : 0 ] b;
wire [ 31: 0 ] c;
adder adder_i (
.a(a),
.b(b),
.c(c)
);
parameter CLKPERIODE = 100;
initial clk = 1'b1;
always #(CLKPERIODE/2) clk = !clk;
initial begin
$monitor ("adder=%h", c);
#1
a = 32'h08000000;
b = 32'hF8000000;
#(CLKPERIODE)
$finish();
end
endmodule
由于我是 Verilog 的新手,我很难找到哪里出错了。我正在使用这个模块来计算定点算术中的泰勒级数。有什么建议吗?
【问题讨论】:
-
在二进制补码数中没有 -0 这样的东西。这意味着你的代码是错误的。你为什么要重新发明减法?只需使用带符号的向量,- 运算符将为您完成所有工作,并且不会出错。
-
您究竟是从哪里获得
-0的?哪个工具报告它?无论如何,正如前面的评论所解释的那样,verilog 中没有这样的东西。您应该能够在 verilog 中显示二进制/十六进制数字以了解发生了什么。 -
即使您出于教育目的重新发明减法,它也过于复杂。 adder 只需要一个异或和一个与门
-
从您的实现来看,您似乎假设输入是符号+幅度格式。除非有一个非常非常好的理由这样做,否则您应该像其他人指出的那样使用二进制补码。这将在 Verilog 中为您提供开箱即用的加法/减法等。
-
-0 只存在于恭维中。
a - b与a + twos_compliment(b)相同。最好的部分是a或b都可以表示为正或负的两个恭维。
标签: verilog fixed-point