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

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

3天内不再提示

基于verilog的浮点乘法器实现

q67N_gh_b6a4c0d 来源:玩儿转FPGA 作者:玩儿转FPGA 2021-08-10 16:29 次阅读

好久不见,甚是想念。在后台看到好多朋友私信我各种问题,其中想白piao代码的居多,为了回馈大家,今天我就奉上一段代码,让大家随便使用,希望大家能顺利完成项目结束996。

//Single Precision//Copyright:hjdmodule multiplier( input_a, input_b, input_a_stb, input_b_stb, output_z_ack, clk, rst, output_z, output_z_stb, input_a_ack, input_b_ack);

input clk; input rst;

input [31:0] input_a; input input_a_stb; output input_a_ack;

input [31:0] input_b; input input_b_stb; output input_b_ack;

output [31:0] output_z; output output_z_stb; input output_z_ack;

reg s_output_z_stb; reg [31:0] s_output_z; reg s_input_a_ack; reg s_input_b_ack;

reg [3:0] state; parameter get_a = 4‘d0, get_b = 4’d1, unpack = 4‘d2, special_cases = 4’d3, normalise_a = 4‘d4, normalise_b = 4’d5, multiply_0 = 4‘d6, multiply_1 = 4’d7, normalise_1 = 4‘d8, normalise_2 = 4’d9, round = 4‘d10, pack = 4’d11, put_z = 4‘d12;

reg [31:0] a, b, z; reg [23:0] a_m, b_m, z_m; reg [9:0] a_e, b_e, z_e; reg a_s, b_s, z_s; reg guard, round_bit, sticky; reg [47:0] product;

always @(posedge clk) begin

case(state)

get_a: begin s_input_a_ack 《= 1; if (s_input_a_ack && input_a_stb) begin a 《= input_a; s_input_a_ack 《= 0; state 《= get_b; end end

get_b: begin s_input_b_ack 《= 1; if (s_input_b_ack && input_b_stb) begin b 《= input_b; s_input_b_ack 《= 0; state 《= unpack; end end

unpack: begin a_m 《= a[22 : 0]; b_m 《= b[22 : 0]; a_e 《= a[30 : 23] - 127; b_e 《= b[30 : 23] - 127; a_s 《= a[31]; b_s 《= b[31]; state 《= special_cases; end

special_cases: begin //if a is NaN or b is NaN return NaN if ((a_e == 128 && a_m != 0) || (b_e == 128 && b_m != 0)) begin z[31] 《= 1; z[30:23] 《= 255; z[22] 《= 1; z[21:0] 《= 0; state 《= put_z; //if a is inf return inf end else if (a_e == 128) begin z[31] 《= a_s ^ b_s; z[30:23] 《= 255; z[22:0] 《= 0; //if b is zero return NaN if (($signed(b_e) == -127) && (b_m == 0)) begin z[31] 《= 1; z[30:23] 《= 255; z[22] 《= 1; z[21:0] 《= 0; end state 《= put_z; //if b is inf return inf end else if (b_e == 128) begin z[31] 《= a_s ^ b_s; z[30:23] 《= 255; z[22:0] 《= 0; //if a is zero return NaN if (($signed(a_e) == -127) && (a_m == 0)) begin z[31] 《= 1; z[30:23] 《= 255; z[22] 《= 1; z[21:0] 《= 0; end state 《= put_z; //if a is zero return zero end else if (($signed(a_e) == -127) && (a_m == 0)) begin z[31] 《= a_s ^ b_s; z[30:23] 《= 0; z[22:0] 《= 0; state 《= put_z; //if b is zero return zero end else if (($signed(b_e) == -127) && (b_m == 0)) begin z[31] 《= a_s ^ b_s; z[30:23] 《= 0; z[22:0] 《= 0; state 《= put_z; end else begin //Denormalised Number if ($signed(a_e) == -127) begin a_e 《= -126; end else begin a_m[23] 《= 1; end //Denormalised Number if ($signed(b_e) == -127) begin b_e 《= -126; end else begin b_m[23] 《= 1; end state 《= normalise_a; end end

