aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorTristan Gingold <tgingold@free.fr>2021-06-16 07:47:23 +0200
committerTristan Gingold <tgingold@free.fr>2021-06-16 07:47:23 +0200
commit9a913ec7ac5bc2193ec3df90bf7f43808f5c80c6 (patch)
tree8c7963afd189f9f11826b42924e6afe2540d9ba8 /src
parent0f3f7064aabccd89c1413aab4cac56f8a851fa55 (diff)
downloadghdl-9a913ec7ac5bc2193ec3df90bf7f43808f5c80c6.tar.gz
ghdl-9a913ec7ac5bc2193ec3df90bf7f43808f5c80c6.tar.bz2
ghdl-9a913ec7ac5bc2193ec3df90bf7f43808f5c80c6.zip
netlists-memories: strengthen dyn_extract mux reduction. Fix #1781
Diffstat (limited to 'src')
-rw-r--r--src/synth/netlists-memories.adb52
-rw-r--r--src/synth/synth-environment.adb1
2 files changed, 52 insertions, 1 deletions
diff --git a/src/synth/netlists-memories.adb b/src/synth/netlists-memories.adb
index c682610cb..2b986ac50 100644
--- a/src/synth/netlists-memories.adb
+++ b/src/synth/netlists-memories.adb
@@ -1412,6 +1412,11 @@ package body Netlists.Memories is
raise Internal_Error;
end if;
+ -- Simple case (but important for the memories)
+ if V = Conj then
+ return True;
+ end if;
+
N := Conj;
Inst := Get_Net_Parent (N);
loop
@@ -2591,6 +2596,51 @@ package body Netlists.Memories is
N := Get_Input_Net (Tail_Out, 0);
end loop;
+ -- For memories described by a single process like this:
+ -- if wen then
+ -- mem (addr) := din;
+ -- end if;
+ -- if rden then
+ -- 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
+ -- 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
@@ -2604,9 +2654,9 @@ package body Netlists.Memories is
Next_Inp := Get_Next_Sink (Inp);
Inst := Get_Input_Parent (Inp);
if Get_Id (Inst) = Id_Mux2
- and then Get_Input_Net (Inst, 0) = Sel
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));
diff --git a/src/synth/synth-environment.adb b/src/synth/synth-environment.adb
index bd5202e6a..fd04f0673 100644
--- a/src/synth/synth-environment.adb
+++ b/src/synth/synth-environment.adb
@@ -1369,6 +1369,7 @@ package body Synth.Environment is
--
-- 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...
-- Build mux.
N1_Inst := Get_Net_Parent (N (1));