1, FPGA device, using three 18bit x 18 bit multiplier to implement 32bit float multiplier

2, comparing to Altera float multiplyer IP

   (1)  just half of the LEs were used

(2)  nearly same accuracy

VS2013, simulation by C

/////////////////////////////////////////////////////////////////////////

#include <stdio.h>
#include <string.h>
#include <math.h>
#include <ios>
#include <iostream>

typedef unsigned int uint;
typedef unsigned long long uint64;
typedef long long int64;

uint GetBits(const float& v, int nstart, int cnt){
    uint bits = 0;
    uint vv;
    memcpy(&vv, &v, sizeof(v));
    //printf("%f, 0x%h) << std::endl; ", v, vv);
    for(int i = cnt - 1; i >= 0; i--){
        int idx = nstart + i;
        uint t = 1 << idx;

bits <<= 1;
        int b = (vv >> idx) & 1;
        bits |= b;
        //printf("%d", b);
    }
    //printf("\n");
    return bits;
}

int64 HighestOne(int64 v){
    int idx = -1;
    for(int i = sizeof(v)* 8 - 1; i >= 0; i--){
        if((v >> i) & 1){
            idx = i;
            break;
        }
    }
    return idx;
}

template<typename T1, typename T2>
void SetBit(T1& src, int src_idx, T2& dst, int dst_idx){
    int v = (src >> src_idx) & 1;
    if(v)
        dst |= v << dst_idx;
}

template<typename T1, typename T2>
void SetBits(T1& src, int src_idx, T2& dst, int dst_idx, int count){
    for(int i = 0; i < count; i++){
        SetBit(src, src_idx + i, dst, dst_idx + i);
    }
}

float fpmul(float a, float b){
    int64 s1 = GetBits(a, 31, 1);
    int64 s2 = GetBits(b, 31, 1);
    int64 e1 = GetBits(a, 23, 8);
    int64 e2 = GetBits(b, 23, 8);
    int64 f1 = GetBits(a, 0, 23);
    int64 f2 = GetBits(b, 0, 23);
    int64 a1 = GetBits(a, 14, 9);
    int64 a2 = GetBits(b, 14, 9);
    int64 b1 = GetBits(a, 5, 9);
    int64 b2 = GetBits(b, 5, 9);

//sum = 1 + f1 + f2 + [ (a1*a2) + (a1*b2 + a2*b1)*2^(-9) + (c1*a2 + b1*b2 + a1*c2)*2^(-18) + 0]               
    int64 sum = int64(1 << 23)
        + (f1 + f2)
        + (int64(a1 * a2) << (28 - 23))
        + (int64(a1*b2 + a2*b1) >> (9 - (28 - 23)));
    int nHightIndx = HighestOne(sum);

uint val = 0;
    SetBits(sum, nHightIndx - 23, val, 0, 23);

int e = e1 - 127 + e2 - 127 + 127 + (nHightIndx - 23);
    int s = ((s1 + s2) & 1) ? (1) : (0);

SetBits(e, 0, val, 23, 8);
    SetBit(s, 0, val, 31);

//val = 0x4023d702;
    float v;
    memcpy(&v, &val, sizeof(v));

return v;
}

void Test_fpmul(){
    //float v1 = 0.056984*0.056984;
    //float v = fpmul(0.056984, 0.056984);
    for(int i = -1000; i < 1000; i++){
        float a = -0.23 + i*0.0003;
        float b = 0.19 + i*0.0003;
        float v = fpmul(a, b);
        printf("a(%e), b(%e), a*b=%e, my_fmul=%e\n", a, b, (a*b), v);
    }
}

inline float Hex2Float(uint val){
    float v = 0;
    memcpy(&v, &val, sizeof(val));
    return v;
}

#define HEX2FLOAT(_x)  Hex2Float((0x##_x))