normalise_a: begin if (a_m[23]) begin state 《= normalise_b; end else begin a_m 《= a_m 《《 1; a_e 《= a_e - 1; end end

normalise_b: begin if (b_m[23]) begin state 《= multiply_0; end else begin b_m 《= b_m 《《 1; b_e 《= b_e - 1; end end

multiply_0: begin z_s 《= a_s ^ b_s; z_e 《= a_e + b_e + 1; product 《= a_m * b_m; state 《= multiply_1; end

multiply_1: begin z_m 《= product[47:24]; guard 《= product[23]; round_bit 《= product[22]; sticky 《= (product[21:0] != 0); state 《= normalise_1; end

normalise_1: begin if (z_m[23] == 0) begin z_e 《= z_e - 1; z_m 《= z_m 《《 1; z_m[0] 《= guard; guard 《= round_bit; round_bit 《= 0; end else begin state 《= normalise_2; end end

normalise_2: begin if ($signed(z_e) 《 -126) begin z_e 《= z_e + 1; z_m 《= z_m 》》 1; guard 《= z_m[0]; round_bit 《= guard; sticky 《= sticky | round_bit; end else begin state 《= round; end end

round: begin if (guard && (round_bit | sticky | z_m[0])) begin z_m 《= z_m + 1; if (z_m == 24’hffffff) begin z_e 《=z_e + 1; end end state 《= pack; end

pack: begin z[22 : 0] 《= z_m[22:0]; z[30 : 23] 《= z_e[7:0] + 127; z[31] 《= z_s; if ($signed(z_e) == -126 && z_m[23] == 0) begin z[30 : 23] 《= 0; end //if overflow occurs, return inf if ($signed(z_e) 》 127) begin z[22 : 0] 《= 0; z[30 : 23] 《= 255; z[31] 《= z_s; end state 《= put_z; end

put_z: begin s_output_z_stb 《= 1; s_output_z 《= z; if (s_output_z_stb && output_z_ack) begin s_output_z_stb 《= 0; state 《= get_a; end end

endcase

if (rst == 1) begin state 《= get_a; s_input_a_ack 《= 0; s_input_b_ack 《= 0; s_output_z_stb 《= 0; end

end assign input_a_ack = s_input_a_ack; assign input_b_ack = s_input_b_ack; assign output_z_stb = s_output_z_stb; assign output_z = s_output_z;

endmodule

是不是觉得很复杂?代码非常古老?是的,这是我n年前写的压箱底的东西,但是还是可以正确使用的,上一次更新是在今年4月左右吧,毕竟浮点乘法并不难,浮点加法才是让人掉头发。如果发现bug请私信或留言。还有小朋友问:test bentch呢??当然是,下次一定。

编辑:jq

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

    关注

    0

    文章

    30

    浏览量

    13265
  • Verilog
    +关注

    关注

    28

    文章

    1327

    浏览量

    109312
  • 代码
    +关注

    关注

    30

    文章

    4556

    浏览量

    66814

原文标题:来了来了,verilog的浮点乘法器实现

