diff options
| -rw-r--r-- | src/synth/netlists-inference.adb | 99 | 
1 files changed, 45 insertions, 54 deletions
diff --git a/src/synth/netlists-inference.adb b/src/synth/netlists-inference.adb index 6263cbf62..936bb4f23 100644 --- a/src/synth/netlists-inference.adb +++ b/src/synth/netlists-inference.adb @@ -320,17 +320,21 @@ package body Netlists.Inference is     function Infere_FF_Else (Ctxt : Context_Acc;                              Prev_Val : Net; -                            Off : Uns32; +                            Off      : Uns32;                              Last_Mux : Instance; -                            Clk : Net; +                            Init     : Net; +                            Rst      : Net; +                            Rst_Val  : Net; +                            Data     : Net; +                            Els      : Net; +                            Clk      : Net;                              Clk_Enable : Net; -                            Stmt : Synth.Source.Syn_Src) return Net; +                            Loc        : Location_Type) return Net;     procedure Infere_FF_Mux (Ctxt : Context_Acc;                              Prev_Val : Net;                              Off : Uns32;                              Last_Mux : Instance; -                            Stmt : Synth.Source.Syn_Src;                              Els : out Net;                              Data : out Net)     is @@ -340,7 +344,9 @@ package body Netlists.Inference is        I1 : constant Input := Get_Mux2_I1 (Last_Mux);        Els_Inst : Instance;        Els_Clk : Net; -      Els_En : Net; +      Els_En   : Net; +      Data2    : Net; +      Els2     : Net;     begin        --  There must be no 'else' part for clock expression.        Els := Get_Driver (I0); @@ -360,8 +366,16 @@ package body Netlists.Inference is                (Mux_Loc, "clocked logic requires clocked logic on else part");              Els := No_Net;           else -            Els := Infere_FF_Else (Ctxt, Prev_Val, Off, Els_Inst, -                                   Els_Clk, Els_En, Stmt); +            --  Create and return the DFF. + +            --  1. Remove the mux that creates the loop (will be replaced by +            --     the dff). +            Infere_FF_Mux (Ctxt, Prev_Val, Off, Last_Mux, Els2, Data2); + +            Els := Infere_FF_Else (Ctxt, Prev_Val, Off, Last_Mux, No_Net, +                                   No_Net, No_Net, Data2, Els2, +                                   Els_Clk, Els_En, Get_Location (Last_Mux)); +            Remove_Instance (Last_Mux);           end if;        end if; @@ -424,30 +438,26 @@ package body Netlists.Inference is     function Infere_FF_Else (Ctxt : Context_Acc;                              Prev_Val : Net; -                            Off : Uns32; +                            Off      : Uns32;                              Last_Mux : Instance; -                            Clk : Net; +                            Init     : Net; +                            Rst      : Net; +                            Rst_Val  : Net; +                            Data     : Net; +                            Els      : Net; +                            Clk      : Net;                              Clk_Enable : Net; -                            Stmt : Synth.Source.Syn_Src) return Net +                            Loc        : Location_Type) return Net     is -      Mux_Loc : constant Location_Type := Get_Location (Last_Mux); -      Data : Net; -      Res : Net; -      Els : Net; +      Ndata : Net; +      Res   : Net;     begin -      --  Create and return the DFF. - -      --  1. Remove the mux that creates the loop (will be replaced by the -      --     dff). -      Infere_FF_Mux (Ctxt, Prev_Val, Off, Last_Mux, Stmt, Els, Data); - -      Free_Instance (Last_Mux); -        if Off = 0 +        and then not Synth.Flags.Flag_Debug_Nomemory          and then Can_Infere_RAM (Data, Prev_Val)        then           --  Maybe it is a RAM. -         Data := Infere_RAM (Ctxt, Data, Clk_Enable); +         Ndata := Infere_RAM (Ctxt, Data, Clk_Enable);        elsif Clk_Enable /= No_Net then           --  If there is a condition with the clock, that's an enable which           --  keep the previous value if the condition is false.  Add the mux @@ -457,14 +467,19 @@ package body Netlists.Inference is           begin              Prev := Build2_Extract (Ctxt, Prev_Val, Off, Get_Width (Data)); -            Data := Build_Mux2 (Ctxt, Clk_Enable, Prev, Data); -            Copy_Location (Data, Clk_Enable); +            Ndata := Build_Mux2 (Ctxt, Clk_Enable, Prev, Data); +            Copy_Location (Ndata, Clk_Enable);           end; +      else +         Ndata := Data;        end if;        --  Create the FF. -      Res := Infere_FF_Create (Ctxt, No_Net, No_Net, No_Net, Clk, Data, -                               Els, Mux_Loc); +      Res := Infere_FF_Create (Ctxt, Rst, Rst_Val, Init, Clk, Ndata, Els, Loc); + +      --  The output may already be used (if the target is a variable that +      --  is read).  So redirect the net. +      Redirect_Inputs (Get_Output (Last_Mux, 0), Res);        return Res;     end Infere_FF_Else; @@ -496,7 +511,7 @@ package body Netlists.Inference is        --  1. Remove the mux that creates the loop (will be replaced by the        --     dff). -      Infere_FF_Mux (Ctxt, Prev_Val, Off, Clock_Mux, Stmt, Els, Data); +      Infere_FF_Mux (Ctxt, Prev_Val, Off, Clock_Mux, Els, Data);        --  If the signal declaration has an initial value, get it.        Sig := Get_Net_Parent (Prev_Val); @@ -641,33 +656,9 @@ package body Netlists.Inference is           pragma Assert (Prev_Mux = No_Instance or else Prev_Mux = Last_Mux);        end; -      if Off = 0 -        and then not Synth.Flags.Flag_Debug_Nomemory -        and then Can_Infere_RAM (Data, Prev_Val) -      then -         --  Maybe it is a RAM. -         Data := Infere_RAM (Ctxt, Data, Enable); -      elsif Enable /= No_Net then -         --  If there is a condition with the clock, that's an enable which -         --  keep the previous value if the condition is false.  Add the mux -         --  for it. -         declare -            Prev : Net; -         begin -            Prev := Build2_Extract (Ctxt, Prev_Val, Off, Get_Width (Data)); - -            Data := Build_Mux2 (Ctxt, Enable, Prev, Data); -            Copy_Location (Data, Enable); -         end; -      end if; +      Res := Infere_FF_Else (Ctxt, Prev_Val, Off, Last_Mux, Init, +                             Rst, Rst_Val, Data, Els, Clk, Enable, Mux_Loc); -      --  Create the FF. -      Res := Infere_FF_Create (Ctxt, Rst, Rst_Val, Init, Clk, Data, -                               Els, Mux_Loc); - -      --  The output may already be used (if the target is a variable that -      --  is read).  So redirect the net. -      Redirect_Inputs (Get_Output (Last_Mux, 0), Res);        if Prev_Mux /= No_Instance then           Remove_Instance (Prev_Mux);        end if;  | 
