diff options
author | tmeissner <programming@goodcleanfun.de> | 2020-06-05 13:47:04 +0200 |
---|---|---|
committer | tgingold <tgingold@users.noreply.github.com> | 2020-06-06 07:51:38 +0200 |
commit | e44cd87182452ce6220b028c62caa1bdbb9c55e3 (patch) | |
tree | 5b321c4f3df1ac98254c806617dcad5880a669c7 | |
parent | 2b31399a2db58e5480fcd51569f6353609b4219a (diff) | |
download | ghdl-e44cd87182452ce6220b028c62caa1bdbb9c55e3.tar.gz ghdl-e44cd87182452ce6220b028c62caa1bdbb9c55e3.tar.bz2 ghdl-e44cd87182452ce6220b028c62caa1bdbb9c55e3.zip |
Synthesis of PSL stable() function.
-rw-r--r-- | src/synth/synth-expr.adb | 60 | ||||
-rw-r--r-- | src/vhdl/vhdl-prints.adb | 17 | ||||
-rw-r--r-- | src/vhdl/vhdl-sem_expr.adb | 6 | ||||
-rw-r--r-- | src/vhdl/vhdl-sem_psl.adb | 35 | ||||
-rw-r--r-- | src/vhdl/vhdl-sem_psl.ads | 1 |
5 files changed, 107 insertions, 12 deletions
diff --git a/src/synth/synth-expr.adb b/src/synth/synth-expr.adb index 677df4454..6f8317831 100644 --- a/src/synth/synth-expr.adb +++ b/src/synth/synth-expr.adb @@ -1849,30 +1849,40 @@ package body Synth.Expr is return Res; end Synth_PSL_Expression; + function Synth_Psl_Function_Clock + (Syn_Inst : Synth_Instance_Acc; Call : Node; Ctxt : Context_Acc) + return Net + is + Clock : Node; + Clk : Valtyp; + Clk_Net : Net; + begin + Clock := Get_Clock_Expression (Call); + if Clock /= Null_Node then + Clk := Synth_Expression (Syn_Inst, Clock); + Clk_Net := Get_Net (Ctxt, Clk); + else + Clock := Get_Default_Clock (Call); + pragma Assert (Clock /= Null_Node); + Clk_Net := Synth_PSL_Expression (Syn_Inst, Get_Psl_Boolean (Clock)); + end if; + return Clk_Net; + end Synth_Psl_Function_Clock; + function Synth_Psl_Prev (Syn_Inst : Synth_Instance_Acc; Call : Node) return Valtyp is Ctxt : constant Context_Acc := Get_Build (Syn_Inst); Count : constant Node := Get_Count_Expression (Call); - Clock : Node; Count_Val : Valtyp; Dff : Net; - Clk : Valtyp; Expr : Valtyp; Clk_Net : Net; Num : Int64; begin Expr := Synth_Expression (Syn_Inst, Get_Expression (Call)); - Clock := Get_Clock_Expression (Call); - if Clock /= Null_Node then - Clk := Synth_Expression (Syn_Inst, Clock); - Clk_Net := Get_Net (Ctxt, Clk); - else - Clock := Get_Default_Clock (Call); - pragma Assert (Clock /= Null_Node); - Clk_Net := Synth_PSL_Expression (Syn_Inst, Get_Psl_Boolean (Clock)); - end if; + Clk_Net := Synth_Psl_Function_Clock(Syn_Inst, Call, Ctxt); if Count /= Null_Node then Count_Val := Synth_Expression (Syn_Inst, Count); @@ -1891,6 +1901,32 @@ package body Synth.Expr is return Create_Value_Net (Dff, Expr.Typ); end Synth_Psl_Prev; + function Synth_Psl_Stable (Syn_Inst : Synth_Instance_Acc; Call : Node) + return Valtyp + is + Ctxt : constant Context_Acc := Get_Build (Syn_Inst); + DffCurr : Net; + Dff : Net; + Expr : Valtyp; + Clk_Net : Net; + Res : Net; + begin + Expr := Synth_Expression (Syn_Inst, Get_Expression (Call)); + + Clk_Net := Synth_Psl_Function_Clock(Syn_Inst, Call, Ctxt); + + DffCurr := Get_Net (Ctxt, Expr); + Set_Location (DffCurr, Call); + Dff := Build_Dff (Ctxt, Clk_Net, DffCurr); + Set_Location (Dff, Call); + + Res := Build_Compare(Ctxt, Id_Eq, DffCurr, Dff); + Set_Location (Res, Call); + + return Create_Value_Net (Res, Boolean_Type); + + end Synth_Psl_Stable; + subtype And_Or_Module_Id is Module_Id range Id_And .. Id_Or; function Synth_Short_Circuit (Syn_Inst : Synth_Instance_Acc; @@ -2231,6 +2267,8 @@ package body Synth.Expr is return No_Valtyp; when Iir_Kind_Psl_Prev => return Synth_Psl_Prev (Syn_Inst, Expr); + when Iir_Kind_Psl_Stable => + return Synth_Psl_Stable (Syn_Inst, Expr); when Iir_Kind_Overflow_Literal => Error_Msg_Synth (+Expr, "out of bound expression"); return No_Valtyp; diff --git a/src/vhdl/vhdl-prints.adb b/src/vhdl/vhdl-prints.adb index b8da982a5..a0163a63d 100644 --- a/src/vhdl/vhdl-prints.adb +++ b/src/vhdl/vhdl-prints.adb @@ -2288,6 +2288,21 @@ package body Vhdl.Prints is Disp_Token (Ctxt, Tok_Right_Paren); end Disp_Psl_Prev; + procedure Disp_Psl_Stable (Ctxt : in out Ctxt_Class; Call : Iir) + is + Expr : Iir; + begin + Disp_Token (Ctxt, Tok_Stable); + Disp_Token (Ctxt, Tok_Left_Paren); + Print (Ctxt, Get_Expression (Call)); + Expr := Get_Clock_Expression (Call); + if Expr /= Null_Iir then + Disp_Token (Ctxt, Tok_Comma); + Print (Ctxt, Expr); + end if; + Disp_Token (Ctxt, Tok_Right_Paren); + end Disp_Psl_Stable; + procedure Disp_Psl_Declaration (Ctxt : in out Ctxt_Class; Stmt : Iir) is Decl : constant PSL_Node := Get_Psl_Declaration (Stmt); @@ -4751,6 +4766,8 @@ package body Vhdl.Prints is when Iir_Kind_Psl_Prev => Disp_Psl_Prev (Ctxt, Expr); + when Iir_Kind_Psl_Stable => + Disp_Psl_Stable (Ctxt, Expr); when Iir_Kinds_Type_And_Subtype_Definition => Disp_Type (Ctxt, Expr); diff --git a/src/vhdl/vhdl-sem_expr.adb b/src/vhdl/vhdl-sem_expr.adb index db03456e3..c9cc2bae6 100644 --- a/src/vhdl/vhdl-sem_expr.adb +++ b/src/vhdl/vhdl-sem_expr.adb @@ -415,7 +415,8 @@ package body Vhdl.Sem_Expr is | Iir_Kind_Type_Conversion | Iir_Kind_Function_Call => return Expr; - when Iir_Kind_Psl_Endpoint_Declaration => + when Iir_Kind_Psl_Endpoint_Declaration + | Iir_Kind_Psl_Stable => return Expr; when Iir_Kind_Simple_Name | Iir_Kind_Parenthesis_Name @@ -4828,6 +4829,9 @@ package body Vhdl.Sem_Expr is when Iir_Kind_Psl_Prev => return Sem_Psl.Sem_Prev_Builtin (Expr, A_Type); + when Iir_Kind_Psl_Stable => + return Sem_Psl.Sem_Stable_Builtin (Expr); + when Iir_Kind_Error => -- Always ok. -- Use the error as a type. diff --git a/src/vhdl/vhdl-sem_psl.adb b/src/vhdl/vhdl-sem_psl.adb index c4ebf345e..3d36070a3 100644 --- a/src/vhdl/vhdl-sem_psl.adb +++ b/src/vhdl/vhdl-sem_psl.adb @@ -123,6 +123,41 @@ package body Vhdl.Sem_Psl is return Call; end Sem_Prev_Builtin; + function Sem_Stable_Builtin (Call : Iir) return Iir + is + use Vhdl.Sem_Expr; + use Vhdl.Std_Package; + Expr : Iir; + Clock : Iir; + First : Boolean; + begin + Expr := Get_Expression (Call); + First := Is_Expr_Not_Analyzed (Expr); + Expr := Sem_Expression (Expr, Null_Iir); + if Expr /= Null_Iir then + Set_Expression (Call, Expr); + Set_Type (Call, Vhdl.Std_Package.Boolean_Type_Definition); + Set_Expr_Staticness (Call, None); + end if; + + if First then + -- Analyze count and clock only once. + Clock := Get_Clock_Expression (Call); + if Clock /= Null_Iir then + Clock := Sem_Expression_Wildcard (Clock, Wildcard_Psl_Bit_Type); + Set_Clock_Expression (Call, Clock); + else + if Current_Psl_Default_Clock = Null_Iir then + Error_Msg_Sem (+Call, "no clock for PSL stable builtin"); + else + Set_Default_Clock (Call, Current_Psl_Default_Clock); + end if; + end if; + end if; + + return Call; + end Sem_Stable_Builtin; + -- Convert VHDL and/or/not nodes to PSL nodes. function Convert_Bool (Expr : Iir) return PSL_Node is diff --git a/src/vhdl/vhdl-sem_psl.ads b/src/vhdl/vhdl-sem_psl.ads index c0f6e85d5..9f13ac080 100644 --- a/src/vhdl/vhdl-sem_psl.ads +++ b/src/vhdl/vhdl-sem_psl.ads @@ -23,6 +23,7 @@ package Vhdl.Sem_Psl is function Is_Psl_Bitvector_Type (Atype : Iir) return Boolean; function Sem_Prev_Builtin (Call : Iir; Atype : Iir) return Iir; + function Sem_Stable_Builtin (Call : Iir) return Iir; procedure Sem_Psl_Declaration (Stmt : Iir); procedure Sem_Psl_Endpoint_Declaration (Stmt : Iir); |