Floating point 在systemverilog中显示分数
我想做一个分数运算,然后显示结果。我知道$display以整数显示。但是显示精确数量的解决方案是什么,例如我想显示10/3=3.3,但我得到显示3.0000。这是我的密码。我不想在这里使用真实的数据类型Floating point 在systemverilog中显示分数,floating-point,verilog,system-verilog,Floating Point,Verilog,System Verilog,我想做一个分数运算,然后显示结果。我知道$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;
`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,我对这个问题有一个以前的答案,这应该是这个问题的背景。另一个解决问题的答案是 接着是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
关于这个问题,我有一个先前的答案,这应该是这个问题的背景。另一个解决问题的答案是 接着是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
你需要使用定点算法。看见 比如说
`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
你需要使用定点算法。看见 比如说
`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
它是将我的输入用作实/短实的唯一选项吗?我不能使用逻辑或任何其他数据类型吗?由于我将在输入和输出端口都实现触发器,所以我不确定是否可以将实数数据类型转换为或转换为实数数据类型。这是将输入用作实数/短实数的唯一选项吗?我不能使用逻辑或任何其他数据类型吗?由于我将在输入和输出端口实现一个触发器,我不确定我是否可以在实际数据类型中进行触发器转换。我在遵循以下代码后得到错误:找不到包(固定点)。设计读取将继续,但在此失败后会出现一连串错误。此外,如果您在此错误之前立即遇到vopt-7错误,请检查命令行上的包名称或库搜索路径。我在遵循以下代码后收到错误:找不到包(修复点)。设计读取将继续,但在此失败后会出现一连串错误。此外,如果您在此错误之前遇到vopt-7错误,请检查命令行上的包名称或库搜索路径。