Verilog编写浮点加法器

本文详细介绍了32位浮点数据格式及浮点加法器的实现过程,包括对阶、尾数求和、规格化、舍入和溢出判断等步骤。讨论了不同舍入策略的影响,并给出了Chisel生成的Verilog代码。
摘要由CSDN通过智能技术生成

32位浮点数据格式如下:

S:符号位 1Bit

Exp:阶码位  7Bits

Fra:尾码位 24Bits

相对于浮点乘法器来说,加法器的实现逻辑稍微复杂一点

32 位浮点数据格式: A = (- 1) S ×M ×2E-127。其中加法运算操作分为:

(1) 对阶,使两数的小数点位置对齐。两个浮点数进行运算首先要看阶码是否相同,也就是看小数点有没有对齐;
用十进制来举例,10.32和1.3612相加对计算机而言不能直接对齐小数点,计算机会按照数值的位数对应进行加减法,所以得出的数值是14644,而小数点的位置则会未知;
对阶码首先要求出两阶码的差:Ex - Ey,在对阶时总是小阶向大阶看齐,也就是小数点向左移,比较小的阶码则会变大,直到与比较大的阶码相等为止。


(2) 尾数求和,将对阶后的两尾数按定点加减运算规则求和(差)


(3) 规格化,为增加有效数字的位数,提高运算精度,必须将求和 (差)后的尾数规格化。在浮点加减运算时,尾数求和的是01.xxxxxx或者10.xxxxxxxx在定点加减法运算中称为溢出,但是在浮点加减法运算中,这表示运算结果的绝对值大于1,这时通过将尾数右移实现规格化,称为向右规格化,尾数向右移一位,阶码加1;当尾数不是1.M的形式时,向左规格化,也就是尾数向左移。


(4) 舍入,为提高精度,要考虑尾数右移时丢失的数值位。在对阶或向右规格化结束后,尾数向右移则需要丢掉尾数的低位部分,所以要进行舍入处理。
这里有四种舍入处理的方法:
a.就近舍入:通常所说的“四舍五入”,多余位的值超过规定的最低有效位值的一半,最低有效位值加1.
例如: IEEE 32位标准化格式尾数位为23位,假设超出23位的多余位数字是10010,它的十进制值为18,最低有效位值是100000,换算成十进制值是32,18大于16,所以最低有效位值需要加1.
b.朝0舍入:直接截尾;截尾导致尾数取值比起原值的绝对值小,所以这种方法容易导致误差累积。
c.朝+∞舍入:对于正数来说,只要多余位不全为0,则向最低有效位进1;对于负数来说则是直接截尾。
d.朝-∞舍入:对于负数来说,多余位不全为0则向最低有效位进1;对于正数来说则是直接截尾。


(5) 溢出判断, 即判断结果是否溢出。浮点数的溢出由其阶码表现出来的,如果阶码正常,则浮点加减法正常进行;如果阶码溢出,则需要对解码进行处理,并且对尾数也进行处理。
a.阶码上溢:超过了阶码可以表示的最大值的正数指数,将其看作是∞。
b.阶码下溢:超过了阶码可以表示的最小值的负数指数,将其看作是0。
c.尾数上溢:两个操作数相加产生最高位进1,这时需要将小数点向左移1位,阶码值加1 来重新对齐阶码。
d.尾数下溢:在尾数右移以后,也就是小数点左移之后,尾数的最低有效位应该流出,也就是算入多余位里,要进行舍入处理。

贴Chisel生成的Verilog代码:

module float_add(
  input         clock,
  input         reset,
  input  [31:0] io_a,
  input  [31:0] io_b,
  input         io_in_en,
  output [31:0] io_c,
  output        io_out_en
);
  reg [25:0] fra_min; // @[float_add.scala 21:26]
  reg [31:0] _RAND_0;
  reg [25:0] fra_max; // @[float_add.scala 22:26]
  reg [31:0] _RAND_1;
  reg [8:0] exp_max; // @[float_add.scala 23:26]
  reg [31:0] _RAND_2;
  reg [25:0] fra_add; // @[float_add.scala 24:26]
  reg [31:0] _RAND_3;
  reg [8:0] exp_maxr; // @[float_add.scala 25:30]
  reg [31:0] _RAND_4;
  reg [22:0] fra; // @[float_add.scala 28:26]
  reg [31:0] _RAND_5;
  reg [7:0] exp; // @[float_add.scala 29:26]
  reg [31:0] _RAND_6;
  reg  sign; // @[float_add.scala 30:26]
  reg [31:0] _RAND_7;
  reg  _T; // @[Reg.scala 15:16]
  reg [31:0] _RAND_8;
  reg  _T_1; // @[Reg.scala 15:16]
  reg 
  • 6
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值