inline void Verify(){
    float s;
    std::cout << HEX2FLOAT(3fc30f28) << " x " << HEX2FLOAT(3fc30f28) << std::endl;
    std::cout << HEX2FLOAT(00000000) << std::endl;
    std::cout << "--------------------------------" << std::endl;
    //
    //
    std::cout << HEX2FLOAT(40a7a9fc) << " x " << HEX2FLOAT(40a7a9fc) << std::endl;
    std::cout << HEX2FLOAT(40800000) << std::endl;
    std::cout << "--------------------------------" << std::endl;
    //
    //
    std::cout << HEX2FLOAT(4251954d) << " x " << HEX2FLOAT(4251954d) << std::endl;
    std::cout << HEX2FLOAT(4014a012) << std::endl;
    std::cout << "--------------------------------" << std::endl;
    //
    //
    std::cout << HEX2FLOAT(4402fd52) << " x " << HEX2FLOAT(4402fd52) << std::endl;
    std::cout << HEX2FLOAT(41db9e50) << std::endl;
    std::cout << "--------------------------------" << std::endl;
    //
    //
    std::cout << HEX2FLOAT(4251954d) << " x " << HEX2FLOAT(4402fd52) << std::endl;
    std::cout << HEX2FLOAT(452b9514) << std::endl;
    std::cout << "--------------------------------" << std::endl;
    //
    //
    std::cout << HEX2FLOAT(3f07929f) << " x " << HEX2FLOAT(3f07929f) << std::endl;
    std::cout << HEX2FLOAT(48860c65) << std::endl;
    std::cout << "--------------------------------" << std::endl;
    //
    //
    std::cout << HEX2FLOAT(bf07929f) << " x " << HEX2FLOAT(4402fd52) << std::endl;
    std::cout << HEX2FLOAT(46d67a53) << std::endl;
    std::cout << "--------------------------------" << std::endl;
    //
    //
    std::cout << HEX2FLOAT(4380650b) << " x " << HEX2FLOAT(4380650b) << std::endl;
    std::cout << HEX2FLOAT(3e8f97e9) << std::endl;
    std::cout << "--------------------------------" << std::endl;

std::cout << HEX2FLOAT(3da1ab4b) << " x " << HEX2FLOAT(3da1ab4b) << std::endl;
    std::cout << HEX2FLOAT(c38abd2d) << std::endl;
    std::cout << "--------------------------------" << std::endl;

std::cout << HEX2FLOAT(3da1ab4b) << " x " << HEX2FLOAT(3f07929f) << std::endl;
    std::cout << HEX2FLOAT(4780ca5b) << std::endl;
    std::cout << "--------------------------------" << std::endl;

std::cout << HEX2FLOAT(3da1ab4b) << " x " << HEX2FLOAT(00000000) << std::endl;
    std::cout << HEX2FLOAT(3bcc31b9) << std::endl;
    std::cout << "--------------------------------" << std::endl;

std::cout << HEX2FLOAT(3bbab9a5) << " x " << HEX2FLOAT(3bbab9a5) << std::endl;
    std::cout << HEX2FLOAT(3d2b3bca) << std::endl;
    std::cout << "--------------------------------" << std::endl;

std::cout << HEX2FLOAT(3bbab9a5) << " x " << HEX2FLOAT(3da1ab4b) << std::endl;
    std::cout << HEX2FLOAT(7e21ab4b) << std::endl;
    std::cout << "--------------------------------" << std::endl;

std::cout << HEX2FLOAT(3bbab9a5) << " x " << HEX2FLOAT(3da1ab4b) << std::endl;
    std::cout << HEX2FLOAT(3808323b) << std::endl;
    std::cout << "--------------------------------" << std::endl;

std::cout << HEX2FLOAT(3bbab9a5) << " x " << HEX2FLOAT(3da1ab4b) << std::endl;
    std::cout << HEX2FLOAT(39ebd749) << std::endl;
    std::cout << "--------------------------------" << std::endl;

std::cout << HEX2FLOAT(3bbab9a5) << " x " << HEX2FLOAT(3da1ab4b) << std::endl;
    std::cout << HEX2FLOAT(39ebd749) << std::endl;
    std::cout << "--------------------------------" << std::endl;

std::cout << HEX2FLOAT(3bbab9a5) << " x " << HEX2FLOAT(3da1ab4b) << std::endl;
    std::cout << HEX2FLOAT(39ebd749) << std::endl;
    std::cout << "--------------------------------" << std::endl;

std::cout << HEX2FLOAT(3bbab9a5) << " x " << HEX2FLOAT(3da1ab4b) << std::endl;
    std::cout << HEX2FLOAT(39ebd749) << std::endl;
    std::cout << "--------------------------------" << std::endl;

std::cout << HEX2FLOAT(3bbab9a5) << " x " << HEX2FLOAT(3da1ab4b) << std::endl;
    std::cout << HEX2FLOAT(39ebd749) << std::endl;
    std::cout << "--------------------------------" << std::endl;

std::cout << HEX2FLOAT(3bbab9a5) << " x " << HEX2FLOAT(3da1ab4b) << std::endl;
    std::cout << HEX2FLOAT(39ebd749) << std::endl;
    std::cout << "--------------------------------" << std::endl;

}

