0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

怎么设计一个32bit浮点的加法器呢?

冬至子 来源:FPGA and ICer 作者:Vuko 2023-06-02 16:13 次阅读

设计需求

设计一个32bit浮点的加法器,out = A + B,假设AB均为无符号位,或者换个说法都为正数。

clk为系统时钟rst_n为系统复位,低有效;en信号控制数据输入;busy指示模块工作状态,busy拉高时,输入无效;aIn和bIn是数据输入,out_vld,指示输出数据有效。

设计的信号列表如下:

module float_adder(inputclk,inputrst_n,inputen,input[31:0] aIn,input[31:0] bIn, outputregbusy, outputregout_vld, outputreg[31:0]out);

32bit的浮点格式

EE标准754规定了三种浮点数格式:单精度、双精度、扩展精度。前两者正好对应C语言里头的float、double或者FORTRAN里头的real、double精度类型。本文设计实现的为单精度。

图片

单精度格式

单精度:N共32位,其中S占1位,E占8位,M占23位。

图片

双精度格式

双精度:N共64位,其中S占1位,E占11位,M占52位。

浮点数的加法过程

运算过程:对阶、尾数求和、规格化、舍入、溢出判断

对阶:

和定点数不相同的是,浮点数的指数量级不一定是一样的,所以这也就意味着,尾数直接进行加法运算时会存在问题,也就需要首先对阶数进行处理。该过程有点像科学计数法的加法处理,把科学计数法的指数化为一致,求出来指数相差多少,然后移位处理后再进行加法减法。所以这里处理也要先求阶差。

如果把阶码大的向阶码小的看齐,就要把阶码大的数的尾数部分左移,阶码减小。这个操作有可能在移位过程中把尾数的高位部分移掉,这样就引发了数据的错误,所以,尾数左移在计算机运算中不可取。

如果把阶码小的向阶码大的看齐,在移位过程中如果发生数据丢失,也是最右边的数据位发生丢失,最右边的数据位丢失,只会影响数据的精度,不会影响数据的大小。

尾数求和

这里就是常规的补码加法。

规格化:

右规(尾数的绝对值太大时,右规) 尾数右移一位,阶码加1。当尾数溢出( >1 )时,需要右规。是否溢出,可以通过两位的符号位得出:即尾数出现01.xx…xx或10.xx…xx(两位符号位不同)

提高浮点数的表示精度,这里设计考虑比较简单,我只考虑了同号数据相加的情况,所以这里只设计了右规的情况,不考虑符号位。

舍入判断:

这里直接用截断处理的方式,针对数据相加上溢的情况,规定了运算后上溢后将数据规定为最大值。

实现代码

