diff options
-rw-r--r-- | src/synth/netlists-folds.adb | 25 | ||||
-rw-r--r-- | src/synth/netlists-folds.ads | 5 | ||||
-rw-r--r-- | src/synth/netlists-memories.adb | 27 | ||||
-rw-r--r-- | src/synth/synth-environment.adb | 27 |
4 files changed, 59 insertions, 25 deletions
diff --git a/src/synth/netlists-folds.adb b/src/synth/netlists-folds.adb index 41d06b3ea..c3fc3d022 100644 --- a/src/synth/netlists-folds.adb +++ b/src/synth/netlists-folds.adb @@ -349,4 +349,29 @@ package body Netlists.Folds is return Build_Const_UB32 (Ctxt, 0, 1); end case; end Build2_Compare; + + function Add_Enable_To_Dyn_Insert + (Ctxt : Context_Acc; Inst : Instance; Sel : Net) return Instance + is + In_Mem : constant Input := Get_Input (Inst, 0); + In_V : constant Input := Get_Input (Inst, 1); + In_Idx : constant Input := Get_Input (Inst, 2); + Off : constant Uns32 := Get_Param_Uns32 (Inst, 0); + Res : Net; + begin + Res := Build_Dyn_Insert_En + (Ctxt, Get_Driver (In_Mem), Get_Driver (In_V), Get_Driver (In_Idx), + Sel, Off); + Set_Location (Res, Get_Location (Inst)); + + Disconnect (In_Mem); + Disconnect (In_V); + Disconnect (In_Idx); + Redirect_Inputs (Get_Output (Inst, 0), Res); + + Remove_Instance (Inst); + + return Get_Net_Parent (Res); + end Add_Enable_To_Dyn_Insert; + end Netlists.Folds; diff --git a/src/synth/netlists-folds.ads b/src/synth/netlists-folds.ads index 5eb04a21f..c0590d73b 100644 --- a/src/synth/netlists-folds.ads +++ b/src/synth/netlists-folds.ads @@ -94,4 +94,9 @@ package Netlists.Folds is Id : Compare_Module_Id; L, R : Net) return Net; + -- INST is a dyn_insert gate that will be converted to a dyn_insert_en + -- by using SEL as enable input. + -- The old dyn_insert gate is removed. + function Add_Enable_To_Dyn_Insert + (Ctxt : Context_Acc; Inst : Instance; Sel : Net) return Instance; end Netlists.Folds; diff --git a/src/synth/netlists-memories.adb b/src/synth/netlists-memories.adb index 5c8ea78d8..6c7505842 100644 --- a/src/synth/netlists-memories.adb +++ b/src/synth/netlists-memories.adb @@ -2447,30 +2447,6 @@ package body Netlists.Memories is Instance_Tables.Free (Mems); end Extract_Memories2; - function Add_Enable_To_Dyn_Insert - (Ctxt : Context_Acc; Inst : Instance; Sel : Net) return Instance - is - In_Mem : constant Input := Get_Input (Inst, 0); - In_V : constant Input := Get_Input (Inst, 1); - In_Idx : constant Input := Get_Input (Inst, 2); - Off : constant Uns32 := Get_Param_Uns32 (Inst, 0); - Res : Net; - begin - Res := Build_Dyn_Insert_En - (Ctxt, Get_Driver (In_Mem), Get_Driver (In_V), Get_Driver (In_Idx), - Sel, Off); - Set_Location (Res, Get_Location (Inst)); - - Disconnect (In_Mem); - Disconnect (In_V); - Disconnect (In_Idx); - Redirect_Inputs (Get_Output (Inst, 0), Res); - - Remove_Instance (Inst); - - return Get_Net_Parent (Res); - end Add_Enable_To_Dyn_Insert; - -- Return True iff O is to MUX and any number of Dyn_Extract (possibly -- through mux2). function One_Write_Connection (O : Net; Mux : Instance) return Boolean @@ -2797,7 +2773,8 @@ package body Netlists.Memories is end if; -- But continue with the result: still need to add the SEL. Drv := Get_Output (Inst, 0); - when Id_Dyn_Insert => + when Id_Dyn_Insert + | Id_Dyn_Insert_En => -- Continue the walk with the next element. Drv := Get_Input_Net (Inst, 0); when others => diff --git a/src/synth/synth-environment.adb b/src/synth/synth-environment.adb index 654d74ad2..8b3753aaf 100644 --- a/src/synth/synth-environment.adb +++ b/src/synth/synth-environment.adb @@ -1323,6 +1323,28 @@ package body Synth.Environment is end loop; end Merge_Partial_Assigns; + -- Sub-routine of Merge_Assigns when the net is a dyn_insert + -- Try to transform it to a dyn_insert_en + function Merge_Dyn_Insert (Ctxt : Builders.Context_Acc; + Sel : Net; + N1_Inst : Instance; + N0 : Net) return Net + is + V : Net; + New_Inst : Instance; + begin + -- TODO: handle a serie of dyn_insert + -- TODO: also handle dyn_insert_en + -- TODO: negative SEL ? + V := Get_Input_Net (N1_Inst, 0); + if Same_Net (V, N0) then + New_Inst := Add_Enable_To_Dyn_Insert (Ctxt, N1_Inst, Sel); + return Get_Output (New_Inst, 0); + else + return Build_Mux2 (Ctxt, Sel, N0, Get_Output (N1_Inst, 0)); + end if; + end Merge_Dyn_Insert; + procedure Merge_Assigns (Ctxt : Builders.Context_Acc; Wid : Wire_Id; Sel : Net; @@ -1404,6 +1426,11 @@ package body Synth.Environment is (Ctxt, Res, N (0), Get_Driver (Get_Mux2_I1 (N1_Inst))); end if; end; + elsif not Flags.Flag_Debug_Nomemory1 + and then Get_Id (N1_Inst) = Id_Dyn_Insert + and then not Is_Connected (N (1)) + then + Res := Merge_Dyn_Insert (Ctxt, Sel, N1_Inst, N (0)); elsif N (0) = N (1) then -- Minor optimization: no need to add a mux if both sides are -- equal. But this is important for the control wires. |