void main(){
    Test_fpmul();
    Verify();
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

////////////////////////////// Verilog Implement ///////////////////////////

//`define _DEBUG
module my_fpmul(clk, rst_n, dataa, datab, result
`ifdef _DEBUG
        ,_a1 ,_b1 ,_a2 ,_b2, _e1, _e2
        ,_ss
        ,_sum
        , _se
        ,_sf1f2
        ,_sa1a2
        ,_sa1b2
        ,_sa2b1
`endif
        );

input  clk;
input  rst_n;
input  [31:0] dataa;
input  [31:0] datab;
output [31:0] result;

`ifdef _DEBUG
output [8:0]_a1;
output [8:0]_b1;
output [8:0]_a2;
output [8:0]_b2;
output [8:0]_e1;
output [8:0]_e2;
output _ss;
output [26:0]_sum;
output [8:0]_se;
output [24:0]_sf1f2;
output [22:0]_sa1a2;
output [18:0]_sa1b2;
output [18:0]_sa2b1;
`endif

//clk 1
reg [31:0]datac = 32'h0;
reg s1          = 1'b0;
reg s2          = 1'b0;
reg [8:0]e1     = 8'b0;
reg [8:0]e2     = 8'b0;
reg [22:0]f1    = 23'b0;
reg [22:0]f2    = 23'b0;
reg [17:0]a1     = 18'b0;
reg [17:0]a2     = 18'b0;
reg [17:0]b1     = 18'b0;
reg [17:0]b2     = 18'b0;

//clk 2
reg ss = 1'b0;
reg [24:0]sf1f2 = 25'b0;
reg [22:0]sa1a2 = 23'b0;
reg [18:0]sa1b2 = 19'b0;
reg [18:0]sa2b1 = 19'b0;
reg [26:0]sum   = 32'b0;
reg [8:0]se    = 9'b0;

////clk 3
reg  sss = 1'b0;
reg [7:0]sse   = 8'b0;
reg [22:0]ssum = 23'b0;

//pipline step 1
always@(posedge clk or negedge rst_n) begin
    if (!rst_n) datac <= 32'h0;
    else begin
        s1 <= dataa[31:31];
        s2 <= datab[31:31];
        e1 <= dataa[30:23];
        e2 <= datab[30:23];
        f1 <= dataa[22:0];
        f2 <= datab[22:0];
        a1 <= {9'b0, dataa[22:14]};
        a2 <= {9'b0, datab[22:14]};
        b1 <= {9'b0, dataa[13:5]};
        b2 <= {9'b0, datab[13:5]};
    end
end

//pipline step 2
always@(posedge clk or negedge rst_n) begin
    if (!rst_n) begin
        ss <= 1'b0;
        se <= 1'b0;
        sum <= 27'b0;
    end else begin
        ss <= s1^s2;
        se <= e1 + e2 - 8'd127;        
        sf1f2 = (24'b1 << 23) + (f1 + f2);
        sa1a2 = {a1*a2,5'b0};
        sa1b2 = a1*b2;
        sa2b1 = a2*b1;    
        sum <= sf1f2 + sa1a2 + ((sa1b2 + sa2b1)>>3'd4);
        //sum <= (26'b1 << 23) + (f1 + f2) + {a1*a2,5'b0} + {{9'b0, a1}*{9'b0, a2}, 5'b0} + {9'b0, a1}*{9'b0, b2} + {9'b0, a2}*{9'b0, b1};
    end
end

//pipline step 3
always@(posedge clk or negedge rst_n) begin
    if (!rst_n) begin
        sss <= 1'b0;
        sse <= 8'b0;
        ssum <= 23'b0;
    end else begin    
        sss <= ss;
        if (sum[25]) begin
            sse <= se + 2'd2;
            ssum <= sum[24:2];
        end else if (sum[24]) begin
            sse <= se + 2'd1;
            ssum <= sum[23:1];
        end else begin
            sse <= se;
            ssum <= sum[22:0];
        end
    end
end

assign result = {sss, sse, ssum};

`ifdef _DEBUG
assign _e1 = e1;
assign _e2 = e2;
assign _a1 = a1;
assign _b1 = b1;
assign _a2 = a2;
assign _b2 = b2;
assign _ss = ss;
assign _sum = sum;
assign _se = se;
assign _sf1f2 = sf1f2;
assign _sa1a2 = sa1a2;
assign _sa1b2 = sa1b2;
assign _sa2b1 = sa2b1;
`endif

endmodule

//////////////////////////////////////////////////////////////////////////////

/////////////////////////////Test Bench////////////////////////////////////

//`define _DEBUG

`timescale 1 ns/ 1 ps
module my_fpmul_vlg_tst();
// constants                                           
// general purpose registers
reg eachvec;
// test vector input registers
reg clk;
reg [31:0] dataa;
reg [31:0] datab;
reg rst_n;
// wires                                               
wire [31:0]  result;

`ifdef _DEBUG
wire [8:0]  _a1, _b1, _a2, _b2;
wire[8:0]_e1;
wire[8:0]_e2;
wire _ss;
wire [26:0]_sum;
wire [8:0]_se;
wire [24:0]_sf1f2;
wire [22:0]_sa1a2;
wire [18:0]_sa1b2;
wire [18:0]_sa2b1;
`endif

// assign statements (if any)                          
my_fpmul i1 (
// port map - connection between master ports and signals/registers   
    .clk(clk),
    .rst_n(rst_n),    
    .dataa(dataa),
    .datab(datab),
    .result(result)
`ifdef _DEBUG
    ,._a1(_a1) , ._b1(_b1) , ._a2(_a2) , ._b2(_b2), ._e1(_e1), ._e2(_e2)
    ,._ss(_ss) , ._sum(_sum)    , ._se(_se)
    ,._sf1f2(_sf1f2)
        ,._sa1a2(_sa1a2)
        ,._sa1b2(_sa1b2)
        ,._sa2b1(_sa2b1)
`endif
);

initial begin
    rst_n = 1;
    clk   = 0;
    forever #10 clk = ~clk;
end

initial begin
    repeat(30)
    begin
        #7
        $display("%x * %x : ", dataa, datab);
        #5
        $display("%x", result);
        #8
        $display("\n");
    end    
end

initial begin
    //dataa<=32'h3bbab9a5; //0.0056984  
    //datab<=32'h3bbab9a5; //0.0056984

dataa <= 32'b0;
    datab <= 32'b0;    
    #5;  
    dataa<=32'h3fc30f28; //1.5239  
    datab<=32'h3fc30f28;  
    #20;  
    dataa<=32'h40a7a9fc; //5.2395  
    datab<=32'h40a7a9fc;  
    #20;  
    dataa<=32'h4251954d; //52.3958  
    datab<=32'h4251954d;  
    #20;  
    dataa<=32'h4402fd52; //523.9581  
    datab<=32'h4402fd52;  
    #20;  
    dataa<=32'h4251954d; //52.3958  
    datab<=32'h4402fd52; //523.9581  
    #20;  
    dataa<=32'h3f07929f; //0.529581  
    datab<=32'h3f07929f;  
    #20;  
    dataa<=32'hbf07929f; //-0.529581  
    datab<=32'h4402fd52; //523.9581  
    #20;  
    dataa<=32'h4380650b; //256.7894  
    datab<=32'h4380650b;   
    #20;  
    dataa<=32'h3da1ab4b; //0.07894  
    datab<=32'h3da1ab4b;   
    #20;  
    dataa<=32'h3da1ab4b; //0.07894  
    datab<=32'h3f07929f; //0.529581  
    #20;  
    dataa<=32'h3da1ab4b; //0.07894  
    datab<=32'h0; //0.529581  
    #20;  
    dataa<=32'h3bbab9a5; //0.0056984  
    datab<=32'h3bbab9a5; //0.0056984  
    #20;  
    dataa<=32'h3bbab9a5; //0.0056984  
    datab<=32'h3da1ab4b; //0.07894

#2000
     $stop;
     //$finish;
    
end

endmodule
//////////////////////////////////////////////////////////////////////////////////////////////

FPGA, Float 32bit, multiplyier by Verilog的更多相关文章

  1. 基于FPGA的cordic算法的verilog初步实现

    最近在看cordic算法,由于还不会使用matlab,真是痛苦,一系列的笔算才大概明白了这个算法是怎么回事.于是尝试用verilog来实现.用verilog实现之前先参考软件的程序,于是先看了此博文h ...

  2. 【FPGA】高斯白噪声的Verilog实现

    本文章主要讨论高斯白噪声的FPGA实现.简单的方法可以采用在Matlab中产生服从一定均值和方差的I.Q两路噪声信号.然后将两组数据存在FPGA中进行回放,以此来产生高斯白噪声.这种方法优点是产生方法 ...

  3. FPGA编程—组合逻辑编码器等verilog实现

    本篇博客主要实现对组合逻辑电路的一些常用模块的实现.组合逻辑中,包括译码器,编码器,输入输出选择器,数值比较器,算法单元等.  先来实现编码器,最常用的8-3编码器,这里先讲一下要用到的case ,c ...

  4. FPGA实战操作(1) -- SDRAM(Verilog实现)

    对SDRAM基本概念的介绍以及芯片手册说明,请参考上一篇文章SDRAM操作说明. 1. 说明 如图所示为状态机的简化图示,过程大概可以描述为:SDRAM(IS42S16320D)上电初始化完成后,进入 ...

  5. 134-基于TMS320C6678、FPGA XC5VSX95T的一路Full模式Camera Link图像理平台

    基于TMS320C6678.FPGA XC5VSX95T的一路Full模式Camera Link图像理平台 一.板卡概述 该板卡采用TI公司新一代DSP TMS320C6678,结合FPGA,型号为X ...

  6. 自顶而下设计FPGA

    对IC设计而言,FPGA设计层级大致包括:系统级和行为级,RTL级,门级和晶体管级.然而更普遍的情况,FPGA只是用作实时数据采集控制.某些快速处理算法.PCIe\DDR3等高速数据通道,甚至某些简单 ...

  7. C中的Float分析

    C/C++中, 浮点数,float以及 double 在内存中是怎样存储的? 假如,我有32-bit 8bit 8bit 8bit 0 0 0 0 0 1 1 1 1 对于整形int,我们可以很快得出 ...

  8. 基于FPGA的IIR滤波器

    基于FPGA的IIR滤波器                                                         by方阳 版权声明:本文为博主原创文章,转载请指明转载地址 ...

  9. 学习cordic算法所得(流水线结构、Verilog标准)

    最近学习cordic算法,并利用FPGA实现,在整个学习过程中,对cordic算法原理.FPGA中流水线设计.Verilog标准有了更加深刻的理解. 首先,cordic算法的基本思想是通过一系列固定的 ...

随机推荐

  1. php生成条形码: barcodegen

    实例结构: 1. index.html <!DOCTYPE html> <html> <head> <title>Test with embedded ...

  2. 【python】-- pymsql 外键

    pymsql 外键 本片是以上一篇pymsql操作MySQL的补充,主要演示pymysql的外键操作使用 一.一对一外键关联 1.示意图 2.一对一外键关联示例 2.1.创建表结构,插入数据 from ...

  3. 7 Javascript:表单与验证-非空验证

    表单提交前要检查数据的合法性 在要对表单里的数据进行验证的时候,能够利用getElementById()来訪问网页上不论什么一个元素 每一个表单域都有一个form对象,可被传给不论什么验证表单数据的函 ...

  4. java 从零开始 第三天

    2015年5月2日 51刚过一天,电脑坏了.不开心,就没有更新了 Java中的类型转换 自动类型 在 Java 程序中,不同的基本数据类型的数据之间经常需要进行相互转换.例如: , 代码中 int 型 ...

  5. Windows平台下搭建Git服务器的图文教程(转发)

    Git没有客户端服务器端的概念,但是要共享Git仓库,就需要用到SSH协议(FTP , HTTPS , SFTP等协议也能实现Git共享,此文档不讨论),但是SSH有客户端服务器端,所以在window ...

  6. linux shell 中数组使用方法介绍

    linux shell在编程方面比windows 批处理强大太多,不管是在循环.运算.已经数据类型方面都是不能比較的. 以下是个人在使用时候,对它在数组方面一些操作进行的总结. 1.数组定义 [che ...

  7. (转)Spring 缓存EhCacheFactoryBean

    Spring使用Cache 从3.1开始,Spring引入了对Cache的支持.其使用方法和原理都类似于Spring对事务管理的支持.Spring Cache是作用在方法上的,其核心思想是这样的:当我 ...

  8. 改善程序与设计的55个具体做法 day5

    条款12:复制对象时勿忘其每一个成分 这里的复制是拷贝构造和operator= 每一个成分有几个维度: 1.每个成员变量 这个很好理解,添加新的成员时也要记得为每个新添加的成员执行合适的复制操作 2. ...

  9. 【leetcode刷题笔记】Unique Binary Search Trees

    Given n, how many structurally unique BST's (binary search trees) that store values 1...n? For examp ...

  10. 0522 HTML表单 CSS基础

    一.列表标签 列表标签分为三种. 1.无序列表<ul>,无序列表中的每一项是<li> 英文单词解释如下: ul:unordered list,“无序列表”的意思. li:lis ...