Verilog中的替代品

时间:2018-01-28 00:00:28

标签: verilog fixed-point

我正在研究一个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

加法器的Testbench如下:

`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的新手。我正在使用这个模块来计算定点算术中的泰勒级数。有什么建议吗?

1 个答案:

答案 0 :(得分:0)

我能找到代码产生脏零的唯一情况是两个输入本身都是脏零。即。

AAPT2

看起来会发生这种情况,因为在这种情况下,您的代码会在

处获取分支
a = b = 32'h80000000 = "-0"

并且此分支与具体避免它的其他分支没有相同的检查。您可以通过将该代码移动到always块的末尾来解决此问题,因此无论先前采用哪个分支,它都会运行。