diff options
author | Tristan Gingold <tgingold@free.fr> | 2020-05-02 07:59:09 +0200 |
---|---|---|
committer | Tristan Gingold <tgingold@free.fr> | 2020-05-02 07:59:09 +0200 |
commit | aeb47655ddfed9d3fd85c4986d21a60f83b9a8c6 (patch) | |
tree | aa27d773849c84fffd2fd25bb0893b1bc0ebe7ef /src/synth | |
parent | e98cc23b32e85d7f31ca6427d40c33df70749238 (diff) | |
download | ghdl-aeb47655ddfed9d3fd85c4986d21a60f83b9a8c6.tar.gz ghdl-aeb47655ddfed9d3fd85c4986d21a60f83b9a8c6.tar.bz2 ghdl-aeb47655ddfed9d3fd85c4986d21a60f83b9a8c6.zip |
synth: use static values for control nets when possible.
Diffstat (limited to 'src/synth')
-rw-r--r-- | src/synth/synth-environment.adb | 120 | ||||
-rw-r--r-- | src/synth/synth-environment.ads | 3 | ||||
-rw-r--r-- | src/synth/synth-objtypes.adb | 35 | ||||
-rw-r--r-- | src/synth/synth-objtypes.ads | 6 | ||||
-rw-r--r-- | src/synth/synth-stmts.adb | 186 | ||||
-rw-r--r-- | src/synth/synth-stmts.ads | 1 | ||||
-rw-r--r-- | src/synth/synth-values.adb | 19 | ||||
-rw-r--r-- | src/synth/synth-values.ads | 1 |
8 files changed, 241 insertions, 130 deletions
diff --git a/src/synth/synth-environment.adb b/src/synth/synth-environment.adb index cf5384eb3..ff295dba9 100644 --- a/src/synth/synth-environment.adb +++ b/src/synth/synth-environment.adb @@ -156,6 +156,11 @@ package body Synth.Environment is return Assign_Table.Table (Asgn).Val.Asgns; end Get_Assign_Partial; + function Get_Assign_Partial (Asgn : Seq_Assign) return Seq_Assign_Value is + begin + return Assign_Table.Table (Asgn).Val; + end Get_Assign_Partial; + function New_Partial_Assign (Val : Net; Offset : Uns32) return Partial_Assign is begin @@ -198,8 +203,9 @@ package body Synth.Environment is Nbr => 0)); end Push_Phi; + -- Concatenate when possible partial assignments of HEAD. procedure Merge_Partial_Assignments - (Ctxt : Context_Acc; Head : Partial_Assign) + (Ctxt : Context_Acc; Head : Seq_Assign_Value) is use Netlists.Concats; First : Partial_Assign; @@ -209,7 +215,11 @@ package body Synth.Environment is Next_Off : Uns32; Next_Val : Net; begin - First := Head; + if Head.Is_Static then + return; + end if; + + First := Head.Asgns; loop exit when First = No_Partial_Assign; @@ -1310,26 +1320,81 @@ package body Synth.Environment is end Merge_Assigns; -- Force the value of a Seq_Assign to be a net if needed, return it. - function Get_Assign_Partial_Force (Asgn : Seq_Assign) return Partial_Assign + function Get_Assign_Value_Force (Val : Seq_Assign_Value) + return Partial_Assign is - Asgn_Rec : Seq_Assign_Record renames Assign_Table.Table (Asgn); N : Net; - Res : Partial_Assign; begin - if Asgn_Rec.Val.Is_Static then - N := Synth.Context.Get_Memtyp_Net (Asgn_Rec.Val.Val); - Res := New_Partial_Assign (N, 0); - if False then - -- Overwrite ? - Asgn_Rec.Val := (Is_Static => False, - Asgns => Res); - end if; + if Val.Is_Static then + N := Synth.Context.Get_Memtyp_Net (Val.Val); + return New_Partial_Assign (N, 0); else - Res := Asgn_Rec.Val.Asgns; + return Val.Asgns; end if; - return Res; + end Get_Assign_Value_Force; + + -- Force the value of a Seq_Assign to be a net if needed, return it. + function Get_Assign_Partial_Force (Asgn : Seq_Assign) + return Partial_Assign is + begin + return Get_Assign_Value_Force (Get_Assign_Partial (Asgn)); end Get_Assign_Partial_Force; + function Merge_Static_Assigns (Wid : Wire_Id; Tv, Fv : Seq_Assign_Value) + return Boolean + is + Prev : Memtyp; + begin + -- First case: both TV and FV are static. + if Tv.Is_Static and then Fv.Is_Static then + if Is_Equal (Tv.Val, Fv.Val) then + Phi_Assign_Static (Wid, Tv.Val); + return True; + else + return False; + end if; + end if; + + -- If either TV or FV are not static, they cannot be merged. + if not Tv.Is_Static and then Tv.Asgns /= No_Partial_Assign + then + return False; + end if; + if not Fv.Is_Static and then Fv.Asgns /= No_Partial_Assign + then + return False; + end if; + + -- Get the previous value. + declare + Wire_Rec : Wire_Id_Record renames Wire_Id_Table.Table (Wid); + pragma Assert (Wire_Rec.Kind /= Wire_None); + First_Seq : Seq_Assign; + begin + -- Latest seq assign + First_Seq := Wire_Rec.Cur_Assign; + + -- If no seq assign, fails. + if First_Seq = No_Seq_Assign then + return False; + end if; + + if not Get_Assign_Is_Static (First_Seq) then + return False; + end if; + Prev := Get_Assign_Static_Val (First_Seq); + end; + + if Tv.Is_Static then + pragma Assert (Fv = No_Seq_Assign_Value); + return Is_Equal (Tv.Val, Prev); + else + pragma Assert (Fv.Is_Static); + pragma Assert (Tv = No_Seq_Assign_Value); + return Is_Equal (Fv.Val, Prev); + end if; + end Merge_Static_Assigns; + -- Add muxes for two lists T and F of assignments. procedure Merge_Phis (Ctxt : Builders.Context_Acc; Sel : Net; @@ -1339,7 +1404,7 @@ package body Synth.Environment is T_Asgns : Seq_Assign; F_Asgns : Seq_Assign; W : Wire_Id; - Tp, Fp : Partial_Assign; + Tv, Fv : Seq_Assign_Value; begin T_Asgns := Sort_Phi (T); F_Asgns := Sort_Phi (F); @@ -1352,8 +1417,8 @@ package body Synth.Environment is then -- Has an assignment only for the false branch. W := Get_Wire_Id (F_Asgns); - Fp := Get_Assign_Partial_Force (F_Asgns); - Tp := No_Partial_Assign; + Fv := Get_Assign_Partial (F_Asgns); + Tv := No_Seq_Assign_Value; F_Asgns := Get_Assign_Chain (F_Asgns); elsif F_Asgns = No_Seq_Assign or else (T_Asgns /= No_Seq_Assign @@ -1361,23 +1426,28 @@ package body Synth.Environment is then -- Has an assignment only for the true branch. W := Get_Wire_Id (T_Asgns); - Fp := No_Partial_Assign; - Tp := Get_Assign_Partial_Force (T_Asgns); + Fv := No_Seq_Assign_Value; + Tv := Get_Assign_Partial (T_Asgns); T_Asgns := Get_Assign_Chain (T_Asgns); else -- Has assignments for both the true and the false branch. pragma Assert (Get_Wire_Id (F_Asgns) = Get_Wire_Id (T_Asgns)); W := Get_Wire_Id (F_Asgns); - Fp := Get_Assign_Partial_Force (F_Asgns); - Tp := Get_Assign_Partial_Force (T_Asgns); + Fv := Get_Assign_Partial (F_Asgns); + Tv := Get_Assign_Partial (T_Asgns); T_Asgns := Get_Assign_Chain (T_Asgns); F_Asgns := Get_Assign_Chain (F_Asgns); end if; -- Merge partial assigns as much as possible. This reduce -- propagation of splits. - Merge_Partial_Assignments (Ctxt, Fp); - Merge_Partial_Assignments (Ctxt, Tp); - Merge_Assigns (Ctxt, W, Sel, Fp, Tp, Stmt); + Merge_Partial_Assignments (Ctxt, Fv); + Merge_Partial_Assignments (Ctxt, Tv); + if not Merge_Static_Assigns (W, Tv, Fv) then + Merge_Assigns (Ctxt, W, Sel, + Get_Assign_Value_Force (Fv), + Get_Assign_Value_Force (Tv), + Stmt); + end if; end loop; end Merge_Phis; diff --git a/src/synth/synth-environment.ads b/src/synth/synth-environment.ads index a183e68ca..a2f209302 100644 --- a/src/synth/synth-environment.ads +++ b/src/synth/synth-environment.ads @@ -281,6 +281,9 @@ private end case; end record; + No_Seq_Assign_Value : constant Seq_Assign_Value := + (Is_Static => False, Asgns => No_Partial_Assign); + type Seq_Assign_Record is record -- Target of the assignment. Id : Wire_Id; diff --git a/src/synth/synth-objtypes.adb b/src/synth/synth-objtypes.adb index 8c9867a28..10602256b 100644 --- a/src/synth/synth-objtypes.adb +++ b/src/synth/synth-objtypes.adb @@ -661,14 +661,14 @@ package body Synth.Objtypes is return Read_Fp64 (Mt.Mem); end Read_Fp64; + function To_Address is new Ada.Unchecked_Conversion + (Memory_Ptr, System.Address); + function To_Memory_Ptr is new Ada.Unchecked_Conversion + (System.Address, Memory_Ptr); + function "+" (Base : Memory_Ptr; Off : Size_Type) return Memory_Ptr is use System.Storage_Elements; - - function To_Address is new Ada.Unchecked_Conversion - (Memory_Ptr, System.Address); - function To_Memory_Ptr is new Ada.Unchecked_Conversion - (System.Address, Memory_Ptr); begin return To_Memory_Ptr (To_Address (Base) + Storage_Offset (Off)); end "+"; @@ -758,11 +758,36 @@ package body Synth.Objtypes is return (Vtype, Res); end Create_Memory_Discrete; + function Is_Equal (L, R : Memtyp) return Boolean is + begin + if L = R then + return True; + end if; + + if L.Typ.Sz /= R.Typ.Sz then + return False; + end if; + + -- FIXME: not correct for records, not correct for floats! + for I in 1 .. L.Typ.Sz loop + if L.Mem (I - 1) /= R.Mem (I - 1) then + return False; + end if; + end loop; + return True; + end Is_Equal; + + Bit0_Mem : constant Memory_Element := 0; + Bit1_Mem : constant Memory_Element := 1; + procedure Init is begin Instance_Pool := Global_Pool'Access; Boolean_Type := Create_Bit_Type; Logic_Type := Create_Logic_Type; Bit_Type := Create_Bit_Type; + + Bit0 := (Bit_Type, To_Memory_Ptr (Bit0_Mem'Address)); + Bit1 := (Bit_Type, To_Memory_Ptr (Bit1_Mem'Address)); end Init; end Synth.Objtypes; diff --git a/src/synth/synth-objtypes.ads b/src/synth/synth-objtypes.ads index c79a473c4..91ffcc32e 100644 --- a/src/synth/synth-objtypes.ads +++ b/src/synth/synth-objtypes.ads @@ -281,10 +281,16 @@ package Synth.Objtypes is function Create_Memory (Vtype : Type_Acc) return Memtyp; + function Is_Equal (L, R : Memtyp) return Boolean; + procedure Init; -- Set by Init. Boolean_Type : Type_Acc := null; Logic_Type : Type_Acc := null; Bit_Type : Type_Acc := null; + + -- Also set by init. + Bit0 : Memtyp; + Bit1 : Memtyp; end Synth.Objtypes; diff --git a/src/synth/synth-stmts.adb b/src/synth/synth-stmts.adb index c2e923c65..b24425943 100644 --- a/src/synth/synth-stmts.adb +++ b/src/synth/synth-stmts.adb @@ -20,6 +20,7 @@ with Ada.Unchecked_Deallocation; +with Grt.Types; use Grt.Types; with Grt.Algos; with Areapools; with Name_Table; @@ -1725,6 +1726,7 @@ package body Synth.Stmts is Imp : constant Node := Get_Implementation (Call); Is_Func : constant Boolean := Is_Function_Declaration (Imp); Bod : constant Node := Vhdl.Sem_Inst.Get_Subprogram_Body_Origin (Imp); + Ctxt : constant Context_Acc := Get_Build (Syn_Inst); Res : Valtyp; C : Seq_Context (Mode_Dynamic); Wire_Mark : Wire_Id; @@ -1760,20 +1762,20 @@ package body Synth.Stmts is Set_Wire_Gate (C.W_Val, Build_Control_Signal (Sub_Inst, C.Ret_Typ.W, Imp)); C.Ret_Init := Build_Const_X (Build_Context, C.Ret_Typ.W); - Phi_Assign_Net (Build_Context, C.W_Val, C.Ret_Init, 0); + Phi_Assign_Net (Ctxt, C.W_Val, C.Ret_Init, 0); end if; Set_Wire_Gate (C.W_En, Build_Control_Signal (Sub_Inst, 1, Imp)); if En = No_Net then - Phi_Assign_Net (Build_Context, C.W_En, Get_Inst_Bit1 (Syn_Inst), 0); + Phi_Assign_Static (C.W_En, Bit1); else - Phi_Assign_Net (Build_Context, C.W_En, En, 0); + Phi_Assign_Net (Ctxt, C.W_En, En, 0); end if; Set_Wire_Gate (C.W_Ret, Build_Control_Signal (Sub_Inst, 1, Imp)); - Phi_Assign_Net (Build_Context, C.W_Ret, Get_Inst_Bit1 (Syn_Inst), 0); + Phi_Assign_Static (C.W_Ret, Bit1); Decls.Synth_Declarations (C.Inst, Get_Declaration_Chain (Bod), En, True); if not Is_Error (C.Inst) then @@ -1790,7 +1792,7 @@ package body Synth.Stmts is Res := C.Ret_Value; else Res := Create_Value_Net - (Get_Current_Value (Build_Context, C.W_Val), C.Ret_Value.Typ); + (Get_Current_Value (Ctxt, C.W_Val), C.Ret_Value.Typ); end if; else Res := No_Valtyp; @@ -1809,7 +1811,7 @@ package body Synth.Stmts is -- 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); + Propagate_Phi_Until_Mark (Ctxt, Subprg_Phi, Wire_Mark); -- Free wires. Free_Wire (C.W_En); @@ -2038,49 +2040,88 @@ package body Synth.Stmts is Write_Discrete (V, T); end Update_Index; + -- Return True iff WID is a static wire and its value is 0. + function Is_Static_Bit (Wid : Wire_Id; V : Ghdl_U8) return Boolean + is + M : Memtyp; + begin + if not Is_Static_Wire (Wid) then + return False; + end if; + M := Get_Static_Wire (Wid); + return Read_U8 (M) = V; + end Is_Static_Bit; + + function Is_Static_Bit0 (Wid : Wire_Id) return Boolean is + begin + return Is_Static_Bit (Wid, 0); + end Is_Static_Bit0; + + function Is_Static_Bit1 (Wid : Wire_Id) return Boolean is + begin + return Is_Static_Bit (Wid, 1); + end Is_Static_Bit1; + + pragma Inline (Is_Static_Bit0); + pragma Inline (Is_Static_Bit1); + procedure Loop_Control_Init (C : Seq_Context; Stmt : Node) is Lc : constant Loop_Context_Acc := C.Cur_Loop; - begin + -- We might create new wires that will be destroy at the end of the + -- loop. Use mark and sweep to control their lifetime. Mark (C.Cur_Loop.Wire_Mark); - if (Lc.Prev_Loop /= null and then Lc.Prev_Loop.Need_Quit) then + if Lc.Prev_Loop /= null and then Lc.Prev_Loop.Need_Quit then + -- An exit or next statement that targets an outer loop may suspend + -- the execution of this loop. Lc.W_Quit := Alloc_Wire (Wire_Variable, Lc.Loop_Stmt); Set_Wire_Gate (Lc.W_Quit, Build_Control_Signal (C.Inst, 1, Stmt)); - Phi_Assign_Net (Get_Build (C.Inst), - Lc.W_Quit, Get_Inst_Bit1 (C.Inst), 0); + Phi_Assign_Static (Lc.W_Quit, Bit1); end if; if Get_Exit_Flag (Stmt) or else Get_Next_Flag (Stmt) then - Lc.Saved_En := Get_Current_Value (null, C.W_En); + -- There is an exit or next statement that target this loop. + -- We need to save W_En, as if the execution is suspended due to + -- exit or next, it will resume at the end of the loop. + if Is_Static_Wire (C.W_En) then + pragma Assert (Is_Static_Bit1 (C.W_En)); + Lc.Saved_En := No_Net; + else + Lc.Saved_En := Get_Current_Value (null, C.W_En); + end if; + -- Subloops may be suspended if there is an exit or a next statement + -- for this loop within subloops. Lc.Need_Quit := True; end if; if Get_Exit_Flag (Stmt) then - -- Exit statement for this loop. + -- There is an exit statement for this loop. Create the wire. Lc.W_Exit := Alloc_Wire (Wire_Variable, Lc.Loop_Stmt); Set_Wire_Gate (Lc.W_Exit, Build_Control_Signal (C.Inst, 1, Stmt)); - Phi_Assign_Net (Get_Build (C.Inst), - Lc.W_Exit, Get_Inst_Bit1 (C.Inst), 0); + Phi_Assign_Static (Lc.W_Exit, Bit1); end if; end Loop_Control_Init; - function Loop_Control_And (C : Seq_Context; L, R : Net) return Net + function Loop_Control_And (C : Seq_Context; L : Net; R : Wire_Id) return Net is - B1 : constant Net := Get_Inst_Bit1 (C.Inst); Res : Net; begin - -- Optimize common cases. - if L = B1 then - return R; - elsif R = B1 then + if R = No_Wire_Id or else Is_Static_Bit1 (R) then return L; - else - Res := Build_Dyadic (Get_Build (C.Inst), Id_And, L, R); + end if; + + pragma Assert (not Is_Static_Bit0 (R)); + + -- Optimize common cases. + Res := Get_Current_Value (null, R); + + if L /= No_Net then + Res := Build_Dyadic (Get_Build (C.Inst), Id_And, L, Res); Set_Location (Res, C.Cur_Loop.Loop_Stmt); - return Res; end if; + return Res; end Loop_Control_And; procedure Loop_Control_Update (C : Seq_Context) @@ -2088,30 +2129,29 @@ package body Synth.Stmts is Lc : constant Loop_Context_Acc := C.Cur_Loop; Res : Net; begin + if not Lc.Need_Quit then + -- No next/exit statement for this loop. So no control. + return; + end if; + -- Execution continue iff: -- 1. Loop was enabled (Lc.Saved_En) Res := Lc.Saved_En; - if Res = No_Net then - -- No loop control. - return; - end if; -- 2. No return (C.W_Ret) - if C.W_Ret /= No_Wire_Id then - Res := Loop_Control_And (C, Res, Get_Current_Value (null, C.W_Ret)); - end if; + Res := Loop_Control_And (C, Res, C.W_Ret); -- 3. No exit. - if Lc.W_Exit /= No_Wire_Id then - Res := Loop_Control_And (C, Res, Get_Current_Value (null, Lc.W_Exit)); - end if; + Res := Loop_Control_And (C, Res, Lc.W_Exit); -- 4. No quit. - if Lc.W_Quit /= No_Wire_Id then - Res := Loop_Control_And (C, Res, Get_Current_Value (null, Lc.W_Quit)); - end if; + Res := Loop_Control_And (C, Res, Lc.W_Quit); - Phi_Assign_Net (Get_Build (C.Inst), C.W_En, Res, 0); + if Res /= No_Net then + Phi_Assign_Net (Get_Build (C.Inst), C.W_En, Res, 0); + else + Phi_Assign_Static (C.W_En, Bit1); + end if; end Loop_Control_Update; procedure Loop_Control_Finish (C : Seq_Context) @@ -2119,23 +2159,20 @@ package body Synth.Stmts is Lc : constant Loop_Context_Acc := C.Cur_Loop; Res : Net; begin - -- Execute continue iff: - -- 1. Loop was enabled (Lc.Saved_En) - Res := Lc.Saved_En; - if Res = No_Net then - -- No loop control. + if not Lc.Need_Quit then + -- No next/exit statement for this loop. So no control. return; end if; + -- Execution continue after this loop iff: + -- 1. Loop was enabled (Lc.Saved_En) + Res := Lc.Saved_En; + -- 2. No return (C.W_Ret) - if C.W_Ret /= No_Wire_Id then - Res := Loop_Control_And (C, Res, Get_Current_Value (null, C.W_Ret)); - end if; + Res := Loop_Control_And (C, Res, C.W_Ret); -- 3. No quit (C.W_Quit) - if Lc.W_Quit /= No_Wire_Id then - Res := Loop_Control_And (C, Res, Get_Current_Value (null, Lc.W_Quit)); - end if; + Res := Loop_Control_And (C, Res, Lc.W_Quit); Phi_Discard_Wires (Lc.W_Quit, Lc.W_Exit); @@ -2149,7 +2186,11 @@ package body Synth.Stmts is Release (C.Cur_Loop.Wire_Mark); - Phi_Assign_Net (Get_Build (C.Inst), C.W_En, Res, 0); + if Res /= No_Net then + Phi_Assign_Net (Get_Build (C.Inst), C.W_En, Res, 0); + else + Phi_Assign_Static (C.W_En, Bit1); + end if; end Loop_Control_Finish; procedure Synth_Dynamic_Exit_Next_Statement @@ -2180,7 +2221,7 @@ package body Synth.Stmts is end if; -- Execution is suspended for the current loop. - Phi_Assign_Net (Ctxt, C.W_En, Get_Inst_Bit0 (C.Inst), 0); + Phi_Assign_Static (C.W_En, Bit0); Lc := C.Cur_Loop; @@ -2198,11 +2239,11 @@ package body Synth.Stmts is if Lc.Loop_Stmt = Loop_Label then -- Final loop. if Is_Exit then - Phi_Assign_Net (Ctxt, Lc.W_Exit, Get_Inst_Bit0 (C.Inst), 0); + Phi_Assign_Static (Lc.W_Exit, Bit0); end if; exit; else - Phi_Assign_Net (Ctxt, Lc.W_Quit, Get_Inst_Bit0 (C.Inst), 0); + Phi_Assign_Static (Lc.W_Quit, Bit0); end if; Lc := Lc.Prev_Loop; end loop; @@ -2323,7 +2364,7 @@ package body Synth.Stmts is Loop_Control_Update (C); -- Constant exit. - exit when (Get_Current_Value (null, C.W_En) = Get_Inst_Bit0 (C.Inst)); + exit when Is_Static_Bit0 (C.W_En); -- FIXME: dynamic exits. end loop; @@ -2367,7 +2408,6 @@ package body Synth.Stmts is procedure Synth_Dynamic_While_Loop_Statement (C : in out Seq_Context; Stmt : Node) is - Bit0 : constant Net := Get_Inst_Bit0 (C.Inst); Stmts : constant Node := Get_Sequential_Statement_Chain (Stmt); Cond : constant Node := Get_Condition (Stmt); Val : Valtyp; @@ -2404,21 +2444,9 @@ package body Synth.Stmts is Loop_Control_Update (C); -- Exit from the loop if W_Exit/W_Ret/W_Quit = 0 - if Lc.W_Exit /= No_Wire_Id - and then Get_Current_Value (null, Lc.W_Exit) = Bit0 - then - exit; - end if; - if C.W_Ret /= No_Wire_Id - and then Get_Current_Value (null, C.W_Ret) = Bit0 - then - exit; - end if; - if Lc.W_Quit /= No_Wire_Id - and then Get_Current_Value (null, Lc.W_Quit) = Bit0 - then - exit; - end if; + exit when Lc.W_Exit /= No_Wire_Id and then Is_Static_Bit0 (Lc.W_Exit); + exit when C.W_Ret /= No_Wire_Id and then Is_Static_Bit0 (C.W_Ret); + exit when Lc.W_Quit /= No_Wire_Id and then Is_Static_Bit0 (Lc.W_Quit); Iter_Nbr := Iter_Nbr + 1; if Iter_Nbr > Flags.Flag_Max_Loop and Flags.Flag_Max_Loop /= 0 then @@ -2504,12 +2532,10 @@ package body Synth.Stmts is if Is_Dyn then -- The subprogram has returned. Do not execute further statements. - Phi_Assign_Net (Get_Build (C.Inst), - C.W_En, Get_Inst_Bit0 (C.Inst), 0); + Phi_Assign_Static (C.W_En, Bit0); if C.W_Ret /= No_Wire_Id then - Phi_Assign_Net (Get_Build (C.Inst), - C.W_Ret, Get_Inst_Bit0 (C.Inst), 0); + Phi_Assign_Static (C.W_Ret, Bit0); end if; end if; @@ -2609,14 +2635,12 @@ package body Synth.Stmts is Stmt : Node; Phi_T, Phi_F : Phi_Type; Has_Phi : Boolean; - En : Net; begin Stmt := Stmts; while Is_Valid (Stmt) loop if Is_Dyn then - En := Get_Current_Value (null, C.W_En); - pragma Assert (En /= Get_Inst_Bit0 (C.Inst)); - Has_Phi := En /= Get_Inst_Bit1 (C.Inst); + pragma Assert (not Is_Static_Bit0 (C.W_En)); + Has_Phi := not Is_Static_Bit1 (C.W_En); if Has_Phi then Push_Phi; end if; @@ -2698,7 +2722,8 @@ package body Synth.Stmts is Get_Current_Value (Build_Context, C.W_En), Phi_T, Phi_F, Stmt); end if; - if Get_Current_Value (null, C.W_En) = Get_Inst_Bit0 (C.Inst) then + if Is_Static_Bit0 (C.W_En) then + -- Not more execution. return; end if; else @@ -2755,12 +2780,13 @@ package body Synth.Stmts is Label : constant Name_Id := Get_Identifier (Proc); Decls_Chain : constant Node := Get_Declaration_Chain (Proc); Prev_Instance_Pool : constant Areapool_Acc := Instance_Pool; + Ctxt : constant Context_Acc := Get_Build (Syn_Inst); M : Areapools.Mark_Type; C_Sname : Sname; C : Seq_Context (Mode_Dynamic); begin if Label = Null_Identifier then - C_Sname := New_Internal_Name (Build_Context, Get_Sname (Syn_Inst)); + C_Sname := New_Internal_Name (Ctxt, Get_Sname (Syn_Inst)); else C_Sname := New_Sname_User (Label, Get_Sname (Syn_Inst)); end if; @@ -2784,7 +2810,7 @@ package body Synth.Stmts is end if; Set_Wire_Gate (C.W_En, Build_Control_Signal (Syn_Inst, 1, Proc)); - Phi_Assign_Net (Build_Context, C.W_En, Get_Inst_Bit1 (Syn_Inst), 0); + Phi_Assign_Static (C.W_En, Bit1); case Iir_Kinds_Process_Statement (Get_Kind (Proc)) is when Iir_Kind_Sensitized_Process_Statement => diff --git a/src/synth/synth-stmts.ads b/src/synth/synth-stmts.ads index c946746cd..330cf156e 100644 --- a/src/synth/synth-stmts.ads +++ b/src/synth/synth-stmts.ads @@ -117,6 +117,7 @@ private case Mode is when Mode_Dynamic => + -- Set when this loop has next/exit statements for itself. -- Set to true so that inner loops have to declare W_Quit. Need_Quit : Boolean; diff --git a/src/synth/synth-values.adb b/src/synth/synth-values.adb index 995f41d55..ed042c849 100644 --- a/src/synth/synth-values.adb +++ b/src/synth/synth-values.adb @@ -89,25 +89,6 @@ package body Synth.Values is return (V.Typ, Strip_Alias_Const (V.Val)); end Strip_Alias_Const; - function Is_Equal (L, R : Memtyp) return Boolean is - begin - if L = R then - return True; - end if; - - if L.Typ.Sz /= R.Typ.Sz then - return False; - end if; - - -- FIXME: not correct for records, not correct for floats! - for I in 1 .. L.Typ.Sz loop - if L.Mem (I - 1) /= R.Mem (I - 1) then - return False; - end if; - end loop; - return True; - end Is_Equal; - function Is_Equal (L, R : Valtyp) return Boolean is begin return Is_Equal (Get_Memtyp (L), Get_Memtyp (R)); diff --git a/src/synth/synth-values.ads b/src/synth/synth-values.ads index e90bbedbc..77798c9f0 100644 --- a/src/synth/synth-values.ads +++ b/src/synth/synth-values.ads @@ -110,7 +110,6 @@ package Synth.Values is function Is_Static_Val (Val : Value_Acc) return Boolean; function Is_Equal (L, R : Valtyp) return Boolean; - function Is_Equal (L, R : Memtyp) return Boolean; function Create_Value_Memtyp (Mt : Memtyp) return Valtyp; |