verilog实现IEEE754单精度/半精度浮点数加减运算

 一、IEEE754协议半精度浮点数格式与转换

 格式:

二进制半精度浮点数共16位,索引为0-15,其中第15位是符号位,0代表正1代表负,14-10位是阶码,9-0位是尾数位

浮点数十进制转换为二进制

以6.75为例:

1、正数符号位为0

2、将十进制转换为二进制,6.75(D) → 110.11(B)

3、 转换为1.xxx*10^n的规格化数,类似于十进制的科学记数法,110.11(B) → 1.1011 * 10^2

4、计算5位阶码,偏置值(1111)与第二步中n相加,即1111(B)+2(D) = 10001

5、计算尾数,将第二步中的规格化数小数部分提出并作为尾数位,若长度小于10则向后补零,尾数位即为1011000000,注意整数部分的1被隐藏

6、将符号位、阶码、尾数拼到一起即完成十进制到二进制半精度浮点数的转换:0,10001,1011000000

浮点数二进制转十进制

从十进制转二进制原理倒推即可,这里放一个计算说明图,过程不再赘述

二、IEEE754协议半精度浮点数加减法运算原理及代码

以符号位相同为例介绍加减法原理,符号位不同的情况只需要提前判断符号位便可将运算归类为加法或减法,基本流程都是对阶、尾数相加、规格化、舍入、溢出判断

加法

X:15.5(D)  →  0,10010,1111000000(B)

Y:2.75(D)  → 0,10000,0110000000(B)

1、对阶,比较阶码大小,将小阶码转换为大阶码,因此将Y的阶码转换为X的阶码,阶码加2(D),同时将Y尾数右移两位,注意尾数前隐藏的1,Y尾数(1)0110000000右移两位变为(0)0101100000,隐藏的1变为0,对阶后两者阶码均为10010

2、尾数相加,X尾数没有变化:(1)1111000000,Y的尾数:(0)0101100000

尾数直接相加结果为(10)0100100000

3、需要将尾数相加的结果进行规格化,需要将尾数右移1位同时阶码加1,这样隐藏位从10变为1,规格化结果:阶码10010+1=10011,尾数(1)0010010000

4、舍入,由于尾数右移截断可能产生误差,目前有多种舍入方法来中和误差:

末位恒1:右移后末位置为1;

0舍1入:右移截断的最高位为1则将尾数+1,重新规格化

5、溢出判断:判断阶码是否溢出

6、组合结果0,10011,0010010000

减法

X:8.25(D)  →  0,10010,0000100000(B)

Y:-1.25(D)  → 1,01111,0100000000(B)

1、8.25阶码大,符号位为0

2、对阶,X阶码大,Y阶码加3(D)同时尾数右移,Y尾数(1)0100000000右移3位变为(0)0010100000,隐藏的1变为0

3、尾数相减X(1)0000100000 - Y(0)0010100000 = (0)1110000000

4、规格化,将尾数左移1位同时阶码减1,将隐藏的0变为1,阶码10001,尾数(1)1100000000

5、判断溢出

6、组合结果0,10001,1100000000

verilog代码

初步采用组合逻辑,无时钟延时,后续可能根据实际需求进行优化或修改为时序逻辑

另外目前还没有添加舍入判断,直接进行右移截断

