diff options
Diffstat (limited to 'src/vhdl/vhdl-sem_names.adb')
-rw-r--r-- | src/vhdl/vhdl-sem_names.adb | 465 |
1 files changed, 451 insertions, 14 deletions
diff --git a/src/vhdl/vhdl-sem_names.adb b/src/vhdl/vhdl-sem_names.adb index e6122ea58..daee2e068 100644 --- a/src/vhdl/vhdl-sem_names.adb +++ b/src/vhdl/vhdl-sem_names.adb @@ -1241,6 +1241,87 @@ package body Vhdl.Sem_Names is end if; end Finish_Sem_Signal_Attribute; + procedure Finish_Sem_Quantity_Attribute + (Attr_Name : Iir; Attr : Iir; Params : Iir_Array) + is + Prefix : Iir; + Param : Iir; + begin + Prefix := Get_Prefix (Attr_Name); + Set_Prefix (Attr, Prefix); + Free_Iir (Attr_Name); + + case Get_Kind (Attr) is + when Iir_Kind_Above_Attribute => + pragma Assert (Params'First = 1 and Params'Last = 1); + if Params (1) = Null_Iir then + Error_Msg_Sem (+Attr, "'above requires a parameter"); + else + -- FIXME: AMS-LRM17 16.2.6 + -- Any quantity appearing in the expression shall be denoted by + -- a static name. + Param := Sem_Expression (Params (1), Get_Type (Prefix)); + if Param /= Null_Iir then + Set_Parameter (Attr, Param); + end if; + end if; + when Iir_Kind_Ramp_Attribute + | Iir_Kind_Signal_Slew_Attribute + | Iir_Kind_Quantity_Slew_Attribute => + pragma Assert (Params'First = 1 and Params'Last = 2); + -- AMS-LRM17 16.2.6 + -- S'RAMP [(TRISE [, TFALL])] + -- Parameters: + -- TRISE: a static expression of a floating-point type that + -- evaluates to a nonnegative value. If omitted, it + -- defaults to 0. + -- TFALL: a static expression of a floating-point type that + -- evaluates to a nonnegative value. If omitted, it + -- defaults to the value of TRISE. + -- + -- S'SLEW [(RISING_SLOP [, FALLING_SLOPE])] + -- Parameters: + -- RISING_SLOPE: a static expression of type REAL that + -- evaluates to a positive value. If omitted, it defaults + -- to REAL'HIGH, which is interpreted as an infinite slope. + -- FALLING_SLOPE: a static expression of type REAL that + -- evaluates to a negative value. If omitted, it defaults + -- to the negative of RISING_SLOPE. The value REAL'LOW is + -- interpreted as a negative infinite slope. + -- + -- Q'SLEW [(MAX_RISING_SLOPE [, MAX_FALLING_SLOPE])] + -- Parameters: + -- MAX_RISING_SLOPE: a static expression of type REAL that + -- evaluates to a positive value. If omitted, it defaults + -- to REAL'HIGH, which is interpreted as an infinite slope. + -- MAX_FALLING_SLOPE: a static expression of type REAL that + -- evaluates to a negative value. If omitted, it defaults + -- to the negative of MAX_RISING_SLOPE. The value REAL'LOW + -- is interpreted as a negative infinite slope. + for I in 1 .. 2 loop + Param := Params (I); + exit when Param = Null_Iir; + -- FIXME: type. + Param := Sem_Expression (Param, Real_Type_Definition); + if Param /= Null_Iir then + if Get_Expr_Staticness (Param) < Globally then + Error_Msg_Sem + (+Param, + "parameters of 'ramp must be static expressions"); + end if; + case I is + when 1 => + Set_Parameter (Attr, Param); + when 2 => + Set_Parameter_2 (Attr, Param); + end case; + end if; + end loop; + when others => + Error_Kind ("finish_sem_quantity_attribute", Attr); + end case; + end Finish_Sem_Quantity_Attribute; + function Is_Type_Abstract_Numeric (Atype : Iir) return Boolean is begin case Get_Kind (Atype) is @@ -1647,7 +1728,6 @@ package body Vhdl.Sem_Names is -- and generate). return Finish_Sem_Denoting_Name (Name, Res); when Iir_Kinds_Object_Declaration - | Iir_Kinds_Quantity_Declaration | Iir_Kind_Enumeration_Literal | Iir_Kind_Unit_Declaration | Iir_Kind_Psl_Endpoint_Declaration => @@ -1659,6 +1739,13 @@ package body Vhdl.Sem_Names is Sem_Check_All_Sensitized (Res); Set_Type (Name_Res, Get_Type (Res)); return Name_Res; + when Iir_Kind_Terminal_Declaration + | Iir_Kind_Interface_Terminal_Declaration => + Name_Res := Finish_Sem_Denoting_Name (Name, Res); + Set_Base_Name (Name_Res, Res); + Set_Name_Staticness (Name_Res, Get_Name_Staticness (Res)); + Sem_Check_Pure (Name_Res, Res); + return Name_Res; when Iir_Kind_Attribute_Value => pragma Assert (Get_Kind (Name) = Iir_Kind_Attribute_Name); Prefix := Finish_Sem_Name (Get_Prefix (Name)); @@ -1673,6 +1760,8 @@ package body Vhdl.Sem_Names is return Name; when Iir_Kind_Type_Declaration | Iir_Kind_Subtype_Declaration + | Iir_Kind_Nature_Declaration + | Iir_Kind_Subnature_Declaration | Iir_Kind_Component_Declaration | Iir_Kind_Group_Template_Declaration | Iir_Kind_Group_Declaration @@ -1745,7 +1834,10 @@ package body Vhdl.Sem_Names is Free_Parenthesis_Name (Name, Res); end if; return Res; - when Iir_Kind_Subtype_Attribute => + when Iir_Kind_Subtype_Attribute + | Iir_Kind_Across_Attribute + | Iir_Kind_Through_Attribute + | Iir_Kind_Nature_Reference_Attribute => null; when Iir_Kinds_Signal_Value_Attribute => null; @@ -1756,6 +1848,20 @@ package body Vhdl.Sem_Names is Free_Parenthesis_Name (Name, Res); end if; return Res; + when Iir_Kind_Above_Attribute + | Iir_Kind_Ramp_Attribute + | Iir_Kind_Quantity_Slew_Attribute + | Iir_Kind_Signal_Slew_Attribute => + if Get_Parameter (Res) = Null_Iir then + -- Not finished. Need to emit an error message. + Finish_Sem_Quantity_Attribute (Name, Res, (1 => Null_Iir)); + else + Free_Parenthesis_Name (Name, Res); + end if; + return Res; + when Iir_Kind_Dot_Attribute + | Iir_Kind_Integ_Attribute => + null; when Iir_Kinds_Type_Attribute | Iir_Kind_Base_Attribute => pragma Assert (Get_Kind (Name) = Iir_Kind_Attribute_Name); @@ -1807,7 +1913,12 @@ package body Vhdl.Sem_Names is Finish_Sem_Dereference (Res); Free_Iir (Name); when Iir_Kinds_Signal_Value_Attribute - | Iir_Kind_Subtype_Attribute => + | Iir_Kind_Subtype_Attribute + | Iir_Kind_Through_Attribute + | Iir_Kind_Across_Attribute + | Iir_Kind_Nature_Reference_Attribute + | Iir_Kind_Dot_Attribute + | Iir_Kind_Integ_Attribute => Sem_Name_Free_Result (Name, Res); when others => Error_Kind ("finish_sem_name_1(2)", Res); @@ -2305,7 +2416,47 @@ package body Vhdl.Sem_Names is Set_Named_Entity (Name, Res); end Sem_Selected_Name; - -- If ASSOC_LIST has one element, which is an expression without formal, + -- Extract actuals from ASSOC_CHAIN. Report errors. + procedure Extract_Attribute_Parameters + (Assoc_Chain : Iir; Actuals : out Iir_Array) + is + Assoc : Iir; + begin + pragma Assert (Assoc_Chain /= Null_Iir); + + Assoc := Assoc_Chain; + for I in Actuals'Range loop + if Assoc = Null_Iir then + Actuals (I) := Null_Iir; + else + -- Not 'open' association element ? + if Get_Kind (Assoc) /= Iir_Kind_Association_Element_By_Expression + then + Error_Msg_Sem (+Assoc, "'open' is not an attribute parameter"); + Actuals (Actuals'First) := Null_Iir; + return; + end if; + + -- Not an association (ie no formal) ? + if Get_Formal (Assoc) /= Null_Iir then + Error_Msg_Sem + (+Assoc, "formal not allowed for attribute parameter"); + Actuals (Actuals'First) := Null_Iir; + return; + end if; + + Actuals (I) := Get_Actual (Assoc); + + Assoc := Get_Chain (Assoc); + end if; + end loop; + + if Assoc /= Null_Iir then + Error_Msg_Sem (+Assoc, "too many parameters for the attribute"); + end if; + end Extract_Attribute_Parameters; + + -- If ASSOC_ASSOC has one element, which is an expression without formal, -- return the actual, else return NULL_IIR. function Get_One_Actual (Assoc_Chain : Iir) return Iir is @@ -2786,6 +2937,39 @@ package body Vhdl.Sem_Names is end if; return; + when Iir_Kind_Ramp_Attribute + | Iir_Kind_Quantity_Slew_Attribute + | Iir_Kind_Signal_Slew_Attribute => + declare + Params : Iir_Array (1 .. 2); + begin + -- Try to extract 2 actuals from the name association list. + -- Emit a message in case of error. + Extract_Attribute_Parameters (Assoc_Chain, Params); + + if Params (1) /= Null_Iir then + -- If ok, finish analysis. + Finish_Sem_Quantity_Attribute (Prefix_Name, Prefix, Params); + else + Prefix := Error_Mark; + end if; + -- The meaning of the parenthesis name is the attribute (as + -- the actuals have been moved to the attribute node). + Set_Named_Entity (Name, Prefix); + return; + end; + + when Iir_Kind_Above_Attribute => + if Actual /= Null_Iir then + Finish_Sem_Quantity_Attribute + (Prefix_Name, Prefix, (1 => Actual)); + else + Error_Msg_Sem (+Name, "bad attribute parameter"); + Prefix := Error_Mark; + end if; + Set_Named_Entity (Name, Prefix); + return; + when Iir_Kind_Procedure_Declaration | Iir_Kind_Interface_Procedure_Declaration => Error_Msg_Sem (+Name, "cannot call %n in an expression", @@ -2971,6 +3155,8 @@ package body Vhdl.Sem_Names is when Iir_Kinds_Object_Declaration | Iir_Kind_Type_Declaration | Iir_Kind_Subtype_Declaration + | Iir_Kind_Nature_Declaration + | Iir_Kind_Subnature_Declaration | Iir_Kind_Function_Declaration | Iir_Kind_Procedure_Declaration | Iir_Kind_Enumeration_Literal @@ -3358,6 +3544,85 @@ package body Vhdl.Sem_Names is return Res; end Sem_Subtype_Attribute; + -- For 'Across or 'Through + function Sem_Nature_Type_Attribute (Attr : Iir_Attribute_Name) return Iir + is + Prefix_Name : constant Iir := Get_Prefix (Attr); + Prefix : Iir; + Prefix_Nature : Iir; + Res : Iir; + Attr_Type : Iir; + begin + Prefix := Get_Named_Entity (Prefix_Name); + + -- LRM08 16.2 Predefined attributes + -- Prefix: Any nature or subnature N. + case Get_Kind (Prefix) is + when Iir_Kind_Nature_Declaration + | Iir_Kind_Subnature_Declaration => + null; + when others => + Error_Msg_Sem (+Attr, "prefix must denote a nature"); + return Error_Mark; + end case; + + Prefix_Nature := Get_Nature (Prefix); + + case Get_Identifier (Attr) is + when Std_Names.Name_Across => + Res := Create_Iir (Iir_Kind_Across_Attribute); + Attr_Type := Get_Across_Type (Prefix_Nature); + when Std_Names.Name_Through => + Res := Create_Iir (Iir_Kind_Through_Attribute); + Attr_Type := Get_Across_Type (Prefix_Nature); + when others => + raise Internal_Error; + end case; + pragma Assert (Attr_Type /= Null_Iir); + + Location_Copy (Res, Attr); + Set_Prefix (Res, Prefix); + Set_Type (Res, Attr_Type); + + Set_Base_Name (Res, Get_Base_Name (Prefix_Name)); + Set_Name_Staticness (Res, Get_Name_Staticness (Prefix_Name)); + Set_Type_Staticness (Res, Get_Type_Staticness (Attr_Type)); + + return Res; + end Sem_Nature_Type_Attribute; + + -- For 'Reference + function Sem_Nature_Reference_Attribute (Attr : Iir_Attribute_Name) + return Iir + is + Prefix_Name : constant Iir := Get_Prefix (Attr); + Prefix : Iir; + Res : Iir; + begin + Prefix := Get_Named_Entity (Prefix_Name); + + -- AMS-LRM17 16.2.6 Predefined analog attributes + -- Prefix: Any nature of subnature N. + case Get_Kind (Prefix) is + when Iir_Kind_Nature_Declaration + | Iir_Kind_Subnature_Declaration => + null; + when others => + Error_Msg_Sem (+Attr, "prefix must denote a nature"); + return Error_Mark; + end case; + + Res := Create_Iir (Iir_Kind_Nature_Reference_Attribute); + Location_Copy (Res, Attr); + Set_Prefix (Res, Prefix); + Set_Nature (Res, Get_Nature (Prefix)); + + Set_Base_Name (Res, Get_Base_Name (Prefix_Name)); + Set_Name_Staticness (Res, Get_Name_Staticness (Prefix_Name)); + + return Res; + end Sem_Nature_Reference_Attribute; + function Sem_Signal_Signal_Attribute (Attr : Iir_Attribute_Name; Kind : Iir_Kind) return Iir @@ -3456,6 +3721,9 @@ package body Vhdl.Sem_Names is Res := Create_Iir (Iir_Kind_Driving_Attribute); Set_Type (Res, Boolean_Type_Definition); -- FIXME: check restrictions. + when Name_Ramp => + Res := Create_Iir (Iir_Kind_Ramp_Attribute); + Set_Type (Res, Get_Type (Prefix)); when others => -- Not yet implemented attribute, or really an internal error. raise Internal_Error; @@ -3533,6 +3801,8 @@ package body Vhdl.Sem_Names is Error_Msg_Sem (+Attr, "bad prefix for 'driving or 'driving_value"); end case; + when Iir_Kind_Ramp_Attribute => + null; when others => null; end case; @@ -3686,6 +3956,111 @@ package body Vhdl.Sem_Names is return Res; end Sem_Name_Attribute; + function Sem_Quantity_Attribute (Attr : Iir_Attribute_Name) return Iir + is + use Std_Names; + Prefix_Name : constant Iir := Get_Prefix (Attr); + Prefix: Iir; + Res : Iir; + begin + Prefix := Get_Named_Entity (Prefix_Name); + if not Is_Quantity_Name (Prefix) then + Error_Msg_Sem + (+Attr, "prefix of %i attribute must denote a quantity", +Attr); + return Error_Mark; + end if; + + case Get_Identifier (Attr) is + when Name_Above => + Res := Create_Iir (Iir_Kind_Above_Attribute); + Set_Type (Res, Boolean_Type_Definition); + when Name_Dot => + Res := Create_Iir (Iir_Kind_Dot_Attribute); + Set_Type (Res, Get_Type (Prefix)); + when Name_Integ => + Res := Create_Iir (Iir_Kind_Integ_Attribute); + Set_Type (Res, Get_Type (Prefix)); + when others => + -- Not yet implemented attribute, or really an internal error. + raise Internal_Error; + end case; + + Location_Copy (Res, Attr); + Set_Prefix (Res, Prefix); + + -- AMS-LRM17 16.2.6 Predefined analog an mixed-signal attributes + -- Prefix: Any quantity denoted by the static name Q. + if Get_Name_Staticness (Prefix) < Globally then + Error_Msg_Sem + (+Attr, "prefix of %i attribute must be a static name", +Attr); + end if; + + -- According to LRM 7.4, signal attributes are not static expressions + -- since the prefix (a signal) is not a static expression. + Set_Expr_Staticness (Res, None); + + -- AMS-LRM17 8.1 Names + -- A name is said to be a static name if and only if one of the + -- following conditions holds: + -- [...] + -- - The name is an attribute whose prefix is a static quantity name + -- and whose suffix is one of the predefined attributes 'ABOVE, 'DOT, + -- 'INTEG, 'DELAYED, 'SLEW, 'LTF, 'ZOH, or 'ZTF. + Set_Name_Staticness (Res, Globally); + + return Res; + end Sem_Quantity_Attribute; + + function Sem_Slew_Attribute (Attr : Iir_Attribute_Name) return Iir + is + Prefix_Name : constant Iir := Get_Prefix (Attr); + Prefix: Iir; + Res : Iir; + Res_Type : Iir; + begin + Prefix := Get_Named_Entity (Prefix_Name); + if Is_Quantity_Name (Prefix) then + Res := Create_Iir (Iir_Kind_Quantity_Slew_Attribute); + elsif Is_Signal_Name (Prefix) then + Res := Create_Iir (Iir_Kind_Signal_Slew_Attribute); + else + Error_Msg_Sem + (+Attr, + "prefix of 'slew must denote a quantity or a signal", +Attr); + return Error_Mark; + end if; + + -- AMS-VHDL17 16.2.6 + -- Prefix: Any signal denoted by the static name S whose scalar + -- subelements are of a floating-point type. + -- + -- GHDL: not necessary when the prefix is a quantity. + Res_Type := Get_Type (Prefix); + if not Sem_Types.Is_Nature_Type (Res_Type) then + Error_Msg_Sem (+Attr, "prefix of 'slew must be of nature type"); + end if; + + if Get_Name_Staticness (Prefix) < Globally then + Error_Msg_Sem (+Attr, "prefix of 'slew must be a static name"); + end if; + + Set_Type (Res, Res_Type); + Location_Copy (Res, Attr); + Set_Prefix (Res, Prefix); + Set_Expr_Staticness (Res, None); + + -- AMS-LRM17 8.1 Names + -- A name is said to be a static name if and only if one of the + -- following conditions holds: + -- [...] + -- - The name is an attribute whose prefix is a static quantity name + -- and whose suffix is one of the predefined attributes 'ABOVE, 'DOT, + -- 'INTEG, 'DELAYED, 'SLEW, 'LTF, 'ZOH, or 'ZTF. + Set_Name_Staticness (Res, Globally); + + return Res; + end Sem_Slew_Attribute; + procedure Sem_Attribute_Name (Attr : Iir_Attribute_Name) is use Std_Names; @@ -3818,6 +4193,44 @@ package body Vhdl.Sem_Names is Res := Sem_User_Attribute (Attr); end if; + when Name_Across + | Name_Through => + if Flags.AMS_Vhdl then + Res := Sem_Nature_Type_Attribute (Attr); + else + Res := Sem_User_Attribute (Attr); + end if; + + when Name_Reference => + if Flags.AMS_Vhdl then + Res := Sem_Nature_Reference_Attribute (Attr); + else + Res := Sem_User_Attribute (Attr); + end if; + + when Name_Above + | Name_Dot + | Name_Integ => + if Flags.AMS_Vhdl then + Res := Sem_Quantity_Attribute (Attr); + else + Res := Sem_User_Attribute (Attr); + end if; + + when Name_Ramp => + if Flags.AMS_Vhdl then + Res := Sem_Signal_Attribute (Attr); + else + Res := Sem_User_Attribute (Attr); + end if; + + when Name_Slew => + if Flags.AMS_Vhdl then + Res := Sem_Slew_Attribute (Attr); + else + Res := Sem_User_Attribute (Attr); + end if; + when others => Res := Sem_User_Attribute (Attr); end case; @@ -4182,7 +4595,13 @@ package body Vhdl.Sem_Names is -- FIXME: exclude range and reverse_range. return Eval_Expr_If_Static (Res); when Iir_Kinds_Signal_Attribute - | Iir_Kinds_Signal_Value_Attribute => + | Iir_Kinds_Signal_Value_Attribute + | Iir_Kind_Above_Attribute + | Iir_Kind_Dot_Attribute + | Iir_Kind_Integ_Attribute + | Iir_Kind_Ramp_Attribute + | Iir_Kind_Signal_Slew_Attribute + | Iir_Kind_Quantity_Slew_Attribute => -- Never static return Res; when Iir_Kinds_Type_Attribute @@ -4262,7 +4681,9 @@ package body Vhdl.Sem_Names is end case; when Iir_Kind_Subtype_Attribute | Iir_Kind_Element_Attribute - | Iir_Kind_Base_Attribute => + | Iir_Kind_Base_Attribute + | Iir_Kind_Across_Attribute + | Iir_Kind_Through_Attribute => return Get_Type (Name); when Iir_Kinds_Expression_Attribute => Error_Msg_Sem (+Name, "%n is not a valid type mark", +Name); @@ -4297,12 +4718,15 @@ package body Vhdl.Sem_Names is | Iir_Kinds_Sequential_Statement | Iir_Kind_Type_Declaration | Iir_Kind_Subtype_Declaration + | Iir_Kind_Nature_Declaration + | Iir_Kind_Subnature_Declaration | Iir_Kind_Enumeration_Literal | Iir_Kind_Unit_Declaration | Iir_Kind_Group_Template_Declaration | Iir_Kind_Group_Declaration | Iir_Kind_Attribute_Declaration | Iir_Kinds_Object_Declaration + | Iir_Kind_Terminal_Declaration | Iir_Kind_Entity_Declaration | Iir_Kind_Configuration_Declaration | Iir_Kind_Package_Declaration @@ -4355,15 +4779,28 @@ package body Vhdl.Sem_Names is function Sem_Terminal_Name (Name : Iir) return Iir is Res : Iir; - Ent : Iir; begin - Res := Sem_Denoting_Name (Name); - Ent := Get_Named_Entity (Res); - if Get_Kind (Ent) /= Iir_Kind_Terminal_Declaration then - Error_Class_Match (Name, "terminal"); - Set_Named_Entity (Res, Create_Error_Name (Name)); - end if; - return Res; + Sem_Name (Name); + Res := Get_Named_Entity (Name); + + case Get_Kind (Res) is + when Iir_Kind_Error => + -- A message must have been displayed. + return Name; + when Iir_Kind_Overload_List => + Error_Overload (Res); + Set_Named_Entity (Name, Create_Error_Name (Name)); + return Name; + when Iir_Kind_Terminal_Declaration + | Iir_Kind_Interface_Terminal_Declaration + | Iir_Kind_Nature_Reference_Attribute => + Res := Finish_Sem_Name (Name, Res); + return Res; + when others => + Error_Class_Match (Name, "terminal"); + Set_Named_Entity (Name, Create_Error_Name (Name)); + return Name; + end case; end Sem_Terminal_Name; procedure Error_Class_Match (Name : Iir; Class_Name : String) |