aboutsummaryrefslogtreecommitdiffstats
path: root/src/synth/synth-inference.adb
diff options
context:
space:
mode:
authorTristan Gingold <tgingold@free.fr>2019-10-06 08:46:30 +0200
committerTristan Gingold <tgingold@free.fr>2019-10-06 08:46:30 +0200
commit00f8dd9107cef97100a409731e1d09903c98d24d (patch)
tree0c166a1d32836717afb1a8383c2b9dc978f01905 /src/synth/synth-inference.adb
parentd444e0db133898308795ffbf8081330e6a33ed4f (diff)
downloadghdl-00f8dd9107cef97100a409731e1d09903c98d24d.tar.gz
ghdl-00f8dd9107cef97100a409731e1d09903c98d24d.tar.bz2
ghdl-00f8dd9107cef97100a409731e1d09903c98d24d.zip
synth: add error messages for latches.
Diffstat (limited to 'src/synth/synth-inference.adb')
-rw-r--r--src/synth/synth-inference.adb40
1 files changed, 37 insertions, 3 deletions
diff --git a/src/synth/synth-inference.adb b/src/synth/synth-inference.adb
index df60f0148..94d1734ec 100644
--- a/src/synth/synth-inference.adb
+++ b/src/synth/synth-inference.adb
@@ -24,8 +24,11 @@ with Netlists.Utils; use Netlists.Utils;
with Netlists.Gates; use Netlists.Gates;
with Netlists.Gates_Ports; use Netlists.Gates_Ports;
with Netlists.Locations; use Netlists.Locations;
+with Netlists.Errors; use Netlists.Errors;
with Synth.Flags;
+with Synth.Source; use Synth.Source;
+with Synth.Errors; use Synth.Errors;
package body Synth.Inference is
-- DFF inference.
@@ -451,9 +454,15 @@ package body Synth.Inference is
return Res;
end Is_False_Loop;
- procedure Infere_Latch (Ctxt : Context_Acc; Val : Net; Prev_Val : Net)
+ procedure Infere_Latch (Ctxt : Context_Acc;
+ Wid : Wire_Id;
+ Val : Net;
+ Off : Uns32;
+ Prev_Val : Net;
+ Stmt : Source.Syn_Src)
is
X : Net;
+ Name : Sname;
begin
-- In case of false loop, do not close the loop but assign X.
if Is_False_Loop (Prev_Val) then
@@ -463,7 +472,32 @@ package body Synth.Inference is
end if;
-- Latch or combinational loop.
- raise Internal_Error;
+ if Get_Id (Get_Parent (Prev_Val)) = Id_Output then
+ -- Outputs are connected to a port. The port is the first connection
+ -- made, so it is the last sink. Be more tolerant and look for
+ -- the (only) port connected to the output.
+ declare
+ Inp : Input;
+ Inst : Instance;
+ begin
+ Inp := Get_First_Sink (Prev_Val);
+ loop
+ pragma Assert (Inp /= No_Input);
+ Inst := Get_Input_Parent (Inp);
+ if Get_Id (Inst) >= Id_User_None then
+ Name := Get_Output_Desc (Get_Module (Inst),
+ Get_Port_Idx (Inp)).Name;
+ exit;
+ end if;
+ Inp := Get_Next_Sink (Inp);
+ end loop;
+ end;
+ else
+ Name := Get_Name (Get_Net_Parent (Prev_Val));
+ end if;
+ Error_Msg_Synth (+Stmt, "latch infered for net %n", +Name);
+
+ Add_Conc_Assign (Wid, Val, Off, Stmt);
end Infere_Latch;
procedure Infere (Ctxt : Context_Acc;
@@ -501,7 +535,7 @@ package body Synth.Inference is
Extract_Clock (Get_Driver (Sel), Clk, Enable);
if Clk = No_Net then
-- No clock -> latch or combinational loop
- Infere_Latch (Ctxt, Val, Prev_Val);
+ Infere_Latch (Ctxt, Wid, Val, Off, Prev_Val, Stmt);
else
-- Clock -> FF
Infere_FF (Ctxt, Wid, Prev_Val, Off, Last_Mux, Clk, Enable, Stmt);