From 4bb12b30a53326ac6e3177bc4016317181dd7f7e Mon Sep 17 00:00:00 2001 From: Tristan Gingold Date: Wed, 22 Apr 2020 08:15:48 +0200 Subject: netlists: infere tri gate. --- src/synth/netlists-inference.adb | 26 ++++++++++++++++++++++++++ src/synth/netlists-utils.adb | 14 ++++++++++++++ src/synth/netlists-utils.ads | 4 ++++ 3 files changed, 44 insertions(+) (limited to 'src') diff --git a/src/synth/netlists-inference.adb b/src/synth/netlists-inference.adb index 1155a6047..8b053855e 100644 --- a/src/synth/netlists-inference.adb +++ b/src/synth/netlists-inference.adb @@ -812,6 +812,32 @@ package body Netlists.Inference is return Val; end if; + -- Infere tri-buf. + First_Mux := Get_Net_Parent (Val); + if Get_Id (First_Mux) = Id_Mux2 then + declare + Nsel, N0, N1 : Net; + begin + -- Check for VAL <= SEL ? N1 : 'Z' + if Get_Id (Get_Input_Instance (First_Mux, 1)) = Id_Const_Z then + -- Disconnect the mux. + Nsel := Disconnect_And_Get (First_Mux, 0); + N0 := Disconnect_And_Get (First_Mux, 1); + N1 := Disconnect_And_Get (First_Mux, 2); + -- Build the tri buf. + Res := Build_Tri (Ctxt, Nsel, N1); + -- Remove the 'Z' (shouldn't be connected). + Remove_Instance (Get_Net_Parent (N0)); + -- Copy location. + Copy_Location (Res, First_Mux); + -- Redirect tri output. + Redirect_Inputs (Get_Output (First_Mux, 0), Res); + Remove_Instance (First_Mux); + return Res; + end if; + end; + end if; + Find_Longest_Loop (Val, Prev_Val, Last_Mux, Len); if Len <= 0 then -- No logical loop or self assignment. diff --git a/src/synth/netlists-utils.adb b/src/synth/netlists-utils.adb index bf33cb13e..fa1494820 100644 --- a/src/synth/netlists-utils.adb +++ b/src/synth/netlists-utils.adb @@ -237,6 +237,20 @@ package body Netlists.Utils is return Inp = No_Input; end Has_One_Connection; + function Disconnect_And_Get (I : Input) return Net + is + N : Net; + begin + N := Get_Driver (I); + Disconnect (I); + return N; + end Disconnect_And_Get; + + function Disconnect_And_Get (Inst : Instance; I : Port_Idx) return Net is + begin + return Disconnect_And_Get (Get_Input (Inst, I)); + end Disconnect_And_Get; + procedure Disconnect_And_Free (I : Input) is I_Net : constant Net := Get_Driver (I); diff --git a/src/synth/netlists-utils.ads b/src/synth/netlists-utils.ads index e4981b38a..aeeb5cc78 100644 --- a/src/synth/netlists-utils.ads +++ b/src/synth/netlists-utils.ads @@ -85,6 +85,10 @@ package Netlists.Utils is -- disconnect and free it. procedure Disconnect_And_Free (I : Input); + -- Disconnect an input and return the previous driver. + function Disconnect_And_Get (I : Input) return Net; + function Disconnect_And_Get (Inst : Instance; I : Port_Idx) return Net; + -- Return true IFF L and R is the same net. -- Either because L = R (obvious case) or because both are the same -- selection of the same net. -- cgit v1.2.3