flash-attention-rtl / rtl /src /fa_exp_approx.sv
SNAPKITTYWEST's picture
October 2026 main drop: mirror from GitHub
2166d7e verified
Raw History Blame Contribute Delete
1.43 kB
// EXP_APPROX: exp(-delta/256) in Q0.16 (65536 == 1.0) for delta >= 0.
// y = delta * log2(e); n = integer part, f = fraction
// 2^-f ~ 16-segment LUT with linear interpolation; result = 2^-f >> n
// One cycle of latency.
module fa_exp_approx
import fa_pkg::*;
(
input logic clk,
input logic rst_n,
input logic in_valid,
input logic [31:0] delta, // non-negative, logit units (1/256)
output logic out_valid,
output logic [16:0] result
);
logic [11:0] dcl;
logic [23:0] y8;
logic [4:0] n;
logic [7:0] f;
logic [16:0] t0, t1, diff, base;
logic [20:0] interp;
logic [16:0] res_c;
always_comb begin
dcl = (delta > 32'd4095) ? 12'd4095 : delta[11:0];
y8 = 24'(dcl) * 24'd369 >> 8;
n = y8[12:8];
f = y8[7:0];
t0 = exp_lut({1'b0, f[7:4]});
t1 = exp_lut({1'b0, f[7:4]} + 5'd1);
diff = t0 - t1;
interp = diff * f[3:0];
base = t0 - 17'(interp >> 4);
res_c = (y8[23:8] >= 16'd16) ? 17'd0 : (base >> n);
end
always_ff @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
out_valid <= 1'b0;
result <= '0;
end else begin
out_valid <= in_valid;
result <= res_c;
end
end
endmodule : fa_exp_approx