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

Float 계산 회로의 Verilog 구현



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

부동 소수점 숫자 설명에서
양의 가산까지

목적



float 공부
float32의 하드웨어 구현

부동 소수점 수에 대해



단정밀도 소수점 수에 대해
Wikipedia

왼쪽부터
· 부호
・지수부(8bit)
・가수부(23bit)
될 것입니다.

값을 계산하는 방법은 엉망입니다.
\text{value} = 仮数部 \times 2^{指数部}

로 표시됩니다.

Wikipedia에서는
{\displaystyle {\text{value}}=(-1)^{\text{sign}}\left(1+\sum _{i=1}^{23}\ b_{-i}2^{-i}\right)\times 2^{e-127}}

라고 설명합니다.

가수부의 표기법(예:7.25)


7 = 111 \\
0.25 = 0.01\\
7.25 = 111.01

앞에서 언급했듯이 지수 부분에 따라 얼마든지
설명 방법을 사용할 수 있습니다.
따라서 최상위 비트를 1로 설정하고,
다음이 소수가되도록 결정하십시오.
7.25 = 111.01 = 1.1101 \times 2^2

위의 최상위 레벨이 1 인 조건에서 최상위 레벨은 생략합니다.
7.25 = 1101 \times 2^2

지수부 표기법 (예 : 7.25)



상기보다
7.25 = 1101 \times 2^2

2라는 정보를 입력하십시오.

지수부는 8bit이므로,
언사인드라면 0 ~ 255
사인드라면 -128 ~ 127
값을 취할 수 있습니다.

부동 소수점 숫자에서
Unsigned Signed 표기법입니다.
0은 8'b0111_1111로 표시됩니다.
2는 8'b1000_0000입니다.
즉, 127 개의 바이어스 값을 더한 값으로 표시합니다.
예를 들어, -42 는
127 + (-42) = 85 = 8'\text{b}0101\_0101

될 것입니다.

특별 표기(0)



0은 지수 부분을 -128로 보입니다.
즉, 지수 부분은 8'b0입니다.

부동 소수점 숫자의 추가



올레올레 부동 소수점 가산 회로의 타이밍은 아래 그림과 같이 설계되었습니다.
0 추가하지 않음, 양수 만.


이하 상세

1. 값 비교



숫자 비교를 수행하고 큰 값을 vb (값 큰), 작은 값을 vs (값 작은)에 저장합니다.
//TIM1
reg [31:0] vb;
reg [31:0] vs;

always @(posedge clk) begin
    if (v2[30:23] < v1[30:23]) begin
        vb <= v1;
        vs <= v2;
    end else begin
        vb <= v2;
        vs <= v1;
    end
end  

2. 지수부 거리의 계산



시프트 량을 파악하기 위해 각 수치의 지수 부분 거리를 계산합니다.
다른 사람은 파이프 라인에서 파손되지 않도록 보호합니다.
//TIM2
reg [7:0] dexp;
reg [7:0] vexp;
reg [22:0] vb2;
reg [22:0] vs2;

always @(posedge clk) begin
    dexp <= vb[30:23] - vs[30:23];
    vexp <= vb[30:23];

    vb2 <= vb[22:0];
    vs2 <= vs[22:0];                                                                                     
end

3. 값 이동, 추가 준비



더하기 위해 1을 추가하거나 값을 이동하여 숫자를 맞 춥니 다.
이 때 작은 숫자는 시프트 할 때 잘립니다 (올바른지 모르겠습니다).
//TIM3
reg [7:0] vexp2;
reg [24:0] vb3;
reg [24:0] vs3;

always @(posedge clk) begin
    vexp2 <= vexp;

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

시프트 방법은 머리가 좋은 방법을 모르기 때문에 적절하게 만들었습니다.
//Value Small Shift Function
function [23:0] vssf(input [23:0] v, input [7:0] num);
begin
    case(num)
    8'd0: vssf = v;
    8'd1: vssf = {1'b0, v[23:1]};
    8'd2: vssf = {2'b0, v[23:2]};
    8'd3: vssf = {3'b0, v[23:3]};
    8'd4: vssf = {4'b0, v[23:4]};

    8'd5: vssf = {5'b0, v[23:5]};
    8'd6: vssf = {6'b0, v[23:6]};
    8'd7: vssf = {7'b0, v[23:7]};
    8'd8: vssf = {8'b0, v[23:8]};
    8'd9: vssf = {9'b0, v[23:9]};

    8'd10: vssf = {10'b0, v[23:10]};
    8'd11: vssf = {11'b0, v[23:11]};
    8'd12: vssf = {12'b0, v[23:12]};
    8'd13: vssf = {13'b0, v[23:13]};
    8'd14: vssf = {14'b0, v[23:14]};

    8'd15: vssf = {15'b0, v[23:15]};
    8'd16: vssf = {16'b0, v[23:16]};
    8'd17: vssf = {17'b0, v[23:17]};
    8'd18: vssf = {18'b0, v[23:18]};
    8'd19: vssf = {19'b0, v[23:19]};

    8'd20: vssf = {20'b0, v[23:20]};
    8'd21: vssf = {21'b0, v[23:21]};
    8'd22: vssf = {22'b0, v[23:22]};
    8'd23: vssf = {23'b0, v[23]};
    default: vssf = 24'b0;
endcase
end
endfunction

4. 가산



자릿수가 일치하기 때문에 추가 만 수행됩니다.
//TIM4
reg [7:0] vexp3;
reg [24:0] r;

always @(posedge clk) begin
    vexp3 <= vexp2;

    r <= vb3 + vs3;                                                                                
end

5. 유형 생성



자릿수 상승을 고려하여 float 유형을 생성합니다.
 //TIM5
reg [31:0] res;

always @(posedge clk) begin
    res[31] <= 1'b0;

    if (r[24]) begin
        res[30:23] <= vexp3 + 8'b1;
        res[22:0] <= r[23:1];
    end else begin
        res[30:23] <= vexp3;
        res[22:0] <= r[22:0];
    end
end

만든 코드



github
시뮬레이션에서 오류가 발생하지 않았을 때까지 확인하십시오.

좋은 웹페이지 즐겨찾기