当前位置:文档之家› 单精度浮点乘法器

单精度浮点乘法器

EDA/SOPC课程设计报告题目:单精度浮点乘法器姓名:张恺学号:120260230同组人:刘龙指导教师:王晨旭成绩:目录目录 (II)第1章课程设计的要求 (1)1.1 课程设计的目的 (1)1.2 课程设计的条件 (1)1.3 课程设计的要求 (1)第2章课程设计的内容 (2)2.1 设计思路 (2)2.1.1 符合IEEE-754标准的单精度浮点乘法器规格 (2)2.1.2 操作数类型 (2)2.1.3 运算规则 (3)2.1.4 逻辑门级框图 (3)2.2 软件流程图 (4)2.3 HDL代码阐述 (6)2.4 Modelsim验证 (10)2.4.1 验证代码 (10)2.4.2 验证波形 (12)2.5 硬件调试 (12)2.5.1 基本说明 (12)2.5.2 具体操作 (13)2.6 虚拟机下的DC综合 (17)2.7 虚拟机下的SDF反标仿真 (19)第3章课程设计的心得 (20)第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 单精度浮点数的规格2.1.2 操作数类型符号/1位阶码/8位尾数/23位NaN 0/1 11111111 非0无穷0/1 11111111 23’b00 0/1 00000000 任意正常0/1 (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 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)beginif(~rst)beginsign_a<=0;sign_b<=0;zhishu_a<=0;zhishu_b<=0;zz_a<=0;zz_b<=0;end //输入复位模块else if (en)beginsign_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 //使能赋初值模块endalways@(sign_a or sign_b or zhishu_a or zhishu_b or zz_a or zz_b)beginif(~rst)beginzhishu_c=0;zz_c=0;sign_c=0;yichu=2'b01;end //输出复位模块else beginif(zhishu_a==255&&(|zz_a[22:0]))beginzhishu_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]))beginzhishu_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])))beginif(zhishu_b==255&&(~(|zz_b[22:0])))beginzhishu_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) beginzhishu_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) beginzhishu_c=zhishu_a;yichu=2'b10;zz_c[46:23]=zz_a;sign_c=sign_a^sign_b;end //数a无穷与数b规格化数相乘为无穷endelse if(zhishu_b==255&&(~(|zz_b[22:0])))beginif(zhishu_a==0) beginzhishu_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)beginzhishu_c=zhishu_b;yichu=2'b10;zz_c[46:23]=zz_b;sign_c=sign_a^sign_b;end //数b无穷与数a规格化数相乘为无穷endelse if((zhishu_a==0)||(zhishu_b==0))beginyichu=2'b00;zhishu_c=8'b00000000;sign_c=0;if(~(|zhishu_a))beginzz_c[46:23]=zz_a;endelse beginzz_c[46:23]=zz_b;endend //数a0与数b0相乘还为0else beginsign_c=sign_a^sign_b;zhishu_c=zhishu_a+zhishu_b-127;zz_c=zz_a*zz_b;if(zz_c[22]==1)beginjiayi=1'b0;zz_c[47:23]=zz_c[47:23]+1'b1;//zz_c[45:23]endelse if(zz_c[47]==1)beginzz_c[47:23]={1'b0,zz_c[47:24]};jiayi=1'b1;endelse beginjiayi=1'b0;zz_c[47:23]=zz_c[47:23];//zz_c[45:23]endif(jiayi) beginzhishu_c=zhishu_c+1;end // 数a规格化数与数b规格化数相乘按照ieee-754标准进行计算if(zhishu_c>=255&&(|zz_c))beginzhishu_c=8'hff;yichu=2'b11;end //得出的结果为不是一个数if(zhishu_c>=255&&(~(|zz_c)))beginzhishu_c=8'hff;yichu=2'b10;end //得出的结果为无穷else if(zhishu_a+zhishu_b<=127)beginyichu=2'b00;zhishu_c=8'b00000000;sign_c=0;end //得出的结果为0else beginyichu=2'b01;zhishu_c=zhishu_c;end //得出的结果为规格化数endendendalways@(posedge clk or negedge rst)beginif(~rst)beginflout_c[31]<=0;flout_c[30:23]<=0;flout_c[22:0]<=0;end //输出结果的复位模块else beginflout_c[31]<=sign_c;flout_c[30:23]<=zhishu_c;flout_c[22:0]<=zz_c[45:23];end //输出结果拼接endendmodule2.4 Modelsim验证2.4.1 验证代码`timescale 1ns/100psmodule 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相连initialclk=0;always#20 clk=~clk; //设置时钟的变化initial beginflout_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//endtaskendinitial begin$dumpfile("zk.vcd");$dumpvars;end //生成vcd文件endmodule2.4.2 验证波形图2-5 Modelsim验证波形2.5 硬件调试2.5.1 基本说明输入flout_a的其中6位,一位符号位,阶码位的前两位和尾数位的后三位;阶码的其他6位都设为1,尾数都设为0。

相关主题