aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorTristan Gingold <tgingold@free.fr>2020-08-06 07:54:40 +0200
committerTristan Gingold <tgingold@free.fr>2020-08-06 07:54:40 +0200
commit959f80c052665d07a28e1b1b20e89d6e12d0ced4 (patch)
tree88eefde6ca7df8c1bb49f289af391d5e113f79ce /src
parenta0d2fd3cab9360d58cf24474f85c73ca3fd31bdc (diff)
downloadghdl-959f80c052665d07a28e1b1b20e89d6e12d0ced4.tar.gz
ghdl-959f80c052665d07a28e1b1b20e89d6e12d0ced4.tar.bz2
ghdl-959f80c052665d07a28e1b1b20e89d6e12d0ced4.zip
synth: push extract on mux2 for inference. For #1421
Diffstat (limited to 'src')
-rw-r--r--src/synth/netlists-folds.adb28
-rw-r--r--src/synth/netlists-folds.ads6
-rw-r--r--src/synth/synth-environment.adb35
3 files changed, 52 insertions, 17 deletions
diff --git a/src/synth/netlists-folds.adb b/src/synth/netlists-folds.adb
index c4138d0cd..411415901 100644
--- a/src/synth/netlists-folds.adb
+++ b/src/synth/netlists-folds.adb
@@ -270,6 +270,34 @@ package body Netlists.Folds is
end if;
end Build2_Extract;
+ function Build2_Extract_Push
+ (Ctxt : Context_Acc; I : Net; Off, W : Width) return Net
+ is
+ Inst : constant Instance := Get_Net_Parent (I);
+ Res : Net;
+ begin
+ if Off = 0 and then W = Get_Width (I) then
+ return I;
+ end if;
+
+ case Get_Id (Inst) is
+ when Id_Extract =>
+ return Build2_Extract_Push
+ (Ctxt, Get_Input_Net (Inst, 0),
+ Off + Get_Param_Uns32 (Inst, 0), W);
+ when Id_Mux2 =>
+ Res := Build_Mux2
+ (Ctxt,
+ Get_Input_Net (Inst, 0),
+ Build2_Extract_Push (Ctxt, Get_Input_Net (Inst, 1), Off, W),
+ Build2_Extract_Push (Ctxt, Get_Input_Net (Inst, 2), Off, W));
+ Set_Location (Res, Get_Location (Inst));
+ return Res;
+ when others =>
+ return Build_Extract (Ctxt, I, Off, W);
+ end case;
+ end Build2_Extract_Push;
+
function Build2_Imp (Ctxt : Context_Acc; A, B : Net; Loc : Location_Type)
return Net
is
diff --git a/src/synth/netlists-folds.ads b/src/synth/netlists-folds.ads
index 6c63f49bc..3ee69f41c 100644
--- a/src/synth/netlists-folds.ads
+++ b/src/synth/netlists-folds.ads
@@ -71,6 +71,12 @@ package Netlists.Folds is
function Build2_Extract
(Ctxt : Context_Acc; I : Net; Off, W : Width) return Net;
+ -- Likewise, but if I is an output of a mux2, build the extract gates
+ -- on the input of the mux2 (recursively).
+ -- The purpose is to keep the control flow of the mux2 tree.
+ function Build2_Extract_Push
+ (Ctxt : Context_Acc; I : Net; Off, W : Width) return Net;
+
-- Return A -> B == !A || B
function Build2_Imp (Ctxt : Context_Acc; A, B : Net; Loc : Location_Type)
return Net;
diff --git a/src/synth/synth-environment.adb b/src/synth/synth-environment.adb
index 18133594e..7f552f352 100644
--- a/src/synth/synth-environment.adb
+++ b/src/synth/synth-environment.adb
@@ -1036,7 +1036,7 @@ package body Synth.Environment is
-- If no seq assign, return current value.
if First_Seq = No_Seq_Assign then
- return Build2_Extract (Ctxt, Wire_Rec.Gate, Off, Wd);
+ return Build2_Extract_Push (Ctxt, Wire_Rec.Gate, Off, Wd);
end if;
-- If the current value is static, just return it.
@@ -1096,8 +1096,9 @@ package body Synth.Environment is
Cur_Wd := Width'Min
(Cur_Wd, Pw - (Cur_Off - Pr.Offset));
Append
- (Vec, Build_Extract (Ctxt, Pr.Value,
- Cur_Off - Pr.Offset, Cur_Wd));
+ (Vec,
+ Build2_Extract_Push (Ctxt, Pr.Value,
+ Cur_Off - Pr.Offset, Cur_Wd));
end if;
exit;
end if;
@@ -1122,8 +1123,8 @@ package body Synth.Environment is
Seq := Get_Assign_Prev (Seq);
if Seq = No_Seq_Assign then
-- Extract from gate.
- Append (Vec, Build_Extract (Ctxt, Wire_Rec.Gate,
- Cur_Off, Cur_Wd));
+ Append (Vec, Build2_Extract_Push (Ctxt, Wire_Rec.Gate,
+ Cur_Off, Cur_Wd));
exit;
end if;
if Get_Assign_Is_Static (Seq) then
@@ -1702,9 +1703,9 @@ package body Synth.Environment is
-- |----------||
-- P.Off P.Next
-- Shrink EL.
- P.Value := Build_Extract (Ctxt, P.Value,
- Off => V_Next - P.Offset,
- W => P_Next - V_Next);
+ P.Value := Build2_Extract_Push (Ctxt, P.Value,
+ Off => V_Next - P.Offset,
+ W => P_Next - V_Next);
P.Offset := V_Next;
if not Inserted then
if Last_El /= No_Partial_Assign then
@@ -1724,9 +1725,9 @@ package body Synth.Environment is
-- |----------||
-- P.Off P.Next
-- Shrink EL.
- P.Value := Build_Extract (Ctxt, P.Value,
- Off => 0,
- W => V.Offset - P.Offset);
+ P.Value := Build2_Extract_Push (Ctxt, P.Value,
+ Off => 0,
+ W => V.Offset - P.Offset);
pragma Assert (not Inserted);
V.Next := P.Next;
P.Next := Asgn;
@@ -1742,14 +1743,14 @@ package body Synth.Environment is
pragma Assert (not Inserted);
Partial_Assign_Table.Append
((Next => P.Next,
- Value => Build_Extract (Ctxt, P.Value,
- Off => V_Next - P.Offset,
- W => P_Next - V_Next),
+ Value => Build2_Extract_Push (Ctxt, P.Value,
+ Off => V_Next - P.Offset,
+ W => P_Next - V_Next),
Offset => V_Next));
V.Next := Partial_Assign_Table.Last;
- P.Value := Build_Extract (Ctxt, P.Value,
- Off => 0,
- W => V.Offset - P.Offset);
+ P.Value := Build2_Extract_Push (Ctxt, P.Value,
+ Off => 0,
+ W => V.Offset - P.Offset);
P.Next := Asgn;
Inserted := True;
-- No more possible overlaps.