diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/ghdldrv/ghdlsynth.adb | 2 | ||||
| -rw-r--r-- | src/synth/netlists-cleanup.adb | 27 | ||||
| -rw-r--r-- | src/synth/netlists-cleanup.ads | 6 | ||||
| -rw-r--r-- | src/synth/netlists-disp_verilog.adb | 3 | ||||
| -rw-r--r-- | src/synth/netlists-expands.adb | 62 | ||||
| -rw-r--r-- | src/synth/netlists-memories.adb | 5 | ||||
| -rw-r--r-- | src/synth/synth-flags.ads | 4 | ||||
| -rw-r--r-- | src/synth/synthesis.adb | 4 | 
8 files changed, 87 insertions, 26 deletions
| diff --git a/src/ghdldrv/ghdlsynth.adb b/src/ghdldrv/ghdlsynth.adb index 8ee8e02d8..138dca8df 100644 --- a/src/ghdldrv/ghdlsynth.adb +++ b/src/ghdldrv/ghdlsynth.adb @@ -227,6 +227,8 @@ package body Ghdlsynth is           Flag_Debug_Elaborate := True;        elsif Option = "-de" then           Flag_Debug_Noexpand := True; +      elsif Option = "-dn" then +         Flag_Debug_Nonull := True;        elsif Option = "-t" then           Flag_Trace_Statements := True;        elsif Option = "-i" then diff --git a/src/synth/netlists-cleanup.adb b/src/synth/netlists-cleanup.adb index c2fc603b4..52b3c87e0 100644 --- a/src/synth/netlists-cleanup.adb +++ b/src/synth/netlists-cleanup.adb @@ -385,4 +385,31 @@ package body Netlists.Cleanup is        end;     end Mark_And_Sweep; +   procedure Replace_Null_Inputs (Ctxt : Context_Acc; M : Module) +   is +      Inst : Instance; +      Drv : Net; +      Inp : Input; +      Null_X : Net; +   begin +      Null_X := No_Net; + +      Inst := Get_First_Instance (M); +      while Inst /= No_Instance loop +         for I in 1 .. Get_Nbr_Inputs (Inst) loop +            Inp := Get_Input (Inst, I - 1); +            Drv := Get_Driver (Inp); +            if Drv /= No_Net and then Get_Width (Drv) = 0 then +               if Null_X = No_Net then +                  Null_X := Build_Const_X (Ctxt, 0); +               end if; +               Disconnect (Inp); +               Connect (Inp, Null_X); +            end if; +         end loop; + +         Inst := Get_Next_Instance (Inst); +      end loop; +   end Replace_Null_Inputs; +  end Netlists.Cleanup; diff --git a/src/synth/netlists-cleanup.ads b/src/synth/netlists-cleanup.ads index be4f0e0fb..a13e66c47 100644 --- a/src/synth/netlists-cleanup.ads +++ b/src/synth/netlists-cleanup.ads @@ -16,6 +16,8 @@  --  You should have received a copy of the GNU General Public License  --  along with this program.  If not, see <gnu.org/licenses>. +with Netlists.Builders; use Netlists.Builders; +  package Netlists.Cleanup is     --  Remove instances of module M whose outputs are not connected.     --  Their inputs will be deconnected, which can result in new instances @@ -26,6 +28,10 @@ package Netlists.Cleanup is     --  sweep algorithm.     procedure Mark_And_Sweep (M : Module); +   --  Reconnection inputs of width 0 (the null inputs) to an Const_X gate. +   --  This will make all the null logic unconnected and ready to be cleaned. +   procedure Replace_Null_Inputs (Ctxt : Context_Acc; M : Module); +     --  Remove Id_Output gates.     procedure Remove_Output_Gates (M : Module);  end Netlists.Cleanup; diff --git a/src/synth/netlists-disp_verilog.adb b/src/synth/netlists-disp_verilog.adb index b2461bf2f..f28a1b536 100644 --- a/src/synth/netlists-disp_verilog.adb +++ b/src/synth/netlists-disp_verilog.adb @@ -1149,9 +1149,6 @@ package body Netlists.Disp_Verilog is                   or else (Flag_Merge_Edge                              and then Id in Edge_Module_Id                              and then not Need_Edge (Inst)) -                 or else (not Flag_Null_Wires -                            and then Get_Nbr_Outputs (Inst) = 1 -                            and then Get_Width (Get_Output (Inst, 0)) = 0)                 then                    --  Not displayed.                    null; diff --git a/src/synth/netlists-expands.adb b/src/synth/netlists-expands.adb index efb9fc93f..0f69dd93d 100644 --- a/src/synth/netlists-expands.adb +++ b/src/synth/netlists-expands.adb @@ -46,6 +46,9 @@ package body Netlists.Expands is        N := Addr_Net;        Nbr_Els := 1;        P := Memidx_Arr'Last; +      if P = 0 then +         return; +      end if;        loop           Ninst := Get_Net_Parent (N);           case Get_Id (Ninst) is @@ -213,34 +216,47 @@ package body Netlists.Expands is        --  2. compute number of cells.        Gather_Memidx (Addr_Net, Memidx_Arr, Nbr_Els); -      --  2. build extract gates -      Els := new Case_Element_Array (1 .. Nbr_Els); -      declare -         Idx : Positive; -         Off : Uns32; -         Sel : Uns64; -      begin -         Idx := 1; -         Off := Get_Param_Uns32 (Inst, 0); -         Sel := 0; -         Fill_Els (Ctxt, Memidx_Arr, 1, Val, Els, Idx, Addr_Net, Off, W, Sel); -      end; +      if Nbr_Els = 1 then +         --  There is only one element, so it's not really dynamic. +         --  Just return the value. +         Res := Get_Input_Net (Inst, 0); +         --  Disconnect the address +         Addr := Disconnect_And_Get (Inst, 1); +         if not Is_Connected (Addr) then +            --  Should be a Const_X. +            Remove_Instance (Get_Net_Parent (Addr)); +         end if; +      else +         --  2. build extract gates +         Els := new Case_Element_Array (1 .. Nbr_Els); +         declare +            Idx : Positive; +            Off : Uns32; +            Sel : Uns64; +         begin +            Idx := 1; +            Off := Get_Param_Uns32 (Inst, 0); +            Sel := 0; +            Fill_Els (Ctxt, Memidx_Arr, +                      1, Val, Els, Idx, Addr_Net, Off, W, Sel); +         end; -      --  3. build mux tree -      Disconnect (Get_Input (Inst, 1)); -      Extract_Address (Ctxt, Addr_Net, Ndims, Addr); -      Truncate_Address (Ctxt, Addr, Nbr_Els); -      Def := No_Net; -      Synth_Case (Ctxt, Addr, Els.all, Def, Res, Loc); +         --  3. build mux tree +         Disconnect (Get_Input (Inst, 1)); +         Extract_Address (Ctxt, Addr_Net, Ndims, Addr); +         Truncate_Address (Ctxt, Addr, Nbr_Els); +         Def := No_Net; +         Synth_Case (Ctxt, Addr, Els.all, Def, Res, Loc); + +         --  4. remove old dyn_extract. +         Remove_Memidx (Memidx_Arr); + +         Free_Case_Element_Array (Els); +      end if; -      --  4. remove old dyn_extract.        Disconnect (Get_Input (Inst, 0));        Redirect_Inputs (Get_Output (Inst, 0), Res);        Remove_Instance (Inst); - -      Remove_Memidx (Memidx_Arr); - -      Free_Case_Element_Array (Els);     end Expand_Dyn_Extract;     procedure Generate_Decoder (Ctxt : Context_Acc; diff --git a/src/synth/netlists-memories.adb b/src/synth/netlists-memories.adb index 2764ec380..ffc3316ba 100644 --- a/src/synth/netlists-memories.adb +++ b/src/synth/netlists-memories.adb @@ -243,6 +243,11 @@ package body Netlists.Memories is                 end if;                 Res := Res + 1;                 N := Get_Input_Net (Inst, 0); +            when Id_Const_X => +               --  For a null wire. +               pragma Assert (Res = 0); +               pragma Assert (Get_Width (N) = 0); +               return 0;              when others =>                 raise Internal_Error;           end case; diff --git a/src/synth/synth-flags.ads b/src/synth/synth-flags.ads index fed17efc1..211c01c1d 100644 --- a/src/synth/synth-flags.ads +++ b/src/synth/synth-flags.ads @@ -51,8 +51,12 @@ package Synth.Flags is     Flag_Debug_Nomemory2 : Boolean := False; +   --  Do not expand dynamic gates.     Flag_Debug_Noexpand : Boolean := False; +   --  Do not transform null net to null X. +   Flag_Debug_Nonull : Boolean := False; +     Flag_Trace_Statements : Boolean := False;     --  Display source of elaborated design. diff --git a/src/synth/synthesis.adb b/src/synth/synthesis.adb index 310a30a59..911b2d5f6 100644 --- a/src/synth/synthesis.adb +++ b/src/synth/synthesis.adb @@ -79,6 +79,10 @@ package body Synthesis is     procedure Instance_Passes (Ctxt : Context_Acc; M : Module) is     begin +      if not Synth.Flags.Flag_Debug_Nonull then +         Netlists.Cleanup.Replace_Null_Inputs (Ctxt, M); +      end if; +        --  Remove unused gates.  This is not only an optimization but also        --  a correctness point: there might be some unsynthesizable gates, like        --  the one created for 'rising_egde (clk) and not rst'. | 
