aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorTristan Gingold <tgingold@free.fr>2022-06-27 19:28:01 +0200
committerTristan Gingold <tgingold@free.fr>2022-06-27 19:37:33 +0200
commita036958a9adc31011729aab02af9eec48f80bc8a (patch)
tree2534000aaa570fde4d0359cf0c969f0d8a7a44cd /src
parent060840d4176d7e5b775616e8a702bd751765c753 (diff)
downloadghdl-a036958a9adc31011729aab02af9eec48f80bc8a.tar.gz
ghdl-a036958a9adc31011729aab02af9eec48f80bc8a.tar.bz2
ghdl-a036958a9adc31011729aab02af9eec48f80bc8a.zip
synth: rework #2109 - remove null wires
Diffstat (limited to 'src')
-rw-r--r--src/ghdldrv/ghdlsynth.adb2
-rw-r--r--src/synth/netlists-cleanup.adb27
-rw-r--r--src/synth/netlists-cleanup.ads6
-rw-r--r--src/synth/netlists-disp_verilog.adb3
-rw-r--r--src/synth/netlists-expands.adb62
-rw-r--r--src/synth/netlists-memories.adb5
-rw-r--r--src/synth/synth-flags.ads4
-rw-r--r--src/synth/synthesis.adb4
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'.