聪明文档网

聪明文档网

最新最全的文档下载
当前位置: 首页> 基于IEEE754浮点乘法器设计程序--verilog

基于IEEE754浮点乘法器设计程序--verilog

时间:2018-07-02 09:49:17    下载该word文档

上溢、下溢与除以零等异常情况在大多数系统中是经常发生的。以双精度浮点数为例,如果只考虑格式化数,则它的溢出有四种情况:

1)正数大于(1-)×2 的情况为正上溢;

2)正数小于0.5×2的情况为正下溢;

3)负数小于-(1-2)×2的情况为负上溢;

4)负数大于0.5×2的情况为负下溢。

在浮点运算过程中一个很重要的步骤是舍入。舍入的目的是使得有效数据的位数保持在固定位数范围内。

IEEE754标准规定了四种舍入模式

1)就近舍入(偶数)目标是使舍入结果尽可能接近实际值。最大误差为±LSB(Least Significant Bit)

2)零舍入RZ通过截断实际值的多余位来实现。最大误差为土LSB

3+∞舍入结果向正无穷大方向舍入。所有值被舍入到下一个可能值,负数的舍入结果将截去多余位,正数的舍入结果为下一个较大的有效值。

4-∞舍入:结果向负无穷大方向舍入。负数的舍入结果将为下一个较小的有效值,正数的舍入结果将截去多余位。

下表给出了不同的舍入方法下的舍入结果,以8位值舍入为4位值为例。

不同舍入方法的舍入值

数值

就近舍入

零舍入

+∞舍入

-∞舍入

.01101001

.0111

.0110

.0111

.0110

-.01101001

-.0111

-.0110

-.0110

-.0111

.10000111

.1000

.1000

.1001

.1000

-10000111

-.1000

-.1000

-.1000

-.1001

.10000000

.1000

.1000

.1000

.1000

浮点运算单元源代码

module alu(flout_a,flout_b,clk,en,rst,flout_c,yichu); //浮点运算单元模块

input[31:0] flout_a; //输入的被乘数

input[31:0] flout_b; //输入的乘数

input clk; //时钟信号

input en; //使能信号

input rst; //复位信号

output[31:0] flout_c; //输出运算结果

output[1:0] yichu; //输出溢出标志

reg[31:0] flout_c;

reg[1:0] yichu;

reg[1:0] overflow;

reg s3;

reg s1,s2; //符号

reg[7:0] exp1,exp2,exp3; //阶码

reg[22:0] man1,man2,man3; //尾数

reg n;

reg[7:0] temp1;

reg[7:0] temp2;

reg[8:0] temp3;

reg[23:0] temp;

reg[45:0] comeout;

reg[23:0] all; //小数部分

reg[1:0] zheng; //整数部分

always@(posedge clk) //提取flout_a的符号,阶码,尾数

begin

if(!rst)

begin

s1<=1'b0;

exp1<=8'b00000000;

man1<=23'b0;

end

else if(en)

begin

s1<=flout_a[31];

exp1<=flout_a[30:23];

man1<=flout_a[22:0];

end

end

always @(posedge clk) //提取flout_b的符号,阶码,尾数

begin

if(!rst)

begin

s2<=1'b0;

exp2<=8'b00000000;

man2<=23'b0;

end

else if(en)

begin

s2<=flout_b[31];

exp2<=flout_b[30:23];

man2<=flout_b[22:0];

end

end

always@(posedge clk) //尾数相乘

begin

if(man1==23'b0000000000_0000000000000)

begin

man3=man1;

n=1'b0;

end

else if(man2==23'b0000000000_0000000000000)

begin

man3=man2;

n=1'b0;

end //处理特殊值

else

begin

comeout=man1*man2;

temp=man1+man2; //1.m*1.n=1+(0.m+0.n)+(0.m*0.n)

all=temp[22:0]+comeout[45:23];

zheng=1'b1+temp[23];

zheng=zheng+all[23]; //整数

if(zheng[1]==1) //整数小于4而大于1

begin

n=1'b1; //左归阶码应加1

if(zheng[0]==1)

man3[22:0]={2'b1,all[22:1]}; //零舍入

else

man3[22:0]={2'b0,all[22:1]};

end

else

begin

n=1'b0;

man3=all[22:0];

end

end

end

always@(posedge clk) //阶码相加

begin

if(exp1[7]==1)

temp1={1'b0,exp1[6:0]};

else temp1={1'b1,exp1[6:0]};

if(exp2[7]==1)

temp2={1'b0,exp2[6:0]};

else temp2={1'b1,exp2[6:0]}; //把阶码的移码形式变为补码形式

temp3=temp1+temp2;

temp3=temp3+n;

if(temp3[8:7]==2'b01)

overflow=2'b01; //阶码上溢

else

begin

if(temp3[8:7]==2'b10)

overflow=2'b10; //阶码下溢

else overflow=2'b00;

end

case(temp3[8:7])

2'b00:exp3={1'b1,temp3[6:0]};

2'b01:exp3=temp3[7:0];

2'b11:exp3={1'b0,temp3[6:0]};

2'b10:exp3=temp3[7:0];

endcase

end

always@(posedge clk) //输出结果

begin

s3=s1^s2;

yichu= overflow;

if(man3==0)

begin

flout_c=32'b0;

yichu=2’b00;

end

else flout_c={s3,exp3[7:0],man3[22:0]};

end

endmodule

  • 29.8

    ¥45 每天只需1.0元
    1个月 推荐
  • 9.9

    ¥15
    1天
  • 59.8

    ¥90
    3个月

选择支付方式

  • 微信付款
郑重提醒:支付后,系统自动为您完成注册

请使用微信扫码支付(元)

订单号:
支付后,系统自动为您完成注册
遇到问题请联系 在线客服

常用手机号:
用于找回密码
图片验证码:
看不清?点击更换
短信验证码:
新密码:
 
绑定后可用手机号登录
请不要关闭本页面,支付完成后请点击【支付完成】按钮
遇到问题请联系 在线客服