Skip to content

Commit 89dc61f

Browse files
reduce fp normalization area
1 parent 858ebba commit 89dc61f

File tree

1 file changed

+42
-39
lines changed

1 file changed

+42
-39
lines changed

src/normalize_fp.v

Lines changed: 42 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
module int18_to_bf16_lzd #(
2-
parameter FRAC_BITS = 8 // Number of fractional bits in Q10.8
2+
parameter FRAC_BITS = 8
33
)(
44
input wire signed [17:0] acc,
55
output reg [15:0] bf16
@@ -13,54 +13,37 @@ module int18_to_bf16_lzd #(
1313
reg [7:0] exp;
1414
reg [6:0] mant;
1515
reg [17:0] normalized;
16-
17-
// Leading zero detector
18-
function [4:0] lzd;
19-
input [17:0] x;
20-
reg [17:0] scan;
21-
begin
22-
// Priority encode from MSB to LSB
23-
scan = x;
24-
25-
casez (scan)
26-
18'b1?????????????????: lzd = 5'd0;
27-
18'b01????????????????: lzd = 5'd1;
28-
18'b001???????????????: lzd = 5'd2;
29-
18'b0001??????????????: lzd = 5'd3;
30-
18'b00001?????????????: lzd = 5'd4;
31-
18'b000001????????????: lzd = 5'd5;
32-
18'b0000001???????????: lzd = 5'd6;
33-
18'b00000001??????????: lzd = 5'd7;
34-
18'b000000001?????????: lzd = 5'd8;
35-
18'b0000000001????????: lzd = 5'd9;
36-
18'b00000000001???????: lzd = 5'd10;
37-
18'b000000000001??????: lzd = 5'd11;
38-
18'b0000000000001?????: lzd = 5'd12;
39-
18'b00000000000001????: lzd = 5'd13;
40-
18'b000000000000001???: lzd = 5'd14;
41-
18'b0000000000000001??: lzd = 5'd15;
42-
18'b00000000000000001?: lzd = 5'd16;
43-
18'b000000000000000001: lzd = 5'd17;
44-
default: lzd = 5'd18; // All zeros
45-
endcase
46-
end
47-
endfunction
48-
16+
17+
// ===================== HIERARCHICAL LEADING ZERO DETECTOR =====================
18+
wire [2:0] lz_hi, lz_mid, lz_lo;
19+
wire nz_hi, nz_mid, nz_lo;
20+
21+
lzd6 lzd_hi (.x(mag[17:12]), .lz(lz_hi), .nz(nz_hi));
22+
lzd6 lzd_mid (.x(mag[11:6]), .lz(lz_mid), .nz(nz_mid));
23+
lzd6 lzd_lo (.x(mag[5:0]), .lz(lz_lo), .nz(nz_lo));
24+
4925
always @(*) begin
5026
// Default assignments (prevent latches)
5127
sign = acc[17];
5228
mag = sign ? -acc : acc;
5329
bf16 = 16'h0;
54-
5530
lz = 5'd0;
5631
exp_unbiased= 9'sd0;
5732
exp = 8'd0;
5833
mant = 7'd0;
5934
normalized = 18'd0;
60-
35+
6136
if (mag != 0) begin
62-
lz = lzd(mag);
63-
37+
// Combine hierarchical LZD results with proper offsets
38+
if (nz_hi)
39+
lz = {2'b00, lz_hi}; // bits [17:12]: offset 0
40+
else if (nz_mid)
41+
lz = 5'd6 + {2'b00, lz_mid}; // bits [11:6]: offset 6
42+
else if (nz_lo)
43+
lz = 5'd12 + {2'b00, lz_lo}; // bits [5:0]: offset 12
44+
else
45+
lz = 5'd18;
46+
6447
// MSB position is (17 - lz), binary point at FRAC_BITS
6548
exp_unbiased = 9'(17) - 9'(lz) - 9'(FRAC_BITS);
6649

@@ -70,12 +53,32 @@ module int18_to_bf16_lzd #(
7053
bf16 = {sign, 8'hFF, 7'd0}; // overflow
7154
end else begin
7255
exp = exp_unbiased + BF16_BIAS;
73-
7456
// normalize so MSB ends up at bit 17
7557
normalized = mag << lz;
7658
mant = normalized[16:10];
7759
bf16 = {sign, exp, mant};
7860
end
7961
end
8062
end
63+
endmodule
64+
65+
// ===================== 6-BIT LEADING ZERO DETECTOR =====================
66+
module lzd6 (
67+
input wire [5:0] x,
68+
output reg [2:0] lz,
69+
output wire nz // Non-zero flag
70+
);
71+
assign nz = |x;
72+
73+
always @(*) begin
74+
casez (x)
75+
6'b1?????: lz = 3'd0;
76+
6'b01????: lz = 3'd1;
77+
6'b001???: lz = 3'd2;
78+
6'b0001??: lz = 3'd3;
79+
6'b00001?: lz = 3'd4;
80+
6'b000001: lz = 3'd5;
81+
default: lz = 3'd6;
82+
endcase
83+
end
8184
endmodule

0 commit comments

Comments
 (0)