module float_adder( input clk, input rst_n, input en, input [31:0] aIn, input [31:0] bIn, output reg busy, output reg out_vld, output reg [31:0]out); //运算过程:对阶、尾数求和、规格化、舍入、溢出判断 //分离阶数、尾数 wire signal_bit = aIn[31]; wire [7:0] pow_a = aIn[30:23]; wire [7:0] pow_b = bIn[30:23]; wire [22:0] val_a = aIn[22:0]; wire [22:0] val_b = bIn[22:0]; //找到输入指数阶数较大,和阶数差 //对阶:在计算机中,采用小阶向大阶看齐的方法,实现对阶。即右移 reg [22:0] pow_max ; reg [23:0] pow_dif ; reg [22:0] val_max ; reg [22:0] val_min ; reg en_dly0; always @(posedge clkornegedge rst_n)beginif(rst_n==0)beginpow_max <='d0; val_max <='d0; val_min <='d0; pow_dif <='d0; en_dly0 <='d0;endelseif( en ==1&& busy ==0)beginif(pow_a >= pow_b)beginpow_max <= pow_a; val_max <= val_a; val_min <= val_b; en_dly0 <='d1;if( pow_a - pow_b >'d23)beginpow_dif <='d23;endelsebeginpow_dif <= pow_a - pow_b;endendelsebeginpow_max <= pow_b; val_max <= val_b; val_min <= val_a; en_dly0 <='d1;if( pow_b - pow_a >'d23)beginpow_dif <='d23;endelsebeginpow_dif <= pow_b - pow_a;endendendelsebeginpow_max <= pow_max; val_max <= val_max; val_min <= val_min; pow_dif <= pow_dif; en_dly0 <='d0;endend//移位忙指示信号 reg shift_busy; reg [4:0] shift_cnt; always @(posedge clkornegedge rst_n)beginif(rst_n==0)beginshift_busy<='d0;endelseif(en_dly0 ==1)beginshift_busy <='d1;endelseif(shift_cnt == pow_dif)beginshift_busy <=0;endend//移位计数 always @(posedge clkornegedge rst_n)beginif(rst_n ==0)beginshift_cnt <='d0;endelseif(shift_busy ==1)beginif(shift_cnt == pow_dif)beginshift_cnt <= shift_cnt;endelsebeginshift_cnt <= shift_cnt +1'b1;endendelsebeginshift_cnt <='d0;endendreg [22:0] val_shift; always @(posedge clkornegedge rst_n)beginif(rst_n ==0)beginval_shift <='d0;endelseif(en_dly0==1'b1)beginval_shift <= val_min;endelseif(shift_busy ==1)beginval_shift <= {1'b0,val_shift[22:1]};endelsebeginval_shift <= val_shift;endend//尾数求和 wire val_add_flag = (shift_cnt == pow_dif)&&(shift_busy ==1); reg [23:0] val_sum; reg val_sum_vld; always @(posedge clkornegedge rst_n)beginif(rst_n==0)beginval_sum<='d0; val_sum_vld<='d0;endelseif(val_add_flag ==1)beginval_sum <= val_max + val_shift; val_sum_vld<='d1;endelsebeginval_sum <= val_sum; val_sum_vld<='d0;endend//规范 always @(posedge clkornegedge rst_n)beginif(rst_n==0)beginout<='d0; out_vld<='d0;endelseif(val_sum_vld ==1)begin//尾数求和有溢出 out_vld<='d1;out[31]<= signal_bit;if(val_sum[23] ==1&&out[30:23] ==8'hFF)beginout[30:23]<=8'hFF;out[22:0] <=23'h7F_FFFF;endelseif(val_sum[23] ==1)beginout[30:23]<= pow_max +1;out[22:0] <= val_sum[23:1];endelsebeginout[30:23]<= pow_max;out[22:0] <= val_sum[22:0];endendelsebeginout<=out; out_vld<='d0;endend//运算忙指示 always @(posedge clkornegedge rst_n)beginif(rst_n==0)beginbusy<='d0;endelseif(en ==1&& busy ==0)beginbusy<='d1;endelseif(out_vld ==1)beginbusy<='d0;endelsebeginbusy <= busy;endendendmodule

仿真代码

这里简单测试了下代码的功能,vwin 了连续输入多个数据,核查是否数据会影响正常计算过程。

