#Float計算回路のVerilog実装
~ FPGA に載せたい ~
オレオレ実装なので間違っていても知りません
加算回路編
Float計算回路のVerilog-HDL実装について -その1
デバッグツール作成編
Float計算回路の(ry-その1.1(float値の16進数表記)
補足とLeadingZeros編
Float計算回路のVerilog-HDL実装について -その1.5 (LeadingZeros)
減算回路編
Float計算回路のVerilog-HDL実装について -その2(減算編)
回路共通化とタイミング調整編
Float計算回路のVerilog-HDL実装について -その2.1(加算回路の共通化とタイミング調整)
共通化編
Float計算回路のVerilog-HDL実装について -その2.5(共通化)
0対応編
Float計算回路のVerilog-HDL実装について -その2.7(0対応)
目的
floatの勉強
float32のハードウェア実装
0 に対応しない積算回路の実装を行う
前回までの加減算回路との共通化は行わない(つもり)
今回のHW
コード
module float_mul(
input wire clk,
input wire [31:0] v1,
input wire [31:0] v2,
output wire [31:0] vres
);
assign vres = res;
// TIM1
reg [7:0] v1e;
reg [7:0] v2e;
reg [23:0] v1v;
reg [23:0] v2v;
reg v1o;
reg v2o;
// TIM2
reg [7:0] re;
reg [47:0] rv;
reg ro;
// TIM3
reg [31:0] res;
always @(posedge clk) begin
// TIM1
v1e <= (v1[30:23] - 8'h7F);
v2e <= (v2[30:23] - 8'h7F);
v1v <= {1'b1, v1[22:0]};
v2v <= {1'b1, v2[22:0]};
v1o <= v1[31];
v2o <= v2[31];
// TIM2
re <= v1e + v2e;
rv <= v1v * v2v;
ro <= v1o ^ v2o;
// TIM3
if (rv[47]) begin
res <= {ro, re + 8'h80, rv[46:24]};
end else begin
res <= {ro, re + 8'h7F, rv[45:23]};
end
end
endmodule
127 と 128
計算中に繰り下がりが起きてるからだよ
シミュレーション結果と誤差
値1 | 値2 | 結果 | 正答 | 誤差 | |
---|---|---|---|---|---|
7.25 | 123.4 | 894.64996 | 894.65 | 0.00004 | |
7.25 | 0.00123 | 0.0089175 | 0.0089175 | 0 | |
0.725 | 123.4 | 89.465004 | 89.465 | 0.000004 | |
0.725 | 0.00123 | 0.00089175004 | 0.00089175 | 0.0000000004 |
プチ改良(?)
// TIM3
if (rv[47]) begin
res <= {ro, re + 8'h80, rv[46:24] + {22'b0, rv[23]}};
end else begin
res <= {ro, re + 8'h7F, rv[45:23] + {22'b0, rv[22]}};
end
四捨五入の導入
多分大丈夫だけど OF しても知らない
シミュレーション結果と誤差
値1 | 値2 | 結果 | 正答 | 誤差 | |
---|---|---|---|---|---|
7.25 | 123.4 | 894.65 | 894.65 | 0 | |
7.25 | 0.00123 | 0.0089175 | 0.0089175 | 0 | |
0.725 | 123.4 | 89.465004 | 89.465 | 0.000004 | |
0.725 | 0.00123 | 0.0008917501 | 0.00089175 | 0.0000000001 |
誤差が大きくなったり小さくなったり変わらなかったり