module float_add16(
    input [15:0]a,
    input [15:0]b,
    output reg [15:0]sum
);
reg sign;//第一位符号位
reg [4:0]exponent_a;
reg [4:0]exponent_b;
reg [10:0]fraction_a;
reg [10:0]fraction_b;//最高位是隐藏的1
reg [4:0]exponent_sum;//可加上第一位判断上溢
reg [11:0]fraction_sum;//保存尾数相加后的进位,以便阶码加减和右规
reg [7:0]exponent_shift;
//用*是所有输入信号敏感
always@(a or b)begin
        exponent_a=a[14:10];
        exponent_b=b[14:10];
        fraction_a={1'b1,a[9:0]};
        fraction_b={1'b1,b[9:0]};
        if(a[15]==b[15])begin//符号位相同则为加法
                sign=a[15];//直接确定符号位
                if(exponent_a==exponent_b)begin//阶码相等直接进行尾数相加
                        fraction_sum = fraction_a + fraction_b;//fraction_sum[11:10]只可能为11或10,尾数要右移一位,阶码加1
                        exponent_sum = exponent_a + 1'b1;//阶码+1
                        fraction_sum = fraction_sum >> 1'b1;
                end
                
                
                else if(exponent_a<exponent_b)begin//对阶:a小阶对b大阶
                        exponent_shift = exponent_b - exponent_a;//确定移多少位
                        exponent_sum = exponent_b;//阶码
                        fraction_a = fraction_a >> (exponent_shift);
                        fraction_sum = fraction_a + fraction_b;
                        case(fraction_sum[11:10])
                                2'b11:begin
                                        exponent_sum=exponent_sum + 1'b1;
                                        fraction_sum = fraction_sum >> 1'b1;
                                        end
                                2'b10:begin
                                        exponent_sum=exponent_sum + 1'b1;
                                        fraction_sum = fraction_sum >> 1'b1;
                                        end
                                default:begin
                                        exponent_sum = exponent_b;
                                        fraction_sum = fraction_a + fraction_b;
                                end
                        endcase
                end
                
                else begin//对阶:b小阶对a大阶
                        exponent_shift = exponent_a - exponent_b;//确定移多少位
                        exponent_sum = exponent_a;//阶码
                        fraction_b = fraction_b >> (exponent_shift);
                        fraction_sum = fraction_a + fraction_b;
                        case(fraction_sum[11:10])
                                2'b11:begin
                                        exponent_sum=exponent_sum + 1'b1;
                                        fraction_sum = fraction_sum >> 1'b1;
                                        end
                                2'b10:begin
                                        exponent_sum=exponent_sum + 1'b1;
                                        fraction_sum = fraction_sum >> 1'b1;
                                        end
                                2'b01,2'b00:begin
                                        exponent_sum = exponent_a;
                                        fraction_sum = fraction_a + fraction_b;
                                end
                        endcase
                end
                
        end
        
        else begin//符号不同视为相减,根据阶码大小判断符号位,再进行后续的对阶和尾数相加
                if(exponent_a>exponent_b)begin//阶码大则数大,阶码相同则比较尾数大小
                        sign=a[15];
                        exponent_shift = exponent_a - exponent_b;
                        exponent_sum = exponent_a;
                        fraction_b = fraction_b >> (exponent_shift);//对阶
                        fraction_sum = fraction_a - fraction_b;//尾数计算
                        if(fraction_sum[10]==0)begin
                                if(fraction_sum[9]==1)begin
                                        fraction_sum = fraction_sum << 1;
					exponent_sum = exponent_sum - 1;
                                end
                                else if(fraction_sum[8]==1)begin
                                        fraction_sum = fraction_sum << 2;
					exponent_sum = exponent_sum - 2;
                                end
                                else if(fraction_sum[7]==1)begin
                                        fraction_sum = fraction_sum << 3;
					exponent_sum = exponent_sum - 3;
                                end
                                else if(fraction_sum[6]==1)begin
                                        fraction_sum = fraction_sum << 4;
					exponent_sum = exponent_sum - 4;
                                end
                                else if(fraction_sum[5]==1)begin
                                        fraction_sum = fraction_sum << 5;
					exponent_sum = exponent_sum - 5;
                                end
                                else if(fraction_sum[4]==1)begin
                                        fraction_sum = fraction_sum << 6;
					exponent_sum = exponent_sum - 6;
                                end
                                else if(fraction_sum[3]==1)begin
                                        fraction_sum = fraction_sum << 7;
					exponent_sum = exponent_sum - 7;
                                end
                                else if(fraction_sum[2]==1)begin
                                        fraction_sum = fraction_sum << 8;
					exponent_sum = exponent_sum - 8;
                                end
                                else if(fraction_sum[1]==1)begin
                                        fraction_sum = fraction_sum << 9;
					exponent_sum = exponent_sum - 9;
                                end
                                else if(fraction_sum[0]==1)begin
                                        fraction_sum = fraction_sum << 10;
					exponent_sum = exponent_sum - 10;
                                end
                        end
                end
                else if(exponent_a<exponent_b)begin
                        sign=b[15];
                        exponent_shift = exponent_b - exponent_a;
                        exponent_sum = exponent_b;
                        fraction_a = fraction_a >> (exponent_shift);//对阶
                        fraction_sum = fraction_b - fraction_a;//尾数计算
                        if(fraction_sum[10]==0)begin
                                if(fraction_sum[9]==1)begin
                                        fraction_sum = fraction_sum << 1;
					exponent_sum = exponent_sum - 1;
                                end
                                else if(fraction_sum[8]==1)begin
                                        fraction_sum = fraction_sum << 2;
					exponent_sum = exponent_sum - 2;
                                end
                                else if(fraction_sum[7]==1)begin
                                        fraction_sum = fraction_sum << 3;
					exponent_sum = exponent_sum - 3;
                                end
                                else if(fraction_sum[6]==1)begin
                                        fraction_sum = fraction_sum << 4;
					exponent_sum = exponent_sum - 4;
                                end
                                else if(fraction_sum[5]==1)begin
                                        fraction_sum = fraction_sum << 5;
					exponent_sum = exponent_sum - 5;
                                end
                                else if(fraction_sum[4]==1)begin
                                        fraction_sum = fraction_sum << 6;
					exponent_sum = exponent_sum - 6;
                                end
                                else if(fraction_sum[3]==1)begin
                                        fraction_sum = fraction_sum << 7;
					exponent_sum = exponent_sum - 7;
                                end
                                else if(fraction_sum[2]==1)begin
                                        fraction_sum = fraction_sum << 8;
					exponent_sum = exponent_sum - 8;
                                end
                                else if(fraction_sum[1]==1)begin
                                        fraction_sum = fraction_sum << 9;
					exponent_sum = exponent_sum - 9;
                                end
                                else if(fraction_sum[0]==1)begin
                                        fraction_sum = fraction_sum << 10;
					exponent_sum = exponent_sum - 10;
                                end
                        end
                end
                else begin
                        if(fraction_a>fraction_b)begin
                                sign=a[15];
                                exponent_shift = exponent_a - exponent_b;
                                exponent_sum = exponent_a;
                                fraction_b = fraction_b >> (exponent_shift);//对阶
                                fraction_sum = fraction_a - fraction_b;//尾数计算
                                if(fraction_sum[10]==0)begin
                                if(fraction_sum[9]==1)begin
                                        fraction_sum = fraction_sum << 1;
					exponent_sum = exponent_sum - 1;
                                end
                                else if(fraction_sum[8]==1)begin
                                        fraction_sum = fraction_sum << 2;
					exponent_sum = exponent_sum - 2;
                                end
                                else if(fraction_sum[7]==1)begin
                                        fraction_sum = fraction_sum << 3;
					exponent_sum = exponent_sum - 3;
                                end
                                else if(fraction_sum[6]==1)begin
                                        fraction_sum = fraction_sum << 4;
					exponent_sum = exponent_sum - 4;
                                end
                                else if(fraction_sum[5]==1)begin
                                        fraction_sum = fraction_sum << 5;
					exponent_sum = exponent_sum - 5;
                                end
                                else if(fraction_sum[4]==1)begin
                                        fraction_sum = fraction_sum << 6;
					exponent_sum = exponent_sum - 6;
                                end
                                else if(fraction_sum[3]==1)begin
                                        fraction_sum = fraction_sum << 7;
					exponent_sum = exponent_sum - 7;
                                end
                                else if(fraction_sum[2]==1)begin
                                        fraction_sum = fraction_sum << 8;
					exponent_sum = exponent_sum - 8;
                                end
                                else if(fraction_sum[1]==1)begin
                                        fraction_sum = fraction_sum << 9;
					exponent_sum = exponent_sum - 9;
                                end
                                else if(fraction_sum[0]==1)begin
                                        fraction_sum = fraction_sum << 10;
					exponent_sum = exponent_sum - 10;
                                end
                        end
                        end
                        else if(fraction_a < fraction_b)begin
                                sign=b[15];
                                exponent_shift = exponent_b - exponent_a;
                                exponent_sum = exponent_b;
                                fraction_a = fraction_a >> (exponent_shift);//对阶
                                fraction_sum = fraction_b - fraction_a;//尾数计算
                                if(fraction_sum[10]==0)begin
                                if(fraction_sum[9]==1)begin
                                        fraction_sum = fraction_sum << 1;
					exponent_sum = exponent_sum - 1;
                                end
                                else if(fraction_sum[8]==1)begin
                                        fraction_sum = fraction_sum << 2;
					exponent_sum = exponent_sum - 2;
                                end
                                else if(fraction_sum[7]==1)begin
                                        fraction_sum = fraction_sum << 3;
					exponent_sum = exponent_sum - 3;
                                end
                                else if(fraction_sum[6]==1)begin
                                        fraction_sum = fraction_sum << 4;
					exponent_sum = exponent_sum - 4;
                                end
                                else if(fraction_sum[5]==1)begin
                                        fraction_sum = fraction_sum << 5;
					exponent_sum = exponent_sum - 5;
                                end
                                else if(fraction_sum[4]==1)begin
                                        fraction_sum = fraction_sum << 6;
					exponent_sum = exponent_sum - 6;
                                end
                                else if(fraction_sum[3]==1)begin
                                        fraction_sum = fraction_sum << 7;
					exponent_sum = exponent_sum - 7;
                                end
                                else if(fraction_sum[2]==1)begin
                                        fraction_sum = fraction_sum << 8;
					exponent_sum = exponent_sum - 8;
                                end
                                else if(fraction_sum[1]==1)begin
                                        fraction_sum = fraction_sum << 9;
					exponent_sum = exponent_sum - 9;
                                end
                                else if(fraction_sum[0]==1)begin
                                        fraction_sum = fraction_sum << 10;
					exponent_sum = exponent_sum - 10;
                                end
                        end
                        end
                        else begin
                                sign=a[15];
                                exponent_shift = exponent_a - exponent_b;
                                exponent_sum = exponent_a;
                                fraction_b = fraction_b >> (exponent_shift);//对阶
                                fraction_sum = fraction_a - fraction_b;//尾数计算
                                if(fraction_sum[10]==0)begin
                                        if(fraction_sum[9]==1)begin
                                                fraction_sum = fraction_sum << 1;
        					exponent_sum = exponent_sum - 1;
                                        end
                                        else if(fraction_sum[8]==1)begin
                                                fraction_sum = fraction_sum << 2;
        					exponent_sum = exponent_sum - 2;
                                        end
                                        else if(fraction_sum[7]==1)begin
                                                fraction_sum = fraction_sum << 3;
        					exponent_sum = exponent_sum - 3;
                                        end
                                        else if(fraction_sum[6]==1)begin
                                                fraction_sum = fraction_sum << 4;
        					exponent_sum = exponent_sum - 4;
                                        end
                                        else if(fraction_sum[5]==1)begin
                                                fraction_sum = fraction_sum << 5;
        					exponent_sum = exponent_sum - 5;
                                        end
                                        else if(fraction_sum[4]==1)begin
                                                fraction_sum = fraction_sum << 6;
        					exponent_sum = exponent_sum - 6;
                                        end
                                        else if(fraction_sum[3]==1)begin
                                                fraction_sum = fraction_sum << 7;
        					exponent_sum = exponent_sum - 7;
                                        end
                                        else if(fraction_sum[2]==1)begin
                                                fraction_sum = fraction_sum << 8;
        					exponent_sum = exponent_sum - 8;
                                        end
                                        else if(fraction_sum[1]==1)begin
                                                fraction_sum = fraction_sum << 9;
        					exponent_sum = exponent_sum - 9;
                                        end
                                        else if(fraction_sum[0]==1)begin
                                                fraction_sum = fraction_sum << 10;
        					exponent_sum = exponent_sum - 10;
                                        end
                                end
                        end
                end
        end
        sum = {sign,exponent_sum,fraction_sum[9:0]};
end

endmodule

附加时序逻辑代码

//add_en后延迟3个周期出结果
module float32_add_reg(
    input clk,
    input rst_n,
    input [31:0]a,
    input [31:0]b,
    input add_en,
    output [31:0]out
    );
    
    reg [7:0]exponent_a;//指数位阶码
    reg [7:0]exponent_b;
    reg [7:0]exponent_out;
    reg sign;
    reg [23:0]fraction_a;//尾数位
    reg [23:0]fraction_b;
    reg [24:0]fraction_out;//尾数位多2位便于右移
    reg [7:0]shift_cnt;
    reg add_en_d0;
    reg add_en_d1;
    reg add_en_d2;
    reg add_en_d3;
    reg [7:0]exponent_out_reg;
    reg [24:0]fraction_out_reg;
    reg [23:0]fraction_a_reg;
    reg [23:0]fraction_b_reg;
    reg same;
    reg different;
    


    always@(posedge clk or negedge rst_n)begin
            if(!rst_n)begin
                same<=1'b0;
                different<=1'b0;
            end
            else begin
                if(a[31]==1 && b[31]==1)begin
                    sign<=1'b1;
                    same<=1'b1;
                    different<=1'b0;
                end
                else if(a[31]==0 && b[31]==0)begin
                    sign<=1'b0;
                    same<=1'b1;
                    different<=1'b0;
                end
                else if(a[31]==1 && b[31]==0 && a[30:0]>b[30:0])begin
                    sign<=a[31];
                    different<=1'b1;
                    same<=1'b0;
                end
                else if(a[31]==1 && b[31]==0 && a[30:0]<b[30:0])begin
                    sign<=b[31];
                    different<=1'b1;
                    same<=1'b0;
                end
                else if(a[31]==0 && b[31]==1 && a[30:0]>b[30:0])begin
                    sign<=a[31];
                    different<=1'b1;
                    same<=1'b0;
                end
                else if(a[31]==0 && b[31]==1 && a[30:0]<b[30:0])begin
                    sign<=b[31];
                    different<=1'b1;
                    same<=1'b0;
                end
            end
    end
    
    
    
    always@(posedge clk or negedge rst_n)begin
            if(!rst_n)begin
                exponent_a<=8'd0;
                exponent_b<=8'd0;
                fraction_a<=23'd0;
                fraction_b<=23'd0;
            end
            else if(add_en)begin
                exponent_a<=a[30:23];
                exponent_b<=b[30:23];
                fraction_a<={1'b1,a[22:0]};
                fraction_b<={1'b1,b[22:0]};
            end
    end
    
    always@(posedge clk or negedge rst_n)begin
            if(!rst_n)begin
                add_en_d0<=1'b0;
                add_en_d1<=1'b0;
                add_en_d2<=1'b0;
                add_en_d3<=1'b0;
            end
            else begin
                add_en_d0<=add_en;
                add_en_d1<=add_en_d0;
                add_en_d2<=add_en_d1;
                add_en_d3<=add_en_d2;
            end
    end
    
    always@(posedge clk or negedge rst_n)begin//对阶
            if(!rst_n)begin
                exponent_out<=8'd0;
                shift_cnt<=8'd0;
            end
            else if(add_en)begin
                    if(a[30:23] < b[30:23])begin
                        shift_cnt<=b[30:23] - a[30:23];
                        exponent_out<=b[30:23];
                    end
                    else if(a[30:23] > b[30:23])begin
                        shift_cnt<=a[30:23] - b[30:23];
                        exponent_out<=a[30:23];
                    end
                    else begin
                        shift_cnt<=8'd0;
                        exponent_out<=a[30:23];
                    end
            end
    end
    
    always@(posedge clk)begin//符号位相同或不同都要尾数右移
            if(!rst_n)begin
                fraction_a_reg<=8'd0;
                fraction_b_reg<=8'd0;
            end
            else if(add_en_d0)begin
                    if(a[30:23] < b[30:23])begin
                        fraction_a_reg<=fraction_a >> shift_cnt;
                        fraction_b_reg<=fraction_b;
                    end
                    else if(a[30:23] > b[30:23])begin
                        fraction_b_reg<=fraction_b >> shift_cnt;
                        fraction_a_reg<=fraction_a;
                    end
            end
    end
    
    always@(posedge clk or negedge rst_n)begin//尾数相加或相减
              if(!rst_n)begin
                    fraction_out<=25'd0;
              end
              else  if(add_en_d1)begin
                    if(same)begin
                          fraction_out<=fraction_a_reg+fraction_b_reg;
                   end
                   else if(different)begin
                         if(a[30:23] < b[30:23])begin
                            fraction_out<=fraction_b_reg-fraction_a_reg;
                         end
                         else if(a[30:23] > b[30:23])begin
                            fraction_out<=fraction_a_reg-fraction_b_reg;
                         end
                   end  
        end
    end
    
    always@(posedge clk or negedge rst_n)begin//规格化
        if(!rst_n)begin
            exponent_out_reg<=1'b0;
            fraction_out_reg<=1'b0;
        end
        
        else if(add_en_d2)begin
             if(fraction_out[24:23] == 2'b11)begin
                   exponent_out_reg<=exponent_out + 1'b1;
                   fraction_out_reg <= fraction_out >> 1'b1;
             end
             else if(fraction_out[24:23] == 2'b10)begin
                                        exponent_out_reg<=exponent_out + 1'b1;
                                        fraction_out_reg <= fraction_out >> 1'b1;
                                        end
             else if(fraction_out[24:23] == 2'b01)  begin                 
                                        exponent_out_reg = exponent_out;
                                        fraction_out_reg = fraction_a + fraction_b;
                                        end
             else if(fraction_out[22]==1'b1)begin
                                        exponent_out_reg<=exponent_out - 1'b1;
                                        fraction_out_reg <= fraction_out << 1'b1;
                                        end
             else if(fraction_out[21]==1'b1)begin
                                        exponent_out_reg<=exponent_out - 2;
                                        fraction_out_reg <= fraction_out << 2;
                                        end
             else if(fraction_out[20]==1'b1)begin
                                        exponent_out_reg<=exponent_out - 3;
                                        fraction_out_reg <= fraction_out << 3;
                                        end
                                        else if(fraction_out[19]==1'b1)begin
                                        exponent_out_reg<=exponent_out - 4;
                                        fraction_out_reg <= fraction_out << 4;
                                        end
                                        else if(fraction_out[18]==1'b1)begin
                                        exponent_out_reg<=exponent_out - 5;
                                        fraction_out_reg <= fraction_out << 5;
                                        end
                                        else if(fraction_out[17]==1'b1)begin
                                        exponent_out_reg<=exponent_out - 6;
                                        fraction_out_reg <= fraction_out << 6;
                                        end
                                        else if(fraction_out[16]==1'b1)begin
                                        exponent_out_reg<=exponent_out - 7;
                                        fraction_out_reg <= fraction_out << 7;
                                        end
                                        else if(fraction_out[15]==1'b1)begin
                                        exponent_out_reg<=exponent_out - 8;
                                        fraction_out_reg <= fraction_out << 8;
                                        end
                                        else if(fraction_out[14]==1'b1)begin
                                        exponent_out_reg<=exponent_out - 9;
                                        fraction_out_reg <= fraction_out << 9;
                                        end
                                        else if(fraction_out[13]==1'b1)begin
                                        exponent_out_reg<=exponent_out - 10;
                                        fraction_out_reg <= fraction_out << 10;
                                        end
                                        else if(fraction_out[12]==1'b1)begin
                                        exponent_out_reg<=exponent_out - 11;
                                        fraction_out_reg <= fraction_out << 11;
                                        end
                                        else if(fraction_out[11]==1'b1)begin
                                        exponent_out_reg<=exponent_out - 12;
                                        fraction_out_reg <= fraction_out << 12;
                                        end
                                        else if(fraction_out[10]==1'b1)begin
                                        exponent_out_reg<=exponent_out - 13;
                                        fraction_out_reg <= fraction_out << 13;
                                        end
                                        else if(fraction_out[9]==1'b1)begin
                                        exponent_out_reg<=exponent_out - 14;
                                        fraction_out_reg <= fraction_out << 14;
                                        end
                                        else if(fraction_out[8]==1'b1)begin
                                        exponent_out_reg<=exponent_out - 15;
                                        fraction_out_reg <= fraction_out << 15;
                                        end
                                        else if(fraction_out[7]==1'b1)begin
                                        exponent_out_reg<=exponent_out - 16;
                                        fraction_out_reg <= fraction_out << 16;
                                        end
                                        else if(fraction_out[6]==1'b1)begin
                                        exponent_out_reg<=exponent_out - 17;
                                        fraction_out_reg <= fraction_out << 17;
                                        end
                                        else if(fraction_out[5]==1'b1)begin
                                        exponent_out_reg<=exponent_out - 18;
                                        fraction_out_reg <= fraction_out << 18;
                                        end
                                        else if(fraction_out[4]==1'b1)begin
                                        exponent_out_reg<=exponent_out - 19;
                                        fraction_out_reg <= fraction_out << 19;
                                        end
                                        else if(fraction_out[3]==1'b1)begin
                                        exponent_out_reg<=exponent_out - 20;
                                        fraction_out_reg <= fraction_out << 20;
                                        end
                                        else if(fraction_out[2]==1'b1)begin
                                        exponent_out_reg<=exponent_out - 21;
                                        fraction_out_reg <= fraction_out << 21;
                                        end
                                        else if(fraction_out[1]==1'b1)begin
                                        exponent_out_reg<=exponent_out - 22;
                                        fraction_out_reg <= fraction_out << 22;
                                        end
                                        else if(fraction_out[0]==1'b1)begin
                                        exponent_out_reg<=exponent_out - 23;
                                        fraction_out_reg <= fraction_out << 23;
                                        end      
                                        else begin//0情况
                                            exponent_out_reg<=exponent_out;
                                            fraction_out_reg<=fraction_out;
                                        end                                                
              end
              
          
    end
    
    assign out = {sign, exponent_out_reg, fraction_out_reg[22:0]};
    
endmodule

  • 12
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 11
    评论
IEEE 754浮点数运算Verilog中可以通过使用FPGA开发板来实现FPGA开发板通常具有高性能和低功耗的特点,可以提供良好的硬件支持。 在Verilog中,可以使用IEEE 754浮点数标准定义数据类型,例如单精度浮点数(32位),双精度浮点数(64位)等。可以使用Verilog内置的运算符来进行浮点数的加、减、乘、除等运算,也可以使用Verilog中的模块来实现特定的浮点数运算,如乘法器、除法器等。 以下是一个使用Verilog实现单精度浮点数加法的例子: ```verilog module float_add(input [31:0] a, input [31:0] b, output [31:0] c); reg [31:0] mantissa_a, mantissa_b; reg [7:0] exp_a, exp_b; reg sign_a, sign_b; reg [31:0] mantissa_c; reg [7:0] exp_c; reg sign_c; assign sign_c = sign_a; assign mantissa_c = mantissa_a + mantissa_b; assign exp_c = exp_a; always @(*) begin sign_a = a[31]; sign_b = b[31]; mantissa_a = {1'b1, a[22:0]}; mantissa_b = {1'b1, b[22:0]}; exp_a = a[30:23] - 127; exp_b = b[30:23] - 127; end always @(*) begin if (mantissa_c[23] == 1) begin mantissa_c = mantissa_c >> 1; exp_c = exp_c + 1; end end always @(*) begin if (exp_a > exp_b) begin mantissa_b = mantissa_b >> (exp_a - exp_b); exp_c = exp_a; end else begin mantissa_a = mantissa_a >> (exp_b - exp_a); exp_c = exp_b; end end always @(*) begin if (sign_a != sign_b) begin if (mantissa_a > mantissa_b) begin mantissa_c = mantissa_a - mantissa_b; sign_c = sign_a; end else begin mantissa_c = mantissa_b - mantissa_a; sign_c = sign_b; end end else begin mantissa_c = mantissa_a + mantissa_b; end end always @(*) begin if (mantissa_c[24] == 1) begin mantissa_c = mantissa_c >> 1; exp_c = exp_c + 1; end end assign c = {sign_c, exp_c + 127, mantissa_c[22:1]}; endmodule ``` 该模块将两个单精度浮点数相加,并输出结果。在该模块中,首先将输入浮点数的符号、尾数和阶码分别提取出来,并进行规格化。然后对阶码和尾数进行调整,使它们的阶码相同,然后进行加法运算。最后再对结果进行规格化,并输出。
评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值