`timescale1ns/1ps module float_adder_tb; // Parameters // Ports reg clk =1; reg rst_n =0; reg en =0; reg [31:0] aIn; reg [31:0] bIn; wire busy; wire out_vld; wire [31:0]out; float_adder float_adder_dut ( .clk (clk ), .rst_n (rst_n ), .en (en ), .aIn (aIn ), .bIn (bIn ), .busy (busy ), .out_vld (out_vld ), .out(out) ); always #5clk = ! clk ; initialbeginrst_n =0; #100; rst_n =1; #100; aIn = {1'b0,8'd2,23'd7}; bIn = {1'b0,8'd2,23'd8}; en =1; #10; aIn = {1'b0,8'd0,23'd7}; bIn = {1'b0,8'd2,23'd8}; en =1; #1000; $finish;endendmodule

仿真测试

从仿真测试中可以看出,当输入信号连续输入两个浮点数时,在busy拉高状态下,第二次输入的数据无效,数据使能信号常为1,也不会影响正常模块运算过程,只有在该次运算完成busy拉低后数据可重新加载。

图片

仿真截图

小结

本文的设计方法对于对阶移位的操作需要循环操作,也即当阶数相差较小时,结果输出延迟较小,在极端情况下,比如阶数差大于10,输出延时会比阶数差为0时,多10个周期,上限为23。如在实际使用时,对延时要求较小的情况,可针对移位操作部分,使用更多的资源来换取性能的提升。可使用case语句对具体情况进行遍历。

针对原始题目中的累加操作,可将任意一个输入和输出相接,即可实现累加操作。此外,如果要实现异号加法情况,则需要仔细考虑对阶,规格化等情况进行进一步设计。

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表德赢Vwin官网 网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • C语言
    +关注

    关注

    180

    文章

    7565

    浏览量

    133434
  • 加法器
    +关注

    关注

    6

    文章

    182

    浏览量

    29920
  • CLK
    CLK
    +关注

    关注

    0

    文章

    124

    浏览量

    17025
  • 累加器
    +关注

    关注

    0

    文章

    50

    浏览量

    9403
收藏 人收藏

    评论

    相关推荐

    运算放大器的同相加法器和反相加法器

      运算放大器构成 加法器可以分为同相 加法器和反相 加法器
    发表于08-05 17:17 2.8w次阅读
    运算放大器的同相<b class='flag-5'>加法器</b>和反相<b class='flag-5'>加法器</b>

    32位浮点加法器设计

    求助谁帮我设计 32位 浮点 加法器,求助啊,谢谢啊 新搜刚学verilog,不会做{:4_106:}
    发表于10-20 20:07

    加法器

    请问下大家,,进位选择 加法器和进位跳跃 加法器的区别是啥啊?我用Verilog实现16位他们的 加法器有什么样的不同啊?还请知道的大神告诉我 下。。
    发表于10-20 20:23

    什么是加法器加法器的原理是什么 ?

    什么是 加法器加法器的原理是什么 反相 加法器等效原理图解析
    发表于03-11 06:30

    加法器,加法器是什么意思

    加法器, 加法器是什么意思 加法器:   加法器是为了实现 加法的。  即是产生数的和的装置。加数和被加数为输入,和数与
    发表于03-08 16:48 5396次阅读

    十进制加法器,十进制加法器工作原理是什么?

    十进制 加法器,十进制 加法器工作原理是什么?   十进制 加法器可由BCD码(二-十进制码)来设计,它可以在二进制 加法器的基础上加上适当的“校正”逻辑来实现,该校正逻
    发表于04-13 10:58 1.3w次阅读

    FPU加法器的设计与实现

    浮点运算器的核心运算部件是 浮点 加法器,它是实现 浮点指令各种运算的基础,其设计优化对于提高 浮点运算的速度和精度相当关键。文章从
    发表于07-06 15:05 47次下载
    FPU<b class='flag-5'>加法器</b>的设计与实现

    同相加法器电路原理与同相加法器计算

    同相 加法器输入阻抗高,输出阻抗低 反相 加法器输入阻抗低,输出阻抗高. 加法器种数位电路,其可进行数字的 加法计算。当选用同相
    发表于09-13 17:23 5.7w次阅读
    同相<b class='flag-5'>加法器</b>电路原理与同相<b class='flag-5'>加法器</b>计算

    怎么设计32位超前进位加法器

    ,影响整个CPU的性能,为了减小这种延迟,遂采用超前进位 加法器(也叫先行进位 加法器),下面来介绍 下设计的原理。
    发表于07-09 10:42 2w次阅读
    怎么设计<b class='flag-5'>一</b><b class='flag-5'>个</b>32位超前进位<b class='flag-5'>加法器</b>?

    加法器设计代码参考

    介绍各种 加法器的Verilog代码和testbench。
    发表于05-31 09:23 19次下载

    超前进位加法器是如何实现记忆的

    行波进位 加法器和超前进位 加法器都是 加法器,都是在逻辑电路中用作两个数相加的电路。我们再来回顾 下行波进位 加法器
    发表于08-05 16:45 1229次阅读
    超前进位<b class='flag-5'>加法器</b>是如何实现记忆的<b class='flag-5'>呢</b>

    加法器的原理及采用加法器的原因

    有关 加法器的知识, 加法器是用来做什么的,故名思义, 加法器是为了实现 加法的,它是 种产生数的和的装置,那么
    的头像 发表于06-09 18:04 4754次阅读

    镜像加法器的电路结构及仿真设计

    镜像 加法器 经过改进的 加法器电路,首先,它取消了进位反相门;
    的头像 发表于07-07 14:20 2169次阅读
    镜像<b class='flag-5'>加法器</b>的电路结构及仿真设计

    加法器的原理是什么加法器有什么作用

    加法器是数字电路中的基本组件之 ,用于执行数值的 加法运算。 加法器的基本原理和作用可以从以下几个方面进行详细阐述。
    的头像 发表于05-23 15:01 1279次阅读
    <b class='flag-5'>加法器</b>的原理是什么 <b class='flag-5'>加法器</b>有什么作用

    串行加法器和并行加法器的区别?

    串行 加法器和并行 加法器是两种基本的数字电路设计,用于执行二进制数的 加法运算。它们在设计哲学、性能特点以及应用场景上有着明显的区别。
    的头像 发表于05-23 15:06 997次阅读