aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorTristan Gingold <tgingold@free.fr>2021-06-17 08:15:08 +0200
committerTristan Gingold <tgingold@free.fr>2021-06-17 08:15:08 +0200
commit067952e4214e82060f9b98032870ae8c13eee79a (patch)
tree4a83d833c468860919059caae43b863521865730 /src
parentb853533397f943615f80a2a0f547fadc0ae0c369 (diff)
downloadghdl-067952e4214e82060f9b98032870ae8c13eee79a.tar.gz
ghdl-067952e4214e82060f9b98032870ae8c13eee79a.tar.bz2
ghdl-067952e4214e82060f9b98032870ae8c13eee79a.zip
synth: add a gate on an optimization to simplify memory handling.
Diffstat (limited to 'src')
-rw-r--r--src/synth/netlists-memories.adb87
-rw-r--r--src/synth/synth-environment.adb18
2 files changed, 38 insertions, 67 deletions
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