Float 계산 회로의 Verilog-HDL 구현에 관하여 - 그 1
5334 단어 FPGAVerilogfloat하드웨어VerilogHDL
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
시뮬레이션에서 오류가 발생하지 않았을 때까지 확인하십시오.
Reference
이 문제에 관하여(Float 계산 회로의 Verilog-HDL 구현에 관하여 - 그 1), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/Soleiyu/items/5bbb991de443e61e318e
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
\text{value} = 仮数部 \times 2^{指数部}
{\displaystyle {\text{value}}=(-1)^{\text{sign}}\left(1+\sum _{i=1}^{23}\ b_{-i}2^{-i}\right)\times 2^{e-127}}
7 = 111 \\
0.25 = 0.01\\
7.25 = 111.01
7.25 = 111.01 = 1.1101 \times 2^2
7.25 = 1101 \times 2^2
7.25 = 1101 \times 2^2
127 + (-42) = 85 = 8'\text{b}0101\_0101
//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
//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
//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
//TIM4
reg [7:0] vexp3;
reg [24:0] r;
always @(posedge clk) begin
vexp3 <= vexp2;
r <= vb3 + vs3;
end
//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
Reference
이 문제에 관하여(Float 계산 회로의 Verilog-HDL 구현에 관하여 - 그 1), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/Soleiyu/items/5bbb991de443e61e318e텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)