aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorTristan Gingold <tgingold@free.fr>2020-04-22 08:15:48 +0200
committerTristan Gingold <tgingold@free.fr>2020-04-22 08:15:48 +0200
commit4bb12b30a53326ac6e3177bc4016317181dd7f7e (patch)
tree17071b82d97c10af35e50a9c6239b189fd8f511a /src
parent7dcc937f7269ea972b890084419512b0d40785e0 (diff)
downloadghdl-4bb12b30a53326ac6e3177bc4016317181dd7f7e.tar.gz
ghdl-4bb12b30a53326ac6e3177bc4016317181dd7f7e.tar.bz2
ghdl-4bb12b30a53326ac6e3177bc4016317181dd7f7e.zip
netlists: infere tri gate.
Diffstat (limited to 'src')
-rw-r--r--src/synth/netlists-inference.adb26
-rw-r--r--src/synth/netlists-utils.adb14
-rw-r--r--src/synth/netlists-utils.ads4
3 files changed, 44 insertions, 0 deletions
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.