From 067952e4214e82060f9b98032870ae8c13eee79a Mon Sep 17 00:00:00 2001 From: Tristan Gingold Date: Thu, 17 Jun 2021 08:15:08 +0200 Subject: synth: add a gate on an optimization to simplify memory handling. --- src/synth/netlists-memories.adb | 87 ++++++++++++----------------------------- src/synth/synth-environment.adb | 18 ++++++--- 2 files changed, 38 insertions(+), 67 deletions(-) (limited to 'src/synth') diff --git a/src/synth/netlists-memories.adb b/src/synth/netlists-memories.adb index 2b986ac50..5c8ea78d8 100644 --- a/src/synth/netlists-memories.adb +++ b/src/synth/netlists-memories.adb @@ -2604,69 +2604,34 @@ package body Netlists.Memories is -- dout := mem (addr); -- end if; -- the writer has just been reduced, but the reader can also be reduced. - -- _ - -- _ / |0-----------------------\ - -- / |1- dyn_extract --| | | - -- dout ---| | \_|1-------\ | - -- \_|0-- dout | | | - -- | wen +- dyn_insert --+--- mem - -- rden _ | | - -- / |1-------/ | - -- mem ----------- isignal -----| | | - -- \_|0-----------------------/ - -- | - -- wen & +clk + -- _ + -- _ / |0-----------------\ + -- / |1-- dyn_extract ---+----| | | + -- dout ---| | | \_|1--- dyn_insert --+--- mem + -- \_|0-- dout | | | + -- | | wen | + -- rden _ | | + -- / |1---/ | + -- mem ----- isignal -----| | | + -- \_|0------------------------------/ + -- | + -- +clk -- Was just reduced to: - -- FIXME: this is not equivalent because of `+clk` on the mem mux. - -- However, because the `+clk` comes from outer blocks, it also - -- applies to dout. - -- _ - -- _ / |0------------------------\ - -- / |1- dyn_extract --| | | - -- dout ---| | \_|1-----\ | - -- \_|0-- dout | | | - -- | wen +- dyn_insert_en --+--- mem - -- rden | | - -- | wen & +clk - -- mem ----------- isignal ---------------/ - -- - -- Now, reduce the mux to the dyn_extract: -- _ - -- / |1------- dyn_extract ------\ - -- dout ---| | | - -- \_|0-- dout | - -- | +- dyn_insert_en --+--- mem - -- rden | | - -- | wen & +clk - -- mem ----------- isignal ---------------/ - -- - - -- If there are muxes for dyn_extract driven by the same SEL - -- net, between N and HEAD_IN, move them to HEAD_OUT as dyn_extract_en. - declare - Tail_Net : constant Net := Get_Output (Tail_Out, 0); - Head_Net : constant Net := Get_Output (Head_Out, 0); - Inp : Input; - Next_Inp : Input; - begin - Inp := Get_First_Sink (Tail_Net); - while Inp /= No_Input loop - Next_Inp := Get_Next_Sink (Inp); - Inst := Get_Input_Parent (Inp); - if Get_Id (Inst) = Id_Mux2 - and then Get_Input_Net (Inst, 1) = Tail_Net - and then Get_Input_Net (Inst, 2) = Head_Net - and then In_Conjunction (Sel, Get_Input_Net (Inst, 0), False) - then - Disconnect (Get_Input (Inst, 0)); - Disconnect (Get_Input (Inst, 1)); - Disconnect (Get_Input (Inst, 2)); - Redirect_Inputs (Get_Output (Inst, 0), Head_Net); - Remove_Instance (Inst); - end if; - Inp := Next_Inp; - end loop; - end; + -- / |1-- dyn_extract ---+--- dyn_insert_en --+--- mem + -- dout ---| | | | + -- \_|0-- dout | | + -- | | | + -- rden _ | | + -- / |1---/ | + -- mem ----- isignal -----| | | + -- \_|0------------------------/ + -- | + -- +clk + + -- Note: Previously, `+clk` and `wen` were fused to the same mux (as an + -- optimization), requiring extraction. Now the optimization is not + -- performed when a wire is read, thus simplifying the reduction here. end Reduce_Muxes; -- Remove the mux2 HEAD (by adding enable to dyn_insert). diff --git a/src/synth/synth-environment.adb b/src/synth/synth-environment.adb index fd04f0673..654d74ad2 100644 --- a/src/synth/synth-environment.adb +++ b/src/synth/synth-environment.adb @@ -1361,19 +1361,25 @@ package body Synth.Environment is end loop; -- Possible optimizations: - -- if C1 then _ _ _ - -- if C2 then R0-|0\ R0-|0\ R0 -|0\ - -- R := V; ==> | |--+ | |- R ==> | |- R - -- end if; V-|_/ +----|_/ V-|_/ - -- end if; C1 C2 C1.C2 + -- if C1 then _ _ _ + -- if C2 then R0-|0\ R0-|0\ R0 -|0\ + -- R := V; ==> | |-- T --+ | |- R ==> | |- R + -- end if; V-|_/ +----|_/ V-|_/ + -- end if; C2 C1 C1.C2 + -- + -- Note: N (0) ~ R0, N (1) ~ T = first mux input -- -- This really helps inference as the net R0 doesn't have to be -- walked twice (in absence of memoization). - -- OTOH, it makes memory handling slightly more complex... + -- This optimization is not performed if T is used. This check is + -- not really necessary as if T is assigned it will also be handled + -- in this procedure and will be muxed by C1. But this simplifies + -- memory handling. -- Build mux. N1_Inst := Get_Net_Parent (N (1)); if Get_Id (N1_Inst) = Id_Mux2 + and then not Is_Connected (N (1)) and then Same_Net (Get_Driver (Get_Mux2_I0 (N1_Inst)), N (0)) then declare -- cgit v1.2.3