diff options
| author | Tristan Gingold <tgingold@free.fr> | 2019-11-27 20:17:35 +0100 | 
|---|---|---|
| committer | Tristan Gingold <tgingold@free.fr> | 2019-11-27 20:17:35 +0100 | 
| commit | 244856a265114d8ede30248cb6d17475b27b766f (patch) | |
| tree | 55c631ecfa14ce0e2beb08ac5e493e19ff58806b /src | |
| parent | 0ae2e726f34f7f12ebc1f7cbfcba5f3edee8b5f4 (diff) | |
| download | ghdl-244856a265114d8ede30248cb6d17475b27b766f.tar.gz ghdl-244856a265114d8ede30248cb6d17475b27b766f.tar.bz2 ghdl-244856a265114d8ede30248cb6d17475b27b766f.zip  | |
synth: rework static calls and loops.  Fix #1034.
Diffstat (limited to 'src')
| -rw-r--r-- | src/synth/synth-stmts.adb | 394 | ||||
| -rw-r--r-- | src/synth/synth-stmts.ads | 79 | 
2 files changed, 368 insertions, 105 deletions
diff --git a/src/synth/synth-stmts.adb b/src/synth/synth-stmts.adb index 68486da58..b0b2518f7 100644 --- a/src/synth/synth-stmts.adb +++ b/src/synth/synth-stmts.adb @@ -1565,54 +1565,47 @@ package body Synth.Stmts is        pragma Assert (Nbr_Inout = Infos'Last);     end Synth_Subprogram_Back_Association; -   function Synth_Subprogram_Call -     (Syn_Inst : Synth_Instance_Acc; Call : Node) return Value_Acc +   function Synth_Dynamic_Subprogram_Call (Syn_Inst : Synth_Instance_Acc; +                                           Sub_Inst : Synth_Instance_Acc; +                                           Call : Node; +                                           Infos : Target_Info_Array) +                                          return Value_Acc     is        Imp  : constant Node := Get_Implementation (Call);        Is_Func : constant Boolean := Is_Function_Declaration (Imp);        Assoc_Chain : constant Node := Get_Parameter_Association_Chain (Call);        Inter_Chain : constant Node := Get_Interface_Declaration_Chain (Imp);        Bod : constant Node := Get_Subprogram_Body (Imp); -      Nbr_Inout : constant Natural := -        Count_Associations (Inter_Chain, Assoc_Chain); -      Infos : Target_Info_Array (1 .. Nbr_Inout); -      Area_Mark : Areapools.Mark_Type;        Res : Value_Acc; -      C : Seq_Context; +      C : Seq_Context (Mode_Dynamic);        Wire_Mark : Wire_Id;        Subprg_Phi : Phi_Type;     begin        Mark (Wire_Mark); -      Areapools.Mark (Area_Mark, Instance_Pool.all); -      C := (Inst => Make_Instance (Syn_Inst, Bod, -                                   New_Internal_Name (Build_Context)), +      C := (Mode => Mode_Dynamic, +            Inst => Sub_Inst,              Cur_Loop => null, -            W_En => Alloc_Wire (Wire_Variable, Imp), -            W_Ret => Alloc_Wire (Wire_Variable, Imp), +            W_En => No_Wire_Id, +            W_Ret => No_Wire_Id,              W_Val => No_Wire_Id,              Ret_Init => No_Net,              Ret_Value => null,              Ret_Typ => null,              Nbr_Ret => 0); +      C.W_En := Alloc_Wire (Wire_Variable, Imp); +      C.W_Ret := Alloc_Wire (Wire_Variable, Imp); +        if Is_Func then           C.W_Val := Alloc_Wire (Wire_Variable, Imp);        end if; -      Synth_Subprogram_Association -        (C.Inst, Syn_Inst, Inter_Chain, Assoc_Chain, Infos); - -      if not Is_Func then -         if Get_Purity_State (Imp) /= Pure then -            Set_Instance_Const (C.Inst, False); -         end if; -      end if; -        Push_Phi;        if Is_Func then           --  Set a default value for the return.           C.Ret_Typ := Get_Value_Type (Syn_Inst, Get_Return_Type (Imp)); +           Set_Wire_Gate (C.W_Val,                          Build_Signal (Build_Context,                                        New_Internal_Name (Build_Context), @@ -1665,12 +1658,101 @@ package body Synth.Stmts is           Free_Wire (C.W_Val);        end if; -      Free_Instance (C.Inst); -      Areapools.Release (Area_Mark, Instance_Pool.all); -        Release (Wire_Mark);        return Res; +   end Synth_Dynamic_Subprogram_Call; + +   function Synth_Static_Subprogram_Call (Syn_Inst : Synth_Instance_Acc; +                                          Sub_Inst : Synth_Instance_Acc; +                                          Call : Node; +                                          Infos : Target_Info_Array) +                                         return Value_Acc +   is +      Imp  : constant Node := Get_Implementation (Call); +      Is_Func : constant Boolean := Is_Function_Declaration (Imp); +      Assoc_Chain : constant Node := Get_Parameter_Association_Chain (Call); +      Inter_Chain : constant Node := Get_Interface_Declaration_Chain (Imp); +      Bod : constant Node := Get_Subprogram_Body (Imp); +      Res : Value_Acc; +      C : Seq_Context (Mode_Static); +   begin +      C := (Mode_Static, +            Inst => Sub_Inst, +            Cur_Loop => null, +            S_En => True, +            Ret_Value => null, +            Ret_Typ => null, +            Nbr_Ret => 0); + +      if Is_Func then +         --  Set a default value for the return. +         C.Ret_Typ := Get_Value_Type (Syn_Inst, Get_Return_Type (Imp)); +      end if; + +      Decls.Synth_Declarations (C.Inst, Get_Declaration_Chain (Bod), True); + +      Synth_Sequential_Statements (C, Get_Sequential_Statement_Chain (Bod)); + +      if Is_Func then +         if C.Nbr_Ret = 0 then +            raise Internal_Error; +         elsif C.Nbr_Ret = 1 and then Is_Static (C.Ret_Value) then +            Res := C.Ret_Value; +         else +            raise Internal_Error; +         end if; +      else +         Res := null; +         Synth_Subprogram_Back_Association +           (C.Inst, Syn_Inst, Inter_Chain, Assoc_Chain, Infos); +      end if; + +      Decls.Finalize_Declarations (C.Inst, Get_Declaration_Chain (Bod), True); +      pragma Unreferenced (Infos); + +      return Res; +   end Synth_Static_Subprogram_Call; + +   function Synth_Subprogram_Call +     (Syn_Inst : Synth_Instance_Acc; Call : Node) return Value_Acc +   is +      Imp  : constant Node := Get_Implementation (Call); +      Is_Func : constant Boolean := Is_Function_Declaration (Imp); +      Assoc_Chain : constant Node := Get_Parameter_Association_Chain (Call); +      Inter_Chain : constant Node := Get_Interface_Declaration_Chain (Imp); +      Bod : constant Node := Get_Subprogram_Body (Imp); +      Nbr_Inout : constant Natural := +        Count_Associations (Inter_Chain, Assoc_Chain); +      Infos : Target_Info_Array (1 .. Nbr_Inout); +      Area_Mark : Areapools.Mark_Type; +      Res : Value_Acc; +      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)); +      Synth_Subprogram_Association +        (Sub_Inst, Syn_Inst, Inter_Chain, Assoc_Chain, Infos); + +      if not Is_Func then +         if Get_Purity_State (Imp) /= Pure then +            Set_Instance_Const (Sub_Inst, False); +         end if; +      end if; + +      if Get_Instance_Const (Sub_Inst) then +         Res := Synth_Static_Subprogram_Call +           (Syn_Inst, Sub_Inst, Call, Infos); +      else +         Res := Synth_Dynamic_Subprogram_Call +           (Syn_Inst, Sub_Inst, Call, Infos); +      end if; + +      Free_Instance (Sub_Inst); +      Areapools.Release (Area_Mark, Instance_Pool.all); + +      return Res;     end Synth_Subprogram_Call;     procedure Synth_Implicit_Procedure_Call @@ -1854,7 +1936,8 @@ package body Synth.Stmts is        Phi_Assign (Get_Build (C.Inst), C.W_En, Res, 0);     end Loop_Control_Finish; -   procedure Synth_Exit_Next_Statement (C : in out Seq_Context; Stmt : Node) +   procedure Synth_Dynamic_Exit_Next_Statement +     (C : in out Seq_Context; Stmt : Node)     is        Cond : constant Node := Get_Condition (Stmt);        Is_Exit : constant Boolean := Get_Kind (Stmt) = Iir_Kind_Exit_Statement; @@ -1912,18 +1995,92 @@ package body Synth.Stmts is           Merge_Phis (Build_Context,                       Get_Net (Cond_Val), Phi_True, Phi_False, Stmt);        end if; -   end Synth_Exit_Next_Statement; +   end Synth_Dynamic_Exit_Next_Statement; -   procedure Synth_For_Loop_Statement (C : in out Seq_Context; Stmt : Node) +   procedure Synth_Static_Exit_Next_Statement +     (C : in out Seq_Context; Stmt : Node) +   is +      Cond : constant Node := Get_Condition (Stmt); +      Is_Exit : constant Boolean := Get_Kind (Stmt) = Iir_Kind_Exit_Statement; +      Loop_Label : Node; +      Lc : Loop_Context_Acc; +      Cond_Val : Value_Acc; +   begin + +      if Cond /= Null_Node then +         Cond_Val := Synth_Expression (C.Inst, Cond); +         pragma Assert (Is_Static_Val (Cond_Val)); +         if Get_Static_Discrete (Cond_Val) = 0 then +            --  Not executed. +            return; +         end if; +      end if; + +      --  Execution is suspended. +      C.S_En := False; + +      Lc := C.Cur_Loop; + +      Loop_Label := Get_Loop_Label (Stmt); +      if Loop_Label = Null_Node then +         Loop_Label := Lc.Loop_Stmt; +      else +         Loop_Label := Get_Named_Entity (Loop_Label); +      end if; + +      loop +         if Lc.Loop_Stmt = Loop_Label then +            if Is_Exit then +               Lc.S_Exit := True; +            end if; +            exit; +         else +            Lc.S_Quit := True; +         end if; +         Lc := Lc.Prev_Loop; +      end loop; +   end Synth_Static_Exit_Next_Statement; + +   procedure Init_For_Loop_Statement (C : in out Seq_Context; +                                      Stmt : Node; +                                      It_Rng : out Type_Acc; +                                      Val : out Value_Acc)     is        Iterator : constant Node := Get_Parameter_Specification (Stmt); -      Stmts : constant Node := Get_Sequential_Statement_Chain (Stmt);        It_Type : constant Node := Get_Declaration_Type (Iterator); +   begin +      if It_Type /= Null_Node then +         Synth_Subtype_Indication (C.Inst, It_Type); +      end if; + +      --  Initial value. +      It_Rng := Get_Value_Type (C.Inst, Get_Type (Iterator)); +      Val := Create_Value_Discrete (It_Rng.Drange.Left, It_Rng); +      Create_Object (C.Inst, Iterator, Val); +   end Init_For_Loop_Statement; + +   procedure Finish_For_Loop_Statement (C : in out Seq_Context; +                                        Stmt : Node) +   is +      Iterator : constant Node := Get_Parameter_Specification (Stmt); +      It_Type : constant Node := Get_Declaration_Type (Iterator); +   begin +      Destroy_Object (C.Inst, Iterator); +      if It_Type /= Null_Node then +         Destroy_Object (C.Inst, It_Type); +      end if; +   end Finish_For_Loop_Statement; + +   procedure Synth_Dynamic_For_Loop_Statement +     (C : in out Seq_Context; Stmt : Node) +   is +      Stmts : constant Node := Get_Sequential_Statement_Chain (Stmt);        It_Rng : Type_Acc;        Val : Value_Acc; -      Lc : aliased Loop_Context; +      Lc : aliased Loop_Context (Mode_Dynamic);     begin -      Lc := (Prev_Loop => C.Cur_Loop, +      Lc := (Mode => Mode_Dynamic, +             Prev_Loop => C.Cur_Loop,               Loop_Stmt => Stmt,               Need_Quit => False,               Saved_En => No_Net, @@ -1934,14 +2091,7 @@ package body Synth.Stmts is        Loop_Control_Init (C, Stmt); -      if It_Type /= Null_Node then -         Synth_Subtype_Indication (C.Inst, It_Type); -      end if; - -      --  Initial value. -      It_Rng := Get_Value_Type (C.Inst, Get_Type (Iterator)); -      Val := Create_Value_Discrete (It_Rng.Drange.Left, It_Rng); -      Create_Object (C.Inst, Iterator, Val); +      Init_For_Loop_Statement (C, Stmt, It_Rng, Val);        while In_Range (It_Rng.Drange, Val.Scal) loop           Synth_Sequential_Statements (C, Stmts); @@ -1950,27 +2100,59 @@ 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 (Get_Current_Value (null, C.W_En) = Get_Inst_Bit0 (C.Inst)); + +         --  FIXME: dynamic exits.        end loop;        Loop_Control_Finish (C); -      Destroy_Object (C.Inst, Iterator); -      if It_Type /= Null_Node then -         Destroy_Object (C.Inst, It_Type); -      end if; +      Finish_For_Loop_Statement (C, Stmt);        C.Cur_Loop := Lc.Prev_Loop; -   end Synth_For_Loop_Statement; +   end Synth_Dynamic_For_Loop_Statement; -   procedure Synth_While_Loop_Statement (C : in out Seq_Context; Stmt : Node) +   procedure Synth_Static_For_Loop_Statement +     (C : in out Seq_Context; Stmt : Node) +   is +      Stmts : constant Node := Get_Sequential_Statement_Chain (Stmt); +      It_Rng : Type_Acc; +      Val : Value_Acc; +      Lc : aliased Loop_Context (Mode_Static); +   begin +      Lc := (Mode_Static, +             Prev_Loop => C.Cur_Loop, +             Loop_Stmt => Stmt, +             S_Exit => False, +             S_Quit => False); +      C.Cur_Loop := Lc'Unrestricted_Access; + +      Init_For_Loop_Statement (C, Stmt, It_Rng, Val); + +      while In_Range (It_Rng.Drange, Val.Scal) loop +         Synth_Sequential_Statements (C, Stmts); +         C.S_En := True; + +         Update_Index (It_Rng.Drange, Val.Scal); + +         exit when Lc.S_Exit or Lc.S_Quit or C.Nbr_Ret > 0; +      end loop; + +      Finish_For_Loop_Statement (C, Stmt); + +      C.Cur_Loop := Lc.Prev_Loop; +   end Synth_Static_For_Loop_Statement; + +   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 : Value_Acc; -      Lc : aliased Loop_Context; +      Lc : aliased Loop_Context (Mode_Dynamic);     begin -      Lc := (Prev_Loop => C.Cur_Loop, +      Lc := (Mode => Mode_Dynamic, +             Prev_Loop => C.Cur_Loop,               Loop_Stmt => Stmt,               Need_Quit => False,               Saved_En => No_Net, @@ -2015,10 +2197,43 @@ package body Synth.Stmts is        Loop_Control_Finish (C);        C.Cur_Loop := Lc.Prev_Loop; -   end Synth_While_Loop_Statement; +   end Synth_Dynamic_While_Loop_Statement; + +   procedure Synth_Static_While_Loop_Statement +     (C : in out Seq_Context; Stmt : Node) +   is +      Stmts : constant Node := Get_Sequential_Statement_Chain (Stmt); +      Cond : constant Node := Get_Condition (Stmt); +      Val : Value_Acc; +      Lc : aliased Loop_Context (Mode_Static); +   begin +      Lc := (Mode => Mode_Static, +             Prev_Loop => C.Cur_Loop, +             Loop_Stmt => Stmt, +             S_Exit => False, +             S_Quit => False); +      C.Cur_Loop := Lc'Unrestricted_Access; + +      loop +         if Cond /= Null_Node then +            Val := Synth_Expression_With_Type (C.Inst, Cond, Boolean_Type); +            pragma Assert (Is_Static (Val)); +            exit when Val.Scal = 0; +         end if; + +         Synth_Sequential_Statements (C, Stmts); +         C.S_En := True; + +         --  Exit from the loop if S_Exit/S_Quit +         exit when Lc.S_Exit or Lc.S_Quit or C.Nbr_Ret > 0; +      end loop; + +      C.Cur_Loop := Lc.Prev_Loop; +   end Synth_Static_While_Loop_Statement;     procedure Synth_Return_Statement (C : in out Seq_Context; Stmt : Node)     is +      Is_Dyn : constant Boolean := not Get_Instance_Const (C.Inst);        Val : Value_Acc;        Expr : constant Node := Get_Expression (Stmt);     begin @@ -2035,18 +2250,25 @@ package body Synth.Stmts is                 --  the returned values.  So adjust it.                 --  All the returned values must have the same length.                 C.Ret_Typ := Val.Typ; -               Set_Width (Get_Wire_Gate (C.W_Val), C.Ret_Typ.W); -               Set_Width (C.Ret_Init, C.Ret_Typ.W); +               if Is_Dyn then +                  Set_Width (Get_Wire_Gate (C.W_Val), C.Ret_Typ.W); +                  Set_Width (C.Ret_Init, C.Ret_Typ.W); +               end if;              end if;           end if; -         Phi_Assign (Get_Build (C.Inst), C.W_Val, Get_Net (Val), 0); +         if Is_Dyn then +            Phi_Assign (Get_Build (C.Inst), C.W_Val, Get_Net (Val), 0); +         end if;        end if; -      --  The subprogram has returned.  Do not execute further statements. -      Phi_Assign (Get_Build (C.Inst), C.W_En, Get_Inst_Bit0 (C.Inst), 0); +      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); -      if C.W_Ret /= No_Wire_Id then -         Phi_Assign (Get_Build (C.Inst), C.W_Ret, 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); +         end if;        end if;        C.Nbr_Ret := C.Nbr_Ret + 1; @@ -2055,6 +2277,7 @@ package body Synth.Stmts is     procedure Synth_Sequential_Statements       (C : in out Seq_Context; Stmts : Node)     is +      Is_Dyn : constant Boolean := not Get_Instance_Const (C.Inst);        Stmt : Node;        Phi_T, Phi_F : Phi_Type;        Has_Phi : Boolean; @@ -2062,11 +2285,13 @@ package body Synth.Stmts is     begin        Stmt := Stmts;        while Is_Valid (Stmt) loop -         En := Get_Current_Value (null, C.W_En); -         pragma Assert (En /= Get_Inst_Bit0 (C.Inst)); -         Has_Phi := En /= Get_Inst_Bit1 (C.Inst); -         if Has_Phi then -            Push_Phi; +         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); +            if Has_Phi then +               Push_Phi; +            end if;           end if;           if Flags.Flag_Trace_Statements then @@ -2100,9 +2325,17 @@ package body Synth.Stmts is              when Iir_Kind_Case_Statement =>                 Synth_Case_Statement (C, Stmt);              when Iir_Kind_For_Loop_Statement => -               Synth_For_Loop_Statement (C, Stmt); +               if Is_Dyn then +                  Synth_Dynamic_For_Loop_Statement (C, Stmt); +               else +                  Synth_Static_For_Loop_Statement (C, Stmt); +               end if;              when Iir_Kind_While_Loop_Statement => -               Synth_While_Loop_Statement (C, Stmt); +               if Is_Dyn then +                  Synth_Dynamic_While_Loop_Statement (C, Stmt); +               else +                  Synth_Static_While_Loop_Statement (C, Stmt); +               end if;              when Iir_Kind_Null_Statement =>                 --  Easy                 null; @@ -2116,20 +2349,30 @@ package body Synth.Stmts is                 null;              when Iir_Kind_Exit_Statement                | Iir_Kind_Next_Statement => -               Synth_Exit_Next_Statement (C, Stmt); +               if Is_Dyn then +                  Synth_Dynamic_Exit_Next_Statement (C, Stmt); +               else +                  Synth_Static_Exit_Next_Statement (C, Stmt); +               end if;              when others =>                 Error_Kind ("synth_sequential_statements", Stmt);           end case; -         if Has_Phi then -            Pop_Phi (Phi_T); -            Push_Phi; -            Pop_Phi (Phi_F); -            Merge_Phis (Build_Context, -                        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 -            return; +         if Is_Dyn then +            if Has_Phi then +               Pop_Phi (Phi_T); +               Push_Phi; +               Pop_Phi (Phi_F); +               Merge_Phis (Build_Context, +                           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 +               return; +            end if; +         else +            if not C.S_En or C.Nbr_Ret /= 0 then +               return; +            end if;           end if;           Stmt := Get_Chain (Stmt);        end loop; @@ -2182,14 +2425,15 @@ package body Synth.Stmts is        Prev_Instance_Pool : constant Areapool_Acc := Instance_Pool;        M : Areapools.Mark_Type;        C_Sname : Sname; -      C : Seq_Context; +      C : Seq_Context (Mode_Dynamic);     begin        if Label = Null_Identifier then           C_Sname := New_Internal_Name (Build_Context, Get_Sname (Syn_Inst));        else           C_Sname := New_Sname (Get_Sname (Syn_Inst), Label);        end if; -      C := (Inst => Make_Instance (Syn_Inst, Proc, C_Sname), +      C := (Mode => Mode_Dynamic, +            Inst => Make_Instance (Syn_Inst, Proc, C_Sname),              Cur_Loop => null,              W_En => Alloc_Wire (Wire_Variable, Proc),              W_Ret => No_Wire_Id, diff --git a/src/synth/synth-stmts.ads b/src/synth/synth-stmts.ads index aed471c03..af05e3917 100644 --- a/src/synth/synth-stmts.ads +++ b/src/synth/synth-stmts.ads @@ -68,51 +68,70 @@ package Synth.Stmts is     procedure Update_Index (Rng : Discrete_Range_Type; Idx : in out Int64);  private -   type Loop_Context; +   --  There are 2 execution mode: +   --  * static: it is like simulation, all the inputs are known, neither +   --    gates nor signals are generated.  This mode is used during +   --    elaboration and when all inputs of a subprogram are known. +   --  * dynamic: inputs can be wires so gates are generated.  But many types +   --    (like file or access) cannot be handled. +   type Mode_Type is (Mode_Static, Mode_Dynamic); + +   type Loop_Context (Mode : Mode_Type);     type Loop_Context_Acc is access all Loop_Context; -   type Loop_Context is record +   type Loop_Context (Mode : Mode_Type) is record        Prev_Loop : Loop_Context_Acc;        Loop_Stmt : Node; -      --  Set to true so that inner loops have to declare W_Quit. -      Need_Quit : Boolean; - -      --  Value of W_En at the entry of the loop. -      Saved_En : Net; - -      --  Set to 0 in case of exit for the loop. -      --  Set to 0 in case of exit/next for outer loop. -      --  Initialized to 1. -      W_Exit : Wire_Id; - -      --  Set to 0 if this loop has to be quited because of an exit/next for -      --  an outer loop. -      --  Initialized to 1. -      W_Quit : Wire_Id; - -      --  Mark to release wires. -      Wire_Mark : Wire_Id; +      case Mode is +         when Mode_Dynamic => +            --  Set to true so that inner loops have to declare W_Quit. +            Need_Quit : Boolean; + +            --  Value of W_En at the entry of the loop. +            Saved_En : Net; + +            --  Set to 0 in case of exit for the loop. +            --  Set to 0 in case of exit/next for outer loop. +            --  Initialized to 1. +            W_Exit : Wire_Id; + +            --  Set to 0 if this loop has to be quited because of an +            --  exit/next for an outer loop.  Initialized to 1. +            W_Quit : Wire_Id; + +            --  Mark to release wires. +            Wire_Mark : Wire_Id; +         when Mode_Static => +            S_Exit : Boolean; +            S_Quit : Boolean; +      end case;     end record;     --  Context for sequential statements. -   type Seq_Context is record +   type Seq_Context (Mode : Mode_Type) is record        Inst : Synth_Instance_Acc;        Cur_Loop : Loop_Context_Acc; -      --  Enable execution. -      W_En : Wire_Id; +      Ret_Value : Value_Acc; +      Ret_Typ : Type_Acc; +      Nbr_Ret : Int32; -      W_Ret : Wire_Id; +      case Mode is +         when Mode_Dynamic => +            --  Enable execution. +            W_En : Wire_Id; -      --  Return value. -      W_Val : Wire_Id; +            W_Ret : Wire_Id; -      Ret_Init : Net; +            --  Return value. +            W_Val : Wire_Id; -      Ret_Value : Value_Acc; -      Ret_Typ : Type_Acc; -      Nbr_Ret : Int32; +            Ret_Init : Net; + +         when Mode_Static => +            S_En : Boolean; +      end case;     end record;  end Synth.Stmts;  | 
