Float 계산 회로의 Verilog-HDL 구현에 대해 - 그 2.1 (가산 회로의 공통화와 타이밍 조정)

Float 계산 회로의 Verilog 구현



~ FPGA에 올리고 싶다 ~
올레올레 구현이므로 잘못되어도 몰라요

가산회로편
Float 계산 회로의 Verilog-HDL 구현에 관하여 - 그 1

디버그 툴 작성편
Float 계산 회로의 (ry-그 1.1(float값의 16진수 표기)

보충과 LeadingZeros편
플로팅 컴퓨팅 회로의 Verilog-HDL 구현 - 1.5 (LeadingZeros)

감산회로편
Float 계산 회로의 Verilog-HDL 구현에 대해 -그 2(감산편)

목적



float 공부
float32의 하드웨어 구현

그 1에서 작성한 가산 회로와 그 2에서 작성한 감산 회로를 공통화하기 위해,
가산 회로 (의 타이밍 등)를 조정한다.

사양은 그 1에 준거

사양



아래 그림 오른쪽이 마지막으로 만든 감산 회로
아래 그림 왼쪽이 이번에 작성한 가산 회로

네 번째 시계의 부호 만 다른



약어 코드



float_add2.sv
module float_add(
    input wire clk,
    input wire [31:0] v1,
    input wire [31:0] v2,

    output wire [31:0] vres
);

    assign vres = res;

    //TIM1
    reg [31:0] vb;
    reg [31:0] vs;

    //TIM2
    reg [7:0] dexp;
    reg [7:0] vexp;
    reg [22:0] vb2;
    reg [22:0] vs2;

    //TIM3
    reg [7:0] vexp2;
    reg [24:0] vb3;
    reg [24:0] vs3;

    //TIM4
    reg [7:0] vexp3;
    reg [24:0] r;

    //TIM5,6
    reg [7:0] vexp4;
    reg [7:0] vexp5;
    reg [23:0] lzr;
    wire [7:0] lznum;
    wire [23:0] lzres;

    lzsv lzm(
        .clk(clk),
        .v(r),
        .num(lznum),
        .res(lzres)
    );

    //TIM7
    reg [31:0] res;

    always @(posedge clk) begin

        // TIM1 //
        if (v2[30:23] < v1[30:23]) begin
            vb <= v1;
            vs <= v2;
        end else if (v1[30:23] < v2[30:23]) begin
            vb <= v2;
            vs <= v1;
        end else if (v2[22:0] < v1[22:0]) begin
            vb <= v1;
            vs <= v2;
        end else begin
            vb <= v2;
            vs <= v1;
        end

        // TIM2 //
        dexp <= vb[30:23] - vs[30:23];
        vexp <= vb[30:23];

        vb2 <= vb;
        vs2 <= vs;

        // TIM3 //
        vexp2 <= vexp;

        vb3 <= {2'b1, vb2};
        vs3 <= {1'b0, vssf({1'b1, vs2}, dexp)};

        // TIM4 //
        vexp3 <= vexp2;

        r <= vb3 + vs3;
    //  r <= vb3 - vs3;

        // TIM5 //
        vexp4 <= vexp3;
        vexp5 <= vexp4 - lznum;

        lzr <= lzres;

        // TIM6 //
        res[31] <= 1'b0;
        res[30:23] <= vexp5;
        res[22:0] <= lzr[22:0];

    end

//Value Small Shift Function
function [23:0] vssf(input [23:0] v, input [7:0] num);
(略)
endfunction

endmodule

TIM4의 코멘트 아웃을 역으로 함으로써, 감산할 수 있는 것도 확인되고 있다

새로운 LeadingZeros 용 모듈



가산 회로에서도 LeadingZeros 모듈을 사용하기 때문에,
자릿수 감소뿐만 아니라 자릿수 상승도이 LeadingZeros 모듈을 지원해야합니다.

leadingzeros2.sv
module lzsv(
    input wire clk,
    input wire [24:0] v,

    output wire [7:0] num,
    output wire [23:0] res
);

// {num8, res24}
 reg [31:0] cnum;
 assign num = cnum[31:24];
 assign res = cnum[23:0];

always @(posedge clk) begin
    if (v[24]) cnum <= {8'hFF, v[24:1]};
    else if (v[23]) cnum <= {8'd0, v[23:0]};
    else if (v[22]) cnum <= {8'd1, v[22:0],  1'b0};
    else if (v[21]) cnum <= {8'd2, v[21:0],  2'b0};
    else if (v[20]) cnum <= {8'd3, v[20:0],  3'b0};
    else if (v[19]) cnum <= {8'd4, v[19:0],  4'b0};

    (略)

    else if (v[ 1]) cnum <= {8'd22, v[ 1:0], 22'b0};
    else if (v[ 0]) cnum <= {8'd23, 24'h800_000};
    else cnum <= {8'd24, 24'd0};
end

endmodule

자리수 계산시에 -1을 빼도록(듯이) 지향하기 위해(때문에) 24bit째가 1일 때 FF(-1)를 돌려준다

시뮬레이션 결과


123.4 + 7.25 = 130.65\\
=> 42F6\_CCCD + 40E8\_0000 = 4302\_A666


123.4 - 7.25 = 116.15\\
=> 42F6\_CCCD - 40E8\_0000 = 42E8\_4CCD

좋은 웹페이지 즐겨찾기