我想做一个分数算术,然后显示结果。我知道$ display以整数形式显示。但是显示确切数量的解决方案是什么,例如我想显示10/3 = 3.3但是我显示3.0000。这是我的代码。我不想在这里使用真实数据类型。
`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
我得到的输出是a = 3.000000,b = 11.700000,c = 0.000000,d = 0.000000
我的期望是a = 3.333333,b = 11.700000,c = 6.666666,d = 12.700000
答案 0 :(得分: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
答案 1 :(得分: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