diff options
author | gingold <gingold@b72b5c32-5f01-0410-b925-b5c7b92870f7> | 2006-10-02 04:33:36 +0000 |
---|---|---|
committer | gingold <gingold@b72b5c32-5f01-0410-b925-b5c7b92870f7> | 2006-10-02 04:33:36 +0000 |
commit | a81f695b15865268fea6ee062a381ba8e43a02b4 (patch) | |
tree | 8bc86734eda054c31b705ceab4f4762e96422750 /translate/translation.adb | |
parent | f51d97cdfbb61a3c1b0456b32b5076d03ba5f8ac (diff) | |
download | ghdl-a81f695b15865268fea6ee062a381ba8e43a02b4.tar.gz ghdl-a81f695b15865268fea6ee062a381ba8e43a02b4.tar.bz2 ghdl-a81f695b15865268fea6ee062a381ba8e43a02b4.zip |
direct drivers and bugs fix
Diffstat (limited to 'translate/translation.adb')
-rw-r--r-- | translate/translation.adb | 1210 |
1 files changed, 913 insertions, 297 deletions
diff --git a/translate/translation.adb b/translate/translation.adb index b1ed78788..90f961f0a 100644 --- a/translate/translation.adb +++ b/translate/translation.adb @@ -40,6 +40,7 @@ with Nodes; with GNAT.Table; with Canon; with Trans_Decls; use Trans_Decls; +with Trans_Analyzes; package body Translation is @@ -132,13 +133,16 @@ package body Translation is -- Signals. Ghdl_Scalar_Bytes : O_Tnode; Ghdl_Signal_Type : O_Tnode; - Ghdl_Signal_Value_Node : O_Fnode; - Ghdl_Signal_Driving_Value_Node : O_Fnode; - Ghdl_Signal_Last_Value_Node : O_Fnode; - Ghdl_Signal_Last_Event_Node : O_Fnode; - Ghdl_Signal_Last_Active_Node : O_Fnode; - Ghdl_Signal_Event_Node : O_Fnode; - Ghdl_Signal_Active_Node : O_Fnode; + Ghdl_Signal_Value_Field : O_Fnode; + Ghdl_Signal_Driving_Value_Field : O_Fnode; + Ghdl_Signal_Last_Value_Field : O_Fnode; + Ghdl_Signal_Last_Event_Field : O_Fnode; + Ghdl_Signal_Last_Active_Field : O_Fnode; + Ghdl_Signal_Active_Chain_Field : O_Fnode; + Ghdl_Signal_Event_Field : O_Fnode; + Ghdl_Signal_Active_Field : O_Fnode; + Ghdl_Signal_Has_Active_Field : O_Fnode; + Ghdl_Signal_Ptr : O_Tnode; Ghdl_Signal_Ptr_Ptr : O_Tnode; @@ -286,10 +290,10 @@ package body Translation is type Var_Ident_Type is private; --function Create_Var_Identifier (Id : Name_Id; Str : String) -- return Var_Ident_Type; - function Create_Var_Identifier (Id : Iir) - return Var_Ident_Type; - function Create_Var_Identifier (Id : String) - return Var_Ident_Type; + function Create_Var_Identifier (Id : Iir) return Var_Ident_Type; + function Create_Var_Identifier (Id : String) return Var_Ident_Type; + function Create_Var_Identifier (Id : Iir; Str : String; Val : Natural) + return Var_Ident_Type; function Create_Uniq_Identifier return Var_Ident_Type; type Var_Type (<>) is limited private; @@ -1033,6 +1037,13 @@ package body Translation is Record_Ptr_Type : O_Tnode; end record; + type Direct_Driver_Type is record + Sig : Iir; + Var : Var_Acc; + end record; + type Direct_Driver_Arr is array (Natural range <>) of Direct_Driver_Type; + type Direct_Drivers_Acc is access Direct_Driver_Arr; + type Ortho_Info_Type; type Ortho_Info_Acc is access Ortho_Info_Type; @@ -1117,6 +1128,8 @@ package body Translation is Object_Static : Boolean; -- The object itself. Object_Var : Var_Acc; + -- Direct driver for signal (if any). + Object_Driver : Var_Acc := null; -- RTI constant for the object. Object_Rti : O_Dnode := O_Dnode_Null; -- Function to compute the value of object (used for implicit @@ -1134,14 +1147,12 @@ package body Translation is Interface_Field : O_Fnode; -- Type of the interface. Interface_Type : O_Tnode; - -- Ortho node for the interface of the protected subprogram. - Interface_Protected : O_Dnode; when Kind_Disconnect => -- Variable which contains the time_expression of the -- disconnection specification Disconnect_Var : Var_Acc; when Kind_Process => - -- Type of process declarations. + -- Type of process declarations record. Process_Decls_Type : O_Tnode; -- Field in the parent block for the declarations in the process. @@ -1150,6 +1161,9 @@ package body Translation is -- Subprogram for the process. Process_Subprg : O_Dnode; + -- List of drivers if Flag_Direct_Drivers. + Process_Drivers : Direct_Drivers_Acc := null; + -- RTI for the process. Process_Rti_Const : O_Dnode := O_Dnode_Null; when Kind_Loop => @@ -1888,6 +1902,12 @@ package body Translation is procedure Elab_Signal_Declaration_Object (Decl : Iir; Parent : Iir; Check_Null : Boolean); + -- True of SIG has a direct driver. + function Has_Direct_Driver (Sig : Iir) return Boolean; + + -- Allocate memory for direct driver if necessary. + procedure Elab_Direct_Driver_Declaration_Storage (Decl : Iir); + -- Generate code to create object OBJ and initialize it with value VAL. procedure Elab_Object_Value (Obj : Iir; Value : Iir); @@ -1930,6 +1950,11 @@ package body Translation is -- SIG is true if RES is a signal object. function Translate_Name (Name : Iir) return Mnode; + -- Translate signal NAME into its node (SIG) and its direct driver + -- node (DRV). + procedure Translate_Direct_Driver + (Name : Iir; Sig : out Mnode; Drv : out Mnode); + -- Same as Translate_Name, but only for formal names. -- If SCOPE_TYPE and SCOPE_PARAM are not null, use them for the scope -- of the base name. @@ -2167,6 +2192,8 @@ package body Translation is (Sig : O_Enode; Sig_Type : Iir; Field : O_Fnode) return O_Lnode; + function Get_Signal_Field (Sig : Mnode; Field : O_Fnode) return O_Lnode; + function Translate_Length_Array_Attribute (Expr : Iir; Rtype : Iir) return O_Enode; function Translate_Low_Array_Attribute (Expr : Iir) return O_Enode; @@ -3693,11 +3720,7 @@ package body Translation is procedure Register_Signal (Targ : Mnode; Targ_Type : Iir; Proc : O_Dnode) - is - Proc_1 : O_Dnode := Proc; - begin - Register_Signal_1 (Targ, Targ_Type, Proc_1); - end Register_Signal; + renames Register_Signal_1; procedure Register_Signal_List (List : Iir_List; Proc : O_Dnode) is @@ -9722,6 +9745,42 @@ package body Translation is Close_Temp; end Elab_Signal_Declaration_Storage; + function Has_Direct_Driver (Sig : Iir) return Boolean + is + Info : Ortho_Info_Acc; + begin + Info := Get_Info (Get_Base_Name (Sig)); + return Info.Kind = Kind_Object + and then Info.Object_Driver /= null; + end Has_Direct_Driver; + + procedure Elab_Direct_Driver_Declaration_Storage (Decl : Iir) + is + Sig_Type : Iir; + Type_Info : Type_Info_Acc; + Sig_Info : Ortho_Info_Acc; + Name_Node : Mnode; + begin + Open_Temp; + + Sig_Type := Get_Type (Decl); + Sig_Info := Get_Info (Decl); + Type_Info := Get_Info (Sig_Type); + + if Type_Info.Type_Mode = Type_Mode_Fat_Array then + Name_Node := Get_Var (Sig_Info.Object_Driver, + Type_Info, Mode_Value); + Name_Node := Stabilize (Name_Node); + Chap3.Allocate_Fat_Array_Base (Alloc_System, Name_Node, Sig_Type); + elsif Type_Info.C /= null then + Name_Node := Get_Var (Sig_Info.Object_Driver, + Type_Info, Mode_Value); + Allocate_Complex_Object (Sig_Type, Alloc_System, Name_Node); + end if; + + Close_Temp; + end Elab_Direct_Driver_Declaration_Storage; + -- Create signal object. -- Note: DECL can be a signal sub-element (used when signals are -- collapsed). @@ -10120,7 +10179,7 @@ package body Translation is (Decl_Type, Get_Identifier (Decl)); Info := Add_Info (Decl, Kind_Alias); - case Get_Kind (Get_Base_Name (Decl)) is + case Get_Kind (Get_Object_Prefix (Decl)) is when Iir_Kind_Signal_Declaration | Iir_Kind_Signal_Interface_Declaration | Iir_Kind_Guard_Signal_Declaration => @@ -10176,7 +10235,6 @@ package body Translation is Chap3.Elab_Object_Subtype (Decl_Type); Name := Get_Name (Decl); Name_Type := Get_Type (Name); - -- Evaluate names. Name_Node := Chap6.Translate_Name (Name); Kind := Get_Object_Kind (Name_Node); N_Info := Get_Info (Name_Type); @@ -11758,110 +11816,109 @@ package body Translation is Data : Connect_Data; Mode : Connect_Mode; begin - if Get_Kind (Assoc) = Iir_Kind_Association_Element_By_Expression - and then Get_Collapse_Signal_Flag (Assoc) = By_Copy - then - Open_Temp; - Formal := Get_Formal (Assoc); - Actual := Get_Actual (Assoc); - Formal_Type := Get_Type (Formal); - Actual_Type := Get_Type (Actual); - if Get_In_Conversion (Assoc) = Null_Iir - and then Get_Out_Conversion (Assoc) = Null_Iir - then - Formal_Node := Chap6.Translate_Name (Formal); - if Get_Object_Kind (Formal_Node) /= Mode_Signal then - raise Internal_Error; - end if; - if Is_Signal (Actual) then - -- LRM93 4.3.1.2 - -- For a signal of a scalar type, each source - -- is either a driver or an OUT, INOUT, BUFFER - -- or LINKAGE port of a component instance or - -- of a block statement with which the signal - -- is associated. - - -- LRM93 12.6.2 - -- For a scalar signal S, the effective value of S is - -- determined in the following manner: - -- * If S is [...] a port of mode BUFFER or [...], - -- then the effective value of S is the same as - -- the driving value of S. - -- * If S is a connected port of mode IN or INOUT, - -- then the effective value of S is the same as - -- the effective value of the actual part of the - -- association element that associates an actual - -- with S. - -- * [...] - case Get_Mode (Get_Base_Name (Formal)) is - when Iir_In_Mode => - Mode := Connect_Effective; - when Iir_Inout_Mode => - Mode := Connect_Both; - when Iir_Out_Mode - | Iir_Buffer_Mode - | Iir_Linkage_Mode => - Mode := Connect_Source; - when Iir_Unknown_Mode => - raise Internal_Error; - end case; + if Get_Kind (Assoc) /= Iir_Kind_Association_Element_By_Expression then + raise Internal_Error; + end if; - -- translate actual (abort if not a signal). - Actual_Node := Chap6.Translate_Name (Actual); - if Get_Object_Kind (Actual_Node) /= Mode_Signal then + Open_Temp; + Formal := Get_Formal (Assoc); + Actual := Get_Actual (Assoc); + Formal_Type := Get_Type (Formal); + Actual_Type := Get_Type (Actual); + if Get_In_Conversion (Assoc) = Null_Iir + and then Get_Out_Conversion (Assoc) = Null_Iir + then + Formal_Node := Chap6.Translate_Name (Formal); + if Get_Object_Kind (Formal_Node) /= Mode_Signal then + raise Internal_Error; + end if; + if Is_Signal (Actual) then + -- LRM93 4.3.1.2 + -- For a signal of a scalar type, each source is either + -- a driver or an OUT, INOUT, BUFFER or LINKAGE port of + -- a component instance or of a block statement with + -- which the signalis associated. + + -- LRM93 12.6.2 + -- For a scalar signal S, the effective value of S is + -- determined in the following manner: + -- * If S is [...] a port of mode BUFFER or [...], + -- then the effective value of S is the same as + -- the driving value of S. + -- * If S is a connected port of mode IN or INOUT, + -- then the effective value of S is the same as + -- the effective value of the actual part of the + -- association element that associates an actual + -- with S. + -- * [...] + case Get_Mode (Get_Base_Name (Formal)) is + when Iir_In_Mode => + Mode := Connect_Effective; + when Iir_Inout_Mode => + Mode := Connect_Both; + when Iir_Out_Mode + | Iir_Buffer_Mode + | Iir_Linkage_Mode => + Mode := Connect_Source; + when Iir_Unknown_Mode => raise Internal_Error; - end if; - else - declare - Actual_Val : O_Enode; - begin - Actual_Val := Chap7.Translate_Expression - (Actual, Formal_Type); - Actual_Node := E2M - (Actual_Val, Get_Info (Formal_Type), Mode_Value); - Mode := Connect_Value; - end; - end if; + end case; - if Get_Kind (Formal_Type) in Iir_Kinds_Array_Type_Definition - then - -- Check length matches. - Stabilize (Formal_Node); - Stabilize (Actual_Node); - Chap3.Check_Array_Match (Formal_Type, Formal_Node, - Actual_Type, Actual_Node, - Assoc); + -- translate actual (abort if not a signal). + Actual_Node := Chap6.Translate_Name (Actual); + if Get_Object_Kind (Actual_Node) /= Mode_Signal then + raise Internal_Error; end if; + else + declare + Actual_Val : O_Enode; + begin + Actual_Val := Chap7.Translate_Expression + (Actual, Formal_Type); + Actual_Node := E2M + (Actual_Val, Get_Info (Formal_Type), Mode_Value); + Mode := Connect_Value; + end; + end if; + + if Get_Kind (Formal_Type) in Iir_Kinds_Array_Type_Definition + then + -- Check length matches. + Stabilize (Formal_Node); + Stabilize (Actual_Node); + Chap3.Check_Array_Match (Formal_Type, Formal_Node, + Actual_Type, Actual_Node, + Assoc); + end if; + Data := (Actual_Node => Actual_Node, + Actual_Type => Actual_Type, + Mode => Mode, + By_Copy => By_Copy); + Connect (Formal_Node, Formal_Type, Data); + else + if Get_In_Conversion (Assoc) /= Null_Iir then + Chap4.Elab_In_Conversion (Assoc, Actual_Node); + Formal_Node := Chap6.Translate_Name (Formal); Data := (Actual_Node => Actual_Node, - Actual_Type => Actual_Type, - Mode => Mode, - By_Copy => By_Copy); + Actual_Type => Formal_Type, + Mode => Connect_Effective, + By_Copy => False); Connect (Formal_Node, Formal_Type, Data); - else - if Get_In_Conversion (Assoc) /= Null_Iir then - Chap4.Elab_In_Conversion (Assoc, Actual_Node); - Formal_Node := Chap6.Translate_Name (Formal); - Data := (Actual_Node => Actual_Node, - Actual_Type => Formal_Type, - Mode => Connect_Effective, - By_Copy => False); - Connect (Formal_Node, Formal_Type, Data); - end if; - if Get_Out_Conversion (Assoc) /= Null_Iir then - -- flow: FORMAL to ACTUAL - Chap4.Elab_Out_Conversion (Assoc, Formal_Node); - Actual_Node := Chap6.Translate_Name (Actual); - Data := (Actual_Node => Actual_Node, - Actual_Type => Actual_Type, - Mode => Connect_Source, - By_Copy => False); - Connect (Formal_Node, Actual_Type, Data); - end if; end if; - - Close_Temp; + if Get_Out_Conversion (Assoc) /= Null_Iir then + -- flow: FORMAL to ACTUAL + Chap4.Elab_Out_Conversion (Assoc, Formal_Node); + Actual_Node := Chap6.Translate_Name (Actual); + Data := (Actual_Node => Actual_Node, + Actual_Type => Actual_Type, + Mode => Connect_Source, + By_Copy => False); + Connect (Formal_Node, Actual_Type, Data); + end if; end if; + + Close_Temp; end Elab_Port_Map_Aspect_Assoc; -- Return TRUE if the collapse_signal_flag is set for each individual @@ -12477,8 +12534,13 @@ package body Translation is end Translate_Thin_Index_Offset; -- Translate an indexed name. - function Translate_Indexed_Name (Prefix_Orig : Mnode; Expr : Iir) - return Mnode + type Indexed_Name_Data is record + Offset : O_Dnode; + Res : Mnode; + end record; + + function Translate_Indexed_Name_Init (Prefix_Orig : Mnode; Expr : Iir) + return Indexed_Name_Data is Prefix : Mnode; Prefix_Type : Iir; @@ -12571,13 +12633,44 @@ package body Translation is Close_Temp; end loop; - R := New_Obj_Value (Offset); - return Chap3.Index_Base - (Chap3.Get_Array_Base (Prefix), Prefix_Type, R); + return (Offset => Offset, + Res => Chap3.Index_Base + (Chap3.Get_Array_Base (Prefix), Prefix_Type, + New_Obj_Value (Offset))); + end Translate_Indexed_Name_Init; + + function Translate_Indexed_Name_Finish + (Prefix : Mnode; Expr : Iir; Data : Indexed_Name_Data) + return Mnode + is + begin + return Chap3.Index_Base (Chap3.Get_Array_Base (Prefix), + Get_Type (Get_Prefix (Expr)), + New_Obj_Value (Data.Offset)); + end Translate_Indexed_Name_Finish; + + function Translate_Indexed_Name (Prefix : Mnode; Expr : Iir) + return Mnode + is + begin + return Translate_Indexed_Name_Init (Prefix, Expr).Res; end Translate_Indexed_Name; - function Translate_Slice_Name (Prefix : Mnode; Expr : Iir_Slice_Name) - return Mnode + type Slice_Name_Data is record + Off : Unsigned_64; + Is_Off : Boolean; + + Unsigned_Diff : O_Dnode; + + -- Variable pointing to the prefix. + Prefix_Var : Mnode; + + -- Variable pointing to slice. + Slice_Range : Mnode; + end record; + + procedure Translate_Slice_Name_Init + (Prefix : Mnode; Expr : Iir_Slice_Name; Data : out Slice_Name_Data) is -- Type of the prefix. Prefix_Type : Iir; @@ -12599,9 +12692,6 @@ package body Translation is -- Suffix of the slice (discrete range). Expr_Range : Iir; - -- Object kind of the prefix. - Kind : Object_Kind_Type; - -- Variable pointing to the prefix. Prefix_Var : Mnode; @@ -12612,9 +12702,6 @@ package body Translation is Slice_Range : Mnode; Prefix_Range : Mnode; - Res_L : O_Lnode; - Res_D : O_Dnode; - Diff : O_Dnode; Unsigned_Diff : O_Dnode; If_Blk1 : O_If_Block; @@ -12626,8 +12713,6 @@ package body Translation is Index_Type := Get_Nth_Element (Get_Index_Subtype_List (Prefix_Type), 0); - Kind := Get_Object_Kind (Prefix); - -- Evaluate slice bounds. Chap3.Create_Array_Subtype (Slice_Type, True); @@ -12637,6 +12722,9 @@ package body Translation is if Slice_Info.Type_Mode = Type_Mode_Array and then Prefix_Info.Type_Mode = Type_Mode_Array then + Data.Is_Off := True; + Data.Prefix_Var := Prefix; + -- Both prefix and result are constrained array. declare Prefix_Left, Slice_Left : Iir_Int64; @@ -12655,7 +12743,8 @@ package body Translation is Slice_Length := Eval_Discrete_Range_Length (Slice_Range); if Slice_Length = 0 then -- Null slice. - return Prefix; + Data.Off := 0; + return; end if; if Get_Direction (Index_Range) /= Get_Direction (Slice_Range) then @@ -12681,17 +12770,14 @@ package body Translation is raise Internal_Error; end if; end if; - return Lv2M - (New_Slice (M2Lv (Prefix), - Slice_Info.Ortho_Type (Kind), - New_Lit (New_Unsigned_Literal - (Ghdl_Index_Type, - Unsigned_64 (Off)))), - Slice_Info, - Kind); + Data.Off := Unsigned_64 (Off); + + return; end; end if; + Data.Is_Off := False; + Slice_Binfo := Get_Info (Get_Base_Type (Slice_Type)); -- Save prefix. @@ -12798,39 +12884,92 @@ package body Translation is Check_Bound_Error (New_Dyadic_Op (ON_Or, Err_1, Err_2), Expr, 1); end; - -- Create the result (fat array) and assign the bounds field. - case Slice_Info.Type_Mode is - when Type_Mode_Fat_Array => - Res_D := Create_Temp (Slice_Info.Ortho_Type (Kind)); - New_Assign_Stmt - (New_Selected_Element (New_Obj (Res_D), - Slice_Info.T.Bounds_Field (Kind)), - New_Value (M2Lp (Slice_Range))); - New_Assign_Stmt - (New_Selected_Element (New_Obj (Res_D), - Slice_Info.T.Base_Field (Kind)), - New_Address - (New_Slice (M2Lv (Chap3.Get_Array_Base (Prefix_Var)), - Slice_Info.T.Base_Type (Kind), - New_Obj_Value (Unsigned_Diff)), - Slice_Info.T.Base_Ptr_Type (Kind))); - return Dv2M (Res_D, Slice_Info, Kind); - when Type_Mode_Array - | Type_Mode_Ptr_Array => - Res_L := New_Slice - (M2Lv (Chap3.Get_Array_Base (Prefix_Var)), - Slice_Info.T.Base_Type (Kind), - New_Obj_Value (Unsigned_Diff)); - return Lv2M (Res_L, - True, - Slice_Info.T.Base_Type (Kind), - Slice_Info.T.Base_Ptr_Type (Kind), - Slice_Info, Kind); - when others => - raise Internal_Error; - end case; + Data.Slice_Range := Slice_Range; + Data.Prefix_Var := Prefix_Var; + Data.Unsigned_Diff := Unsigned_Diff; + Data.Is_Off := False; + end Translate_Slice_Name_Init; + + function Translate_Slice_Name_Finish + (Prefix : Mnode; Expr : Iir_Slice_Name; Data : Slice_Name_Data) + return Mnode + is + -- Type of the prefix. + Prefix_Type : Iir; + + -- Type info of the prefix. + Prefix_Info : Type_Info_Acc; - --Finish_If_Stmt (If_Blk); + -- Type of the slice. + Slice_Type : Iir; + Slice_Info : Type_Info_Acc; + + -- Object kind of the prefix. + Kind : Object_Kind_Type; + + Res_L : O_Lnode; + Res_D : O_Dnode; + begin + -- Evaluate the prefix. + Slice_Type := Get_Type (Expr); + Prefix_Type := Get_Type (Get_Prefix (Expr)); + + Kind := Get_Object_Kind (Prefix); + + Prefix_Info := Get_Info (Prefix_Type); + Slice_Info := Get_Info (Slice_Type); + + if Data.Is_Off then + return Lv2M + (New_Slice (M2Lv (Prefix), + Slice_Info.Ortho_Type (Kind), + New_Lit (New_Unsigned_Literal + (Ghdl_Index_Type, Data.Off))), + Slice_Info, + Kind); + else + -- Create the result (fat array) and assign the bounds field. + case Slice_Info.Type_Mode is + when Type_Mode_Fat_Array => + Res_D := Create_Temp (Slice_Info.Ortho_Type (Kind)); + New_Assign_Stmt + (New_Selected_Element (New_Obj (Res_D), + Slice_Info.T.Bounds_Field (Kind)), + New_Value (M2Lp (Data.Slice_Range))); + New_Assign_Stmt + (New_Selected_Element (New_Obj (Res_D), + Slice_Info.T.Base_Field (Kind)), + New_Address + (New_Slice (M2Lv (Chap3.Get_Array_Base (Prefix)), + Slice_Info.T.Base_Type (Kind), + New_Obj_Value (Data.Unsigned_Diff)), + Slice_Info.T.Base_Ptr_Type (Kind))); + return Dv2M (Res_D, Slice_Info, Kind); + when Type_Mode_Array + | Type_Mode_Ptr_Array => + Res_L := New_Slice + (M2Lv (Chap3.Get_Array_Base (Prefix)), + Slice_Info.T.Base_Type (Kind), + New_Obj_Value (Data.Unsigned_Diff)); + return Lv2M (Res_L, + True, + Slice_Info.T.Base_Type (Kind), + Slice_Info.T.Base_Ptr_Type (Kind), + Slice_Info, Kind); + when others => + raise Internal_Error; + end case; + end if; + end Translate_Slice_Name_Finish; + + function Translate_Slice_Name + (Prefix : Mnode; Expr : Iir_Slice_Name) + return Mnode + is + Data : Slice_Name_Data; + begin + Translate_Slice_Name_Init (Prefix, Expr, Data); + return Translate_Slice_Name_Finish (Data.Prefix_Var, Expr, Data); end Translate_Slice_Name; function Translate_Interface_Name @@ -13079,6 +13218,66 @@ package body Translation is Error_Kind ("translate_name", Name); end case; end Translate_Name; + + procedure Translate_Direct_Driver + (Name : Iir; Sig : out Mnode; Drv : out Mnode) + is + Name_Type : Iir; + Name_Info : Ortho_Info_Acc; + Type_Info : Type_Info_Acc; + begin + Name_Type := Get_Type (Name); + Name_Info := Get_Info (Name); + Type_Info := Get_Info (Name_Type); + case Get_Kind (Name) is + when Iir_Kind_Signal_Declaration + | Iir_Kind_Signal_Interface_Declaration => + Sig := Get_Var (Name_Info.Object_Var, Type_Info, Mode_Signal); + Drv := Get_Var (Name_Info.Object_Driver, Type_Info, Mode_Value); + when Iir_Kind_Simple_Name + | Iir_Kind_Selected_Name => + Translate_Direct_Driver (Get_Named_Entity (Name), Sig, Drv); + when Iir_Kind_Slice_Name => + declare + Data : Slice_Name_Data; + Pfx_Sig : Mnode; + Pfx_Drv : Mnode; + begin + Translate_Direct_Driver + (Get_Prefix (Name), Pfx_Sig, Pfx_Drv); + Translate_Slice_Name_Init (Pfx_Sig, Name, Data); + Sig := Translate_Slice_Name_Finish + (Data.Prefix_Var, Name, Data); + Drv := Translate_Slice_Name_Finish (Pfx_Drv, Name, Data); + end; + when Iir_Kind_Indexed_Name => + declare + Data : Indexed_Name_Data; + Pfx_Sig : Mnode; + Pfx_Drv : Mnode; + begin + Translate_Direct_Driver + (Get_Prefix (Name), Pfx_Sig, Pfx_Drv); + Data := Translate_Indexed_Name_Init (Pfx_Sig, Name); + Sig := Data.Res; + Drv := Translate_Indexed_Name_Finish (Pfx_Drv, Name, Data); + end; + when Iir_Kind_Selected_Element => + declare + El : Iir; + Pfx_Sig : Mnode; + Pfx_Drv : Mnode; + begin + Translate_Direct_Driver + (Get_Prefix (Name), Pfx_Sig, Pfx_Drv); + El := Get_Selected_Element (Name); + Sig := Translate_Selected_Element (Pfx_Sig, El); + Drv := Translate_Selected_Element (Pfx_Drv, El); + end; + when others => + Error_Kind ("translate_direct_driver", Name); + end case; + end Translate_Direct_Driver; end Chap6; package body Chap7 is @@ -15647,7 +15846,7 @@ package body Translation is begin New_Assign_Stmt (Chap14.Get_Signal_Value_Field (M2E (Targ), Targ_Type, - Ghdl_Signal_Driving_Value_Node), + Ghdl_Signal_Driving_Value_Field), M2E (Data)); end Translate_Signal_Assign_Driving_Non_Composite; @@ -15750,7 +15949,7 @@ package body Translation is return O_Enode is begin return New_Value (Chap14.Get_Signal_Value_Field - (Sig, Sig_Type, Ghdl_Signal_Driving_Value_Node)); + (Sig, Sig_Type, Ghdl_Signal_Driving_Value_Field)); end Read_Signal_Driving_Value; function Translate_Signal_Driving_Value_1 is new Translate_Signal_Value @@ -16097,10 +16296,10 @@ package body Translation is when Iir_Kind_Last_Event_Attribute => return Chap14.Translate_Last_Time_Attribute - (Get_Prefix (Expr), Ghdl_Signal_Last_Event_Node); + (Get_Prefix (Expr), Ghdl_Signal_Last_Event_Field); when Iir_Kind_Last_Active_Attribute => return Chap14.Translate_Last_Time_Attribute - (Get_Prefix (Expr), Ghdl_Signal_Last_Active_Node); + (Get_Prefix (Expr), Ghdl_Signal_Last_Active_Field); when Iir_Kind_Driving_Value_Attribute => Res := Chap14.Translate_Driving_Value_Attribute (Expr); @@ -19702,34 +19901,6 @@ package body Translation is end if; end Gen_Simple_Signal_Assign_Non_Composite; --- procedure Gen_Simple_Signal_Prepare_Data_Composite (Val : O_Enode; --- Targ_Type : Iir) is --- begin --- null; --- end Gen_Simple_Signal_Prepare_Data_Composite; - --- function Gen_Simple_Signal_Update_Data_Array (Val : O_Enode; --- Targ_Type : Iir; --- Index : O_Lnode) --- return O_Enode --- is --- Base : O_Lnode; --- begin --- Base := Chap3.Get_Array_Base --- (New_Access_Element (Val), Targ_Type, Mode_Value); --- return New_Value (New_Indexed_Element (Base, New_Value (Index))); --- end Gen_Simple_Signal_Update_Data_Array; - --- function Gen_Simple_Signal_Update_Data_Record --- (Val : O_Enode; Targ_Type : Iir; El : Iir_Element_Declaration) --- return O_Enode --- is --- begin --- return New_Value (New_Selected_Element --- (New_Access_Element (Val), --- Get_Info (El).Field_Node (Mode_Value))); --- end Gen_Simple_Signal_Update_Data_Record; - procedure Gen_Simple_Signal_Assign is new Foreach_Non_Composite (Data_Type => O_Enode, Composite_Data_Type => Mnode, @@ -20120,6 +20291,152 @@ package body Translation is end if; end Translate_Signal_Target_Aggr; + type Signal_Direct_Assign_Data is record + Drv : Mnode; + Expr : Mnode; + end record; + + procedure Gen_Signal_Direct_Assign_Non_Composite + (Targ : Mnode; Targ_Type : Iir; Data : Signal_Direct_Assign_Data) + is + Targ_Sig : Mnode; + If_Blk : O_If_Block; + Cond : O_Dnode; + Drv : Mnode; + begin + Open_Temp; + Targ_Sig := Stabilize (Targ, True); + Cond := Create_Temp (Ghdl_Bool_Type); + Drv := Stabilize (Data.Drv, False); + + -- Set driver. + Chap7.Translate_Assign + (Drv, M2E (Data.Expr), Null_Iir, Targ_Type); + + -- Test if the signal is active. + Start_If_Stmt + (If_Blk, + New_Value (Chap14.Get_Signal_Field + (Targ_Sig, Ghdl_Signal_Has_Active_Field))); + -- Either because has_active is true. + New_Assign_Stmt (New_Obj (Cond), + New_Lit (Ghdl_Bool_True_Node)); + New_Else_Stmt (If_Blk); + -- Or because the value. is different from the current value. + New_Assign_Stmt + (New_Obj (Cond), + New_Compare_Op (ON_Neq, + New_Value (New_Access_Element (M2E (Targ_Sig))), + M2E (Drv), + Ghdl_Bool_Type)); + Finish_If_Stmt (If_Blk); + + -- Put signal into active list. + Start_If_Stmt + (If_Blk, + New_Dyadic_Op + (ON_And, + New_Obj_Value (Cond), + New_Compare_Op + (ON_Eq, + New_Value (Chap14.Get_Signal_Field + (Targ_Sig, Ghdl_Signal_Active_Chain_Field)), + New_Lit (New_Null_Access (Ghdl_Signal_Ptr)), + Ghdl_Bool_Type))); + New_Assign_Stmt + (Chap14.Get_Signal_Field (Targ_Sig, Ghdl_Signal_Active_Chain_Field), + New_Obj_Value (Ghdl_Signal_Active_Chain)); + New_Assign_Stmt + (New_Obj (Ghdl_Signal_Active_Chain), + New_Convert_Ov (New_Value (M2Lv (Targ_Sig)), + Ghdl_Signal_Ptr)); + Finish_If_Stmt (If_Blk); + Close_Temp; + end Gen_Signal_Direct_Assign_Non_Composite; + + function Gen_Signal_Direct_Prepare_Data_Composite + (Targ : Mnode; Targ_Type : Iir; Val : Signal_Direct_Assign_Data) + return Signal_Direct_Assign_Data + is + pragma Unreferenced (Targ, Targ_Type); + begin + return Val; + end Gen_Signal_Direct_Prepare_Data_Composite; + + function Gen_Signal_Direct_Prepare_Data_Record + (Targ : Mnode; Targ_Type : Iir; Val : Signal_Direct_Assign_Data) + return Signal_Direct_Assign_Data + is + pragma Unreferenced (Targ, Targ_Type); + begin + return Signal_Direct_Assign_Data' + (Drv => Stabilize (Val.Drv), + Expr => Stabilize (Val.Expr)); + end Gen_Signal_Direct_Prepare_Data_Record; + + function Gen_Signal_Direct_Update_Data_Array + (Val : Signal_Direct_Assign_Data; + Targ_Type : Iir; + Index : O_Dnode) + return Signal_Direct_Assign_Data + is + begin + return Signal_Direct_Assign_Data' + (Drv => Chap3.Index_Base (Chap3.Get_Array_Base (Val.Drv), + Targ_Type, New_Obj_Value (Index)), + Expr => Chap3.Index_Base (Chap3.Get_Array_Base (Val.Expr), + Targ_Type, New_Obj_Value (Index))); + end Gen_Signal_Direct_Update_Data_Array; + + function Gen_Signal_Direct_Update_Data_Record + (Val : Signal_Direct_Assign_Data; + Targ_Type : Iir; + El : Iir_Element_Declaration) + return Signal_Direct_Assign_Data + is + pragma Unreferenced (Targ_Type); + begin + return Signal_Direct_Assign_Data' + (Drv => Chap6.Translate_Selected_Element (Val.Drv, El), + Expr => Chap6.Translate_Selected_Element (Val.Expr, El)); + end Gen_Signal_Direct_Update_Data_Record; + + procedure Gen_Signal_Direct_Finish_Data_Composite + (Data : in out Signal_Direct_Assign_Data) + is + pragma Unreferenced (Data); + begin + null; + end Gen_Signal_Direct_Finish_Data_Composite; + + procedure Gen_Signal_Direct_Assign is new Foreach_Non_Composite + (Data_Type => Signal_Direct_Assign_Data, + Composite_Data_Type => Signal_Direct_Assign_Data, + Do_Non_Composite => Gen_Signal_Direct_Assign_Non_Composite, + Prepare_Data_Array => Gen_Signal_Direct_Prepare_Data_Composite, + Update_Data_Array => Gen_Signal_Direct_Update_Data_Array, + Finish_Data_Array => Gen_Signal_Direct_Finish_Data_Composite, + Prepare_Data_Record => Gen_Signal_Direct_Prepare_Data_Record, + Update_Data_Record => Gen_Signal_Direct_Update_Data_Record, + Finish_Data_Record => Gen_Signal_Direct_Finish_Data_Composite); + + procedure Translate_Direct_Signal_Assignment (Stmt : Iir; We : Iir) + is + Target : Iir; + Target_Type : Iir; + Arg : Signal_Direct_Assign_Data; + Targ_Sig : Mnode; + begin + Target := Get_Target (Stmt); + Target_Type := Get_Type (Target); + Chap6.Translate_Direct_Driver (Target, Targ_Sig, Arg.Drv); + + Arg.Expr := E2M (Chap7.Translate_Expression (We, Target_Type), + Get_Info (Target_Type), Mode_Value); + Gen_Signal_Direct_Assign (Targ_Sig, Target_Type, Arg); + return; + end Translate_Direct_Signal_Assignment; + procedure Translate_Signal_Assignment_Statement (Stmt : Iir) is Target : Iir; @@ -20128,22 +20445,44 @@ package body Translation is Targ : Mnode; Val : O_Enode; Value : Iir; + Is_Simple : Boolean; begin Target := Get_Target (Stmt); Target_Type := Get_Type (Target); + We := Get_Waveform_Chain (Stmt); + + if We /= Null_Iir + and then Get_Chain (We) = Null_Iir + and then Get_Time (We) = Null_Iir + and then Get_Delay_Mechanism (Stmt) = Iir_Inertial_Delay + and then Get_Reject_Time_Expression (Stmt) = Null_Iir + then + -- Simple signal assignment ? + Value := Get_We_Value (We); + Is_Simple := Get_Kind (Value) /= Iir_Kind_Null_Literal; + else + Is_Simple := False; + end if; + if Get_Kind (Target) = Iir_Kind_Aggregate then Chap3.Translate_Anonymous_Type_Definition (Target_Type, True); Targ := Create_Temp (Get_Info (Target_Type), Mode_Signal); Chap4.Allocate_Complex_Object (Target_Type, Alloc_Stack, Targ); Translate_Signal_Target_Aggr (Targ, Target, Target_Type); else + if Is_Simple + and then Flag_Direct_Drivers + and then Chap4.Has_Direct_Driver (Target) + then + Translate_Direct_Signal_Assignment (Stmt, Value); + return; + end if; Targ := Chap6.Translate_Name (Target); if Get_Object_Kind (Targ) /= Mode_Signal then raise Internal_Error; end if; end if; - We := Get_Waveform_Chain (Stmt); if We = Null_Iir then -- Implicit disconnect statment. Register_Signal (Targ, Target_Type, Ghdl_Signal_Disconnect); @@ -20356,6 +20695,56 @@ package body Translation is end Chap8; package body Chap9 is + procedure Set_Direct_Drivers (Proc : Iir) + is + Proc_Info : Proc_Info_Acc := Get_Info (Proc); + Drivers : Direct_Drivers_Acc := Proc_Info.Process_Drivers; + Info : Ortho_Info_Acc; + Var : Var_Acc; + Sig : Iir; + begin + for I in Drivers.all'Range loop + Var := Drivers (I).Var; + Sig := Get_Base_Name (Drivers (I).Sig); + if Var /= null then + Info := Get_Info (Sig); + case Info.Kind is + when Kind_Object => + Info.Object_Driver := Var; + when Kind_Alias => + null; + when others => + raise Internal_Error; + end case; + end if; + end loop; + end Set_Direct_Drivers; + + procedure Reset_Direct_Drivers (Proc : Iir) + is + Proc_Info : Proc_Info_Acc := Get_Info (Proc); + Drivers : Direct_Drivers_Acc := Proc_Info.Process_Drivers; + Info : Ortho_Info_Acc; + Var : Var_Acc; + Sig : Iir; + begin + for I in Drivers.all'Range loop + Var := Drivers (I).Var; + Sig := Get_Base_Name (Drivers (I).Sig); + if Var /= null then + Info := Get_Info (Sig); + case Info.Kind is + when Kind_Object => + Info.Object_Driver := null; + when Kind_Alias => + null; + when others => + raise Internal_Error; + end case; + end if; + end loop; + end Reset_Direct_Drivers; + procedure Translate_Process_Statement (Proc : Iir; Base : Block_Info_Acc) is Inter_List : O_Inter_List; @@ -20373,8 +20762,10 @@ package body Translation is Push_Local_Factory; -- Push scope for architecture declarations. Push_Scope (Base.Block_Decls_Type, Instance); + Chap8.Translate_Statements_Chain (Get_Sequential_Statement_Chain (Proc)); + Pop_Scope (Base.Block_Decls_Type); Pop_Local_Factory; Finish_Subprogram_Body; @@ -20435,6 +20826,62 @@ package body Translation is end if; end Translate_Component_Instantiation_Statement; + procedure Translate_Process_Declarations (Proc : Iir) + is + Mark : Id_Mark_Type; + Info : Ortho_Info_Acc; + Itype : O_Tnode; + Field : O_Fnode; + + Drivers : Iir_List; + Nbr_Drivers : Natural; + Sig : Iir; + begin + -- Create process record. + Push_Identifier_Prefix (Mark, Get_Identifier (Proc)); + Push_Instance_Factory (O_Tnode_Null); + Info := Add_Info (Proc, Kind_Process); + Chap4.Translate_Declaration_Chain (Proc); + + if Flag_Direct_Drivers then + Drivers := Trans_Analyzes.Extract_Drivers (Proc); + if Flag_Dump_Drivers then + Trans_Analyzes.Dump_Drivers (Proc, Drivers); + end if; + + Nbr_Drivers := Get_Nbr_Elements (Drivers); + Info.Process_Drivers := new Direct_Driver_Arr (1 .. Nbr_Drivers); + for I in 1 .. Nbr_Drivers loop + Sig := Get_Nth_Element (Drivers, I - 1); + Info.Process_Drivers (I) := (Sig => Sig, Var => null); + Sig := Get_Base_Name (Sig); + if Get_Kind (Sig) /= Iir_Kind_Object_Alias_Declaration + and then not Get_After_Drivers_Flag (Sig) + then + Info.Process_Drivers (I).Var := + Create_Var (Create_Var_Identifier (Sig, "_DDRV", I), + Chap4.Get_Object_Type + (Get_Info (Get_Type (Sig)), Mode_Value)); + + -- Do not create driver severals times. + Set_After_Drivers_Flag (Sig, True); + end if; + end loop; + Trans_Analyzes.Free_Drivers_List (Drivers); + end if; + Pop_Instance_Factory (Itype); + New_Type_Decl (Create_Identifier ("INSTTYPE"), Itype); + Pop_Identifier_Prefix (Mark); + + -- Create a field in the parent record. + Field := Add_Instance_Factory_Field + (Create_Identifier_Without_Prefix (Proc), Itype); + + -- Set info in child record. + Info.Process_Decls_Type := Itype; + Info.Process_Parent_Field := Field; + end Translate_Process_Declarations; + -- Create the instance for block BLOCK. -- BLOCK can be either an entity, an architecture or a block statement. procedure Translate_Block_Declarations (Block : Iir; Origin : Iir) @@ -20448,27 +20895,7 @@ package body Translation is case Get_Kind (El) is when Iir_Kind_Process_Statement | Iir_Kind_Sensitized_Process_Statement => - declare - Mark : Id_Mark_Type; - Info : Ortho_Info_Acc; - Itype : O_Tnode; - Field : O_Fnode; - begin - Push_Identifier_Prefix (Mark, Get_Identifier (El)); - -- Start child record. - Push_Instance_Factory (O_Tnode_Null); - Info := Add_Info (El, Kind_Process); - Chap4.Translate_Declaration_Chain (El); - Pop_Instance_Factory (Itype); - New_Type_Decl (Create_Identifier ("INSTTYPE"), Itype); - Pop_Identifier_Prefix (Mark); - -- Create a field in the parent record. - Field := Add_Instance_Factory_Field - (Create_Identifier_Without_Prefix (El), Itype); - -- Set info in child record. - Info.Process_Decls_Type := Itype; - Info.Process_Parent_Field := Field; - end; + Translate_Process_Declarations (El); when Iir_Kind_Component_Instantiation_Statement => Translate_Component_Instantiation_Statement (El); when Iir_Kind_Block_Statement => @@ -20668,9 +21095,17 @@ package body Translation is Push_Scope (Info.Process_Decls_Type, Info.Process_Parent_Field, Block_Info.Block_Decls_Type); + if Flag_Direct_Drivers then + Chap9.Set_Direct_Drivers (Stmt); + end if; + Chap4.Translate_Declaration_Chain_Subprograms (Stmt, Base_Block); Translate_Process_Statement (Stmt, Base_Info); + + if Flag_Direct_Drivers then + Chap9.Reset_Direct_Drivers (Stmt); + end if; Pop_Scope (Info.Process_Decls_Type); end; when Iir_Kind_Component_Instantiation_Statement => @@ -20736,54 +21171,149 @@ package body Translation is -- If the type is referenced again, the variables must be reachable. -- This is not the case for elaborator subprogram (which may references -- slices in the sensitivity or driver list) and the process subprg. - procedure Destroy_Types_In_List (List : Iir_List) + procedure Destroy_Types_In_Name (Name : Iir) is El : Iir; Atype : Iir; Info : Type_Info_Acc; begin + El := Name; + loop + Atype := Null_Iir; + case Get_Kind (El) is + when Iir_Kind_Selected_Element + | Iir_Kind_Indexed_Name => + El := Get_Prefix (El); + when Iir_Kind_Slice_Name => + Atype := Get_Type (El); + El := Get_Prefix (El); + when Iir_Kind_Object_Alias_Declaration => + El := Get_Name (El); + when Iir_Kind_Stable_Attribute + | Iir_Kind_Quiet_Attribute + | Iir_Kind_Delayed_Attribute + | Iir_Kind_Transaction_Attribute => + El := Get_Prefix (El); + when Iir_Kind_Signal_Declaration + | Iir_Kind_Signal_Interface_Declaration + | Iir_Kind_Guard_Signal_Declaration => + exit; + when others => + Error_Kind ("destroy_types_in_name", El); + end case; + if Atype /= Null_Iir + and then Is_Anonymous_Type_Definition (Atype) + then + Info := Get_Info (Atype); + if Info /= null then + Free_Type_Info (Info, False); + Clear_Info (Atype); + end if; + end if; + end loop; + end Destroy_Types_In_Name; + + procedure Destroy_Types_In_List (List : Iir_List) + is + El : Iir; + begin if List = Null_Iir_List then return; end if; for I in Natural loop El := Get_Nth_Element (List, I); exit when El = Null_Iir; - loop - Atype := Null_Iir; - case Get_Kind (El) is - when Iir_Kind_Selected_Element - | Iir_Kind_Indexed_Name => - El := Get_Prefix (El); - when Iir_Kind_Slice_Name => - Atype := Get_Type (El); - El := Get_Prefix (El); - when Iir_Kind_Object_Alias_Declaration => - El := Get_Name (El); - when Iir_Kind_Stable_Attribute - | Iir_Kind_Quiet_Attribute - | Iir_Kind_Delayed_Attribute - | Iir_Kind_Transaction_Attribute => - El := Get_Prefix (El); - when Iir_Kind_Signal_Declaration - | Iir_Kind_Signal_Interface_Declaration - | Iir_Kind_Guard_Signal_Declaration => - exit; - when others => - Error_Kind ("destroy_types_in_list", El); - end case; - if Atype /= Null_Iir - and then Is_Anonymous_Type_Definition (Atype) - then - Info := Get_Info (Atype); - if Info /= null then - Free_Type_Info (Info, False); - Clear_Info (Atype); - end if; - end if; - end loop; + Destroy_Types_In_Name (El); end loop; end Destroy_Types_In_List; + procedure Gen_Register_Direct_Driver_Non_Composite + (Targ : Mnode; Targ_Type : Iir; Drv : Mnode) + is + pragma Unreferenced (Targ_Type); + Constr : O_Assoc_List; + begin + Start_Association (Constr, Ghdl_Signal_Direct_Driver); + New_Association + (Constr, New_Convert_Ov (New_Value (M2Lv (Targ)), Ghdl_Signal_Ptr)); + New_Association + (Constr, New_Unchecked_Address (M2Lv (Drv), Ghdl_Ptr_Type)); + New_Procedure_Call (Constr); + end Gen_Register_Direct_Driver_Non_Composite; + + function Gen_Register_Direct_Driver_Prepare_Data_Composite + (Targ : Mnode; Targ_Type : Iir; Val : Mnode) + return Mnode + is + pragma Unreferenced (Targ, Targ_Type); + begin + return Val; + end Gen_Register_Direct_Driver_Prepare_Data_Composite; + + function Gen_Register_Direct_Driver_Prepare_Data_Record + (Targ : Mnode; Targ_Type : Iir; Val : Mnode) + return Mnode + is + pragma Unreferenced (Targ, Targ_Type); + begin + return Stabilize (Val); + end Gen_Register_Direct_Driver_Prepare_Data_Record; + + function Gen_Register_Direct_Driver_Update_Data_Array + (Val : Mnode; Targ_Type : Iir; Index : O_Dnode) + return Mnode + is + begin + return Chap3.Index_Base (Chap3.Get_Array_Base (Val), + Targ_Type, New_Obj_Value (Index)); + end Gen_Register_Direct_Driver_Update_Data_Array; + + function Gen_Register_Direct_Driver_Update_Data_Record + (Val : Mnode; Targ_Type : Iir; El : Iir_Element_Declaration) + return Mnode + is + pragma Unreferenced (Targ_Type); + begin + return Chap6.Translate_Selected_Element (Val, El); + end Gen_Register_Direct_Driver_Update_Data_Record; + + procedure Gen_Register_Direct_Driver_Finish_Data_Composite + (Data : in out Mnode) + is + pragma Unreferenced (Data); + begin + null; + end Gen_Register_Direct_Driver_Finish_Data_Composite; + + procedure Gen_Register_Direct_Driver is new Foreach_Non_Composite + (Data_Type => Mnode, + Composite_Data_Type => Mnode, + Do_Non_Composite => Gen_Register_Direct_Driver_Non_Composite, + Prepare_Data_Array => + Gen_Register_Direct_Driver_Prepare_Data_Composite, + Update_Data_Array => Gen_Register_Direct_Driver_Update_Data_Array, + Finish_Data_Array => Gen_Register_Direct_Driver_Finish_Data_Composite, + Prepare_Data_Record => Gen_Register_Direct_Driver_Prepare_Data_Record, + Update_Data_Record => Gen_Register_Direct_Driver_Update_Data_Record, + Finish_Data_Record => + Gen_Register_Direct_Driver_Finish_Data_Composite); + +-- procedure Register_Scalar_Direct_Driver (Sig : Mnode; +-- Sig_Type : Iir; +-- Drv : Mnode) +-- is +-- pragma Unreferenced (Sig_Type); +-- Constr : O_Assoc_List; +-- begin +-- Start_Association (Constr, Ghdl_Signal_Direct_Driver); +-- New_Association +-- (Constr, New_Convert_Ov (New_Value (M2Lv (Sig)), Ghdl_Signal_Ptr)); +-- New_Association +-- (Constr, New_Unchecked_Address (M2Lv (Drv), Ghdl_Ptr_Type)); +-- New_Procedure_Call (Constr); +-- end Register_Scalar_Direct_Driver; + + -- PROC: the process to be elaborated -- BLOCK_INFO: info for the block containing the process -- BASE_INFO: info for the global block @@ -20845,9 +21375,47 @@ package body Translation is -- an alias declaration. Chap4.Elab_Declaration_Chain (Proc, Final); - List := Get_Driver_List (Proc); - Destroy_Types_In_List (List); - Register_Signal_List (List, Ghdl_Process_Add_Driver); + -- Register drivers. + if Flag_Direct_Drivers then + Chap9.Set_Direct_Drivers (Proc); + + declare + Sig : Iir; + Base : Iir; + Sig_Node, Drv_Node : Mnode; + begin + for I in Info.Process_Drivers.all'Range loop + Sig := Info.Process_Drivers (I).Sig; + Open_Temp; + Base := Get_Base_Name (Sig); + if Info.Process_Drivers (I).Var /= null then + -- Elaborate direct driver. Done only once. + Chap4.Elab_Direct_Driver_Declaration_Storage (Base); + end if; + if Chap4.Has_Direct_Driver (Base) then + -- Signal has a direct driver. + Chap6.Translate_Direct_Driver (Sig, Sig_Node, Drv_Node); + Gen_Register_Direct_Driver + (Sig_Node, Get_Type (Sig), Drv_Node); + else + Register_Signal (Chap6.Translate_Name (Sig), + Get_Type (Sig), + Ghdl_Process_Add_Driver); + end if; + Close_Temp; + end loop; + end; + + Chap9.Reset_Direct_Drivers (Proc); + else + List := Trans_Analyzes.Extract_Drivers (Proc); + Destroy_Types_In_List (List); + Register_Signal_List (List, Ghdl_Process_Add_Driver); + if Flag_Dump_Drivers then + Trans_Analyzes.Dump_Drivers (Proc, List); + end if; + Trans_Analyzes.Free_Drivers_List (List); + end if; if Is_Sensitized then List := Get_Sensitivity_List (Proc); @@ -22349,22 +22917,49 @@ package body Translation is return Get_Identifier (Identifier_Buffer (1 .. Identifier_Len - 2)); end Create_Identifier; + function Create_Var_Identifier_From_Buffer (L : Natural) + return Var_Ident_Type + is + Start : Natural; + begin + if Is_Local_Scope then + Start := Identifier_Start; + else + Start := 1; + end if; + return (Id => Get_Identifier (Identifier_Buffer (Start .. L))); + end Create_Var_Identifier_From_Buffer; + function Create_Var_Identifier (Id : Iir) return Var_Ident_Type is - Res : Var_Ident_Type; + L : Natural := Identifier_Len; begin - Res.Id := Create_Id (Get_Identifier (Id), "", Is_Local_Scope); - return Res; + Add_Identifier (L, Get_Identifier (Id)); + return Create_Var_Identifier_From_Buffer (L); end Create_Var_Identifier; function Create_Var_Identifier (Id : String) return Var_Ident_Type is - Res : Var_Ident_Type; + L : Natural := Identifier_Len; begin - Res.Id := Create_Id (Null_Identifier, Id, Is_Local_Scope); - return Res; + Add_String (L, Id); + return Create_Var_Identifier_From_Buffer (L); + end Create_Var_Identifier; + + function Create_Var_Identifier (Id : Iir; Str : String; Val : Natural) + return Var_Ident_Type + is + L : Natural := Identifier_Len; + begin + Add_Identifier (L, Get_Identifier (Id)); + Add_String (L, Str); + if Val > 0 then + Add_String (L, "O"); + Add_Nat (L, Val); + end if; + return Create_Var_Identifier_From_Buffer (L); end Create_Var_Identifier; function Create_Uniq_Identifier return Var_Ident_Type @@ -22728,19 +23323,6 @@ package body Translation is end case; end Translate_Succ_Pred_Attribute; - -- Read the boolean attribute (active or event) FIELD of simple signal - -- SIG. - function Read_Bool_Signal_Attribute (Sig : O_Enode; Field : O_Fnode) - return O_Enode - is - S : O_Enode; - begin - S := New_Convert_Ov (Sig, Ghdl_Signal_Ptr); - return New_Value - (New_Selected_Element (New_Access_Element (S), Field)); - --Ghdl_Signal_Event_Node)); - end Read_Bool_Signal_Attribute; - type Bool_Sigattr_Data_Type is record Label : O_Snode; Field : O_Fnode; @@ -22752,8 +23334,7 @@ package body Translation is pragma Unreferenced (Targ_Type); begin Gen_Exit_When (Data.Label, - Read_Bool_Signal_Attribute (New_Value (M2Lv (Targ)), - Data.Field)); + New_Value (Get_Signal_Field (Targ, Data.Field))); end Bool_Sigattr_Non_Composite_Signal; function Bool_Sigattr_Prepare_Data_Composite @@ -22819,7 +23400,7 @@ package body Translation is if Get_Kind (Prefix_Type) in Iir_Kinds_Scalar_Type_Definition then -- Effecient handling for a scalar signal. Name := Chap6.Translate_Name (Prefix); - return Read_Bool_Signal_Attribute (New_Value (M2Lv (Name)), Field); + return New_Value (Get_Signal_Field (Name, Field)); else -- Element per element handling for composite signals. Res := Create_Temp (Std_Boolean_Type_Node); @@ -22839,13 +23420,14 @@ package body Translation is function Translate_Event_Attribute (Attr : Iir) return O_Enode is begin - return Translate_Bool_Signal_Attribute (Attr, Ghdl_Signal_Event_Node); + return Translate_Bool_Signal_Attribute + (Attr, Ghdl_Signal_Event_Field); end Translate_Event_Attribute; function Translate_Active_Attribute (Attr : Iir) return O_Enode is begin return Translate_Bool_Signal_Attribute - (Attr, Ghdl_Signal_Active_Node); + (Attr, Ghdl_Signal_Active_Field); end Translate_Active_Attribute; -- Read signal value FIELD of signal SIG. @@ -22862,11 +23444,20 @@ package body Translation is (New_Unchecked_Address (New_Selected_Element (T, Field), S_Type)); end Get_Signal_Value_Field; + function Get_Signal_Field (Sig : Mnode; Field : O_Fnode) + return O_Lnode + is + S : O_Enode; + begin + S := New_Convert_Ov (New_Value (M2Lv (Sig)), Ghdl_Signal_Ptr); + return New_Selected_Element (New_Access_Element (S), Field); + end Get_Signal_Field; + function Read_Last_Value (Sig : O_Enode; Sig_Type : Iir) return O_Enode is begin return New_Value (Get_Signal_Value_Field - (Sig, Sig_Type, Ghdl_Signal_Last_Value_Node)); + (Sig, Sig_Type, Ghdl_Signal_Last_Value_Field)); end Read_Last_Value; function Translate_Last_Value is new Chap7.Translate_Signal_Value @@ -27031,39 +27622,53 @@ package body Translation is (Chararray_Type, New_Unsigned_Literal (Ghdl_Index_Type, 8)); New_Type_Decl (Get_Identifier ("__ghdl_scalar_bytes"), Ghdl_Scalar_Bytes); + + Ghdl_Signal_Ptr := New_Access_Type (O_Tnode_Null); + New_Type_Decl (Get_Identifier ("__ghdl_signal_ptr"), Ghdl_Signal_Ptr); + -- Type __signal_signal is record Start_Record_Type (Rec); - New_Record_Field (Rec, Ghdl_Signal_Value_Node, + New_Record_Field (Rec, Ghdl_Signal_Value_Field, Get_Identifier ("value"), Ghdl_Scalar_Bytes); - New_Record_Field (Rec, Ghdl_Signal_Driving_Value_Node, + New_Record_Field (Rec, Ghdl_Signal_Driving_Value_Field, Get_Identifier ("driving_value"), Ghdl_Scalar_Bytes); - New_Record_Field (Rec, Ghdl_Signal_Last_Value_Node, + New_Record_Field (Rec, Ghdl_Signal_Last_Value_Field, Get_Identifier ("last_value"), Ghdl_Scalar_Bytes); - New_Record_Field (Rec, Ghdl_Signal_Last_Event_Node, + New_Record_Field (Rec, Ghdl_Signal_Last_Event_Field, Get_Identifier ("last_event"), Time_Otype); - New_Record_Field (Rec, Ghdl_Signal_Last_Active_Node, + New_Record_Field (Rec, Ghdl_Signal_Last_Active_Field, Get_Identifier ("last_active"), Time_Otype); - New_Record_Field (Rec, Ghdl_Signal_Event_Node, + New_Record_Field (Rec, Ghdl_Signal_Active_Chain_Field, + Get_Identifier ("active_chain"), + Ghdl_Signal_Ptr); + New_Record_Field (Rec, Ghdl_Signal_Event_Field, Get_Identifier ("event"), Std_Boolean_Type_Node); - New_Record_Field (Rec, Ghdl_Signal_Active_Node, + New_Record_Field (Rec, Ghdl_Signal_Active_Field, Get_Identifier ("active"), Std_Boolean_Type_Node); + New_Record_Field (Rec, Ghdl_Signal_Has_Active_Field, + Get_Identifier ("has_active"), + Ghdl_Bool_Type); Finish_Record_Type (Rec, Ghdl_Signal_Type); New_Type_Decl (Get_Identifier ("__ghdl_signal"), Ghdl_Signal_Type); - Ghdl_Signal_Ptr := New_Access_Type (Ghdl_Signal_Type); - New_Type_Decl (Get_Identifier ("__ghdl_signal_ptr"), Ghdl_Signal_Ptr); + Finish_Access_Type (Ghdl_Signal_Ptr, Ghdl_Signal_Type); Ghdl_Signal_Ptr_Ptr := New_Access_Type (Ghdl_Signal_Ptr); New_Type_Decl (Get_Identifier ("__ghdl_signal_ptr_ptr"), Ghdl_Signal_Ptr_Ptr); + New_Var_Decl (Ghdl_Signal_Active_Chain, + Get_Identifier ("__ghdl_signal_active_chain"), + O_Storage_External, + Ghdl_Signal_Ptr); + -- procedure __ghdl_signal_merge_rti -- (sig : ghdl_signal_ptr; rti : ghdl_rti_access) Start_Procedure_Decl @@ -27305,6 +27910,17 @@ package body Translation is New_Interface_Decl (Interfaces, Param, Wki_Sig, Ghdl_Signal_Ptr); Finish_Subprogram_Decl (Interfaces, Ghdl_Process_Add_Driver); + -- procedure __ghdl_signal_direct_driver (sig : __ghdl_signal_ptr; + -- Drv : Ghdl_Ptr_type); + Start_Procedure_Decl + (Interfaces, Get_Identifier ("__ghdl_signal_direct_driver"), + O_Storage_External); + New_Interface_Decl + (Interfaces, Param, Wki_Sig, Ghdl_Signal_Ptr); + New_Interface_Decl + (Interfaces, Param, Get_Identifier ("drv"), Ghdl_Ptr_Type); + Finish_Subprogram_Decl (Interfaces, Ghdl_Signal_Direct_Driver); + declare procedure Create_Signal_Conversion (Name : String; Res : out O_Dnode) is |