diff options
author | Tristan Gingold <tgingold@free.fr> | 2019-10-14 21:56:25 +0200 |
---|---|---|
committer | Tristan Gingold <tgingold@free.fr> | 2019-10-14 21:56:25 +0200 |
commit | b029b0a43111143a0790aefa677beecb289e2b4a (patch) | |
tree | 76ebc7db7a651ab4d835c21d0dd26f7afcd2f32f /src/synth | |
parent | 987b58addadbef067a3dca4e3c687f098e0b265a (diff) | |
download | ghdl-b029b0a43111143a0790aefa677beecb289e2b4a.tar.gz ghdl-b029b0a43111143a0790aefa677beecb289e2b4a.tar.bz2 ghdl-b029b0a43111143a0790aefa677beecb289e2b4a.zip |
synth-inference: handle multiple connections.
Diffstat (limited to 'src/synth')
-rw-r--r-- | src/synth/synth-inference.adb | 45 |
1 files changed, 31 insertions, 14 deletions
diff --git a/src/synth/synth-inference.adb b/src/synth/synth-inference.adb index 5505110d2..e66a8a386 100644 --- a/src/synth/synth-inference.adb +++ b/src/synth/synth-inference.adb @@ -148,7 +148,7 @@ package body Synth.Inference is end if; end Find_Longest_Loop; - procedure Extract_Clock_And (Inst : Instance) + procedure Extract_Clock_And (Ctxt : Context_Acc; Inst : Instance) is begin pragma Assert (Get_Id (Inst) = Id_And); @@ -162,7 +162,7 @@ package body Synth.Inference is when Id_Edge => null; when Id_And => - Extract_Clock_And (Inst0); + Extract_Clock_And (Ctxt, Inst0); -- If we have: AND convert to: AND -- / \ / \ @@ -176,20 +176,28 @@ package body Synth.Inference is begin if Get_Id (Inst3) = Id_Edge then declare + Can_Rotate : constant Boolean := + Has_One_Connection (N0); I2 : constant Input := Get_Input (Inst0, 1); N2 : constant Net := Get_Driver (I2); I1 : constant Input := Get_Input (Inst, 1); N1 : constant Net := Get_Driver (I1); + N4 : Net; begin Disconnect (I0); - Disconnect (I2); Disconnect (I1); - Disconnect (I3); - Connect (I0, N3); - Connect (I1, N0); - Connect (I3, N2); - Connect (I2, N1); + if Can_Rotate then + Disconnect (I2); + Disconnect (I3); + + Connect (I1, N0); + Connect (I3, N2); + Connect (I2, N1); + else + N4 := Build_Dyadic (Ctxt, Id_And, N2, N1); + Connect (I1, N4); + end if; end; end if; end; @@ -216,7 +224,7 @@ package body Synth.Inference is Connect (I0, N1); end; when Id_And => - Extract_Clock_And (Inst0); + Extract_Clock_And (Ctxt, Inst0); -- If we have: AND convert to: AND -- / \ / \ @@ -229,14 +237,22 @@ package body Synth.Inference is begin if Get_Id (Get_Net_Parent (N3)) = Id_Edge then declare + Can_Rotate : constant Boolean := + Has_One_Connection (N0); I1 : constant Input := Get_Input (Inst, 0); N1 : constant Net := Get_Driver (I1); + N4 : Net; begin Disconnect (I3); Disconnect (I1); - Connect (I1, N3); - Connect (I3, N1); + if Can_Rotate then + Connect (I3, N1); + else + N4 := Build_Dyadic + (Ctxt, Id_And, N1, Get_Input_Net (Inst0, 1)); + Connect (I3, N4); + end if; end; end if; end; @@ -248,7 +264,8 @@ package body Synth.Inference is -- Walk the And-net N, and extract clock (posedge/negedge) if found. -- ENABLE is N without the clock. - procedure Extract_Clock (N : Net; Clk : out Net; Enable : out Net) + procedure Extract_Clock + (Ctxt : Context_Acc; N : Net; Clk : out Net; Enable : out Net) is Inst : constant Instance := Get_Net_Parent (N); begin @@ -261,7 +278,7 @@ package body Synth.Inference is Clk := Get_Input_Net (Inst, 0); when Id_And => -- Canonicalize conditions. - Extract_Clock_And (Inst); + Extract_Clock_And (Ctxt, Inst); -- Condition should be in the form: CLK and EXPR declare @@ -653,7 +670,7 @@ package body Synth.Inference is else -- So there is a logical loop. Sel := Get_Mux2_Sel (Last_Mux); - Extract_Clock (Get_Driver (Sel), Clk, Enable); + Extract_Clock (Ctxt, Get_Driver (Sel), Clk, Enable); if Clk = No_Net then -- No clock -> latch or combinational loop Infere_Latch (Ctxt, Wid, Val, Off, Prev_Val, Stmt); |