From 72a54333ba9f47e4d7126ef1d4c92d497b4dc22a Mon Sep 17 00:00:00 2001 From: Tristan Gingold Date: Thu, 20 Apr 2023 07:54:00 +0200 Subject: synth-vhdl_expr: improve support of external names. --- src/synth/synth-vhdl_expr.adb | 182 ++++++++++++++++++++++++++++-------------- 1 file changed, 120 insertions(+), 62 deletions(-) diff --git a/src/synth/synth-vhdl_expr.adb b/src/synth/synth-vhdl_expr.adb index c73b2133e..65e0a9d27 100644 --- a/src/synth/synth-vhdl_expr.adb +++ b/src/synth/synth-vhdl_expr.adb @@ -831,71 +831,136 @@ package body Synth.Vhdl_Expr is end case; end Synth_Subtype_Conversion; + function Synth_Pathname_Object (Loc_Inst : Synth_Instance_Acc; + Name : Node; + Cur_Inst : Synth_Instance_Acc; + Path : Node) return Valtyp + is + Id : constant Name_Id := Get_Identifier (Path); + Scope : constant Node := Get_Source_Scope (Cur_Inst); + Obj : Node; + Res : Valtyp; + begin + -- Object simple name. + case Get_Kind (Scope) is + when Iir_Kind_Architecture_Body => + Obj := Find_Name_In_Chain (Get_Declaration_Chain (Scope), Id); + when others => + Error_Kind ("synth_pathname_object(1)", Scope); + end case; + + -- LRM08 8.7 External names + -- It is an error when evaluating an external name if the identified + -- declarative region does not contain a declaration of an object + -- whose simple name is the object simple name of the external + -- pathname. + if Obj = Null_Node then + Error_Msg_Synth + (Loc_Inst, Path, "cannot find object %i in %i", (+Id, +Scope)); + return No_Valtyp; + end if; + + -- LRM08 8.7 External names + -- It is also an error when evaluating an external name if the object + -- denoted by an external constant name is not a constant, or if the + -- object denoted by an external signal name is not a signal, or if + -- the object denoted by an external variable name is not a variable. + case Get_Kind (Obj) is + when Iir_Kind_Signal_Declaration => + case Iir_Kinds_External_Name (Get_Kind (Name)) is + when Iir_Kind_External_Signal_Name => + Res := Get_Value (Cur_Inst, Obj); + when Iir_Kind_External_Constant_Name + | Iir_Kind_External_Variable_Name => + Error_Msg_Synth + (Loc_Inst, Path, "object name %i is a signal", +Obj); + return No_Valtyp; + end case; + when others => + Error_Kind ("synth_pathname_object(2)", Obj); + end case; + + -- LRM08 8.7 External names + -- Moreover, it is an error if the base type of the object denoted by + -- an external name is not the same as the base type mark in the + -- subtype indication of the external name. + declare + Obj_Type : constant Node := Get_Type (Obj); + Name_Type : constant Node := Get_Type (Name); + begin + if Get_Base_Type (Obj_Type) /= Get_Base_Type (Name_Type) then + Error_Msg_Synth + (Loc_Inst, Path, "external name and object have different type"); + return No_Valtyp; + end if; + end; + + -- LRM08 8.7 External names + -- If the subtype indication denotes a composite subtype, then the + -- object denoted by the external name is viewed as if it were of the + -- subtype specified by the subtype indication. For each index range, + -- if any, in the subtype, if the subtype defines the index range, the + -- object is viewed with that index range; otherwise, the object + -- is viewed with the index range of the object. The view specified + -- by the subtype shall include a matching element (see 9.2.3) for + -- each element of the object denoted by the external name. + -- + -- If the subtype indication denotes a scalar subtype, then the object + -- denoted by the external name is viewed as if it were of the subtype + -- specified by the subtype indication; moreover, it is a error when + -- evaluating the external name if this subtype does not have the same + -- bounds and direction as the subtype of the object denoted by the + -- external name. + + -- TODO. + + return Res; + end Synth_Pathname_Object; + function Synth_Pathname (Loc_Inst : Synth_Instance_Acc; Name : Node; Cur_Inst : Synth_Instance_Acc; Path : Node) return Valtyp is Suffix : constant Node := Get_Pathname_Suffix (Path); - Id : constant Name_Id := Get_Identifier (Path); - Scope : constant Node := Get_Source_Scope (Cur_Inst); + Id : Name_Id; + Scope : Node; Res : Node; begin if Suffix = Null_Node then -- Object simple name. - case Get_Kind (Scope) is - when Iir_Kind_Architecture_Body => - Res := Find_Name_In_Chain (Get_Declaration_Chain (Scope), Id); - when others => - Error_Kind ("synth_pathname(obj)", Scope); - end case; - if Res = Null_Node then - Error_Msg_Synth - (Loc_Inst, Path, "cannot find object %i in %i", (+Id, +Scope)); - return No_Valtyp; - end if; - case Get_Kind (Res) is - when Iir_Kind_Signal_Declaration => - case Iir_Kinds_External_Name (Get_Kind (Name)) is - when Iir_Kind_External_Signal_Name => - return Get_Value (Cur_Inst, Res); - when Iir_Kind_External_Constant_Name - | Iir_Kind_External_Variable_Name => - Error_Msg_Synth - (Loc_Inst, Path, "object name %i is a signal", +Res); - return No_Valtyp; - end case; - when others => - Error_Kind ("synth_pathname(1)", Res); - end case; - else - -- Find name in concurrent statements. - case Get_Kind (Scope) is - when Iir_Kind_Architecture_Body => - Res := Find_Name_In_Chain - (Get_Concurrent_Statement_Chain (Scope), Id); - when others => - Error_Kind ("synth_pathname(scope)", Scope); - end case; - if Res = Null_Node then - Error_Msg_Synth - (Loc_Inst, Path, - "cannot find path element %i in %i", (+Id, +Scope)); - return No_Valtyp; - end if; - case Get_Kind (Res) is - when Iir_Kind_Component_Instantiation_Statement => - if Is_Entity_Instantiation (Res) then - return Synth_Pathname - (Loc_Inst, Name, Get_Sub_Instance (Cur_Inst, Res), Suffix); - else - -- TODO: skip component. - raise Internal_Error; - end if; - when others => - Error_Kind ("synth_pathname(2)", Res); - end case; + return Synth_Pathname_Object (Loc_Inst, Name, Cur_Inst, Path); + end if; + + Id := Get_Identifier (Path); + Scope := Get_Source_Scope (Cur_Inst); + + -- Find name in concurrent statements. + case Get_Kind (Scope) is + when Iir_Kind_Architecture_Body => + Res := Find_Name_In_Chain + (Get_Concurrent_Statement_Chain (Scope), Id); + when others => + Error_Kind ("synth_pathname(scope)", Scope); + end case; + if Res = Null_Node then + Error_Msg_Synth + (Loc_Inst, Path, + "cannot find path element %i in %i", (+Id, +Scope)); + return No_Valtyp; end if; + case Get_Kind (Res) is + when Iir_Kind_Component_Instantiation_Statement => + if Is_Entity_Instantiation (Res) then + return Synth_Pathname + (Loc_Inst, Name, Get_Sub_Instance (Cur_Inst, Res), Suffix); + else + -- TODO: skip component. + raise Internal_Error; + end if; + when others => + Error_Kind ("synth_pathname(2)", Res); + end case; end Synth_Pathname; function Synth_Absolute_Pathname @@ -922,21 +987,14 @@ package body Synth.Vhdl_Expr is return Valtyp is Path : Node; - Res : Valtyp; begin Path := Get_External_Pathname (Name); case Get_Kind (Path) is when Iir_Kind_Absolute_Pathname => - Res := Synth_Absolute_Pathname (Syn_Inst, Name, Path); + return Synth_Absolute_Pathname (Syn_Inst, Name, Path); when others => Error_Kind ("synth_external_name", Path); end case; - if Res = No_Valtyp then - return No_Valtyp; - end if; - - -- TODO: type. - return Res; end Synth_External_Name; function Synth_Name (Syn_Inst : Synth_Instance_Acc; Name : Node) -- cgit v1.2.3