设为首页收藏本站淘宝杂货铺

从F到0 - From F to 0

 找回密码
 注册已关闭
搜索
查看: 100|回复: 0
收起左侧

Quartus Verilog HDL/FPGA 实现32位单精度与64位双精度IEEE754编码浮点数小数互相转换

[复制链接]
发表于 2023-11-30 22:00:07 | 显示全部楼层 |阅读模式
main.png
  1. module float_decode(                //解码float(单精度浮点数)的符号位,指数位,尾数位
  2.         input [31:0] float,        //[32位宽] 单精度浮点数输入
  3.         output sign,                        //符号位 0:正数 1:负数
  4.         output signed [7:0] exponent,        //[8位宽有符号] 指数位 范围:-127~128 此值为正数表示小数大于等于2的N次方,负数表示小数大于0小于1(无视符号位),最大则INF或NAN
  5.         output [22:0] fraction                        //[23位宽] 尾数位 范围:0~8388607 (指数位最大 0:INF 非0:NAN)
  6. );
  7. assign sign = float[31];
  8. assign exponent = float[30:23] - 8'd127;
  9. assign fraction = float[22:0];
  10. endmodule

  11. module float_encode(                //编码float(单精度浮点数)的符号位,指数位,尾数位
  12.         input sign,                //符号位
  13.         input signed [7:0] exponent,        //[8位宽有符号] 指数位
  14.         input [22:0] fraction,                        //[23位宽] 尾数位
  15.         output [31:0] float                                //单精度浮点数输出
  16. );
  17. wire [7:0] i = exponent + 8'd127;
  18. assign float = {sign,i,fraction};
  19. endmodule

  20. module double_decode(        //解码double(双精度浮点数)的符号位,指数位,尾数位
  21.         input [63:0] double,        //[64位宽] 双精度浮点数输入
  22.         output sign,                        //符号位 0:正数 1:负数
  23.         output signed [10:0] exponent,                //[11位宽有符号] 指数位 范围:-1023~1024
  24.         output [51:0] fraction                        //[52位宽] 尾数位 范围:0~4503599627370495
  25. );
  26. assign sign = double[63];
  27. assign exponent = double[62:52] - 11'd1023;
  28. assign fraction = double[51:0];
  29. endmodule

  30. module double_encode(        //编码double(双精度浮点数)的符号位,指数位,尾数位
  31.         input sign,                                                                //符号位
  32.         input signed [10:0] exponent,                //[11位宽有符号] 指数位
  33.         input [51:0] fraction,                                //[52位宽] 尾数位
  34.         output [63:0] double                                        //[64位宽] 双精度浮点数输出
  35. );
  36. wire [10:0] i = exponent + 11'd1023;
  37. assign double = {sign,i,fraction};
  38. endmodule

  39. module float_to_double(                //将32位单精度浮点数转换成64位双精度浮点数
  40.         input [31:0] float,                //[32位宽] 单精度浮点数输入 输入INF(无穷大)或NAN 输出INF或NAN
  41.         output [63:0] double                //[64位宽] 双精度浮点数输出
  42. );
  43. wire sign;
  44. wire signed [7:0] exponent;
  45. wire [22:0] fraction;

  46. float_decode float_decode(
  47.         .float(float),
  48.         .sign(sign),
  49.         .exponent(exponent),
  50.         .fraction(fraction)
  51. );

  52. double_encode double_encode(
  53.         .sign(sign),
  54.         .exponent((exponent == -8'd128) ? 11'd1024 : exponent),
  55.         .fraction({fraction,29'd0}),
  56.         .double(double)
  57. );
  58. endmodule

  59. module double_to_float(                //将64位双精度浮点数转换成32位单精度浮点数
  60.         input [63:0] double,                //[64位宽] 双精度浮点数输入
  61.         output [31:0] float                //[32位宽] 单精度浮点数输出 超范围返回INF(无穷大)
  62. );
  63. wire sign;
  64. wire signed [10:0] double_exponent;

  65. wire [51:0] fraction_double;
  66. wire [22:0] fraction_float = fraction_double[51:29];
  67. wire max = (double_exponent > 128) ? 1'b1 : 1'b0;
  68. wire min = (double_exponent < -127) ? 1'b1 : 1'b0;
  69. wire signed [7:0] float_exponent = max ? 8'd128 : (min ? -8'd127 : double_exponent[7:0]);
  70. wire [22:0] round = (!(&fraction_float) && fraction_double[28]) ? 23'd1 : 23'd0;

  71. double_decode double_decode(
  72.         .double(double),
  73.         .sign(sign),
  74.         .exponent(double_exponent),
  75.         .fraction(fraction_double)
  76. );

  77. float_encode float_encode(
  78.         .sign(sign),
  79.         .exponent(float_exponent),
  80.         .fraction((min | max) ? 23'd0 : fraction_float + round),
  81.         .float(float)
  82. );

  83. endmodule

  84. /*
  85. 浮点小数:123.456 IEEE754编码规范:
  86. 单精度:32'h42F6E979 双精度:64'h405EDD2F1A9FBE77
  87. 单精度正无穷:32‘h7F800000 双精度正无穷:64'h7FF0000000000000
  88. 单精度负无穷:32‘hFF800000 双精度负无穷:64'hFFF0000000000000
  89. */
  90. module main(
  91.         input [63:0] double_in,
  92.         input [31:0] float_in,
  93.         output [63:0] double_out,
  94.         output [31:0] float_out
  95. );

  96. double_to_float double_to_float(
  97.         .double(double_in),
  98.         .float(float_out)
  99. );

  100. float_to_double float_to_double(
  101.         .float(float_in),
  102.         .double(double_out)
  103. );
  104. endmodule
复制代码

相关帖子

您需要登录后才可以回帖 登录 | 注册已关闭

本版积分规则

QQ|手机版|Archiver|从F到0 ( 蒙ICP备17002595号-1 )
蒙公网安备15010402000325号

腾讯云安全认证

GMT+8, 2024-4-27 19:39 , Processed in 1.115064 second(s), 23 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表