From 00f8dd9107cef97100a409731e1d09903c98d24d Mon Sep 17 00:00:00 2001 From: Tristan Gingold Date: Sun, 6 Oct 2019 08:46:30 +0200 Subject: synth: add error messages for latches. --- src/synth/netlists-errors.adb | 121 ++++++++++++++++++++++++++++++++++++++++ src/synth/netlists-errors.ads | 29 ++++++++++ src/synth/synth-environment.adb | 1 - src/synth/synth-inference.adb | 40 ++++++++++++- src/synth/synth-source.ads | 11 +++- src/synth/synthesis.adb | 2 + 6 files changed, 198 insertions(+), 6 deletions(-) create mode 100644 src/synth/netlists-errors.adb create mode 100644 src/synth/netlists-errors.ads (limited to 'src') diff --git a/src/synth/netlists-errors.adb b/src/synth/netlists-errors.adb new file mode 100644 index 000000000..880ae1418 --- /dev/null +++ b/src/synth/netlists-errors.adb @@ -0,0 +1,121 @@ +-- Error handling for synthesis. +-- Copyright (C) 2017 Tristan Gingold +-- +-- This file is part of GHDL. +-- +-- This program is free software; you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation; either version 2 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program; if not, write to the Free Software +-- Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, +-- MA 02110-1301, USA. + +package body Netlists.Errors is + function "+" (N : Instance) return Earg_Type is + begin + return Make_Earg_Synth_Instance (Uns32 (N)); + end "+"; + + function "+" (N : Net) return Earg_Type is + begin + return Make_Earg_Synth_Net (Uns32 (N)); + end "+"; + + function "+" (N : Sname) return Earg_Type is + begin + return Make_Earg_Synth_Name (Uns32 (N)); + end "+"; + + procedure Output_Name_1 (N : Sname) + is + Prefix : Sname; + begin + -- Do not crash on No_Name. + if N = No_Sname then + Output_Message ("*nil*"); + return; + end if; + + Prefix := Get_Sname_Prefix (N); + if Prefix /= No_Sname then + Output_Name_1 (Prefix); + Output_Message ("."); + end if; + + case Get_Sname_Kind (N) is + when Sname_User => + Output_Identifier (Get_Sname_Suffix (N)); + when Sname_Artificial => + Output_Identifier (Get_Sname_Suffix (N)); + when Sname_Version => + Output_Message ("n"); + Output_Uns32 (Get_Sname_Version (N)); + end case; + end Output_Name_1; + + procedure Synth_Instance_Handler + (Format : Character; Err : Error_Record; Val : Uns32) + is + pragma Unreferenced (Err); + Inst : constant Instance := Instance (Val); + begin + if Format = 'n' then + Output_Name_1 (Get_Name (Inst)); + else + raise Internal_Error; + end if; + end Synth_Instance_Handler; + + procedure Synth_Net_Handler + (Format : Character; Err : Error_Record; Val : Uns32) + is + pragma Unreferenced (Err); + N : constant Net := Net (Val); + begin + if Format = 'n' then + declare + Inst : constant Instance := Get_Net_Parent (N); + Idx : constant Port_Idx := Get_Port_Idx (N); + begin + if Is_Self_Instance (Inst) then + Output_Name_1 (Get_Input_Desc (Get_Module (Inst), Idx).Name); + else + Output_Name_1 (Get_Output_Desc (Get_Module (Inst), Idx).Name); + end if; + end; + else + raise Internal_Error; + end if; + end Synth_Net_Handler; + + procedure Synth_Name_Handler + (Format : Character; Err : Error_Record; Val : Uns32) + is + pragma Unreferenced (Err); + N : constant Sname := Sname (Val); + begin + if Format = 'n' then + Output_Name_1 (N); + else + raise Internal_Error; + end if; + end Synth_Name_Handler; + + procedure Initialize is + begin + Register_Earg_Handler + (Earg_Synth_Instance, Synth_Instance_Handler'Access); + Register_Earg_Handler + (Earg_Synth_Net, Synth_Net_Handler'Access); + Register_Earg_Handler + (Earg_Synth_Name, Synth_Name_Handler'Access); + end Initialize; +end Netlists.Errors; diff --git a/src/synth/netlists-errors.ads b/src/synth/netlists-errors.ads new file mode 100644 index 000000000..d51504393 --- /dev/null +++ b/src/synth/netlists-errors.ads @@ -0,0 +1,29 @@ +-- Error handling for synthesis. +-- Copyright (C) 2017 Tristan Gingold +-- +-- This file is part of GHDL. +-- +-- This program is free software; you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation; either version 2 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program; if not, write to the Free Software +-- Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, +-- MA 02110-1301, USA. + +with Errorout; use Errorout; + +package Netlists.Errors is + function "+" (N : Instance) return Earg_Type; + function "+" (N : Net) return Earg_Type; + function "+" (N : Sname) return Earg_Type; + + procedure Initialize; +end Netlists.Errors; diff --git a/src/synth/synth-environment.adb b/src/synth/synth-environment.adb index d769a959c..20b3441cd 100644 --- a/src/synth/synth-environment.adb +++ b/src/synth/synth-environment.adb @@ -30,7 +30,6 @@ with Synth.Errors; use Synth.Errors; with Synth.Source; use Synth.Source; with Vhdl.Nodes; -with Vhdl.Errors; use Vhdl.Errors; package body Synth.Environment is procedure Phi_Assign 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); diff --git a/src/synth/synth-source.ads b/src/synth/synth-source.ads index 1a2db0209..ed640463d 100644 --- a/src/synth/synth-source.ads +++ b/src/synth/synth-source.ads @@ -18,13 +18,20 @@ -- Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, -- MA 02110-1301, USA. +with Types; use Types; +with Errorout; + with Netlists; with Vhdl.Nodes; use Vhdl.Nodes; +with Vhdl.Errors; package Synth.Source is - subtype Syn_Src is Iir; - No_Syn_Src : constant Syn_Src := Null_Iir; + subtype Syn_Src is Node; + No_Syn_Src : constant Syn_Src := Null_Node; + + function "+" (N : Node) return Location_Type renames Vhdl.Errors."+"; + function "+" (N : Node) return Errorout.Earg_Type renames Vhdl.Errors."+"; procedure Set_Location (N : Netlists.Net; Src : Syn_Src); pragma Inline (Set_Location); diff --git a/src/synth/synthesis.adb b/src/synth/synthesis.adb index 5d41ad70f..d5dcf61fd 100644 --- a/src/synth/synthesis.adb +++ b/src/synth/synthesis.adb @@ -20,6 +20,7 @@ with Vhdl.Utils; use Vhdl.Utils; +with Netlists.Errors; with Synth.Values; use Synth.Values; with Synth.Decls; use Synth.Decls; with Synth.Insts; use Synth.Insts; @@ -127,6 +128,7 @@ package body Synthesis is Top_Instance := Make_Base_Instance; + Netlists.Errors.Initialize; Synth.Values.Init; Synth.Insts.Init; -- cgit v1.2.3