(完整)单精度浮点乘法器

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

(完整)单精度浮点乘法器
编辑整理:
尊敬的读者朋友们:
这里是精品文档编辑中心,本文档内容是由我和我的同事精心编辑整理后发布的,发布之前我们对文中内容进行仔细校对,但是难免会有疏漏的地方,但是任然希望((完整)单精度浮点乘法器)的内容能够给您的工作和学习带来便利。

同时也真诚的希望收到您的建议和反馈,这将是我们进步的源泉,前进的动力。

本文可编辑可修改,如果觉得对您有帮助请收藏以便随时查阅,最后祝您生活愉快业绩进步,以下为(完整)单精度浮点乘法器的全部内容。

EDA/SOPC课程设计报告题目: 单精度浮点乘法器
姓名: 张恺
学号:120260230
同组人:刘龙
指导教师:王晨旭
成绩:
目录
第1章课程设计的要求
1.1 课程设计的目的
●通过课堂所讲授的内容以及私下查阅资料,自主完成课程设计的题目,提高编
程能力,培养用计算机解决实际问题的能力,积累调试程序的经验,更好的消化
老师课堂所讲授的内容,对Verilog这种语言也有了更深的了解;
●掌握较大工程的基本开发技能;
●培养综合运用Modelsim,ISE,Debussy工具进行硬件开发的能力;
●培养数字系统设计的基本能力;
●通过课设积累起的编程以及硬件的能力对于今后的考研抑或是找工作都有非常
实际性的效果;
1.2 课程设计的条件
●设计条件1:gVim编辑器以及Mentor公司开发的FPGA仿真软件Modelsim;
●设计条件2:Xilinx公司开发的硬件设计工具ISE以及Xilinx公司的开发板;
●设计条件3:虚拟机环境下的Linux系统具有的Design Compiler工具;
●设计条件4:虚拟机环境下的Linux系统具有的SDF工具以及Debussy工具;
1.3 课程设计的要求
●设计要求1:能够在Modelsim工具下正确的完成程序的编译以及成功的实现波
形的仿真;
●设计要求2:能够在ISE工具下正确的完成程序的综合以及合理的绑定管脚并
成功的将程序下载到开发板里,在开发板中实现程序的功能;
●设计要求3:能够在虚拟机的Linux系统下采用Design Compiler完成逻辑综
合,并且评估其时序面积;
●设计要求4:能够在虚拟机的Linux系统下完成SDF反标仿真;
第2章课程设计的内容
2.1 设计思路
对于单精度浮点乘法器这一课程题目,重点在于正确理解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 单精度浮点数的规格
说明:
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 HDL代码阐述
module mux(flout_a,flout_b,clk,en,rst,flout_c,yichu);
module mux(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 sign_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;//尾数
reg jiayi;//中间变量
always@(posedge clk or negedge rst)begin
if(~rst)begin
sign_a<=0;
sign_b〈=0;
zhishu_a<=0;
zhishu_b<=0;
zz_a<=0;
zz_b<=0;
end //输入复位模块
else if (en)begin
sign_a<=flout_a[31];
sign_b<=flout_b[31];
zhishu_a〈=flout_a[30:23];
zhishu_b〈=flout_b[30:23];
zz_a<={1'b1,flout_a[22:0]};
zz_b<={1’b1,flout_b[22:0]};
end //使能赋初值模块
end
always@(sign_a or sign_b or zhishu_a or zhishu_b or zz_a or zz_b)begin if(~rst)begin
zhishu_c=0;
zz_c=0;
sign_c=0;
yichu=2’b01;
end //输出复位模块
else begin
if(zhishu_a==255&&(|zz_a[22:0]))begin
zhishu_c=zhishu_a;
yichu=2’b11;
zz_c[46:23]=zz_a;
sign_c=sign_a^sign_b;
end //数a不是一个数与数b任何数相乘都是不是一个数
else if(zhishu_b==255&&(|zz_b[22:0]))begin
zhishu_c=zhishu_b;
yichu=2'b11;
zz_c[46:23]=zz_b;
sign_c=sign_a^sign_b;
end //数b不是一个数与数a任何数相乘都是不是一个数 else if(zhishu_a==255&&(~(|zz_a[22:0])))begin
if(zhishu_b==255&&(~(|zz_b[22:0])))begin
zhishu_c=zhishu_a;
yichu=2'b10;
zz_c[46:23]=zz_a;
sign_c=sign_a^sign_b;
end //数a无穷与数b无穷相乘还是无穷
else if(zhishu_b==0) begin
zhishu_c=zhishu_a;
yichu=2'b11;
zz_c[46:23]=1’b1;
sign_c=sign_a^sign_b;
end //数a无穷与数b0相乘为不是一个数
else if(zhishu_b<255&&zhishu_b〉0) begin
zhishu_c=zhishu_a;
yichu=2’b10;
zz_c[46:23]=zz_a;
sign_c=sign_a^sign_b;
end //数a无穷与数b规格化数相乘为无穷
end
else if(zhishu_b==255&&(~(|zz_b[22:0])))begin
if(zhishu_a==0) begin
zhishu_c=zhishu_b;
yichu=2'b11;
zz_c[46:23]=zz_b+1’b1;
sign_c=sign_a^sign_b;
end //数b无穷与数a0相乘为不是一个数
else if(zhishu_a<255&&zhishu_a〉0)begin
zhishu_c=zhishu_b;
yichu=2’b10;
zz_c[46:23]=zz_b;
sign_c=sign_a^sign_b;
end //数b无穷与数a规格化数相乘为无穷
end
else if((zhishu_a==0)||(zhishu_b==0))begin
yichu=2’b00;
zhishu_c=8’b00000000;
sign_c=0;
if(~(|zhishu_a))begin
zz_c[46:23]=zz_a;
end
else begin
zz_c[46:23]=zz_b;
end
end //数a0与数b0相乘还为0
else begin
sign_c=sign_a^sign_b;
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’b1;//zz_c[45:23]
end
else if(zz_c[47]==1)begin
zz_c[47:23]={1’b0,zz_c[47:24]};
jiayi=1’b1;
end
else begin
jiayi=1’b0;
zz_c[47:23]=zz_c[47:23];//zz_c[45:23]
end
if(jiayi) begin
zhishu_c=zhishu_c+1;
end // 数a规格化数与数b规格化数相乘按照ieee-754标准进行计算
if(zhishu_c>=255&&(|zz_c))begin
zhishu_c=8’hff;
yichu=2’b11;
end //得出的结果为不是一个数
if(zhishu_c〉=255&&(~(|zz_c)))begin
zhishu_c=8’hff;
yichu=2'b10;
end //得出的结果为无穷
else if(zhishu_a+zhishu_b<=127)begin
yichu=2'b00;
zhishu_c=8’b00000000;
sign_c=0;
end //得出的结果为0
else begin
yichu=2'b01;
zhishu_c=zhishu_c;
end //得出的结果为规格化数
end
end
end
always@(posedge clk or negedge rst)begin
if(~rst)begin
flout_c[31]〈=0;
flout_c[30:23]<=0;
flout_c[22:0]<=0;
end //输出结果的复位模块
else begin
flout_c[31]〈=sign_c;
flout_c[30:23]〈=zhishu_c;
flout_c[22:0]<=zz_c[45:23];
end //输出结果拼接
end
endmodule
2.4 Modelsim验证
2.4.1 验证代码
`timescale 1ns/100ps
module mux_tb();
reg [31:0]flout_a,flout_b;
reg clk,en,rst;
wire [31:0]flout_c;
wire yichu;//声明变量类型
mux dut(.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#20 clk=~clk; //设置时钟的变化
initial begin
flout_b=32’h00000001;
flout_a=32'h7f800000;
en=1;
rst=0;
#100;
rst=1;
#800000;
flout_b=32'h20000001;
flout_a=32'h7f800000;
#800000;
flout_b=32'h00000001;
flout_a=32’h7f800001;
#800000;
flout_b=32'h20000001;
flout_a=32’h7f800001;
#800000;
flout_b=32'h00000001;
flout_a=32'h20000001;
#800000;
flout_b=32’h20000001;
flout_a=32’h20000001;
#800000;
flout_b=32'h7f800000;
flout_a=32'h7f800000;
#800000;
flout_b=32'h7f800001;
flout_a=32’h7f800001;
#800000;
flout_b=32'h7f800001;
flout_a=32’h7f800000;
#800000;
flout_b=32'h0af800001;
flout_a=32’h20000001;
#800000;//设置输入变量,使能信号,复位信号随时间发生变化
$stop;
//task delay;
// input [31:0]mum;
//repeat(num)@(posedge clk)begin
//repeat(100)@(posedge clk);
//end
//endtask
end
initial begin
$dumpfile("zk。

vcd");
$dumpvars;
end //生成vcd文件
endmodule
2.4.2 验证波形
图2—5 Modelsim验证波形
2.5 硬件调试
2.5.1 基本说明
输入flout_a的其中6位,一位符号位,阶码位的前两位和尾数位的后三位;阶码的其他6位都设为1,尾数都设为0。

输入flout_b的一位符号位,前两位阶码位和后三位尾数位;其余阶码位当chose=1时为全1 ,当chose=0时为全0,尾数的其它位为0.
以下为乘数的输入位规定:
以下为被乘数的输入位规定:
以下为根据以上标号组合而成的结果的形式:结果为2位溢出标志位,1位符号位,3位阶码位(前两位为阶码最高位,第三位为阶码最低位),后四位为尾数后四位.结果如下
经验证开发板显示结果与上表格相同.
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;
NET "flout_a[4]" IOSTANDARD = LVCMOS33;
NET "flout_a[3]” IOSTANDARD = LVCMOS33;
NET ”flout_a[2]” IOSTANDARD = LVCMOS33;
NET "flout_a[1]” IOSTANDARD = LVC MOS33;
NET ”flout_a[0]” IOSTANDARD = LVCMOS33;
NET "flout_b[5]" IOSTANDARD = LVCMOS33;
NET ”flout_b[4]" IOSTANDARD = LVCMOS33;
NET "flout_b[3]” IOSTANDARD = LVCMOS33;
NET ”flout_b[2]" IOSTANDARD = LVCMOS33;
NET ”flout_b[1]” IOSTANDARD = LVCMOS33;
NET ”flou t_b[0]" IOSTANDARD = LVCMOS33;
NET "flout_c[7]” IOSTANDARD = LVCMOS33;
NET "flout_c[6]" IOSTANDARD = LVCMOS33;
NET ”flout_c[5]" IOSTANDARD = LVCMOS33;
NET "flout_c[4]” IOSTANDARD = LVCMOS33;
NET ”flout_c[3]" IOSTANDARD = LVCMOS33;
NET ”flout_c[2]” IOSTANDA RD = LVCMOS33;
NET ”flout_c[1]” IOSTANDARD = LVCMOS33;
NET ”flout_c[0]" IOSTANDARD = LVCMOS33;
NET ”yichu[1]” IOSTANDARD = LVCMOS33;
NET "yichu[0]” IOSTANDARD = LVCMOS33;
NET ”flout_a[5]" LOC = P4;
NET ”flout_a[4]” LOC = P3;
NET "flout_a[3]" LOC = R3;
NET "flout_a[2]” LOC = T1;
NET ”flout_a[1]" LOC = T3;
NET ”flout_a[0]” LOC = U2;
NET ”flout_b[5]" LOC = V7;
NET ”flout_b[4]” LOC = R5;
NET ”flout_b[3]" LOC = R6;
NET ”flout_b[2]” LOC = R7;
NET "flout_b[1]” LOC = U8;
NET "flout_b[0]” LOC = U9;
NET "flout_c[7]” LOC = P2;
NET ”flout_c[6]" LOC = R2;
NET ”flout_c[5]” LOC = U1;
NET ”flout_c[4]” LOC = P5;
NET ”flout_c[3]" LOC = R1;
NET ”flout_c[2]" LOC = V1;
NET ”flout_c[1]" LOC = U3;
NET ”flout_c[0]” LOC = V4;
NET "yichu[1]" LOC = V9;
NET ”yichu[0]" LOC = T8;
NET ”chose" LOC = V2;
NET ”en” LOC = U4;
NET ”rst" LOC = V5;
NET "clk” LOC = E3;
NET ”chose” IOSTANDARD = LVCMOS33;
NET "clk" IOSTANDARD = LVCMOS33;
NET "en" IOSTANDARD = LVCMOS33;
NET "rst” IOSTANDARD = LVCMOS33;
4。

综合、翻译、适配。

点击 Implement Design,选择run 进行综合、翻译等。

当进行到Map时出现了错误,原因大概是总线时钟不能由下面的一排开关控制,因此经过查阅资料,将“NET ”clk" CLOCK_DEDICATED_ROUTE = FALSE”这句话存入top.ucf中,即可将错误降低为警告,继续运行.或将时钟绑定至E3管脚此问题得以解决。

5. 下载程序。

将板子通过 USB 供电,并将并口与计算机相连,打开板子电源开关。

选择所要下载的.jed 文件,待芯片成为绿色,右击芯片,选择 Program,当出现program succeed,程序已经下载到板子的芯片上,就可以通过改变输入来观察输出跟料想的是否一样。

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文件里截取的.u359的相关信息。

可以看到,A导致Y的上升时间为1。

223ns,与波形一致。

图2-12
第3章课程设计的心得
本次课设历时近一个月,使用了ISE、Modelsim、Linux系统下的Design Compiler、SDF 和FPGA开发板,完成了基于IEEE-754标准的单精度浮点乘法器的FPGA实现,既是对前期课程《电子设计自动化基础》的复习与巩固,也对后续的毕业设计奠定了深厚的基础。

经过此次课程设计的实践与学习,感觉自己收获很大,相比较于以往在教室里听老师传授给我们知识,课程设计这种形式自主性与能动性更强,很大程度上提高了我的自主学习能力,一边回顾老师课上所讲授的内容,一边自己上网、或是去图书馆查阅资料等多种形式学习方式,让我体验到了自主学习的乐趣,而且,当眼前所面临的一个又一个难题被解决时是有极大成就感的。

再来说一下我整个课程设计的经历,起初刚刚拿到题目的时候我是很茫然的,对于各种软件、硬件完全不了解,更是从未涉及过有关单精度浮点乘法器的内容。

但慢慢的,我了解了这个题目相关的IEEE-754标准,大致熟悉了Windows和Linux系统下的各个软件的使用,以及老师给的FPGA开发板的管脚图等,值得一提的是,虽然第一次使用Linux系统,我觉得相比windows系统,Linux有其一定的优势和长处,精简而快捷,操作方便,全命令动作,而这也是windows图形化界面所不具备的优势.
我真的特别感激与珍惜这次课设的经历,虽然不是尽善尽美,但确实收获颇多,我相信这也会成为我整个大学生涯都特别难忘的经历。

同时,这次课设让我明白了学习一门知识,不是一般的机械式套用,而是要学会思考,弄清楚其中的每一个细节,明白为什么要往左而不是往右,明白每一个命令是干什么的,有什么作用,可以完成什么功能。

我们追求的不是死记硬背烂熟于心,而是熟能生巧信手拈来.唯有如此,才可融会贯通,一通百通,才会取得更多更快的进步。

最后,再次感谢老师与同学对我的帮助。

相关文档
最新文档