文章出处:【微信号:gh_b6a4c0db5bbe,微信公众号:成信FPGA学堂】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    verilog语音实现浮点运算

    Verilog可以通过使用IEEE标准的浮点数表示来实现浮点运算。下面是一个基本的Verilog模块示例,展示了如何进行加法、
    发表于 03-25 21:49

    如何设计一个16比特的减法器呢?

    减法电路是基本集成运放电路的一种,算术运算电路主要包括数字**加法器电路、数字减法器电路、数字乘法器电路和数字除法器电路。
    的头像 发表于 02-19 10:00 362次阅读
    如何设计一个16比特的减<b class='flag-5'>法器</b>呢?

    乘法器AD734上电后发热严重,数据漂移的原因?怎么解决?

    乘法器AD734上电后发热比较严重,输入与地短接的情况下,输出数据不稳定,用数据卡采集可以看到明显的漂移,[size=13.3333px]采用的是芯片手册上的最基本的乘法电路,这种现象的原因是什么,是PCB设计的问题吗。
    发表于 12-15 06:44

    pipeline ADC的实现原理及基本结构(1)

    假设单级的分辨率为n,它由S/H电路、n位的子ADC、n位的子DAC、减法器以及乘法器构成,一般也将n位的子DAC、减法器以及乘法器统称为MDAC(multiplying DAC)。
    的头像 发表于 12-14 12:34 907次阅读
    pipeline ADC的<b class='flag-5'>实现</b>原理及基本结构(1)

    用AD835的Datasheet上的电路做了一个乘法器电路,出现两个直流偏置的原因?

    我用AD835的Datasheet上的电路做了一个乘法器电路,但是测试的时候发现,当输入信号大于峰值大于600mV左右的时候,1和8两个引脚端就会突然出现两个直流偏置,约-1.5V,请问有人用该芯片出现过这种问题吗?求指教。。。。
    发表于 11-27 06:43

    求助,关于二象限乘法器AD539的一些疑问

    各位,请教乘法器的一些问题: 1.二象限乘法器AD539中控制通道Vx只能输入正信号,但是否只能为直流电平(用做电压控制放大器)? 2.如果控制通道Vx输入交流信号,理论上是否应该做偏置,使之在
    发表于 11-22 07:48

    用AD835乘法器做的一个电路,当X和Y的频率相同时,输出的波形问题求解

    请教大神,我用AD835乘法器做的一个电路,当X和Y的频率相同时,相乘时输出是正弦波,但是当频率不相同时输出波形就会变为这种波形,请问有人知道是什么问题??谢谢!附件里有一张图是同频率相乘,波形是对的,另一张是不同频率相乘的图!
    发表于 11-22 06:54

    集成乘法器幅度调制与解调实验

    掌握用MCl496集成模拟乘法器实现AM和DSB调制的方法,并研究已调波与调制信号、载波之间关系
    的头像 发表于 11-08 15:38 2168次阅读
    集成<b class='flag-5'>乘法器</b>幅度调制与解调实验

    使用IAR IDE仿真RL78内置硬件乘法器和除法器注意事项

    使用IAR IDE仿真RL78内置硬件乘法器和除法器注意事项
    的头像 发表于 10-30 17:04 584次阅读
    使用IAR IDE仿真RL78内置硬件<b class='flag-5'>乘法器</b>和除<b class='flag-5'>法器</b>注意事项

    Altera FPGA内置的乘法器为何是18位的?

    Altera的FPGA内置的乘法器为何是18位的?
    发表于 10-18 07:01

    硬件乘法器是怎么实现的?

    硬件乘法器是怎么实现
    发表于 09-22 06:53

    集成电路中低功耗乘法器实现与设计方案

    限度的低功耗效果。本文紧跟市场发展动向,从以上应用角度出发,着力研究集成电路设计中小数乘法器的前端低功耗算法以及实现技术,并且改进了现有低功耗设计技术的一些不足之处。
    发表于 09-19 07:42

    乘法器Verilog HDL实现方案

    两个N位二进制数x、y的乘积用简单的方法计算就是利用移位操作来实现
    的头像 发表于 06-21 09:01 602次阅读
    <b class='flag-5'>乘法器</b>的<b class='flag-5'>Verilog</b> HDL<b class='flag-5'>实现</b>方案

    FPGA常用运算模块-复数乘法器

    本文是本系列的第五篇,本文主要介绍FPGA常用运算模块-复数乘法器,xilinx提供了相关的IP以便于用户进行开发使用。
    的头像 发表于 05-22 16:23 1416次阅读
    FPGA常用运算模块-复数<b class='flag-5'>乘法器</b>

    FPGA常用运算模块-加减法器乘法器

    本文是本系列的第二篇,本文主要介绍FPGA常用运算模块-加减法器乘法器,xilinx提供了相关的IP以便于用户进行开发使用。
    的头像 发表于 05-22 16:13 2817次阅读
    FPGA常用运算模块-加减<b class='flag-5'>法器</b>和<b class='flag-5'>乘法器</b>