【问题标题】:Testbench of floating point adder in verilogVerilog中浮点加法器的测试台
【发布时间】:2015-04-01 07:45:32
【问题描述】:

我想写floating point double precision adder。在那个测试台上,我遇到了一些问题。

*adder 是一个模块,它获取两个 64 位数字并给出它们的总和。

这是我的测试台:

module testadder;
  reg [63:0]           a;
  reg [63:0]           b;
  wire [63:0]          sum; 
  reg[10:0] expa,expb,expsum;
  reg signa,signb,signsum,one;
  reg[51:0] fa,fb,fsum;
  real ta,tb,fa2,fb2,sumcheck,fsum2,resultmodulesum;
  integer i;  
  reg [10:0]h23;

adder nameofinstance(sum,a,b);
initial begin  
   for(i=0;i<1000;i=i+1)
   begin
     h23=1023;
     one=1'b1;
   a = {$random(),$random()};
   b = {$random(),$random()};
   #10;
    expa=a[62:52]-h23;
    expb=b[62:52]-h23;
    fa=a[51:0];
    fb=b[51:0];
    signa=a[63];
    signb=b[63];
    fa2 = ( $bitstoreal(fa)/(2**52) )+ one ;
    ta=(-1)**(signa)*fa2*(2**expa);
    fb2 = ( $bitstoreal(fb)/(2**52) ) + one;
    tb=(-1)**(signb)*fb2*(2**expb);
    sumcheck=ta+tb;
    fsum=sum[51:0];
    signsum=sum[63];
    fsum2 = ( $bitstoreal(fsum)/(2**52) ) +one;
    expsum=$bitstoreal(sum[62:52])-1023;
    resultmodulesum=(-1)**(signsum)*fsum2*(2**expsum);
    if(sumcheck!=resultmodulesum)
      $display("wrong");


 end
end
endmodule




 module adder(sum,a, b);
    input [63:0]   a;
    input [63:0] b;
    reg [63:0] fa,fb;
    always @(a or b) begin
    fa={1'b1,a[51:0],12'b0};
    fb={1'b1,b[51:0],12'b0};
    end
    endmodule
  1. 当我将( $bitstoreal(fa)/(2**52) ) 加一时,fa2 得到 1!但是当我不添加它时,fa2 会得到(fa/2^52) 的实际值。 所以我将我的代码更改为类似的代码以避免添加一个,但出现了另一个问题!

我更改ta,tbresultmodulesum: (以 fa 为例)

 fa2 = ( $bitstoreal(fa)/(2**52) ) ;
 ta=(-1)**(signa)*(fa2*(2**expa)+(2**expa));

2.那么我知道你总是会去(-1)**(signa)*(2**expa); 这意味着 fa2*(2**expa) 是 0 !但我不知道为什么以及我该怎么做才能使它正确。 我认为即使我没有更改我的fa2fa2(其中添加了一个)提供正确的输出,我的ta 也可能有问题。

3.我的模块还有一个问题,真的很奇怪! 加法器代码模块的一小部分来自测试台代码。 就是当我调试我的代码时,fb 的第 63 位是 0!有什么想法吗?

【问题讨论】:

  • 你认为$bitstoreal 是做什么的?您是否已单独检查此功能,是否按预期工作?如果模块加法器与问题无关,可以将其删除。
  • 我预计它将二进制数转换为实数,并且在我看到的示例中是这样做的。我错了吗?问题3.关于模块加法器@morgan
  • 我以为它只是用于类型转换,允许将实数转换为 64 位,以便可以通过 64 位端口传递,使用 $realtobits$bitstoreal 我的印象是他中间的位暴露了 IEEE 754 定义的浮点双精度位。除非设置了部分指数,否则这看起来是正确的数字。
  • 你能解释更多吗?我不明白你的意思。我说过它像你的想法一样转换,我不明白你想在这些句子中说什么:“我的印象是他在中间的位暴露了 IEEE 754 定义的浮点双精度位。这个除非设置了部分指数,否则它看起来像是正确的数字。”我的代码有什么问题?@morgan
  • $bitstoreal 将 IEEE 754 双位部分转换为实数。 $realtobits 将实数转换为 IEEE 754 双位模式。在您的代码中,您对这些功能的使用对我来说并不明显。您对变量名的使用并不清楚什么是指数和分数IEEE 754 double

标签: verilog


【解决方案1】:

这不是一个完整的答案,但超出了 cmets 所能表达的范围。

对于浮点双精度模型,我本来希望看到以下内容:

reg [63:0] a;
reg [63:0] b;

//Built in real for verification of code
real result;
real a_real;
real b_real;

initial begin
  a = {$random(),$random()};
  b = {$random(),$random()};

  #1ps;
  a_real = $bitstoreal(a);
  b_real = $bitstoreal(b);
  result = a_real + b_real;

  $display("a      %64b", a);
  $display("b      %64b", b);
  $display("a_real %f", a_real);
  $display("b_real %g", b_real);
  $display("result %f",  result);

  #1ps;
  $finish;
end

为了将随机双打分成几部分,我本来希望看到如下内容:

wire a_sign;           // 1 bit
wire [10:0] a_exponent;//11 bit
wire [51:0] a_fraction;//52 bit

assign a_sign     = a[63]   ;
assign a_exponent = a[62:52];
assign a_fraction = a[51:0] ;

wire b_sign;           // 1 bit
wire [10:0] b_exponent;//11 bit
wire [51:0] b_fraction;//52 bit

assign b_sign     = b[63]   ;
assign b_exponent = b[62:52];
assign b_fraction = b[51:0] ;

【讨论】:

  • 在这里我做了一些类似你的第二个代码的事情,但我想计算这些表示的实数,所以表示的十进制值为:*(-1)^s x f x 2^e 其中 e = E - 偏差和 f = ( F/(2^n) ) + 1,然后我将这两个小数相加并将答案与模块答案进行比较,以了解它是否正确。 (您可以在我的问题中提到的链接中看到公式*)@morgan
  • h23 在这里是偏差(在我的代码中),n 是 52,所以我写这个:fa2 = ( $bitstoreal(fa)/(2**52) )+ one ; fa2 is f and fa is F in previous comment。还有ta=(-1)**(signa)*fa2*(2**expa);是公式
  • 我了解我的问题摩根。这是关于理解 $bitstoreal 和 $realtobits 的工作。 tnx
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多