diff options
author | Tristan Gingold <tgingold@free.fr> | 2022-09-21 04:07:52 +0200 |
---|---|---|
committer | Tristan Gingold <tgingold@free.fr> | 2022-09-25 11:43:23 +0200 |
commit | 5a868c938d1fc8d185fffdc537fc84661e7f6840 (patch) | |
tree | 14d55c4fe7daaf425d7182a81d1e3df65aac20f5 /src/synth | |
parent | d51bc79357607a59a1ec90b5a54ced5c0a7bb1e3 (diff) | |
download | ghdl-5a868c938d1fc8d185fffdc537fc84661e7f6840.tar.gz ghdl-5a868c938d1fc8d185fffdc537fc84661e7f6840.tar.bz2 ghdl-5a868c938d1fc8d185fffdc537fc84661e7f6840.zip |
synth-vhdl_stmts: refactoring
Diffstat (limited to 'src/synth')
-rw-r--r-- | src/synth/synth-vhdl_stmts.adb | 397 |
1 files changed, 208 insertions, 189 deletions
diff --git a/src/synth/synth-vhdl_stmts.adb b/src/synth/synth-vhdl_stmts.adb index 2986025b2..837961b8b 100644 --- a/src/synth/synth-vhdl_stmts.adb +++ b/src/synth/synth-vhdl_stmts.adb @@ -1954,14 +1954,16 @@ package body Synth.Vhdl_Stmts is end case; end Info_To_Valtyp; - procedure Synth_Subprogram_Associations (Subprg_Inst : Synth_Instance_Acc; - Caller_Inst : Synth_Instance_Acc; - Init : Association_Iterator_Init) + procedure Synth_Subprogram_Association + (Subprg_Inst : Synth_Instance_Acc; + Caller_Inst : Synth_Instance_Acc; + Inter : Node; + Assoc : Node; + Iterator : in out Association_Iterator) is + pragma Unreferenced (Iterator); Marker : Mark_Type; - Inter : Node; Inter_Type : Node; - Assoc : Node; Actual : Node; Formal : Node; Formal_Base : Valtyp; @@ -1969,218 +1971,235 @@ package body Synth.Vhdl_Stmts is Formal_Offs : Value_Offsets; Formal_Dyn : Dyn_Name; Val : Valtyp; - Iterator : Association_Iterator; Info : Target_Info; Actual_Inst : Synth_Instance_Acc; begin Mark_Expr_Pool (Marker); - Set_Instance_Const (Subprg_Inst, True); - - -- Process in INTER order. - Association_Iterate_Init (Iterator, Init); - loop - Association_Iterate_Next (Iterator, Inter, Assoc); - exit when Inter = Null_Node; - - -- Actual and formal. - Actual_Inst := Caller_Inst; - if Assoc /= Null_Node - and then - Get_Kind (Assoc) = Iir_Kind_Association_Element_By_Individual + -- Actual and formal. + Actual_Inst := Caller_Inst; + if Assoc /= Null_Node + and then Get_Kind (Assoc) = Iir_Kind_Association_Element_By_Individual + then + -- Special case: preliminary individual association. + Formal := Inter; + Actual := Null_Node; + else + if Assoc = Null_Node + or else Get_Kind (Assoc) = Iir_Kind_Association_Element_Open then + -- Missing association or open association: use default value. Formal := Inter; - Actual := Null_Node; - else - if Assoc = Null_Node - or else Get_Kind (Assoc) = Iir_Kind_Association_Element_Open - then - Formal := Inter; - Actual := Get_Default_Value (Inter); - Actual_Inst := Subprg_Inst; - elsif Get_Kind (Assoc) = Iir_Kind_Association_Element_By_Expression - then - if Get_Whole_Association_Flag (Assoc) then - Formal := Inter; - else - Formal := Get_Formal (Assoc); - end if; - Actual := Get_Actual (Assoc); - else + Actual := Get_Default_Value (Inter); + Actual_Inst := Subprg_Inst; + elsif Get_Kind (Assoc) = Iir_Kind_Association_Element_By_Expression + then + -- Normal case: formal and actual. + if Get_Whole_Association_Flag (Assoc) then Formal := Inter; - Actual := Assoc; - end if; - end if; - - if Formal = Inter then - -- Special case for protected type as the slot describes - -- declarations. - Inter_Type := Get_Type (Inter); - if Get_Kind (Inter_Type) = Iir_Kind_Protected_Type_Declaration then - Formal_Typ := Protected_Type; else - Formal_Typ := Get_Subtype_Object (Subprg_Inst, Inter_Type); + Formal := Get_Formal (Assoc); end if; - Formal_Offs := No_Value_Offsets; - Formal_Dyn := No_Dyn_Name; + Actual := Get_Actual (Assoc); else - Synth_Assignment_Prefix - (Caller_Inst, Subprg_Inst, Formal, - Formal_Base, Formal_Typ, Formal_Offs, Formal_Dyn); + -- Just an expression. + Formal := Inter; + Actual := Assoc; end if; + end if; - if Actual = Null_Node then - -- For By_Individual. - Val := Create_Value_Memory (Formal_Typ, Expr_Pool'Access); - elsif Get_Mode (Inter) /= Iir_In_Mode - or else Get_Kind (Inter) = Iir_Kind_Interface_Signal_Declaration - or else Get_Kind (Inter) = Iir_Kind_Interface_File_Declaration - then - Info := Synth_Target (Caller_Inst, Actual); + if Formal = Inter then + -- Special case for protected type as the slot describes + -- declarations. + Inter_Type := Get_Type (Inter); + if Get_Kind (Inter_Type) = Iir_Kind_Protected_Type_Declaration then + Formal_Typ := Protected_Type; else - -- For constants and in variables. - Val := Synth_Expression_With_Type - (Actual_Inst, Actual, Formal_Typ); - if Val = No_Valtyp then - Set_Error (Subprg_Inst); - return; - end if; - Val := Synth_Subtype_Conversion - (Subprg_Inst, Val, Formal_Typ, True, Assoc); - if Val = No_Valtyp then - Set_Error (Subprg_Inst); - return; - end if; - Val := Unshare (Val, Instance_Pool); - Val.Typ := Unshare (Val.Typ, Instance_Pool); - if Get_Instance_Const (Subprg_Inst) - and then not Flags.Flag_Simulation - and then not Is_Static (Val.Val) - then - Set_Instance_Const (Subprg_Inst, False); - end if; + Formal_Typ := Get_Subtype_Object (Subprg_Inst, Inter_Type); end if; + Formal_Offs := No_Value_Offsets; + Formal_Dyn := No_Dyn_Name; + else + -- Individual association. + Synth_Assignment_Prefix + (Caller_Inst, Subprg_Inst, Formal, + Formal_Base, Formal_Typ, Formal_Offs, Formal_Dyn); + pragma Assert (Formal_Dyn = No_Dyn_Name); + end if; - if Formal /= Inter - and then not Get_Whole_Association_Flag (Assoc) + if Actual = Null_Node then + -- For By_Individual. + Val := Create_Value_Memory (Formal_Typ, Expr_Pool'Access); + elsif Get_Mode (Inter) /= Iir_In_Mode + or else Get_Kind (Inter) = Iir_Kind_Interface_Signal_Declaration + or else Get_Kind (Inter) = Iir_Kind_Interface_File_Declaration + then + -- Actual is a reference. + Info := Synth_Target (Caller_Inst, Actual); + else + -- For constants and in variables. + Val := Synth_Expression_With_Type (Actual_Inst, Actual, Formal_Typ); + if Val = No_Valtyp then + Set_Error (Subprg_Inst); + return; + end if; + Val := Synth_Subtype_Conversion + (Subprg_Inst, Val, Formal_Typ, True, Assoc); + if Val = No_Valtyp then + Set_Error (Subprg_Inst); + return; + end if; + Val := Unshare (Val, Instance_Pool); + Val.Typ := Unshare (Val.Typ, Instance_Pool); + if Get_Instance_Const (Subprg_Inst) + and then not Flags.Flag_Simulation + and then not Is_Static (Val.Val) then - raise Internal_Error; + Set_Instance_Const (Subprg_Inst, False); end if; + end if; + + if Formal /= Inter + and then not Get_Whole_Association_Flag (Assoc) + then + raise Internal_Error; + end if; - case Iir_Kinds_Interface_Object_Declaration (Get_Kind (Inter)) is - when Iir_Kind_Interface_Constant_Declaration => - -- Pass by copy. - Create_Object (Subprg_Inst, Inter, Val); - when Iir_Kind_Interface_Variable_Declaration => - -- Always pass by value. - if Is_Copyback_Parameter (Inter) then - -- For the copy back: keep info of formal. - Create_Object (Caller_Inst, Assoc, Info_To_Valtyp (Info)); + case Iir_Kinds_Interface_Object_Declaration (Get_Kind (Inter)) is + when Iir_Kind_Interface_Constant_Declaration => + -- Pass by copy. + Create_Object (Subprg_Inst, Inter, Val); + when Iir_Kind_Interface_Variable_Declaration => + -- Always pass by value. + if Is_Copyback_Parameter (Inter) then + -- For the copy back: keep info of formal. + Create_Object (Caller_Inst, Assoc, Info_To_Valtyp (Info)); + end if; + if Get_Mode (Inter) /= Iir_In_Mode then + if Info.Kind /= Target_Memory + and then Info.Obj.Val.Kind = Value_Memory + then + -- FIXME: the subtype conversion will copy the value, so + -- allocate here in current_pool ? + Val := Create_Value_Memory (Info.Targ_Type, Instance_Pool); + Copy_Memory (Val.Val.Mem, + Info.Obj.Val.Mem + Info.Off.Mem_Off, + Info.Targ_Type.Sz); + elsif Info.Kind = Target_Simple + and then Info.Obj.Val.Kind = Value_File + then + -- For vhdl-87 + Val := Create_Value_File + (Info.Targ_Type, Info.Obj.Val.File, Instance_Pool); + else + Val := Synth_Read (Caller_Inst, Info, Assoc); + Val := Unshare (Val, Instance_Pool); + if not Flags.Flag_Simulation then + Set_Instance_Const (Subprg_Inst, False); + end if; end if; - if Get_Mode (Inter) /= Iir_In_Mode then - if Info.Kind /= Target_Memory - and then Info.Obj.Val.Kind = Value_Memory - then - -- FIXME: the subtype conversion will copy the value, so - -- allocate here in current_pool ? - Val := Create_Value_Memory - (Info.Targ_Type, Instance_Pool); - Copy_Memory (Val.Val.Mem, - Info.Obj.Val.Mem + Info.Off.Mem_Off, - Info.Targ_Type.Sz); - elsif Info.Kind = Target_Simple - and then Info.Obj.Val.Kind = Value_File - then - -- For vhdl-87 - Val := Create_Value_File - (Info.Targ_Type, Info.Obj.Val.File, Instance_Pool); + end if; + if Get_Mode (Inter) /= Iir_Out_Mode then + -- Always passed by value + Val := Synth_Subtype_Conversion + (Subprg_Inst, Val, Formal_Typ, True, Assoc); + Val := Unshare (Val, Instance_Pool); + else + -- Use default value + -- FIXME: also for wires ? + if Val.Val.Kind = Value_Memory then + if Is_Bounded_Type (Formal_Typ) then + Write_Value_Default (Val.Val.Mem, Formal_Typ); else - Val := Synth_Read (Caller_Inst, Info, Assoc); - Val := Unshare (Val, Instance_Pool); - if not Flags.Flag_Simulation then - Set_Instance_Const (Subprg_Inst, False); - end if; + Write_Value_Default (Val.Val.Mem, Val.Typ); end if; end if; - if Get_Mode (Inter) /= Iir_Out_Mode then - -- Always passed by value - Val := Synth_Subtype_Conversion - (Subprg_Inst, Val, Formal_Typ, True, Assoc); - Val := Unshare (Val, Instance_Pool); - else - -- Use default value - -- FIXME: also for wires ? - if Val.Val.Kind = Value_Memory then - if Is_Bounded_Type (Formal_Typ) then - Write_Value_Default (Val.Val.Mem, Formal_Typ); - else - Write_Value_Default (Val.Val.Mem, Val.Typ); - end if; + end if; + Val.Typ := Unshare (Val.Typ, Instance_Pool); + Create_Object (Subprg_Inst, Inter, Val); + when Iir_Kind_Interface_Signal_Declaration => + -- Always pass by reference (use an alias). + if Info.Kind = Target_Memory then + raise Internal_Error; + end if; + if not Flags.Flag_Simulation then + Set_Instance_Const (Subprg_Inst, False); + end if; + Val := Create_Value_Alias + (Info.Obj, Info.Off, Info.Targ_Type, Instance_Pool); + -- LRM08 4.2.2.3 Signal parameters + -- If an actual signal is associated with a signal parameter + -- of mode IN or INOUT, and if the type of the formal is a + -- scalar type, then it is an error if the subtype of the + -- actual is not compatible with the subtype of the formal. + -- Similarly, if an actual signal is associated with a signal + -- parameter of mode OUT or INOUT, and if the type of the + -- actual is a scalar type, then it is an error if the subtype + -- of the formal is not compatible with the subtype of the + -- actual. + if Get_Kind (Get_Type (Inter)) in + Iir_Kinds_Scalar_Type_And_Subtype_Definition + then + if Get_Mode (Inter) in Iir_In_Modes then + if not Is_Scalar_Subtype_Compatible (Val.Typ, Formal_Typ) + then + Error_Msg_Synth + (+Actual, + "scalar subtype of actual is not compatible with " + & "signal formal interface"); end if; end if; - Val.Typ := Unshare (Val.Typ, Instance_Pool); - Create_Object (Subprg_Inst, Inter, Val); - when Iir_Kind_Interface_Signal_Declaration => - -- Always pass by reference (use an alias). - if Info.Kind = Target_Memory then - raise Internal_Error; - end if; - if not Flags.Flag_Simulation then - Set_Instance_Const (Subprg_Inst, False); - end if; - Val := Create_Value_Alias - (Info.Obj, Info.Off, Info.Targ_Type, Instance_Pool); - -- LRM08 4.2.2.3 Signal parameters - -- If an actual signal is associated with a signal parameter - -- of mode IN or INOUT, and if the type of the formal is a - -- scalar type, then it is an error if the subtype of the - -- actual is not compatible with the subtype of the formal. - -- Similarly, if an actual signal is associated with a signal - -- parameter of mode OUT or INOUT, and if the type of the - -- actual is a scalar type, then it is an error if the subtype - -- of the formal is not compatible with the subtype of the - -- actual. - if Get_Kind (Get_Type (Inter)) in - Iir_Kinds_Scalar_Type_And_Subtype_Definition - then - if Get_Mode (Inter) in Iir_In_Modes then - if not Is_Scalar_Subtype_Compatible (Val.Typ, Formal_Typ) - then - Error_Msg_Synth - (+Actual, - "scalar subtype of actual is not compatible with " - & "signal formal interface"); - end if; - end if; - if Get_Mode (Inter) in Iir_Out_Modes then - if not Is_Scalar_Subtype_Compatible (Formal_Typ, Val.Typ) - then - Error_Msg_Synth - (+Actual, - "signal formal interface scalar subtype is not " - & "compatible with of actual subtype"); - end if; + if Get_Mode (Inter) in Iir_Out_Modes then + if not Is_Scalar_Subtype_Compatible (Formal_Typ, Val.Typ) + then + Error_Msg_Synth + (+Actual, + "signal formal interface scalar subtype is not " + & "compatible with of actual subtype"); end if; - else - -- Check matching. - -- This is equivalent to subtype conversion for non-scalar - -- types. - Val := Synth_Subtype_Conversion - (Subprg_Inst, Val, Formal_Typ, True, Assoc); - Val := Unshare (Val, Instance_Pool); end if; - if Val.Typ /= null then - Val.Typ := Unshare (Val.Typ, Instance_Pool); - end if; - Create_Object (Subprg_Inst, Inter, Val); - when Iir_Kind_Interface_File_Declaration => - Val := Info.Obj; - Create_Object (Subprg_Inst, Inter, Val); - when Iir_Kind_Interface_Quantity_Declaration => - raise Internal_Error; - end case; + else + -- Check matching. + -- This is equivalent to subtype conversion for non-scalar + -- types. + Val := Synth_Subtype_Conversion + (Subprg_Inst, Val, Formal_Typ, True, Assoc); + Val := Unshare (Val, Instance_Pool); + end if; + if Val.Typ /= null then + Val.Typ := Unshare (Val.Typ, Instance_Pool); + end if; + Create_Object (Subprg_Inst, Inter, Val); + when Iir_Kind_Interface_File_Declaration => + Val := Info.Obj; + Create_Object (Subprg_Inst, Inter, Val); + when Iir_Kind_Interface_Quantity_Declaration => + raise Internal_Error; + end case; - Release_Expr_Pool (Marker); + Release_Expr_Pool (Marker); + end Synth_Subprogram_Association; + + procedure Synth_Subprogram_Associations (Subprg_Inst : Synth_Instance_Acc; + Caller_Inst : Synth_Instance_Acc; + Init : Association_Iterator_Init) + is + Inter : Node; + Assoc : Node; + Iterator : Association_Iterator; + begin + Set_Instance_Const (Subprg_Inst, True); + + -- Process in INTER order. + Association_Iterate_Init (Iterator, Init); + loop + Association_Iterate_Next (Iterator, Inter, Assoc); + exit when Inter = Null_Node; + + Synth_Subprogram_Association + (Subprg_Inst, Caller_Inst, Inter, Assoc, Iterator); + + exit when Is_Error (Subprg_Inst); end loop; end Synth_Subprogram_Associations; |