长整数有符号定点到实数转换系统Verilog



我需要将一个长数作为固定点转换为双说唱演示。 定点数学用于合成过程,实数数据类型仅用于验证和模拟。

如果我在具有多种数据类型的链中进行多次转换以调整格式,那么这还不够或完全错误。

在我的情况下,44位的定点尾数我有3位整数+符号位。Q 表示法,如"sfix_44_48"

例如,我这样做是为了将定点整数转换为实数值(获取数字 0.5f(:

logic signed [47:0] fp_number = 48'h0800_0000_0000; // it should be 0.5f
real r_val;
real rr_val;
real rrr_val;
real tmp;
initial
begin
r_val = $itor(fp_number)/(2**44); // doesn't solve the problem.
rr_val = real'{fp_number}/(2**44); // doesn't solve the problem.
$cast(tmp,fp_number>>>44); // doesn't solve the problem
rrr_val = tmp;
end

$itor(...( 限制为 32 位整数部分。 由于上述结果,我在Modelsim模拟上得到零或NaN。

在所有这些皈依中都没有运气。 SV LRM似乎没有明确的方法来进行这种转换。

SV 解决方法是什么,允许模拟轻松分析大于 32 位大小的数据? 请。

三.

你想使用

rr_val = real'(fp_number)/(2.0**44);

请勿使用 Verilog 中的任何$TtoT功能。它们具有固定的数据类型输入和输出。

2**44计算为 32 位 2 补码值并溢出,得到 0。您可以改用2.0real'(2)

感谢@dave_59我发布了这段代码,它显示了转换的混乱。

logic signed [47:0] fp_number  = 48'h0800_0000_0000; // it should be 0.5f
logic signed [31:0] fp_number2 = 32'h0800_0000; // it should be 0.5f
real r_val;
real rr_val;
real rrr_val;
real rrrr_val;
initial
begin
$display("48bit fp convertion sfix_44_48");
r_val    = real'{fp_number}/(2**44);   //  doesn't solve the problem (curly braces valid sintax but wrong convertion + wrong convertion on the denominator).
rr_val   = real'{fp_number}/(2.0**44); //  doesn't solve the problem (curly braces valid sintax but wrong convertion + denominator convertion OK).
rrr_val  = real'(fp_number)/(2**44);   //  doesn't solve the problem (numerator OK + the power operation is not properly converted to a Real number as result).
rrrr_val = real'(fp_number)/(2.0**44); //  solve the problem with long integer fixed points convertion (the braces are not curly anymore).
$display("r_val[%08f]",r_val,", rr_val[%08f]",rr_val,", rrr_val[%08f]",rrr_val,", rrrr_val[%08f]",rrrr_val); // it should be 0.5 on the fourth data
$display("32bit fp convertion sfix_28_32");
r_val    = real'{fp_number2}/(2**28);   //  result totally different than previous 48bit operation, doesn't solve the problem (curly braces valid sintax but wrong convertion + wrong convertion on the denominator).
rr_val   = real'{fp_number2}/(2.0**28); //  doesn't solve the problem (curly braces valid sintax but wrong convertion + denominator convertion OK).
rrr_val  = real'(fp_number2)/(2**28);   //  with a 32bit range it apparently solve the problem (numerator OK + the power operation is OK with this range).
rrrr_val = real'(fp_number2)/(2.0**28); //  solve the problem with long integer fixed points convertion (the braces are not curly anymore).
$display("r_val[%08f]",r_val,", rr_val[%08f]",rr_val,", rrr_val[%08f]",rrr_val,", rrrr_val[%08f]",rrrr_val); // it should be 0.5 on the fourth data
end

48位唯一有效的转换是第四种情况。 对于 32 位,第三种情况有效,第四种情况也有效。

  • 首先:经典的pow(...)操作必须使用此语法完成,(2.0**BIT)当应用缩放固定点时,它将使用(2**BIT)创建一个实数除法,而不是整数除法。

在这种情况下,上述操作被管理为浮点/双精度(C 样式(或实数(SystemVerilog( * 第二:real'()铸造操作必须与无大括号一起使用。 我没有 Linting 工具来正确检查语法,因此由于使用大括号的操作的有效性,我希望收到警告。

  • 第三:如果 INTEGER 分母限制在 32 位操作,则子结果是可以的。 结果如下所示:
SIM START.
# 48bit fp convertion sfix_44_48
# ** Error (suppressible): (vsim-8604) ./blocks/sim/test_tb.sv(141): NaN (not a number) resulted from a division operation.
# ** Error (suppressible): (vsim-8630) Infinity results from division operation.
#    Time: 0 ps  Iteration: 0  Process: /test_tb/#INITIAL#138 File: ./blocks/sim/test_tb.sv Line: 143
# r_val[-1.#IND00], rr_val[0.000000], rrr_val[1.#INF00], rrrr_val[0.500000]
# 32bit fp convertion sfix_28_32
SIM END.
# r_val[0.000000], rr_val[0.000000], rrr_val[0.500000], rrrr_val[0.500000]

解决方案是避免任何不受保护的强制转换,例如带有大括号边界的强制转换:

r_val  = real'{ byteU,byteH,byteL}  / (2.0**44) ; // WRONG
rr_val = real'({byteU,byteH,byteL}) / (2.0**44) ; // CORRECT

如果出现比例因子,则操作(通常/(必须使用相同类型的操作数(实数/实数(来完成。

不安全的方式是(真实的/长期的(,这会导致一场噩梦。

最新更新