FPGA - lenet -加法器

372 阅读3分钟

FP16 半精度浮点数

image.png

符号 1bit。指数位5位。小数位10位。

number = (-1)^s X 1.M X 2^(E-15)

S为符号位,M为小数位,E为指数位。

sign为符号位,0表示这个浮点数为正,1表示这个浮点数为负。

尾数可以理解为是一个浮点数小数点后的数,如1.11,尾数就为1100000000(1),最后的隐含1主要用于计算时,隐含1可能存在可以进位的情况。

所以我们可以得到,半精度浮点数的值得计算方式为(-1)^sign×2^(指数位的值)×(1+0.尾数位)

加法器

半加器用于位求和。

半加器 只适用于最低位

半加器不考虑低位进位来的进位值,只有两个输入,两个输出。由一个与门和异或门构成.

image.png

sum = a^b cout = a&b

module add_half(input wire a,input wire b, output reg sum ,output reg cout);

    always@(*)
        begin
            sum = a^b;
            ciut = a&b;

        end

endmodule

全加器

当多位数相加时,半加器可用于最低位求和,并给出进位数。第二位的相加有两个待加数和,还有一个来自前面低位送来的进位数。这三个数相加,得出本位和数(全加和数)和进位数。这种就是“全加"。

使用两个半加器和一个或门 实现一个全加器。

module add_half(
   input                A   ,
   input                B   ,
 
   output   wire        S   ,
   output   wire        C   
);

assign S = A ^ B;
assign C = A & B;
endmodule
module add_full(a,b,cin,cout,sum);
    input a,b,cin;
    output sum,cout;
    
    wire w1,w2,w3;
    
    add_half(
    .A(a)  ,
    .B(b)  ,

    .S(w1)  ,
    .C(w2)  
);

add_half(
   . A(cin) ,
   . B(w1) ,
 
   . S(sum) ,
   . C(w3) 
);


assign cout = w2 | w3;

对于多位输入的全加器

例如八位全加器用verilog实现:

module adder_full(a,b,cin,,cout,sum);
input [7:0]a,b;
input cin;

output [7:0]sum;
output cout;

	assign {cout,sum} = a+b+cin;
 
endmodule

串行进位加法器

根据全加法器实现串行进位加法器


module add_4(
   input         [3:0]  A   ,
   input         [3:0]  B   ,
   input                Ci  , 

   output	wire [3:0]  S   ,
   output   wire        Co   
);
    //暂存进位
    wire  [3:0] C;
    add_full add_full_inst1(A[0], B[0], Ci  , S[0], C[0]);
    add_full add_full_inst2(A[1], B[1], C[0], S[1], C[1]);
    add_full add_full_inst3(A[2], B[2], C[1], S[2], C[2]);
    add_full add_full_inst4(A[3], B[3], C[2], S[3], Co  );

endmodule

超前进位加法器

超前进位加法器 (Carry-Lookahead Adder,CLA)是高速加法器,每一级进位有附加的组合电路产生。高位的运算不需要地位的等待,因此速度很高。

超前进位公式: image.png

根据公式对于进位我们每次只需算出前一位的 a|b a&b. 然后根据公式计算。

module four_bit_add(a,b,sum,cout,cin)
    input [3:0]a,b;
    input cin;
    
    output [3:0]sum;
    output cout;
    
    //辅助寄存器
    wire [4:0] g,p,c;
    
    assign c[0] = cin;
    assign p = a|b;
    assign g = a&b;
    
    assign c[1] = g[0] | (p[0] & c[0]);
    assign c[2] = g[1] |(p[1] & (g[0] | (p[0] & c[0])));
    assign c[3] = g[2] |(p[2] & (g[1] |(p[1] & (g[0] | (p[0] & c[0])))));
    assign c[4] = g[3] |(g[2] |(p[2] & (g[1] |(p[1] & (g[0] | (p[0] & c[0])))))));
    
   // 和半加器的逻辑一直  异或 a|b  后的结果 与进位进行异或。
    assign sum = p ^ c[3:0];
    assign cout  = c[4];
   

endmodule