diff options
| author | Alejandro Soto <alejandro@34project.org> | 2023-11-16 20:48:30 -0600 |
|---|---|---|
| committer | Alejandro Soto <alejandro@34project.org> | 2023-11-16 21:37:57 -0600 |
| commit | b11e2758446ac82328a8c410d38b80174dc3a1ed (patch) | |
| tree | ca9a8772cc480173dc9c80f2417f6487245647f4 /rtl/gfx/gfx_fixed_fma.sv | |
| parent | 231d477d007f99b8c5ba1e0f3cea2a68229b2495 (diff) | |
rtl/gfx: fix lpm_mult-based FMA
Diffstat (limited to 'rtl/gfx/gfx_fixed_fma.sv')
| -rw-r--r-- | rtl/gfx/gfx_fixed_fma.sv | 22 |
1 files changed, 14 insertions, 8 deletions
diff --git a/rtl/gfx/gfx_fixed_fma.sv b/rtl/gfx/gfx_fixed_fma.sv index b458010..ec26477 100644 --- a/rtl/gfx/gfx_fixed_fma.sv +++ b/rtl/gfx/gfx_fixed_fma.sv @@ -12,10 +12,9 @@ module gfx_fixed_fma output fixed q ); - logic[$bits(fixed) + `FIXED_FRAC - 1:0] q_ext; - `ifndef VERILATOR - assign q = q_ext[$bits(fixed) + `FIXED_FRAC - 1:`FIXED_FRAC]; + logic[2 * $bits(fixed) - `FIXED_FRAC - 1:0] q_ext; + assign q = q_ext[$bits(fixed) - 1:0]; lpm_mult mult ( @@ -24,19 +23,26 @@ module gfx_fixed_fma .clken(!stall), .sum({c, {`FIXED_FRAC{1'b0}}}), - .dataa({{`FIXED_FRAC{a[$bits(a) - 1]}}, a}), - .datab({{`FIXED_FRAC{b[$bits(b) - 1]}}, b}), + .dataa(a), + .datab(b), .result(q_ext) ); defparam - mult.lpm_widtha = $bits(fixed) + `FIXED_FRAC, - mult.lpm_widthb = $bits(fixed) + `FIXED_FRAC, + mult.lpm_widtha = $bits(fixed), + mult.lpm_widthb = $bits(fixed), mult.lpm_widths = $bits(fixed) + `FIXED_FRAC, - mult.lpm_widthp = $bits(fixed) + `FIXED_FRAC, + /* Esto es crucial. No está documentado en ningún lado (aparte de un + * comentario en r/fpga). Si lpm_widthp < lpm_widtha + lpm_widthb, + * entonces result contiene los lpm_widthp bits más significativos + * del producto, no los menos significativos como tendría sentido. + */ + mult.lpm_widthp = 2 * $bits(fixed) - `FIXED_FRAC, mult.lpm_representation = "SIGNED", mult.lpm_pipeline = `FIXED_FMA_STAGES; `else + logic[$bits(fixed) + `FIXED_FRAC - 1:0] q_ext; + fixed a_hold, b_hold, c_hold; assign q = q_ext[$bits(fixed) + `FIXED_FRAC - 1:`FIXED_FRAC] + c_hold; |
