2016-09-20 99 views
0

我想做一个小数运算,然后显示结果。我知道$ display以整数显示。但是,如何显示确切数量的解决方案是什么?例如,我想要显示10/3 = 3.3,但显示3.0000。这是我的代码。我不想在这里使用真正的数据类型。在systemverilog中显示分数

`timescale 1ns/1ps 

module fp_check 
(a,b,c,d); 

    input logic signed [7:0] a; 
    input real b; 
    output real c; 
    output logic [7:0] d; 

    assign c = a*2; 
    assign d = b+1; 

endmodule 

module fp_test; 

    logic signed [7:0] a; 
    real b; 
    real c; 
    logic signed [7:0] d; 

    initial 
    begin 
     a = 3.3333; 
     b = 11.7; 
     $display("a =%f, b=%f,c=%f,d=%f", a,b,c,d); 
    end 

    fp_check s (.a(a), .b(b), .c(c), .d(d)); 
endmodule 

输出我得到的是一个= 3.000000,B = 11.700000,C = 0.000000,d = 0.000000

我想到的是一个= 3.333333,B = 11.700000,C = 6.666666,d = 12.700000

+0

你宣布了''和'D'为整数类型,而不是一个'real'(浮点)类型。 – toolic

+0

将'$ display'改为'$ monitor'以避免竞争。你应该看到:'a = 3.000000,b = 11.700000,c = 6.000000,d = 13.000000' – toolic

+0

是唯一选择使用我的输入作为真实/虚拟实境吗?我可以不使用逻辑或其他数据类型吗?由于我会在输入和输出端口上实现触发器,因此我不确定是否可以触发或触发真正的数据类型。 –

回答

1

您需要使用定点算术。见http://amakersblog.blogspot.com/2008/07/fixed-point-arithmetic-with-verilog.html 例如

`timescale 1ns/1ps 
package fixed_point; 

parameter M = 8; 
parameter F = 12; 

typedef bit signed [M-1:-F] fp_t; 
function fp_t real2fp(real value); 
    return value*2.0**F; 
endfunction : real2fp 
function real fp2real(fp_t value); 
    return value/2.0**F; 
endfunction : real2fp 
endpackage : fixed_point 

import fixed_point::*; 


module fp_check (
    input fp_t a, 
    input fp_t b, 
    output fp_t c, 
    output fp_t d); 


    assign c = a*2; 
    assign d = b+real2fp(1); 

endmodule 

module fp_test; 

    fp_t a,b,c,d; 
     initial 
    begin 
     a = real2fp(3.3333); 
     b = real2fp(11.7); 
     $strobe("a =%f, b=%f,c=%f,d=%f", fp2real(a),fp2real(b),fp2real(c),fp2real(d)); 

    end 

    fp_check s (.a(a), .b(b), .c(c), .d(d)); 
endmodule : fp_test 
+0

我遇到以下代码后出现错误:找不到包(fixed_point)。设计阅读将继续进行,但期望在发生这种故障后发生级联错误。此外,如果在出现此错误之前遇到vopt-7错误,请在命令行上检查软件包名称或库搜索路径。 –

1

我有一个关于这个问题的上一个答案Verilog Fractional multiplication?这应该很好地为这个问题的背景。另一个解决how precision is required的答案。

从他们与4位整数4位小数继位代表:

Base 2: Twos complement 4 integer, 4 bit frational 
-2^3 2^2 2^1 2^0 . 2^-1 2^-2 2^-3 2^-4 
    -8 4 2 1 . 0.5 0.25 0.125 0.0625 

应该开始变得明显,这里是你的榜样期待“3.333333”作为一个答案,除非问题你实现一个理性的分割器,它将分子和分母保持为单独的数字,二进制系统不可能保持'1/3'的值。我们可以非常接近,但从不完全一样。另一方面,1/4很容易。

在与整数执行定点数学的方法是你想小数位的数量规模,例如:

integer a = 10; 
integer b = 3; 
localparam FRAC = 4; 

initial begin 
    #1; 
    //Scaling to the power of 2.0 not 2. This forces a real evaluagion of the number for display. 
    $display("No Scaling down : %f", (a*2.0**FRAC/b*2.0**FRAC)); 
    //Scaling back down by 4 to the power because of fractional bit growth 
    $display("Scaled back down : %f", (a*2.0**FRAC/b*2.0**FRAC)*4.0**-FRAC); 
end