diff options
author | Tristan Gingold <tgingold@free.fr> | 2020-04-09 21:24:04 +0200 |
---|---|---|
committer | Tristan Gingold <tgingold@free.fr> | 2020-04-09 21:24:36 +0200 |
commit | 32a60efc00452a5eb037f5d1f5dabb687c170c99 (patch) | |
tree | f38b3337d35da9479255e5a7e97934eb1ff2731a /src/synth/synth-stmts.adb | |
parent | db918fedf1af6da741bb6dd280719cb0f139b583 (diff) | |
download | ghdl-32a60efc00452a5eb037f5d1f5dabb687c170c99.tar.gz ghdl-32a60efc00452a5eb037f5d1f5dabb687c170c99.tar.bz2 ghdl-32a60efc00452a5eb037f5d1f5dabb687c170c99.zip |
synth: refactoring to store static values in wires.
Diffstat (limited to 'src/synth/synth-stmts.adb')
-rw-r--r-- | src/synth/synth-stmts.adb | 148 |
1 files changed, 81 insertions, 67 deletions
diff --git a/src/synth/synth-stmts.adb b/src/synth/synth-stmts.adb index 8717842d9..4f846d1fb 100644 --- a/src/synth/synth-stmts.adb +++ b/src/synth/synth-stmts.adb @@ -89,24 +89,6 @@ package body Synth.Stmts is end if; end Synth_Waveform; - procedure Synth_Assign (Wid : Wire_Id; - Typ : Type_Acc; - Val : Valtyp; - Offset : Uns32; - Loc : Source.Syn_Src) - is - Cval : Valtyp; - N : Net; - begin - Cval := Synth_Subtype_Conversion (Val, Typ, False, Loc); - if Cval = No_Valtyp then - -- In case of error. - return; - end if; - N := Get_Net (Cval); - Phi_Assign (Build_Context, Wid, N, Offset); - end Synth_Assign; - procedure Synth_Assignment_Prefix (Syn_Inst : Synth_Instance_Acc; Pfx : Node; Dest_Base : out Valtyp; @@ -139,7 +121,7 @@ package body Synth.Stmts is if Targ.Val.Kind = Value_Alias then -- Replace alias by the aliased name. - Dest_Base := (Targ.Typ, Targ.Val.A_Obj); + Dest_Base := (Targ.Val.A_Typ, Targ.Val.A_Obj); Dest_Off := Targ.Val.A_Off; else Dest_Base := Targ; @@ -147,6 +129,7 @@ package body Synth.Stmts is end if; end; when Iir_Kind_Function_Call => + -- Can be the prefix of .all Dest_Base := Synth_Expression (Syn_Inst, Pfx); Dest_Typ := Dest_Base.Typ; Dest_Off := (0, 0); @@ -156,13 +139,13 @@ package body Synth.Stmts is declare Voff : Net; Off : Value_Offsets; - Dest_W : Width; + Pfx_W : Width; begin Synth_Assignment_Prefix (Syn_Inst, Get_Prefix (Pfx), Dest_Base, Dest_Typ, Dest_Off, Dest_Voff, Dest_Rdwd); Strip_Const (Dest_Base); - Dest_W := Dest_Base.Typ.W; + Pfx_W := Dest_Typ.W; Synth_Indexed_Name (Syn_Inst, Pfx, Dest_Typ, Voff, Off); Dest_Typ := Get_Array_Element (Dest_Typ); @@ -173,7 +156,7 @@ package body Synth.Stmts is if Voff /= No_Net then if Dest_Voff = No_Net then Dest_Voff := Voff; - Dest_Rdwd := Dest_W; + Dest_Rdwd := Pfx_W; else Dest_Voff := Build_Addidx (Get_Build (Syn_Inst), Dest_Voff, Voff); @@ -204,11 +187,13 @@ package body Synth.Stmts is Res_Bnd : Bound_Type; Sl_Voff : Net; Sl_Off : Value_Offsets; + Pfx_W : Width; begin Synth_Assignment_Prefix (Syn_Inst, Get_Prefix (Pfx), Dest_Base, Dest_Typ, Dest_Off, Dest_Voff, Dest_Rdwd); Strip_Const (Dest_Base); + Pfx_W := Dest_Typ.W; Get_Onedimensional_Array_Bounds (Dest_Typ, Pfx_Bnd, El_Typ); Synth_Slice_Suffix (Syn_Inst, Pfx, Pfx_Bnd, El_Typ, @@ -223,7 +208,7 @@ package body Synth.Stmts is Dest_Voff := Build_Addidx (Get_Build (Syn_Inst), Dest_Voff, Sl_Voff); else - Dest_Rdwd := Dest_Base.Typ.W; + Dest_Rdwd := Pfx_W; Dest_Voff := Sl_Voff; end if; Dest_Typ := Create_Slice_Type (Res_Bnd.Len, El_Typ); @@ -251,7 +236,16 @@ package body Synth.Stmts is end Synth_Assignment_Prefix; type Target_Kind is - (Target_Simple, Target_Aggregate, Target_Memory); + ( + -- The target is an object or a static part of it. + Target_Simple, + + -- The target is an aggregate. + Target_Aggregate, + + -- The assignment is dynamically indexed. + Target_Memory + ); type Target_Info (Kind : Target_Kind := Target_Simple) is record -- In all cases, the type of the target is known or computed. @@ -424,46 +418,55 @@ package body Synth.Stmts is procedure Synth_Assignment (Syn_Inst : Synth_Instance_Acc; Target : Target_Info; Val : Valtyp; - Loc : Node) is + Loc : Node) + is + V : Valtyp; begin + V := Synth_Subtype_Conversion (Val, Target.Targ_Type, False, Loc); + pragma Unreferenced (Val); + if V = No_Valtyp then + -- In case of error. + return; + end if; + case Target.Kind is when Target_Aggregate => Synth_Assignment_Aggregate - (Syn_Inst, Target.Aggr, Target.Targ_Type, Val, Loc); + (Syn_Inst, Target.Aggr, Target.Targ_Type, V, Loc); when Target_Simple => if Target.Obj.Val.Kind = Value_Wire then - Synth_Assign (Target.Obj.Val.W, Target.Targ_Type, - Val, Target.Off.Net_Off, Loc); + if Is_Static (V.Val) + and then V.Typ.W = Target.Obj.Typ.W + then + pragma Assert (Target.Off = (0, 0)); + Phi_Assign_Static (Target.Obj.Val.W, Get_Memtyp (V)); + else + Phi_Assign_Net (Get_Build (Syn_Inst), Target.Obj.Val.W, + Get_Net (V), Target.Off.Net_Off); + end if; else - if not Is_Static (Val.Val) then + if not Is_Static (V.Val) then -- Maybe the error message is too cryptic ? Error_Msg_Synth (+Loc, "cannot assign a net to a static value"); else - declare - V : Valtyp; - begin - V := Val; - Strip_Const (V); - Copy_Memory (Target.Obj.Val.Mem + Target.Off.Mem_Off, - V.Val.Mem, V.Typ.Sz); - end; + Strip_Const (V); + Copy_Memory (Target.Obj.Val.Mem + Target.Off.Mem_Off, + V.Val.Mem, V.Typ.Sz); end if; end if; when Target_Memory => declare - V : Net; + N : Net; begin - V := Get_Current_Assign_Value + N := Get_Current_Assign_Value (Get_Build (Syn_Inst), Target.Mem_Obj.Val.W, Target.Mem_Moff, Target.Mem_Mwidth); - V := Build_Dyn_Insert (Get_Build (Syn_Inst), V, Get_Net (Val), + N := Build_Dyn_Insert (Get_Build (Syn_Inst), N, Get_Net (V), Target.Mem_Voff, Target.Mem_Doff); - Set_Location (V, Loc); - Synth_Assign - (Target.Mem_Obj.Val.W, Target.Targ_Type, - Create_Value_Net (V, Target.Targ_Type), - Target.Mem_Moff, Loc); + Set_Location (N, Loc); + Phi_Assign_Net (Get_Build (Syn_Inst), Target.Mem_Obj.Val.W, + N, Target.Mem_Moff); end; end case; end Synth_Assignment; @@ -712,7 +715,8 @@ package body Synth.Stmts is Off := 0; Has_Zx := False; Vec := (others => (0, 0)); - Value2logvec (Expr_Val, Vec, Off, Has_Zx); + Value2logvec (Get_Memtyp (Expr_Val), 0, Expr_Val.Typ.W, + Vec, Off, Has_Zx); if Has_Zx then Error_Msg_Synth (+Expr, "meta-values never match"); end if; @@ -771,6 +775,7 @@ package body Synth.Stmts is Wid_Heap_Sort (Arr'Length); end Sort_Wire_Id_Array; + -- Count the number of wires used in all the alternatives. function Count_Wires_In_Alternatives (Alts : Alternative_Data_Array) return Natural is @@ -793,6 +798,7 @@ package body Synth.Stmts is return Res; end Count_Wires_In_Alternatives; + -- Fill ARR from wire_id of ALTS. procedure Fill_Wire_Id_Array (Arr : out Wire_Id_Array; Alts : Alternative_Data_Array) is @@ -955,7 +961,8 @@ package body Synth.Stmts is -- If there is an assignment to Wi in Alt, it will define the -- value. if Get_Wire_Id (Alts (I).Asgns) = Wi then - Pasgns (Int32 (I)) := Get_Assign_Partial (Alts (I).Asgns); + Pasgns (Int32 (I)) := + Get_Assign_Partial_Force (Alts (I).Asgns); Alts (I).Asgns := Get_Assign_Chain (Alts (I).Asgns); else Pasgns (Int32 (I)) := No_Partial_Assign; @@ -1502,7 +1509,7 @@ package body Synth.Stmts is -- Always pass by value. Nbr_Inout := Nbr_Inout + 1; Infos (Nbr_Inout) := Info; - if Info.Kind = Target_Simple + if Info.Kind /= Target_Memory and then Is_Static (Info.Obj.Val) then Val := Create_Value_Memory (Info.Targ_Type); @@ -1514,11 +1521,11 @@ package body Synth.Stmts is end if; when Iir_Kind_Interface_Signal_Declaration => -- Always pass by reference (use an alias). - if Info.Kind /= Target_Simple then + if Info.Kind = Target_Memory then raise Internal_Error; end if; Val := Create_Value_Alias - (Info.Obj.Val, Info.Off, Info.Targ_Type); + (Info.Obj, Info.Off, Info.Targ_Type); when Iir_Kind_Interface_File_Declaration => Val := Info.Obj; when Iir_Kind_Interface_Quantity_Declaration => @@ -1694,18 +1701,18 @@ package body Synth.Stmts is New_Internal_Name (Build_Context), C.Ret_Typ.W)); C.Ret_Init := Build_Const_X (Build_Context, C.Ret_Typ.W); - Phi_Assign (Build_Context, C.W_Val, C.Ret_Init, 0); + Phi_Assign_Net (Build_Context, C.W_Val, C.Ret_Init, 0); end if; Set_Wire_Gate (C.W_En, Build_Signal (Build_Context, New_Internal_Name (Build_Context), 1)); - Phi_Assign (Build_Context, C.W_En, Get_Inst_Bit1 (Syn_Inst), 0); + Phi_Assign_Net (Build_Context, C.W_En, Get_Inst_Bit1 (Syn_Inst), 0); Set_Wire_Gate (C.W_Ret, Build_Signal (Build_Context, New_Internal_Name (Build_Context), 1)); - Phi_Assign (Build_Context, C.W_Ret, Get_Inst_Bit1 (Syn_Inst), 0); + Phi_Assign_Net (Build_Context, C.W_Ret, Get_Inst_Bit1 (Syn_Inst), 0); Decls.Synth_Declarations (C.Inst, Get_Declaration_Chain (Bod), True); if not Is_Error (C.Inst) then @@ -1736,6 +1743,10 @@ package body Synth.Stmts is pragma Unreferenced (Infos); -- Propagate assignments. + -- Wires that have been created for this subprogram will be destroyed. + -- But assignment for outer wires (passed through parameters) have + -- to be kept. We cannot merge phi because this won't be allowed for + -- local wires. Propagate_Phi_Until_Mark (Get_Build (C.Inst), Subprg_Phi, Wire_Mark); -- Free wires. @@ -1972,7 +1983,8 @@ package body Synth.Stmts is Set_Wire_Gate (Lc.W_Quit, Build_Signal (Get_Build (C.Inst), New_Internal_Name (Build_Context), 1)); - Phi_Assign (Get_Build (C.Inst), Lc.W_Quit, Get_Inst_Bit1 (C.Inst), 0); + Phi_Assign_Net (Get_Build (C.Inst), + Lc.W_Quit, Get_Inst_Bit1 (C.Inst), 0); end if; if Get_Exit_Flag (Stmt) or else Get_Next_Flag (Stmt) then @@ -1986,7 +1998,8 @@ package body Synth.Stmts is Set_Wire_Gate (Lc.W_Exit, Build_Signal (Get_Build (C.Inst), New_Internal_Name (Build_Context), 1)); - Phi_Assign (Get_Build (C.Inst), Lc.W_Exit, Get_Inst_Bit1 (C.Inst), 0); + Phi_Assign_Net (Get_Build (C.Inst), + Lc.W_Exit, Get_Inst_Bit1 (C.Inst), 0); end if; end Loop_Control_Init; @@ -2032,7 +2045,7 @@ package body Synth.Stmts is Res := Loop_Control_And (C, Res, Get_Current_Value (null, Lc.W_Quit)); end if; - Phi_Assign (Get_Build (C.Inst), C.W_En, Res, 0); + Phi_Assign_Net (Get_Build (C.Inst), C.W_En, Res, 0); end Loop_Control_Update; procedure Loop_Control_Finish (C : Seq_Context) @@ -2070,7 +2083,7 @@ package body Synth.Stmts is Release (C.Cur_Loop.Wire_Mark); - Phi_Assign (Get_Build (C.Inst), C.W_En, Res, 0); + Phi_Assign_Net (Get_Build (C.Inst), C.W_En, Res, 0); end Loop_Control_Finish; procedure Synth_Dynamic_Exit_Next_Statement @@ -2099,7 +2112,7 @@ package body Synth.Stmts is end if; -- Execution is suspended. - Phi_Assign (Get_Build (C.Inst), C.W_En, Get_Inst_Bit0 (C.Inst), 0); + Phi_Assign_Net (Get_Build (C.Inst), C.W_En, Get_Inst_Bit0 (C.Inst), 0); Lc := C.Cur_Loop; @@ -2113,13 +2126,13 @@ package body Synth.Stmts is loop if Lc.Loop_Stmt = Loop_Label then if Is_Exit then - Phi_Assign (Get_Build (C.Inst), Lc.W_Exit, - Get_Inst_Bit0 (C.Inst), 0); + Phi_Assign_Net (Get_Build (C.Inst), + Lc.W_Exit, Get_Inst_Bit0 (C.Inst), 0); end if; exit; else - Phi_Assign (Get_Build (C.Inst), Lc.W_Quit, - Get_Inst_Bit0 (C.Inst), 0); + Phi_Assign_Net (Get_Build (C.Inst), + Lc.W_Quit, Get_Inst_Bit0 (C.Inst), 0); end if; Lc := Lc.Prev_Loop; end loop; @@ -2395,17 +2408,18 @@ package body Synth.Stmts is end if; end if; if Is_Dyn then - Phi_Assign (Get_Build (C.Inst), C.W_Val, Get_Net (Val), 0); + Phi_Assign_Net (Get_Build (C.Inst), C.W_Val, Get_Net (Val), 0); end if; end if; if Is_Dyn then -- The subprogram has returned. Do not execute further statements. - Phi_Assign (Get_Build (C.Inst), C.W_En, Get_Inst_Bit0 (C.Inst), 0); + Phi_Assign_Net (Get_Build (C.Inst), + C.W_En, Get_Inst_Bit0 (C.Inst), 0); if C.W_Ret /= No_Wire_Id then - Phi_Assign (Get_Build (C.Inst), C.W_Ret, - Get_Inst_Bit0 (C.Inst), 0); + Phi_Assign_Net (Get_Build (C.Inst), + C.W_Ret, Get_Inst_Bit0 (C.Inst), 0); end if; end if; @@ -2684,7 +2698,7 @@ package body Synth.Stmts is Set_Wire_Gate (C.W_En, Build_Signal (Build_Context, New_Internal_Name (Build_Context), 1)); - Phi_Assign (Build_Context, C.W_En, Get_Inst_Bit1 (Syn_Inst), 0); + Phi_Assign_Net (Build_Context, C.W_En, Get_Inst_Bit1 (Syn_Inst), 0); case Iir_Kinds_Process_Statement (Get_Kind (Proc)) is when Iir_Kind_Sensitized_Process_Statement => |