diff options
author | Tristan Gingold <tgingold@free.fr> | 2020-01-08 07:27:14 +0100 |
---|---|---|
committer | Tristan Gingold <tgingold@free.fr> | 2020-01-08 07:28:29 +0100 |
commit | e4384df2d52f319b2a8e45b3a1a26277d88760b5 (patch) | |
tree | db40677456c84e8f159d4d94190589237e173344 /src/synth/synth-stmts.adb | |
parent | 513ea00c0d355c1534b8ed6f28a78ca15c91d612 (diff) | |
download | ghdl-e4384df2d52f319b2a8e45b3a1a26277d88760b5.tar.gz ghdl-e4384df2d52f319b2a8e45b3a1a26277d88760b5.tar.bz2 ghdl-e4384df2d52f319b2a8e45b3a1a26277d88760b5.zip |
synth: improve support of out/inout variable parameters.
Diffstat (limited to 'src/synth/synth-stmts.adb')
-rw-r--r-- | src/synth/synth-stmts.adb | 74 |
1 files changed, 66 insertions, 8 deletions
diff --git a/src/synth/synth-stmts.adb b/src/synth/synth-stmts.adb index 4717cd488..4986ea1b1 100644 --- a/src/synth/synth-stmts.adb +++ b/src/synth/synth-stmts.adb @@ -51,6 +51,7 @@ with Synth.Flags; with Synth.Debugger; with Netlists.Builders; use Netlists.Builders; +with Netlists.Folds; use Netlists.Folds; with Netlists.Gates; with Netlists.Utils; use Netlists.Utils; with Netlists.Locations; use Netlists.Locations; @@ -538,6 +539,22 @@ package body Synth.Stmts is return Create_Value_Net (N, Typ); end Synth_Read_Memory; + function Synth_Read (Syn_Inst : Synth_Instance_Acc; + Targ : Target_Info; + Loc : Node) return Value_Acc + is + N : Net; + begin + if Targ.Kind = Target_Simple then + N := Build2_Extract (Get_Build (Syn_Inst), + Get_Net (Targ.Obj), Targ.Off, Targ.Targ_Type.W); + return Create_Value_Net (N, Targ.Targ_Type); + else + return Synth_Read_Memory (Syn_Inst, Targ.Obj, Targ.Off, No_Net, + Targ.Targ_Type, Loc); + end if; + end Synth_Read; + -- Concurrent or sequential simple signal assignment procedure Synth_Simple_Signal_Assignment (Syn_Inst : Synth_Instance_Acc; Stmt : Node) @@ -1432,12 +1449,8 @@ package body Synth.Stmts is raise Internal_Error; end if; Val := Info.Obj; - elsif Info.Kind = Target_Simple then - Val := Info.Obj; else - Val := Synth_Read_Memory - (Caller_Inst, Info.Obj, Info.Off, No_Net, - Info.Targ_Type, Assoc); + Val := Synth_Read (Caller_Inst, Info, Assoc); end if; when Iir_Kind_Interface_Signal_Declaration => -- Always pass by reference (use an alias). @@ -1463,7 +1476,13 @@ package body Synth.Stmts is Create_Object (Subprg_Inst, Inter, Val); when Iir_Kind_Interface_Variable_Declaration => -- Arguments are passed by copy. - Create_Object (Subprg_Inst, Inter, Unshare (Val, Current_Pool)); + if Is_Static (Val) or else Get_Mode (Inter) = Iir_In_Mode then + Val := Unshare (Val, Current_Pool); + else + -- Will be changed to a wire. + null; + end if; + Create_Object (Subprg_Inst, Inter, Val); when Iir_Kind_Interface_Signal_Declaration => Create_Object (Subprg_Inst, Inter, Val); when Iir_Kind_Interface_File_Declaration => @@ -1486,6 +1505,37 @@ package body Synth.Stmts is Inter_Chain, Assoc_Chain, Infos); end Synth_Subprogram_Association; + -- Create wires for out and inout interface variables. + procedure Synth_Subprogram_Association_Wires + (Subprg_Inst : Synth_Instance_Acc; Inter_Chain : Node; Assoc_Chain : Node) + is + Inter : Node; + Assoc : Node; + Val : Value_Acc; + Iterator : Association_Iterator; + Wire : Wire_Id; + begin + -- Process in INTER order. + Association_Iterate_Init (Iterator, Inter_Chain, Assoc_Chain); + loop + Association_Iterate_Next (Iterator, Inter, Assoc); + exit when Inter = Null_Node; + + if Get_Mode (Inter) in Iir_Out_Modes + and then Get_Kind (Inter) = Iir_Kind_Interface_Variable_Declaration + then + Val := Get_Value (Subprg_Inst, Inter); + -- Arguments are passed by copy. + Wire := Alloc_Wire (Wire_Variable, Inter); + Set_Wire_Gate (Wire, Get_Net (Val)); + + Val := Create_Value_Wire (Wire, Val.Typ); + Create_Object_Force (Subprg_Inst, Inter, null); + Create_Object_Force (Subprg_Inst, Inter, Val); + end if; + end loop; + end Synth_Subprogram_Association_Wires; + procedure Synth_Subprogram_Back_Association (Subprg_Inst : Synth_Instance_Acc; Caller_Inst : Synth_Instance_Acc; @@ -1513,6 +1563,12 @@ package body Synth.Stmts is Nbr_Inout := Nbr_Inout + 1; Val := Get_Value (Subprg_Inst, Inter); Synth_Assignment (Caller_Inst, Infos (Nbr_Inout), Val, Assoc); + + -- Free wire used for out/inout interface variables. + if Val.Kind = Value_Wire then + Phi_Discard_Wires (Val.W, No_Wire_Id); + Free_Wire (Val.W); + end if; end if; Next_Association_Interface (Assoc, Assoc_Inter); @@ -1557,6 +1613,8 @@ package body Synth.Stmts is Push_Phi; + Synth_Subprogram_Association_Wires (Sub_Inst, Inter_Chain, Assoc_Chain); + if Is_Func then -- Set a default value for the return. C.Ret_Typ := Get_Value_Type (Syn_Inst, Get_Return_Type (Imp)); @@ -1685,8 +1743,8 @@ package body Synth.Stmts is Sub_Inst : Synth_Instance_Acc; begin Areapools.Mark (Area_Mark, Instance_Pool.all); - Sub_Inst := Make_Instance (Syn_Inst, Bod, - New_Internal_Name (Build_Context)); + Sub_Inst := Make_Instance (Syn_Inst, Bod, + New_Internal_Name (Build_Context)); Synth_Subprogram_Association (Sub_Inst, Syn_Inst, Inter_Chain, Assoc_Chain, Infos); |