单精度浮点乘法器汇总Word文档格式.docx
《单精度浮点乘法器汇总Word文档格式.docx》由会员分享,可在线阅读,更多相关《单精度浮点乘法器汇总Word文档格式.docx(22页珍藏版)》请在冰豆网上搜索。
![单精度浮点乘法器汇总Word文档格式.docx](https://file1.bdocx.com/fileroot1/2022-12/7/ea3c9cda-4a76-4f07-835a-05ad066f3b31/ea3c9cda-4a76-4f07-835a-05ad066f3b311.gif)
对于单精度浮点乘法器这一课程题目,重点在于正确理解IEEE-754标准,设计出符合IEEE-754标准的单精度浮点乘法器。
2.1.1符合IEEE-754标准的单精度浮点乘法器规格
单精度浮点数32位由高位至低位可划分为1位符号位(s),8位阶码(e),23位尾数(f)。
0<
e<
255时为规格化数;
e=0且f=0为正负0;
e=0且f不等于0,为非规格化数;
e=255且f=0,为正负无穷;
e=255且f不等于0,为NaN(不是一个数)。
图2-1单精度浮点数的规格
2.1.2操作数类型
符号/1位
阶码/8位
尾数/23位
NaN
0/1
11111111
非0
无穷
23’b0
00000000
任意
正常
(0,255)
表2-1
说明:
1、NaN和任何数相乘都为NaN;
2、无穷和0相乘为NaN,和其他数相乘都为无穷;
3、0和替他数相乘都为0;
4、正常数和正常数相乘再对他们的乘积进行判断(以上的每一种情况都是在其前面情况不成立情况下进行的);
5、如flout_a与flout_b中有至少一个异常,那么flout_c的尾数部分为优先级高的异常情况的尾数部分,无穷和0相乘特殊,指定其尾数为23’b01,0的符号位为0,其他为sign_a^sign_b;
2.1.3运算规则
两个规格化的单精度浮点数相乘时,运算规则如下:
(1)符号位相异或得结果;
(2)阶码为e=(e1-127)+(e2-127)+127;
(3)尾数为两个尾数都扩展一位后再相乘,得出的为一个48位数cf1,取出cf1的第24位至第48位赋给cf3,即cf3=cf1[47:
23],此时若cf1[22]=0,舍去第1位至23位,若cf1[22]=1,向第24位进1,并且舍去第1位至第23位;
尾数规格化:
判断cf3[24]是否为1,若cf3[24]=1,cf3右移1位,阶码位加1,若cf3[24]=0,则不用进行规格化;
最后尾数取cf3[22:
0]。
2.1.4逻辑门级框图
图2-2逻辑门级框架简图
2.2软件流程图
图2-3总流程图
图2-4计算部分详细流程图
2.3HDL代码阐述
modulemux(flout_a,flout_b,clk,en,rst,flout_c,yichu);
input[31:
0]flout_a;
0]flout_b;
//设置两个输入的单精度浮点数
inputclk;
//时钟信号
inputen;
//使能信号
inputrst;
//复位信号
output[31:
0]flout_c;
//输出的单精度浮点数
output[1:
0]yichu;
//溢出信号
reg[31:
reg[1:
//变量类型声明
regsign_a,sign_b,sign_c;
//符号位
reg[7:
0]zhishu_a,zhishu_b,zhishu_c;
//阶码
reg[23:
0]zz_a,zz_b;
reg[47:
0]zz_c;
//尾数
regjiayi;
//中间变量
always@(posedgeclkornegedgerst)begin
if(~rst)begin
sign_a<
=0;
sign_b<
zhishu_a<
zhishu_b<
zz_a<
zz_b<
end//输入复位模块
elseif(en)begin
=flout_a[31];
=flout_b[31];
=flout_a[30:
23];
=flout_b[30:
={1'
b1,flout_a[22:
0]};
b1,flout_b[22:
end//使能赋初值模块
end
always@(sign_aorsign_borzhishu_aorzhishu_borzz_aorzz_b)begin
zhishu_c=0;
zz_c=0;
sign_c=0;
yichu=2'
b01;
end//输出复位模块
elsebegin
if(zhishu_a==255&
&
(|zz_a[22:
0]))begin
zhishu_c=zhishu_a;
b11;
zz_c[46:
23]=zz_a;
sign_c=sign_a^sign_b;
end//数a不是一个数与数b任何数相乘都是不是一个数
elseif(zhishu_b==255&
(|zz_b[22:
zhishu_c=zhishu_b;
23]=zz_b;
end//数b不是一个数与数a任何数相乘都是不是一个数
elseif(zhishu_a==255&
(~(|zz_a[22:
0])))begin
if(zhishu_b==255&
(~(|zz_b[22:
b10;
end//数a无穷与数b无穷相乘还是无穷
elseif(zhishu_b==0)begin
23]=1'
b1;
end//数a无穷与数b0相乘为不是一个数
elseif(zhishu_b<
255&
zhishu_b>
0)begin
end//数a无穷与数b规格化数相乘为无穷
if(zhishu_a==0)begin
23]=zz_b+1'
end//数b无穷与数a0相乘为不是一个数
elseif(zhishu_a<
zhishu_a>
0)begin
end//数b无穷与数a规格化数相乘为无穷
elseif((zhishu_a==0)||(zhishu_b==0))begin
b00;
zhishu_c=8'
b00000000;
if(~(|zhishu_a))begin
end//数a0与数b0相乘还为0
zhishu_c=zhishu_a+zhishu_b-127;
zz_c=zz_a*zz_b;
if(zz_c[22]==1)begin
jiayi=1'
b0;
zz_c[47:
23]=zz_c[47:
23]+1'
//zz_c[45:
23]
elseif(zz_c[47]==1)begin
23]={1'
b0,zz_c[47:
24]};
23]
if(jiayi)begin
zhishu_c=zhishu_c+1;
end//数a规格化数与数b规格化数相乘按照ieee-754标准进行计算
if(zhishu_c>
=255&
(|zz_c))begin
hff;
end//得出的结果为不是一个数
(~(|zz_c)))begin
end//得出的结果为无穷
elseif(zhishu_a+zhishu_b<
=127)begin
end//得出的结果为0
zhishu_c=zhishu_c;
end//得出的结果为规格化数
flout_c[31]<
flout_c[30:
23]<
flout_c[22:
0]<
end//输出结果的复位模块
=sign_c;
=zhishu_c;
=zz_c[45:
end//输出结果拼接
endmodule
2.4Modelsim验证
2.4.1验证代码
`timescale1ns/100ps
modulemux_tb();
reg[31:
0]flout_a,flout_b;
regclk,en,rst;
wire[31:
0]flout_c;
wireyichu;
//声明变量类型
muxdut(.flout_a(flout_a),
.flout_b(flout_b),
.clk(clk),
.en(en),
.rst(rst),
.flout_c(flout_c),
.yichu(yichu));
//与源程序的例化dut相连
initial
clk=0;
always#20clk=~clk;
//设置时钟的变化
initialbegin
flout_b=32'
h00000001;
flout_a=32'
h7f800000;
en=1;
rst=0;
#100;
rst=1;
#800000;
h20000001;
h7f800001;
h0af800001;
//设置输入变量,使能信号,复位信号随时间发生变化
$stop;
//taskdelay;
//input[31:
0]mum;
//repeat(num)@(posedgeclk)begin
//repeat(100)@(posedgeclk);
//end
//endtask
$dumpfile("
zk.vcd"
);
$dumpvars;
end//生成vcd文件
2.4.2验证波形
图2-5Modelsim验证波形
2.5硬件调试
2.5.1基本说明
输入flout_a的其中6位,一位符号位,阶码位的前两位和尾数位的后三位;
阶码的其他6位都设为1,尾数都设为0。
输入flout_b的一位符号位,前两位阶码位和后三位尾数位;
其余阶码位当chose=1时为全1,当chose=0时为全0,尾数的其它位为0。
以下为乘数的输入位规定:
标号
类型
符号位
阶码位
尾数位
A
11
000
B
001
C
01
表2-2
以下为被乘数的输入位规定:
1
Chose=1
2
3
1’
零
00
Chose=0
2’
表2-3
以下为根据以上标号组合而成的结果的形式:
结果为2位溢出标志位,1位符号位,3位阶码位(前两位为阶码最高位,第三位为阶码最低位),后四位为尾数后四位。
结果如下
组合
A1’
A2’
B1’
B2’
C1’
C2’
A1
B2
A2
C3
溢出标志
10
阶码前两位,最后一位
111
010
011
尾数后四位
0001
0000
0010
表2-4
经验证开发板显示结果与上表格相同。
2.5.2具体操作
1.如图2-6所示,新建一个工程mux。
图2-6新建工程
2.如图2-7所示,向工程中添加mux_banzi.v。
图2-7添加.v文件
3.绑定管脚。
flout_a与flout_b以及chose,rst,en绑到15个输入开关上,flout_c以及yichu绑到10个灯上。
NET"
flout_a[5]"
IOSTANDARD=LVCMOS33;
flout_a[4]"
flout_a[3]"
flout_a[2]"
flout_a[1]"
flout_a[0]"
flout_b[5]"
flout_b[4]"
flout_b[3]"
flout_b[2]"
flout_b[1]"
flout_b[0]"
flout_c[7]"
flout_c[6]"
flout_c[5]"
flout_c[4]"
flout_c[3]"
flout_c[2]"
flout_c[1]"
flout_c[0]"
yichu[1]"
yichu[0]"
LOC=P4;
LOC=P3;
LOC=R3;
LOC=T1;
LOC=T3;
LOC=U2;
LOC=V7;
LOC=R5;
LOC=R6;
LOC=R7;
LOC=U8;
LOC=U9;
LOC=P2;
LOC=R2;
LOC=U1;
LOC=P5;
LOC=R1;
LOC=V1;
LOC=U3;
LOC=V4;
LOC=V9;
LOC=T8;
chose"
LOC=V2;
en"
LOC=U4;
rst"
LOC=V5;
clk"
LOC=E3;
4.综合、翻译、适配。
点击ImplementDesign,选择run进行综合、翻译等。
当进行到Map时出现了错误,原因大概是总线时钟不能由下面的一排开关控制,因此经过查阅资料,将“NET"
CLOCK_DEDICATED_ROUTE=FALSE”这句话存入top.ucf中,即可将错误降低为警告,继续运行。
或将时钟绑定至E3管脚此问题得以解决。
5.下载程序。
将板子通过USB供电,并将并口与计算机相连,打开板子电源开关。
选择所要下载的.jed文件,待芯片成为绿色,右击芯片,选择Program,当出现programsucceed,程序已经下载到板子的芯片上,就可以通过改变输入来观察输出跟料想的是否一样。
2.6虚拟机下的DC综合
综合出来的面积如图2-8:
图2-8“report_area”
综合得到的时序如图2-9:
图2-9“report_timing”
2.7虚拟机下的SDF反标仿真
如图2-10所示,得到的结果与反标之前是相同的,反标之后的门延迟与之前不相同。
图2-10反标仿真波形图
图2-11是把延迟放大之后的观察情况:
可以观察到A导致Y的上升延迟时间是1.223ns。
图2-11延迟放大后的波形图
图2-12是从.SDF文