aboutsummaryrefslogtreecommitdiffstats
path: root/src/synth
diff options
context:
space:
mode:
authorTristan Gingold <tgingold@free.fr>2020-05-02 15:38:51 +0200
committerTristan Gingold <tgingold@free.fr>2020-05-04 19:04:05 +0200
commit2a60624876cef4505bd05af8ac18276d37fffdf4 (patch)
tree074a66b84919b37d726a2b8e3adedc280a9758e0 /src/synth
parent84b548ddb8dd089f7953bbda0fa8db424f02ef09 (diff)
downloadghdl-2a60624876cef4505bd05af8ac18276d37fffdf4.tar.gz
ghdl-2a60624876cef4505bd05af8ac18276d37fffdf4.tar.bz2
ghdl-2a60624876cef4505bd05af8ac18276d37fffdf4.zip
synth: preliminary support of sequential assertions. For #1273
Diffstat (limited to 'src/synth')
-rw-r--r--src/synth/netlists-disp_vhdl.adb2
-rw-r--r--src/synth/synth-stmts.adb115
-rw-r--r--src/synth/synth-stmts.ads5
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 =>