Float 계산 회로의 Verilog-HDL 구현에 대해 - 그 2.1 (가산 회로의 공통화와 타이밍 조정)
4895 단어 FPGAVerilogfloat하드웨어VerilogHDL
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.svmodule 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.svmodule 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
Reference
이 문제에 관하여(Float 계산 회로의 Verilog-HDL 구현에 대해 - 그 2.1 (가산 회로의 공통화와 타이밍 조정)), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/Soleiyu/items/85e9543463f068fe5047
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
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
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
123.4 + 7.25 = 130.65\\
=> 42F6\_CCCD + 40E8\_0000 = 4302\_A666
123.4 - 7.25 = 116.15\\
=> 42F6\_CCCD - 40E8\_0000 = 42E8\_4CCD
Reference
이 문제에 관하여(Float 계산 회로의 Verilog-HDL 구현에 대해 - 그 2.1 (가산 회로의 공통화와 타이밍 조정)), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/Soleiyu/items/85e9543463f068fe5047텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)