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

    文章

    31

    浏览量

    13662
  • Verilog
    +关注

    关注

    30

    文章

    1370

    浏览量

    114107
  • 代码
    +关注

    关注

    30

    文章

    4940

    浏览量

    73118

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

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

收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    使用Xilinx 7系列FPGA的四位乘法器设计

    (Shinshu University)研究团队的最新设计中,一个专为 Xilinx 7 系列 FPGA 量身打造的 4 位乘法器使用了仅 11 个 LUT + 2 个 CARRY4 块,关键路径延迟达到 2.75 ns。这是一次令人印象深刻的工艺优化实践。
    的头像 发表于 11-17 09:49 2656次阅读
    使用Xilinx 7系列FPGA的四位<b class='flag-5'>乘法器</b>设计

    E203在基于wallace树+booth编码的乘法器优化后的跑分结果

    优化思路 E203为了实现低功耗的要求,乘法器为基于booth编码和移位加法器结合的思路,优点是只需要一个加法器,而且该加法器还和除
    发表于 10-27 07:54

    E203V2长周期乘法器核心booth算法解读

    ,可以看到E203V2乘法器为了实现低功耗小面积的目标,与alu_regular模块内的加法器共享硬件单元,数据通道中加法器的操作数选择部分源码如下所示: 由此可以看出乘除
    发表于 10-24 09:33

    Verilog实现使用Booth编码和Wallace树的定点补码乘法器原理

    对于有符号整数乘法操作,E203使用常用的Booth编码产生部分积,然后使用迭代的方法,每个周期使用加法器对部分积进行累加,经过多个周期的迭代之后得到最终的乘积。其基本硬件原理图如图所示,从而实现
    发表于 10-23 08:01

    关于E203内核高性能乘法器优化(二)

    不同加法树与乘法器结合 1.传统Booth算法+Wallace树加法器 以下数据在32位宽乘法实现时结果供参考: 相同条件下,阵列乘法器
    发表于 10-23 07:33

    改进wallance树乘法器优化方法

    周期复用加法器的部分积加和算法,我们采用了改进的wallance树结构进行部分积的快速压缩,实现了单周期的乘法计算。 经过时序分析,我们的单周期乘法器时钟频率可以提高至140Hz,对比
    发表于 10-23 06:37

    关于E203内核高性能乘法器优化(一)

    与n位被乘数的每一位相乘,总共相乘n次得到n个结果,这n个结果排列成阶梯形状,两两相加得到最终结果,迭代乘法器的原理也是如此。如下图迭代乘法器的结构所示: 实现n位乘法运算的迭代
    发表于 10-23 06:09

    蜂鸟乘法器设计分享

    蜂鸟的乘法器主体设计在ALU模块的子单元MDV模块中,MDV模块包括乘除法器逻辑设计,它只包含运算控制,但并不包含具体运算,它们都需要将部分积或者部分余数传入数据通路(dpath模块)中,从而实现
    发表于 10-22 08:21

    基4-Booth单周期乘法器的具体设计

    本文主要讲解基4 Booth和wallace数高性能乘法器的设计,同时针对实际情况进行了些许优化。 基4-Booth单周期乘法器设计 针对e203的应用场景,本队考虑了其架构修改所要
    发表于 10-22 08:07

    改进型乘法器结构设计

    的高32位。控制信号控制部分积产生和部分积压缩对操作数和部分积的处理,从而完成乘法器乘法运算。 译码模块对乘法指令进行译码,基4 Booth编码接收控制信号对被乘数和乘数进行符号扩展并产生18个
    发表于 10-22 07:51

    蜂鸟E203乘法器改进

    蜂鸟E203为了节约资源,乘法运算采用循环移位方式计算最终结果,这样的乘法器需要经过较多时钟周期来处理数据,导致处理数据效率较低。为了提高计算效率,这里分享一种基于流水线思想的乘法器,即采用多个
    发表于 10-22 07:28

    蜂鸟E203内核乘法器的优化

    乘法器的优化实现一般从两个方面入手。第一是减少生成的部分积数量,另外就是减少部分积累加的延时。 在开源的E203源码中,32*32乘法器是利用radix-4 booth编码产生部分积,每个周期做一次
    发表于 10-22 06:11

    优化boot4乘法器方法

    优化电路设计:在电路设计中,可以采用更快速的逻辑单元和存储器元件,优化关键路径和信号传输路线,从而降低延迟,缩短乘法器的运算周期。 固定位宽:Boot4乘法器可以处理不同位宽的数据,但是处理不同位宽
    发表于 10-21 12:13

    ADL5390 RF矢量乘法器技术手册

    ADL5390矢量乘法器由一对匹配的宽带可变增益放大器组成,二者输出相加,每个放大器具有单独的线性幅度增益控制。如果两个输入RF信号正交,则可以将该矢量乘法器配置为矢量调制器,或将增益控制引脚用作
    的头像 发表于 04-09 10:02 720次阅读
    ADL5390 RF矢量<b class='flag-5'>乘法器</b>技术手册

    ADA-28F00WG乘法器Marki

    ADA-28F00WG是一种高性能的模拟乘法器,能够将两个输入信号(电压或电流)进行乘法运算,并输出其结果。ADA-28F00WG乘法器采用高质量材料制造,并结合了最新的肖特基二极管和MMIC技术
    发表于 02-12 09:25