diff options
-rw-r--r-- | src/synth/netlists-disp_vhdl.adb | 2 | ||||
-rw-r--r-- | src/synth/synth-stmts.adb | 115 | ||||
-rw-r--r-- | src/synth/synth-stmts.ads | 5 |
3 files changed, 99 insertions, 23 deletions
diff --git a/src/synth/netlists-disp_vhdl.adb b/src/synth/netlists-disp_vhdl.adb index 6faf3337f..a4644d4f6 100644 --- a/src/synth/netlists-disp_vhdl.adb +++ b/src/synth/netlists-disp_vhdl.adb @@ -1248,7 +1248,7 @@ package body Netlists.Disp_Vhdl is Put_Line (";"); when Id_Assert => Disp_Template - (" \l0: assert \i0 = '1' severity error;" & NL, Inst); + (" \l0: postponed assert \i0 = '1' severity error;" & NL, Inst); when Id_Assume => Disp_Template (" \l0: assert \i0 = '1' severity warning; -- assume" & NL, diff --git a/src/synth/synth-stmts.adb b/src/synth/synth-stmts.adb index b24425943..2f354ee6d 100644 --- a/src/synth/synth-stmts.adb +++ b/src/synth/synth-stmts.adb @@ -621,22 +621,34 @@ package body Synth.Stmts is end Synth_Conditional_Signal_Assignment; -- Return the enable net from C. - function Get_En (C : Seq_Context) return Net is + function Get_En (C : Seq_Context; Loc : Source.Syn_Src) return Net + is + Ncond, Nen : Net; begin if C.Mode = Mode_Static then + -- Always enabled. return No_Net; end if; + + Ncond := C.W_Cond; + if Is_Static_Wire (C.W_En) then - -- Must be True! - return No_Net; - else - return Get_Current_Value (Get_Build (C.Inst), C.W_En); + -- Cannot be 0. + return Ncond; end if; + + Nen := Get_Current_Value (Get_Build (C.Inst), C.W_En); + if Ncond = No_Net then + return Nen; + end if; + Nen := Build_Dyadic (Get_Build (C.Inst), Id_And, Nen, Ncond); + Set_Location (Nen, Loc); + return Nen; end Get_En; procedure Synth_Variable_Assignment (C : Seq_Context; Stmt : Node) is - En : constant Net := Get_En (C); + En : constant Net := Get_En (C, Stmt); Targ : Target_Info; Val : Valtyp; begin @@ -654,7 +666,7 @@ package body Synth.Stmts is (C : Seq_Context; Stmt : Node) is Target : constant Node := Get_Target (Stmt); - En : constant Net := Get_En (C); + En : constant Net := Get_En (C, Stmt); Targ_Type : Type_Acc; Cond : Node; Ce : Node; @@ -692,11 +704,15 @@ package body Synth.Stmts is is Cond : constant Node := Get_Condition (Stmt); Els : constant Node := Get_Else_Clause (Stmt); + Ctxt : constant Context_Acc := Get_Build (C.Inst); Cond_Val : Valtyp; + Cond_Net : Net; + Not_Cond_Net : Net; Phi_True : Phi_Type; Phi_False : Phi_Type; + Prev_Cond : Net; begin - Cond_Val := Synth_Expression (C.Inst, Cond, Get_En (C)); + Cond_Val := Synth_Expression (C.Inst, Cond, Get_En (C, Stmt)); if Cond_Val = No_Valtyp then Set_Error (C.Inst); return; @@ -722,13 +738,37 @@ package body Synth.Stmts is end if; end if; else + Prev_Cond := C.W_Cond; + Cond_Net := Get_Net (Cond_Val); + + -- Set W_Cond (for the 'then' part). + if Prev_Cond = No_Net then + C.W_Cond := Cond_Net; + else + C.W_Cond := Build_Dyadic (Ctxt, Id_And, Prev_Cond, Cond_Net); + Set_Location (C.W_Cond, Stmt); + end if; + + -- The statements for the 'then' part. Push_Phi; Synth_Sequential_Statements (C, Get_Sequential_Statement_Chain (Stmt)); Pop_Phi (Phi_True); Push_Phi; + if Is_Valid (Els) then + -- Set W_Cond (for the 'else' part). + Not_Cond_Net := Build_Monadic (Ctxt, Id_Not, Cond_Net); + Set_Location (Not_Cond_Net, Stmt); + if Prev_Cond = No_Net then + C.W_Cond := Not_Cond_Net; + else + C.W_Cond := Build_Dyadic + (Ctxt, Id_And, Prev_Cond, Not_Cond_Net); + Set_Location (C.W_Cond, Stmt); + end if; + if Is_Null (Get_Condition (Els)) then -- Final else part. Synth_Sequential_Statements @@ -738,10 +778,12 @@ package body Synth.Stmts is Synth_If_Statement (C, Els); end if; end if; + + -- Restore value. + C.W_Cond := Prev_Cond; Pop_Phi (Phi_False); - Merge_Phis (Get_Build (C.Inst), - Get_Net (Cond_Val), Phi_True, Phi_False, Stmt); + Merge_Phis (Ctxt, Cond_Net, Phi_True, Phi_False, Stmt); end if; end Synth_If_Statement; @@ -954,7 +996,7 @@ package body Synth.Stmts is Choice_Data (Choice_Idx) := (Val => Convert_To_Uns64 (C.Inst, Get_Choice_Expression (Choice), - Get_En (C)), + Get_En (C, Stmt)), Alt => Alt_Idx); when Iir_Kind_Choice_By_Others => Others_Alt_Idx := Alt_Idx; @@ -1166,7 +1208,8 @@ package body Synth.Stmts is Expr : constant Node := Get_Expression (Stmt); Sel : Valtyp; begin - Sel := Synth_Expression_With_Basetype (C.Inst, Expr, Get_En (C)); + Sel := Synth_Expression_With_Basetype + (C.Inst, Expr, Get_En (C, Stmt)); Strip_Const (Sel); if Is_Static (Sel.Val) then case Sel.Typ.Kind is @@ -1739,6 +1782,7 @@ package body Synth.Stmts is W_En => No_Wire_Id, W_Ret => No_Wire_Id, W_Val => No_Wire_Id, + W_Cond => No_Net, Ret_Init => No_Net, Ret_Value => No_Valtyp, Ret_Typ => null, @@ -1767,11 +1811,9 @@ package body Synth.Stmts is Set_Wire_Gate (C.W_En, Build_Control_Signal (Sub_Inst, 1, Imp)); - if En = No_Net then - Phi_Assign_Static (C.W_En, Bit1); - else - Phi_Assign_Net (Ctxt, C.W_En, En, 0); - end if; + Phi_Assign_Static (C.W_En, Bit1); + + C.W_Cond := En; Set_Wire_Gate (C.W_Ret, Build_Control_Signal (Sub_Inst, 1, Imp)); @@ -2207,7 +2249,7 @@ package body Synth.Stmts is Phi_False : Phi_Type; begin if Cond /= Null_Node then - Cond_Val := Synth_Expression (C.Inst, Cond, Get_En (C)); + Cond_Val := Synth_Expression (C.Inst, Cond, Get_En (C, Stmt)); Static_Cond := Is_Static_Val (Cond_Val.Val); if Static_Cond then if Get_Static_Discrete (Cond_Val) = 0 then @@ -2503,7 +2545,7 @@ package body Synth.Stmts is if Expr /= Null_Node then -- Return in function. Val := Synth_Expression_With_Type - (C.Inst, Expr, C.Ret_Typ, Get_En (C)); + (C.Inst, Expr, C.Ret_Typ, Get_En (C, Stmt)); if Val = No_Valtyp then Set_Error (C.Inst); return; @@ -2628,6 +2670,30 @@ package body Synth.Stmts is Synth_Static_Report (C, Stmt); end Synth_Static_Assertion_Statement; + procedure Synth_Dynamic_Assertion_Statement (C : Seq_Context; Stmt : Node) + is + Ctxt : constant Context_Acc := Get_Build (C.Inst); + En : constant Net := Get_En (C, Stmt); + Loc : constant Location_Type := Get_Location (Stmt); + Cond : Valtyp; + N : Net; + Inst : Instance; + begin + Cond := Synth_Expression + (C.Inst, Get_Assertion_Condition (Stmt), No_Net); + if Cond = No_Valtyp then + Set_Error (C.Inst); + return; + end if; + N := Get_Net (Cond); + if En /= No_Net then + -- Build: En -> Cond + N := Build2_Imp (Ctxt, En, N, Loc); + end if; + Inst := Build_Assert (Ctxt, Synth_Label (Stmt), N); + Set_Location (Inst, Loc); + end Synth_Dynamic_Assertion_Statement; + procedure Synth_Sequential_Statements (C : in out Seq_Context; Stmts : Node) is @@ -2667,9 +2733,11 @@ package body Synth.Stmts is when Iir_Kind_If_Statement => Synth_If_Statement (C, Stmt); when Iir_Kind_Simple_Signal_Assignment_Statement => - Synth_Simple_Signal_Assignment (C.Inst, Stmt, Get_En (C)); + Synth_Simple_Signal_Assignment + (C.Inst, Stmt, Get_En (C, Stmt)); when Iir_Kind_Conditional_Signal_Assignment_Statement => - Synth_Conditional_Signal_Assignment (C.Inst, Stmt, Get_En (C)); + Synth_Conditional_Signal_Assignment + (C.Inst, Stmt, Get_En (C, Stmt)); when Iir_Kind_Variable_Assignment_Statement => Synth_Variable_Assignment (C, Stmt); when Iir_Kind_Conditional_Variable_Assignment_Statement => @@ -2694,7 +2762,7 @@ package body Synth.Stmts is when Iir_Kind_Return_Statement => Synth_Return_Statement (C, Stmt); when Iir_Kind_Procedure_Call_Statement => - Synth_Procedure_Call (C.Inst, Stmt, Get_En (C)); + Synth_Procedure_Call (C.Inst, Stmt, Get_En (C, Stmt)); when Iir_Kind_Report_Statement => if not Is_Dyn then Synth_Static_Report_Statement (C, Stmt); @@ -2702,6 +2770,8 @@ package body Synth.Stmts is when Iir_Kind_Assertion_Statement => if not Is_Dyn then Synth_Static_Assertion_Statement (C, Stmt); + else + Synth_Dynamic_Assertion_Statement (C, Stmt); end if; when Iir_Kind_Exit_Statement | Iir_Kind_Next_Statement => @@ -2796,6 +2866,7 @@ package body Synth.Stmts is W_En => Alloc_Wire (Wire_Variable, Proc), W_Ret => No_Wire_Id, W_Val => No_Wire_Id, + W_Cond => No_Net, Ret_Init => No_Net, Ret_Value => No_Valtyp, Ret_Typ => null, diff --git a/src/synth/synth-stmts.ads b/src/synth/synth-stmts.ads index 330cf156e..3d5c12081 100644 --- a/src/synth/synth-stmts.ads +++ b/src/synth/synth-stmts.ads @@ -161,6 +161,11 @@ private -- Return value. W_Val : Wire_Id; + -- Condition. + -- If No_Net, then it is like True. + -- Set when the execution path is enabled. + W_Cond : Net; + Ret_Init : Net; when Mode_Static => |