diff options
author | T. Meissner <programming@goodcleanfun.de> | 2021-02-09 07:31:00 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-02-09 07:31:00 +0100 |
commit | 7d5bfac5526528e32f5f44b9bea0bbdfee21a589 (patch) | |
tree | a3d749912cca5d83f8cb1da304b90a62713d2d59 | |
parent | a75c135b5bb3c817ff0d9605c5cfabbfa721c13b (diff) | |
download | ghdl-7d5bfac5526528e32f5f44b9bea0bbdfee21a589.tar.gz ghdl-7d5bfac5526528e32f5f44b9bea0bbdfee21a589.tar.bz2 ghdl-7d5bfac5526528e32f5f44b9bea0bbdfee21a589.zip |
Add support for PSL onehot/onehot0 functions (#1633)
* vhdl: parse PSL onehot/onehot0 builtin calls. For #662
* update pyGHDL bindings
* Synthesis of PSL built-in onehot/onehot0 function.
* testsuite/synth: add tests of PSL built-in functions onehot()/onehot0() for #662
* doc: add info about PSL built-in functions onehot()/onehot0() for #662
* synth: refactor synthesis of onehot/onehot0 functions
Co-authored-by: eine <eine@users.noreply.github.com>
28 files changed, 701 insertions, 275 deletions
diff --git a/doc/using/ImplementationOfVHDL.rst b/doc/using/ImplementationOfVHDL.rst index f53b04385..332cd7402 100644 --- a/doc/using/ImplementationOfVHDL.rst +++ b/doc/using/ImplementationOfVHDL.rst @@ -142,7 +142,7 @@ or use a clocked expression (note the use of parentheses): Of course only the simple subset of PSL is allowed. Currently the built-in functions are not implemented, see `issue #662 <https://github.com/ghdl/ghdl/issues/662>`_. -PSL functions `prev()`, `stable()`, `rose()` and `fell()` are supported with GHDL synthesis. +PSL functions `prev()`, `stable()`, `rose()`, `fell()`, `onehot()` and `onehot0()` are supported with GHDL synthesis. PSL usage --------- diff --git a/pyGHDL/libghdl/std_names.py b/pyGHDL/libghdl/std_names.py index e716d86c2..656f54f06 100644 --- a/pyGHDL/libghdl/std_names.py +++ b/pyGHDL/libghdl/std_names.py @@ -788,33 +788,35 @@ class Name: Next_Event = 979 Next_Event_A = 980 Next_Event_E = 981 - Prev = 982 - Rose = 983 - Strong = 984 - W = 985 - Whilenot = 986 - Within = 987 - X = 988 - Last_PSL = 988 - First_Edif = 989 - Celltype = 999 - View = 1000 - Viewtype = 1001 - Direction = 1002 - Contents = 1003 - Net = 1004 - Viewref = 1005 - Cellref = 1006 - Libraryref = 1007 - Portinstance = 1008 - Joined = 1009 - Portref = 1010 - Instanceref = 1011 - Design = 1012 - Designator = 1013 - Owner = 1014 - Member = 1015 - Number = 1016 - Rename = 1017 - Userdata = 1018 - Last_Edif = 1018 + Onehot = 982 + Onehot0 = 983 + Prev = 984 + Rose = 985 + Strong = 986 + W = 987 + Whilenot = 988 + Within = 989 + X = 990 + Last_PSL = 990 + First_Edif = 991 + Celltype = 1001 + View = 1002 + Viewtype = 1003 + Direction = 1004 + Contents = 1005 + Net = 1006 + Viewref = 1007 + Cellref = 1008 + Libraryref = 1009 + Portinstance = 1010 + Joined = 1011 + Portref = 1012 + Instanceref = 1013 + Design = 1014 + Designator = 1015 + Owner = 1016 + Member = 1017 + Number = 1018 + Rename = 1019 + Userdata = 1020 + Last_Edif = 1020 diff --git a/pyGHDL/libghdl/vhdl/nodes.py b/pyGHDL/libghdl/vhdl/nodes.py index 976cc4457..a9acc450a 100644 --- a/pyGHDL/libghdl/vhdl/nodes.py +++ b/pyGHDL/libghdl/vhdl/nodes.py @@ -215,122 +215,124 @@ class Iir_Kind: Psl_Stable = 196 Psl_Rose = 197 Psl_Fell = 198 - Psl_Expression = 199 - Sensitized_Process_Statement = 200 - Process_Statement = 201 - Concurrent_Simple_Signal_Assignment = 202 - Concurrent_Conditional_Signal_Assignment = 203 - Concurrent_Selected_Signal_Assignment = 204 - Concurrent_Assertion_Statement = 205 - Concurrent_Procedure_Call_Statement = 206 - Concurrent_Break_Statement = 207 - Psl_Assert_Directive = 208 - Psl_Assume_Directive = 209 - Psl_Cover_Directive = 210 - Psl_Restrict_Directive = 211 - Block_Statement = 212 - If_Generate_Statement = 213 - Case_Generate_Statement = 214 - For_Generate_Statement = 215 - Component_Instantiation_Statement = 216 - Psl_Default_Clock = 217 - Generate_Statement_Body = 218 - If_Generate_Else_Clause = 219 - Simple_Simultaneous_Statement = 220 - Simultaneous_Null_Statement = 221 - Simultaneous_Procedural_Statement = 222 - Simultaneous_Case_Statement = 223 - Simultaneous_If_Statement = 224 - Simultaneous_Elsif = 225 - Simple_Signal_Assignment_Statement = 226 - Conditional_Signal_Assignment_Statement = 227 - Selected_Waveform_Assignment_Statement = 228 - Signal_Force_Assignment_Statement = 229 - Signal_Release_Assignment_Statement = 230 - Null_Statement = 231 - Assertion_Statement = 232 - Report_Statement = 233 - Wait_Statement = 234 - Variable_Assignment_Statement = 235 - Conditional_Variable_Assignment_Statement = 236 - Return_Statement = 237 - For_Loop_Statement = 238 - While_Loop_Statement = 239 - Next_Statement = 240 - Exit_Statement = 241 - Case_Statement = 242 - Procedure_Call_Statement = 243 - Break_Statement = 244 - If_Statement = 245 - Elsif = 246 - Character_Literal = 247 - Simple_Name = 248 - Selected_Name = 249 - Operator_Symbol = 250 - Reference_Name = 251 - External_Constant_Name = 252 - External_Signal_Name = 253 - External_Variable_Name = 254 - Selected_By_All_Name = 255 - Parenthesis_Name = 256 - Package_Pathname = 257 - Absolute_Pathname = 258 - Relative_Pathname = 259 - Pathname_Element = 260 - Base_Attribute = 261 - Subtype_Attribute = 262 - Element_Attribute = 263 - Across_Attribute = 264 - Through_Attribute = 265 - Nature_Reference_Attribute = 266 - Left_Type_Attribute = 267 - Right_Type_Attribute = 268 - High_Type_Attribute = 269 - Low_Type_Attribute = 270 - Ascending_Type_Attribute = 271 - Image_Attribute = 272 - Value_Attribute = 273 - Pos_Attribute = 274 - Val_Attribute = 275 - Succ_Attribute = 276 - Pred_Attribute = 277 - Leftof_Attribute = 278 - Rightof_Attribute = 279 - Signal_Slew_Attribute = 280 - Quantity_Slew_Attribute = 281 - Ramp_Attribute = 282 - Zoh_Attribute = 283 - Ltf_Attribute = 284 - Ztf_Attribute = 285 - Dot_Attribute = 286 - Integ_Attribute = 287 - Above_Attribute = 288 - Quantity_Delayed_Attribute = 289 - Delayed_Attribute = 290 - Stable_Attribute = 291 - Quiet_Attribute = 292 - Transaction_Attribute = 293 - Event_Attribute = 294 - Active_Attribute = 295 - Last_Event_Attribute = 296 - Last_Active_Attribute = 297 - Last_Value_Attribute = 298 - Driving_Attribute = 299 - Driving_Value_Attribute = 300 - Behavior_Attribute = 301 - Structure_Attribute = 302 - Simple_Name_Attribute = 303 - Instance_Name_Attribute = 304 - Path_Name_Attribute = 305 - Left_Array_Attribute = 306 - Right_Array_Attribute = 307 - High_Array_Attribute = 308 - Low_Array_Attribute = 309 - Length_Array_Attribute = 310 - Ascending_Array_Attribute = 311 - Range_Array_Attribute = 312 - Reverse_Range_Array_Attribute = 313 - Attribute_Name = 314 + Psl_Onehot = 199 + Psl_Onehot0 = 200 + Psl_Expression = 201 + Sensitized_Process_Statement = 202 + Process_Statement = 203 + Concurrent_Simple_Signal_Assignment = 204 + Concurrent_Conditional_Signal_Assignment = 205 + Concurrent_Selected_Signal_Assignment = 206 + Concurrent_Assertion_Statement = 207 + Concurrent_Procedure_Call_Statement = 208 + Concurrent_Break_Statement = 209 + Psl_Assert_Directive = 210 + Psl_Assume_Directive = 211 + Psl_Cover_Directive = 212 + Psl_Restrict_Directive = 213 + Block_Statement = 214 + If_Generate_Statement = 215 + Case_Generate_Statement = 216 + For_Generate_Statement = 217 + Component_Instantiation_Statement = 218 + Psl_Default_Clock = 219 + Generate_Statement_Body = 220 + If_Generate_Else_Clause = 221 + Simple_Simultaneous_Statement = 222 + Simultaneous_Null_Statement = 223 + Simultaneous_Procedural_Statement = 224 + Simultaneous_Case_Statement = 225 + Simultaneous_If_Statement = 226 + Simultaneous_Elsif = 227 + Simple_Signal_Assignment_Statement = 228 + Conditional_Signal_Assignment_Statement = 229 + Selected_Waveform_Assignment_Statement = 230 + Signal_Force_Assignment_Statement = 231 + Signal_Release_Assignment_Statement = 232 + Null_Statement = 233 + Assertion_Statement = 234 + Report_Statement = 235 + Wait_Statement = 236 + Variable_Assignment_Statement = 237 + Conditional_Variable_Assignment_Statement = 238 + Return_Statement = 239 + For_Loop_Statement = 240 + While_Loop_Statement = 241 + Next_Statement = 242 + Exit_Statement = 243 + Case_Statement = 244 + Procedure_Call_Statement = 245 + Break_Statement = 246 + If_Statement = 247 + Elsif = 248 + Character_Literal = 249 + Simple_Name = 250 + Selected_Name = 251 + Operator_Symbol = 252 + Reference_Name = 253 + External_Constant_Name = 254 + External_Signal_Name = 255 + External_Variable_Name = 256 + Selected_By_All_Name = 257 + Parenthesis_Name = 258 + Package_Pathname = 259 + Absolute_Pathname = 260 + Relative_Pathname = 261 + Pathname_Element = 262 + Base_Attribute = 263 + Subtype_Attribute = 264 + Element_Attribute = 265 + Across_Attribute = 266 + Through_Attribute = 267 + Nature_Reference_Attribute = 268 + Left_Type_Attribute = 269 + Right_Type_Attribute = 270 + High_Type_Attribute = 271 + Low_Type_Attribute = 272 + Ascending_Type_Attribute = 273 + Image_Attribute = 274 + Value_Attribute = 275 + Pos_Attribute = 276 + Val_Attribute = 277 + Succ_Attribute = 278 + Pred_Attribute = 279 + Leftof_Attribute = 280 + Rightof_Attribute = 281 + Signal_Slew_Attribute = 282 + Quantity_Slew_Attribute = 283 + Ramp_Attribute = 284 + Zoh_Attribute = 285 + Ltf_Attribute = 286 + Ztf_Attribute = 287 + Dot_Attribute = 288 + Integ_Attribute = 289 + Above_Attribute = 290 + Quantity_Delayed_Attribute = 291 + Delayed_Attribute = 292 + Stable_Attribute = 293 + Quiet_Attribute = 294 + Transaction_Attribute = 295 + Event_Attribute = 296 + Active_Attribute = 297 + Last_Event_Attribute = 298 + Last_Active_Attribute = 299 + Last_Value_Attribute = 300 + Driving_Attribute = 301 + Driving_Value_Attribute = 302 + Behavior_Attribute = 303 + Structure_Attribute = 304 + Simple_Name_Attribute = 305 + Instance_Name_Attribute = 306 + Path_Name_Attribute = 307 + Left_Array_Attribute = 308 + Right_Array_Attribute = 309 + High_Array_Attribute = 310 + Low_Array_Attribute = 311 + Length_Array_Attribute = 312 + Ascending_Array_Attribute = 313 + Range_Array_Attribute = 314 + Reverse_Range_Array_Attribute = 315 + Attribute_Name = 316 @export @@ -565,6 +567,8 @@ class Iir_Kinds: Iir_Kind.Psl_Stable, Iir_Kind.Psl_Rose, Iir_Kind.Psl_Fell, + Iir_Kind.Psl_Onehot, + Iir_Kind.Psl_Onehot0, ] Functions_And_Literals = [ diff --git a/pyGHDL/libghdl/vhdl/tokens.py b/pyGHDL/libghdl/vhdl/tokens.py index a846ea623..54c1d0ef9 100644 --- a/pyGHDL/libghdl/vhdl/tokens.py +++ b/pyGHDL/libghdl/vhdl/tokens.py @@ -227,3 +227,5 @@ class Tok: Stable = 218 Fell = 219 Rose = 220 + Onehot = 221 + Onehot0 = 222 diff --git a/src/ghdldrv/ghdlprint.adb b/src/ghdldrv/ghdlprint.adb index e17862db0..dc8e649be 100644 --- a/src/ghdldrv/ghdlprint.adb +++ b/src/ghdldrv/ghdlprint.adb @@ -447,7 +447,9 @@ package body Ghdlprint is | Tok_Prev | Tok_Stable | Tok_Rose - | Tok_Fell => + | Tok_Fell + | Tok_Onehot + | Tok_Onehot0 => Disp_Spaces; Disp_Text; when Tok_String diff --git a/src/std_names.adb b/src/std_names.adb index 4def79432..1a3fcbe94 100644 --- a/src/std_names.adb +++ b/src/std_names.adb @@ -831,6 +831,8 @@ package body Std_Names is Def ("next_event", Name_Next_Event); Def ("next_event_a", Name_Next_Event_A); Def ("next_event_e", Name_Next_Event_E); + Def ("onehot", Name_Onehot); + Def ("onehot0", Name_Onehot0); Def ("property", Name_Property); Def ("prev", Name_Prev); Def ("rose", Name_Rose); diff --git a/src/std_names.ads b/src/std_names.ads index 2a7fc8dc0..281a26f64 100644 --- a/src/std_names.ads +++ b/src/std_names.ads @@ -973,18 +973,20 @@ package Std_Names is -- Name_Not -- Name_Or -- Name_Property - Name_Prev : constant Name_Id := Name_First_PSL + 26; + Name_Onehot : constant Name_Id := Name_First_PSL + 26; + Name_Onehot0 : constant Name_Id := Name_First_PSL + 27; + Name_Prev : constant Name_Id := Name_First_PSL + 28; -- Name_Restrict -- Name_Restrict_Guarantee - Name_Rose : constant Name_Id := Name_First_PSL + 27; + Name_Rose : constant Name_Id := Name_First_PSL + 29; -- sequence - Name_Strong : constant Name_Id := Name_First_PSL + 28; + Name_Strong : constant Name_Id := Name_First_PSL + 30; -- union -- until - Name_W : constant Name_Id := Name_First_PSL + 29; - Name_Whilenot : constant Name_Id := Name_First_PSL + 30; - Name_Within : constant Name_Id := Name_First_PSL + 31; - Name_X : constant Name_Id := Name_First_PSL + 32; + Name_W : constant Name_Id := Name_First_PSL + 31; + Name_Whilenot : constant Name_Id := Name_First_PSL + 32; + Name_Within : constant Name_Id := Name_First_PSL + 33; + Name_X : constant Name_Id := Name_First_PSL + 34; Name_Last_PSL : constant Name_Id := Name_X; subtype Name_Id_PSL_Keywords is diff --git a/src/synth/synth-expr.adb b/src/synth/synth-expr.adb index c5bc9317b..0e3849149 100644 --- a/src/synth/synth-expr.adb +++ b/src/synth/synth-expr.adb @@ -2057,6 +2057,94 @@ package body Synth.Expr is end Synth_Psl_Fell; + function Synth_Onehot0 (Ctxt : Context_Acc; DffCurr : Net; Call : Node; + Vlen : Uns32) + return Net + is + DffZero : Net; + DffOne : Net; + DffOneHot0 : Net; + Res : Net; + begin + -- Create a constant vector of 0 for comparing + DffZero := Build2_Const_Uns(Ctxt, 0, Vlen); + + -- Create vector of value 1 for subtraction + DffOne := Build2_Const_Uns(Ctxt, 1, Vlen); + + -- Subtraction -> v - 1 + DffOneHot0 := Build_Dyadic (Ctxt, Id_Sub, DffCurr, DffOne); + Set_Location (DffOneHot0, Call); + + -- Binary And -> v & (v - 1) + DffOneHot0 := Build_Dyadic (Ctxt, Id_And, DffCurr, DffOneHot0); + Set_Location (DffOneHot0, Call); + + -- Compare with 0 -> (v & (v - 1)) == 0 + Res := Build_Compare (Ctxt, Id_Eq, DffOneHot0, DffZero); + Set_Location (Res, Call); + + return Res; + end Synth_Onehot0; + + function Synth_Psl_Onehot (Syn_Inst : Synth_Instance_Acc; Call : Node) + return Valtyp + is + Ctxt : constant Context_Acc := Get_Build (Syn_Inst); + Expr : Valtyp; + DffCurr : Net; + DffCurrIsNotZero : Net; + DffOneHot0 : Net; + Res : Net; + Vlen : Uns32; + begin + -- Get parameter & its length + Expr := Synth_Expression (Syn_Inst, Get_Expression (Call)); + Vlen := Expr.Typ.W; + + -- First get net of parameter + DffCurr := Get_Net (Ctxt, Expr); + Set_Location (DffCurr, Call); + + -- Compare parameter with 0 -> v != 0 + DffCurrIsNotZero := Build_Compare (Ctxt, Id_Ne, DffCurr, + Build2_Const_Uns(Ctxt, 0, Vlen)); + Set_Location (DffCurrIsNotZero, Call); + + -- Synth onehot0 + DffOneHot0 := Synth_Onehot0 (Ctxt, DffCurr, Call, Vlen); + Set_Location (DffOneHot0, Call); + + -- Final Binary And -> (v != 0) & ((v & (v - 1)) == 0) + Res := Build_Dyadic (Ctxt, Id_And, DffOneHot0, DffCurrIsNotZero); + Set_Location (Res, Call); + + return Create_Value_Net (Res, Boolean_Type); + end Synth_Psl_Onehot; + + function Synth_Psl_Onehot0 (Syn_Inst : Synth_Instance_Acc; Call : Node) + return Valtyp + is + Ctxt : constant Context_Acc := Get_Build (Syn_Inst); + Expr : Valtyp; + Vlen : Uns32; + DffCurr : Net; + Res : Net; + begin + -- Get parameter & its length + Expr := Synth_Expression (Syn_Inst, Get_Expression (Call)); + Vlen := Expr.Typ.W; + + -- First get net of parameter + DffCurr := Get_Net (Ctxt, Expr); + Set_Location (DffCurr, Call); + + -- Synth onehot0 + Res := Synth_Onehot0 (Ctxt, DffCurr, Call, Vlen); + + return Create_Value_Net (Res, Boolean_Type); + end Synth_Psl_Onehot0; + subtype And_Or_Module_Id is Module_Id range Id_And .. Id_Or; function Synth_Short_Circuit (Syn_Inst : Synth_Instance_Acc; @@ -2425,6 +2513,10 @@ package body Synth.Expr is return Synth_Psl_Rose(Syn_Inst, Expr); when Iir_Kind_Psl_Fell => return Synth_Psl_Fell(Syn_Inst, Expr); + when Iir_Kind_Psl_Onehot => + return Synth_Psl_Onehot(Syn_Inst, Expr); + when Iir_Kind_Psl_Onehot0 => + return Synth_Psl_Onehot0(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-elocations.adb b/src/vhdl/vhdl-elocations.adb index 02526d33b..c00aa0c13 100644 --- a/src/vhdl/vhdl-elocations.adb +++ b/src/vhdl/vhdl-elocations.adb @@ -354,6 +354,8 @@ package body Vhdl.Elocations is | Iir_Kind_Psl_Stable | Iir_Kind_Psl_Rose | Iir_Kind_Psl_Fell + | Iir_Kind_Psl_Onehot + | Iir_Kind_Psl_Onehot0 | Iir_Kind_Psl_Expression | Iir_Kind_Concurrent_Assertion_Statement | Iir_Kind_Concurrent_Procedure_Call_Statement diff --git a/src/vhdl/vhdl-elocations.ads b/src/vhdl/vhdl-elocations.ads index fb208404b..8358645bf 100644 --- a/src/vhdl/vhdl-elocations.ads +++ b/src/vhdl/vhdl-elocations.ads @@ -113,6 +113,8 @@ package Vhdl.Elocations is -- Iir_Kind_Psl_Stable (None) -- Iir_Kind_Psl_Rose (None) -- Iir_Kind_Psl_Fell (None) + -- Iir_Kind_Psl_Onehot (None) + -- Iir_Kind_Psl_Onehot0 (None) -- Iir_Kind_Signature (None) diff --git a/src/vhdl/vhdl-errors.adb b/src/vhdl/vhdl-errors.adb index ac5546130..a03dfe1ab 100644 --- a/src/vhdl/vhdl-errors.adb +++ b/src/vhdl/vhdl-errors.adb @@ -792,6 +792,10 @@ package body Vhdl.Errors is return "PSL rose function"; when Iir_Kind_Psl_Fell => return "PSL fell function"; + when Iir_Kind_Psl_Onehot => + return "PSL onehot function"; + when Iir_Kind_Psl_Onehot0 => + return "PSL onehot0 function"; when Iir_Kind_If_Statement => return Disp_Label (Node, "if statement"); diff --git a/src/vhdl/vhdl-nodes.adb b/src/vhdl/vhdl-nodes.adb index 822c299cd..d4ed0e97b 100644 --- a/src/vhdl/vhdl-nodes.adb +++ b/src/vhdl/vhdl-nodes.adb @@ -1141,6 +1141,8 @@ package body Vhdl.Nodes is | Iir_Kind_Psl_Stable | Iir_Kind_Psl_Rose | Iir_Kind_Psl_Fell + | Iir_Kind_Psl_Onehot + | Iir_Kind_Psl_Onehot0 | Iir_Kind_Psl_Expression | Iir_Kind_Concurrent_Assertion_Statement | Iir_Kind_Concurrent_Procedure_Call_Statement diff --git a/src/vhdl/vhdl-nodes.ads b/src/vhdl/vhdl-nodes.ads index 29029f7e6..e5af859a9 100644 --- a/src/vhdl/vhdl-nodes.ads +++ b/src/vhdl/vhdl-nodes.ads @@ -876,6 +876,15 @@ package Vhdl.Nodes is -- -- Get/Set_Expr_Staticness (State1) + -- Iir_Kind_Psl_Onehot (Short) + -- Iir_Kind_Psl_Onehot0 (Short) + -- + -- Get/Set_Type (Field1) + -- + -- Get/Set_Expression (Field5) + -- + -- Get/Set_Expr_Staticness (State1) + -- Iir_Kind_Signature (Medium) -- -- LRM08 4.5.3 Signatures @@ -5030,6 +5039,8 @@ package Vhdl.Nodes is Iir_Kind_Psl_Stable, Iir_Kind_Psl_Rose, Iir_Kind_Psl_Fell, + Iir_Kind_Psl_Onehot, + Iir_Kind_Psl_Onehot0, Iir_Kind_Psl_Expression, -- Concurrent statements. @@ -6537,7 +6548,9 @@ package Vhdl.Nodes is Iir_Kind_Psl_Prev .. --Iir_Kind_Psl_Stable --Iir_Kind_Psl_Rose - Iir_Kind_Psl_Fell; + --Iir_Kind_Psl_Fell + --Iir_Kind_Psl_Onehot + Iir_Kind_Psl_Onehot0; subtype Iir_Kinds_Functions_And_Literals is Iir_Kind range Iir_Kind_Enumeration_Literal .. diff --git a/src/vhdl/vhdl-nodes_meta.adb b/src/vhdl/vhdl-nodes_meta.adb index 703af8a58..5b4ad1569 100644 --- a/src/vhdl/vhdl-nodes_meta.adb +++ b/src/vhdl/vhdl-nodes_meta.adb @@ -1541,6 +1541,10 @@ package body Vhdl.Nodes_Meta is return "psl_rose"; when Iir_Kind_Psl_Fell => return "psl_fell"; + when Iir_Kind_Psl_Onehot => + return "psl_onehot"; + when Iir_Kind_Psl_Onehot0 => + return "psl_onehot0"; when Iir_Kind_Psl_Expression => return "psl_expression"; when Iir_Kind_Sensitized_Process_Statement => @@ -4240,6 +4244,14 @@ package body Vhdl.Nodes_Meta is Field_Expression, Field_Clock_Expression, Field_Default_Clock, + -- Iir_Kind_Psl_Onehot + Field_Expr_Staticness, + Field_Type, + Field_Expression, + -- Iir_Kind_Psl_Onehot0 + Field_Expr_Staticness, + Field_Type, + Field_Expression, -- Iir_Kind_Psl_Expression Field_Psl_Expression, Field_Type, @@ -5415,122 +5427,124 @@ package body Vhdl.Nodes_Meta is Iir_Kind_Psl_Stable => 1506, Iir_Kind_Psl_Rose => 1511, Iir_Kind_Psl_Fell => 1516, - Iir_Kind_Psl_Expression => 1518, - Iir_Kind_Sensitized_Process_Statement => 1539, - Iir_Kind_Process_Statement => 1559, - Iir_Kind_Concurrent_Simple_Signal_Assignment => 1572, - Iir_Kind_Concurrent_Conditional_Signal_Assignment => 1585, - Iir_Kind_Concurrent_Selected_Signal_Assignment => 1599, - Iir_Kind_Concurrent_Assertion_Statement => 1607, - Iir_Kind_Concurrent_Procedure_Call_Statement => 1614, - Iir_Kind_Concurrent_Break_Statement => 1622, - Iir_Kind_Psl_Assert_Directive => 1635, - Iir_Kind_Psl_Assume_Directive => 1646, - Iir_Kind_Psl_Cover_Directive => 1658, - Iir_Kind_Psl_Restrict_Directive => 1669, - Iir_Kind_Block_Statement => 1683, - Iir_Kind_If_Generate_Statement => 1694, - Iir_Kind_Case_Generate_Statement => 1703, - Iir_Kind_For_Generate_Statement => 1712, - Iir_Kind_Component_Instantiation_Statement => 1723, - Iir_Kind_Psl_Default_Clock => 1727, - Iir_Kind_Generate_Statement_Body => 1738, - Iir_Kind_If_Generate_Else_Clause => 1744, - Iir_Kind_Simple_Simultaneous_Statement => 1751, - Iir_Kind_Simultaneous_Null_Statement => 1755, - Iir_Kind_Simultaneous_Procedural_Statement => 1766, - Iir_Kind_Simultaneous_Case_Statement => 1775, - Iir_Kind_Simultaneous_If_Statement => 1784, - Iir_Kind_Simultaneous_Elsif => 1790, - Iir_Kind_Simple_Signal_Assignment_Statement => 1801, - Iir_Kind_Conditional_Signal_Assignment_Statement => 1812, - Iir_Kind_Selected_Waveform_Assignment_Statement => 1824, - Iir_Kind_Signal_Force_Assignment_Statement => 1834, - Iir_Kind_Signal_Release_Assignment_Statement => 1843, - Iir_Kind_Null_Statement => 1847, - Iir_Kind_Assertion_Statement => 1854, - Iir_Kind_Report_Statement => 1860, - Iir_Kind_Wait_Statement => 1868, - Iir_Kind_Variable_Assignment_Statement => 1875, - Iir_Kind_Conditional_Variable_Assignment_Statement => 1882, - Iir_Kind_Return_Statement => 1888, - Iir_Kind_For_Loop_Statement => 1899, - Iir_Kind_While_Loop_Statement => 1910, - Iir_Kind_Next_Statement => 1917, - Iir_Kind_Exit_Statement => 1924, - Iir_Kind_Case_Statement => 1932, - Iir_Kind_Procedure_Call_Statement => 1938, - Iir_Kind_Break_Statement => 1945, - Iir_Kind_If_Statement => 1955, - Iir_Kind_Elsif => 1961, - Iir_Kind_Character_Literal => 1969, - Iir_Kind_Simple_Name => 1977, - Iir_Kind_Selected_Name => 1986, - Iir_Kind_Operator_Symbol => 1992, - Iir_Kind_Reference_Name => 1997, - Iir_Kind_External_Constant_Name => 2006, - Iir_Kind_External_Signal_Name => 2015, - Iir_Kind_External_Variable_Name => 2025, - Iir_Kind_Selected_By_All_Name => 2031, - Iir_Kind_Parenthesis_Name => 2036, - Iir_Kind_Package_Pathname => 2040, - Iir_Kind_Absolute_Pathname => 2041, - Iir_Kind_Relative_Pathname => 2042, - Iir_Kind_Pathname_Element => 2047, - Iir_Kind_Base_Attribute => 2049, - Iir_Kind_Subtype_Attribute => 2054, - Iir_Kind_Element_Attribute => 2059, - Iir_Kind_Across_Attribute => 2064, - Iir_Kind_Through_Attribute => 2069, - Iir_Kind_Nature_Reference_Attribute => 2073, - Iir_Kind_Left_Type_Attribute => 2078, - Iir_Kind_Right_Type_Attribute => 2083, - Iir_Kind_High_Type_Attribute => 2088, - Iir_Kind_Low_Type_Attribute => 2093, - Iir_Kind_Ascending_Type_Attribute => 2098, - Iir_Kind_Image_Attribute => 2104, - Iir_Kind_Value_Attribute => 2110, - Iir_Kind_Pos_Attribute => 2116, - Iir_Kind_Val_Attribute => 2122, - Iir_Kind_Succ_Attribute => 2128, - Iir_Kind_Pred_Attribute => 2134, - Iir_Kind_Leftof_Attribute => 2140, - Iir_Kind_Rightof_Attribute => 2146, - Iir_Kind_Signal_Slew_Attribute => 2154, - Iir_Kind_Quantity_Slew_Attribute => 2162, - Iir_Kind_Ramp_Attribute => 2170, - Iir_Kind_Zoh_Attribute => 2178, - Iir_Kind_Ltf_Attribute => 2186, - Iir_Kind_Ztf_Attribute => 2196, - Iir_Kind_Dot_Attribute => 2203, - Iir_Kind_Integ_Attribute => 2210, - Iir_Kind_Above_Attribute => 2218, - Iir_Kind_Quantity_Delayed_Attribute => 2226, - Iir_Kind_Delayed_Attribute => 2235, - Iir_Kind_Stable_Attribute => 2244, - Iir_Kind_Quiet_Attribute => 2253, - Iir_Kind_Transaction_Attribute => 2262, - Iir_Kind_Event_Attribute => 2266, - Iir_Kind_Active_Attribute => 2270, - Iir_Kind_Last_Event_Attribute => 2274, - Iir_Kind_Last_Active_Attribute => 2278, - Iir_Kind_Last_Value_Attribute => 2282, - Iir_Kind_Driving_Attribute => 2286, - Iir_Kind_Driving_Value_Attribute => 2290, - Iir_Kind_Behavior_Attribute => 2290, - Iir_Kind_Structure_Attribute => 2290, - Iir_Kind_Simple_Name_Attribute => 2297, - Iir_Kind_Instance_Name_Attribute => 2302, - Iir_Kind_Path_Name_Attribute => 2307, - Iir_Kind_Left_Array_Attribute => 2314, - Iir_Kind_Right_Array_Attribute => 2321, - Iir_Kind_High_Array_Attribute => 2328, - Iir_Kind_Low_Array_Attribute => 2335, - Iir_Kind_Length_Array_Attribute => 2342, - Iir_Kind_Ascending_Array_Attribute => 2349, - Iir_Kind_Range_Array_Attribute => 2356, - Iir_Kind_Reverse_Range_Array_Attribute => 2363, - Iir_Kind_Attribute_Name => 2372 + Iir_Kind_Psl_Onehot => 1519, + Iir_Kind_Psl_Onehot0 => 1522, + Iir_Kind_Psl_Expression => 1524, + Iir_Kind_Sensitized_Process_Statement => 1545, + Iir_Kind_Process_Statement => 1565, + Iir_Kind_Concurrent_Simple_Signal_Assignment => 1578, + Iir_Kind_Concurrent_Conditional_Signal_Assignment => 1591, + Iir_Kind_Concurrent_Selected_Signal_Assignment => 1605, + Iir_Kind_Concurrent_Assertion_Statement => 1613, + Iir_Kind_Concurrent_Procedure_Call_Statement => 1620, + Iir_Kind_Concurrent_Break_Statement => 1628, + Iir_Kind_Psl_Assert_Directive => 1641, + Iir_Kind_Psl_Assume_Directive => 1652, + Iir_Kind_Psl_Cover_Directive => 1664, + Iir_Kind_Psl_Restrict_Directive => 1675, + Iir_Kind_Block_Statement => 1689, + Iir_Kind_If_Generate_Statement => 1700, + Iir_Kind_Case_Generate_Statement => 1709, + Iir_Kind_For_Generate_Statement => 1718, + Iir_Kind_Component_Instantiation_Statement => 1729, + Iir_Kind_Psl_Default_Clock => 1733, + Iir_Kind_Generate_Statement_Body => 1744, + Iir_Kind_If_Generate_Else_Clause => 1750, + Iir_Kind_Simple_Simultaneous_Statement => 1757, + Iir_Kind_Simultaneous_Null_Statement => 1761, + Iir_Kind_Simultaneous_Procedural_Statement => 1772, + Iir_Kind_Simultaneous_Case_Statement => 1781, + Iir_Kind_Simultaneous_If_Statement => 1790, + Iir_Kind_Simultaneous_Elsif => 1796, + Iir_Kind_Simple_Signal_Assignment_Statement => 1807, + Iir_Kind_Conditional_Signal_Assignment_Statement => 1818, + Iir_Kind_Selected_Waveform_Assignment_Statement => 1830, + Iir_Kind_Signal_Force_Assignment_Statement => 1840, + Iir_Kind_Signal_Release_Assignment_Statement => 1849, + Iir_Kind_Null_Statement => 1853, + Iir_Kind_Assertion_Statement => 1860, + Iir_Kind_Report_Statement => 1866, + Iir_Kind_Wait_Statement => 1874, + Iir_Kind_Variable_Assignment_Statement => 1881, + Iir_Kind_Conditional_Variable_Assignment_Statement => 1888, + Iir_Kind_Return_Statement => 1894, + Iir_Kind_For_Loop_Statement => 1905, + Iir_Kind_While_Loop_Statement => 1916, + Iir_Kind_Next_Statement => 1923, + Iir_Kind_Exit_Statement => 1930, + Iir_Kind_Case_Statement => 1938, + Iir_Kind_Procedure_Call_Statement => 1944, + Iir_Kind_Break_Statement => 1951, + Iir_Kind_If_Statement => 1961, + Iir_Kind_Elsif => 1967, + Iir_Kind_Character_Literal => 1975, + Iir_Kind_Simple_Name => 1983, + Iir_Kind_Selected_Name => 1992, + Iir_Kind_Operator_Symbol => 1998, + Iir_Kind_Reference_Name => 2003, + Iir_Kind_External_Constant_Name => 2012, + Iir_Kind_External_Signal_Name => 2021, + Iir_Kind_External_Variable_Name => 2031, + Iir_Kind_Selected_By_All_Name => 2037, + Iir_Kind_Parenthesis_Name => 2042, + Iir_Kind_Package_Pathname => 2046, + Iir_Kind_Absolute_Pathname => 2047, + Iir_Kind_Relative_Pathname => 2048, + Iir_Kind_Pathname_Element => 2053, + Iir_Kind_Base_Attribute => 2055, + Iir_Kind_Subtype_Attribute => 2060, + Iir_Kind_Element_Attribute => 2065, + Iir_Kind_Across_Attribute => 2070, + Iir_Kind_Through_Attribute => 2075, + Iir_Kind_Nature_Reference_Attribute => 2079, + Iir_Kind_Left_Type_Attribute => 2084, + Iir_Kind_Right_Type_Attribute => 2089, + Iir_Kind_High_Type_Attribute => 2094, + Iir_Kind_Low_Type_Attribute => 2099, + Iir_Kind_Ascending_Type_Attribute => 2104, + Iir_Kind_Image_Attribute => 2110, + Iir_Kind_Value_Attribute => 2116, + Iir_Kind_Pos_Attribute => 2122, + Iir_Kind_Val_Attribute => 2128, + Iir_Kind_Succ_Attribute => 2134, + Iir_Kind_Pred_Attribute => 2140, + Iir_Kind_Leftof_Attribute => 2146, + Iir_Kind_Rightof_Attribute => 2152, + Iir_Kind_Signal_Slew_Attribute => 2160, + Iir_Kind_Quantity_Slew_Attribute => 2168, + Iir_Kind_Ramp_Attribute => 2176, + Iir_Kind_Zoh_Attribute => 2184, + Iir_Kind_Ltf_Attribute => 2192, + Iir_Kind_Ztf_Attribute => 2202, + Iir_Kind_Dot_Attribute => 2209, + Iir_Kind_Integ_Attribute => 2216, + Iir_Kind_Above_Attribute => 2224, + Iir_Kind_Quantity_Delayed_Attribute => 2232, + Iir_Kind_Delayed_Attribute => 2241, + Iir_Kind_Stable_Attribute => 2250, + Iir_Kind_Quiet_Attribute => 2259, + Iir_Kind_Transaction_Attribute => 2268, + Iir_Kind_Event_Attribute => 2272, + Iir_Kind_Active_Attribute => 2276, + Iir_Kind_Last_Event_Attribute => 2280, + Iir_Kind_Last_Active_Attribute => 2284, + Iir_Kind_Last_Value_Attribute => 2288, + Iir_Kind_Driving_Attribute => 2292, + Iir_Kind_Driving_Value_Attribute => 2296, + Iir_Kind_Behavior_Attribute => 2296, + Iir_Kind_Structure_Attribute => 2296, + Iir_Kind_Simple_Name_Attribute => 2303, + Iir_Kind_Instance_Name_Attribute => 2308, + Iir_Kind_Path_Name_Attribute => 2313, + Iir_Kind_Left_Array_Attribute => 2320, + Iir_Kind_Right_Array_Attribute => 2327, + Iir_Kind_High_Array_Attribute => 2334, + Iir_Kind_Low_Array_Attribute => 2341, + Iir_Kind_Length_Array_Attribute => 2348, + Iir_Kind_Ascending_Array_Attribute => 2355, + Iir_Kind_Range_Array_Attribute => 2362, + Iir_Kind_Reverse_Range_Array_Attribute => 2369, + Iir_Kind_Attribute_Name => 2378 ); function Get_Fields_First (K : Iir_Kind) return Fields_Index is @@ -8687,6 +8701,8 @@ package body Vhdl.Nodes_Meta is | Iir_Kind_Psl_Stable | Iir_Kind_Psl_Rose | Iir_Kind_Psl_Fell + | Iir_Kind_Psl_Onehot + | Iir_Kind_Psl_Onehot0 | Iir_Kind_Psl_Expression | Iir_Kind_Return_Statement | Iir_Kind_Character_Literal @@ -10628,6 +10644,8 @@ package body Vhdl.Nodes_Meta is | Iir_Kind_Psl_Stable | Iir_Kind_Psl_Rose | Iir_Kind_Psl_Fell + | Iir_Kind_Psl_Onehot + | Iir_Kind_Psl_Onehot0 | Iir_Kind_Concurrent_Selected_Signal_Assignment | Iir_Kind_Case_Generate_Statement | Iir_Kind_Simultaneous_Case_Statement @@ -11175,6 +11193,8 @@ package body Vhdl.Nodes_Meta is | Iir_Kind_Psl_Stable | Iir_Kind_Psl_Rose | Iir_Kind_Psl_Fell + | Iir_Kind_Psl_Onehot + | Iir_Kind_Psl_Onehot0 | Iir_Kind_Character_Literal | Iir_Kind_Simple_Name | Iir_Kind_Selected_Name diff --git a/src/vhdl/vhdl-parse.adb b/src/vhdl/vhdl-parse.adb index 03d73883e..21ffab509 100644 --- a/src/vhdl/vhdl-parse.adb +++ b/src/vhdl/vhdl-parse.adb @@ -6060,6 +6060,8 @@ package body Vhdl.Parse is Set_Clock_Expression (Res, Expr); when Iir_Kind_Psl_Prev => Set_Count_Expression (Res, Expr); + when others => + Error_Msg_Parse ("too many parameter for PSL builtin"); end case; end if; @@ -6243,6 +6245,10 @@ package body Vhdl.Parse is return Parse_PSL_Builtin_Call (Iir_Kind_Psl_Rose); when Tok_Fell => return Parse_PSL_Builtin_Call (Iir_Kind_Psl_Fell); + when Tok_Onehot => + return Parse_PSL_Builtin_Call (Iir_Kind_Psl_Onehot); + when Tok_Onehot0 => + return Parse_PSL_Builtin_Call (Iir_Kind_Psl_Onehot0); when Tok_Minus | Tok_Plus => diff --git a/src/vhdl/vhdl-prints.adb b/src/vhdl/vhdl-prints.adb index 9a51b5563..8fb03bf8e 100644 --- a/src/vhdl/vhdl-prints.adb +++ b/src/vhdl/vhdl-prints.adb @@ -2335,6 +2335,22 @@ package body Vhdl.Prints is Disp_Token (Ctxt, Tok_Right_Paren); end Disp_Psl_Fell; + procedure Disp_Psl_Onehot (Ctxt : in out Ctxt_Class; Call : Iir) is + begin + Disp_Token (Ctxt, Tok_Onehot); + Disp_Token (Ctxt, Tok_Left_Paren); + Print (Ctxt, Get_Expression (Call)); + Disp_Token (Ctxt, Tok_Right_Paren); + end Disp_Psl_Onehot; + + procedure Disp_Psl_Onehot0 (Ctxt : in out Ctxt_Class; Call : Iir) is + begin + Disp_Token (Ctxt, Tok_Onehot0); + Disp_Token (Ctxt, Tok_Left_Paren); + Print (Ctxt, Get_Expression (Call)); + Disp_Token (Ctxt, Tok_Right_Paren); + end Disp_Psl_Onehot0; + procedure Disp_Psl_Declaration (Ctxt : in out Ctxt_Class; Stmt : Iir) is Decl : constant PSL_Node := Get_Psl_Declaration (Stmt); @@ -4844,6 +4860,10 @@ package body Vhdl.Prints is Disp_Psl_Rose (Ctxt, Expr); when Iir_Kind_Psl_Fell => Disp_Psl_Fell (Ctxt, Expr); + when Iir_Kind_Psl_Onehot => + Disp_Psl_Onehot (Ctxt, Expr); + when Iir_Kind_Psl_Onehot0 => + Disp_Psl_Onehot0 (Ctxt, Expr); when Iir_Kinds_Type_And_Subtype_Definition => Disp_Type (Ctxt, Expr); diff --git a/src/vhdl/vhdl-scanner.adb b/src/vhdl/vhdl-scanner.adb index 0dad688a6..177f04bad 100644 --- a/src/vhdl/vhdl-scanner.adb +++ b/src/vhdl/vhdl-scanner.adb @@ -1296,6 +1296,10 @@ package body Vhdl.Scanner is Current_Token := Tok_Rose; when Name_Fell => Current_Token := Tok_Fell; + when Name_Onehot => + Current_Token := Tok_Onehot; + when Name_Onehot0 => + Current_Token := Tok_Onehot0; when Name_Sequence => Current_Token := Tok_Sequence; when Name_Property => @@ -1378,6 +1382,10 @@ package body Vhdl.Scanner is Current_Token := Tok_Rose; when Name_Fell => Current_Token := Tok_Fell; + when Name_Onehot => + Current_Token := Tok_Onehot; + when Name_Onehot0 => + Current_Token := Tok_Onehot0; when Name_Clock => Current_Token := Tok_Psl_Clock; when Name_Const => diff --git a/src/vhdl/vhdl-sem_expr.adb b/src/vhdl/vhdl-sem_expr.adb index b8445bcec..25dbb1fea 100644 --- a/src/vhdl/vhdl-sem_expr.adb +++ b/src/vhdl/vhdl-sem_expr.adb @@ -417,7 +417,9 @@ package body Vhdl.Sem_Expr is | Iir_Kind_Psl_Prev | Iir_Kind_Psl_Stable | Iir_Kind_Psl_Rose - | Iir_Kind_Psl_Fell => + | Iir_Kind_Psl_Fell + | Iir_Kind_Psl_Onehot + | Iir_Kind_Psl_Onehot0 => return Expr; when Iir_Kind_Simple_Name | Iir_Kind_Parenthesis_Name @@ -4920,6 +4922,12 @@ package body Vhdl.Sem_Expr is when Iir_Kind_Psl_Fell => return Sem_Psl.Sem_Fell_Builtin (Expr); + when Iir_Kind_Psl_Onehot => + return Sem_Psl.Sem_Onehot_Builtin (Expr); + + when Iir_Kind_Psl_Onehot0 => + return Sem_Psl.Sem_Onehot0_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 32a985643..f8652f803 100644 --- a/src/vhdl/vhdl-sem_psl.adb +++ b/src/vhdl/vhdl-sem_psl.adb @@ -226,6 +226,38 @@ package body Vhdl.Sem_Psl is return Call; end Sem_Fell_Builtin; + function Sem_Onehot_Builtin (Call : Iir) return Iir + is + use Vhdl.Sem_Expr; + use Vhdl.Std_Package; + Expr : Iir; + begin + Expr := Get_Expression (Call); + 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; + return Call; + end Sem_Onehot_Builtin; + + function Sem_Onehot0_Builtin (Call : Iir) return Iir + is + use Vhdl.Sem_Expr; + use Vhdl.Std_Package; + Expr : Iir; + begin + Expr := Get_Expression (Call); + 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; + return Call; + end Sem_Onehot0_Builtin; + -- Convert VHDL and/or/not nodes to PSL nodes. function Convert_Bool (Expr : Iir) return PSL_Node; diff --git a/src/vhdl/vhdl-sem_psl.ads b/src/vhdl/vhdl-sem_psl.ads index 57bc8c15d..758462a62 100644 --- a/src/vhdl/vhdl-sem_psl.ads +++ b/src/vhdl/vhdl-sem_psl.ads @@ -25,6 +25,8 @@ package Vhdl.Sem_Psl is function Sem_Stable_Builtin (Call : Iir) return Iir; function Sem_Rose_Builtin (Call : Iir) return Iir; function Sem_Fell_Builtin (Call : Iir) return Iir; + function Sem_Onehot_Builtin (Call : Iir) return Iir; + function Sem_Onehot0_Builtin (Call : Iir) return Iir; procedure Sem_Psl_Declaration (Stmt : Iir); procedure Sem_Psl_Endpoint_Declaration (Stmt : Iir); diff --git a/src/vhdl/vhdl-tokens.adb b/src/vhdl/vhdl-tokens.adb index eaddc95fa..e85ccc2a4 100644 --- a/src/vhdl/vhdl-tokens.adb +++ b/src/vhdl/vhdl-tokens.adb @@ -445,6 +445,10 @@ package body Vhdl.Tokens is -- PSL keywords when Tok_Psl_Clock => return "clock"; + when Tok_Onehot0 => + return "onehot0"; + when Tok_Onehot => + return "onehot"; when Tok_Fell => return "fell"; when Tok_Rose => diff --git a/src/vhdl/vhdl-tokens.ads b/src/vhdl/vhdl-tokens.ads index c25600f20..9947f2b8a 100644 --- a/src/vhdl/vhdl-tokens.ads +++ b/src/vhdl/vhdl-tokens.ads @@ -306,7 +306,9 @@ package Vhdl.Tokens is Tok_Prev, Tok_Stable, Tok_Fell, - Tok_Rose + Tok_Rose, + Tok_Onehot, + Tok_Onehot0 ); -- To ease interfacing diff --git a/src/vhdl/vhdl-utils.adb b/src/vhdl/vhdl-utils.adb index 9e5d56b87..f34be5aeb 100644 --- a/src/vhdl/vhdl-utils.adb +++ b/src/vhdl/vhdl-utils.adb @@ -348,6 +348,8 @@ package body Vhdl.Utils is | Iir_Kind_Psl_Stable | Iir_Kind_Psl_Rose | Iir_Kind_Psl_Fell + | Iir_Kind_Psl_Onehot + | Iir_Kind_Psl_Onehot0 | Iir_Kind_If_Generate_Else_Clause | Iir_Kind_Elsif | Iir_Kind_Simultaneous_Elsif diff --git a/testsuite/synth/issue662/psl_onehot.vhdl b/testsuite/synth/issue662/psl_onehot.vhdl new file mode 100644 index 000000000..feaa784df --- /dev/null +++ b/testsuite/synth/issue662/psl_onehot.vhdl @@ -0,0 +1,28 @@ +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +entity psl_onehot is + port (clk : in std_logic; + a, b : in std_logic_vector(3 downto 0); + c : in natural range 0 to 15 + ); +end entity psl_onehot; + + +architecture psl of psl_onehot is +begin + + -- All is sensitive to rising edge of clk + default clock is rising_edge(clk); + + -- This assertion holds + ONEHOT_0_a : assert always onehot(a); + + -- This assertion fails at cycle 12 + ONEHOT_1_a : assert always onehot(b); + + -- This assertion fails at cycle 12 + ONEHOT_2_a : assert always onehot(c); + +end architecture psl; diff --git a/testsuite/synth/issue662/psl_onehot0.vhdl b/testsuite/synth/issue662/psl_onehot0.vhdl new file mode 100644 index 000000000..edd4361c8 --- /dev/null +++ b/testsuite/synth/issue662/psl_onehot0.vhdl @@ -0,0 +1,27 @@ +library ieee; +use ieee.std_logic_1164.all; + +entity psl_onehot0 is + port (clk : in std_logic; + a, b : in std_logic_vector(3 downto 0); + c : in natural range 0 to 15 + ); +end entity psl_onehot0; + + +architecture psl of psl_onehot0 is +begin + + -- All is sensitive to rising edge of clk + default clock is rising_edge(clk); + + -- This assertion holds + ONEHOT0_0_a : assert always onehot0(a); + + -- This assertion fails at cycle 15 + ONEHOT0_1_a : assert always onehot0(b); + + -- This assertion fails at cycle 15 + ONEHOT0_2_a : assert always onehot(c); + +end architecture psl; diff --git a/testsuite/synth/issue662/tb_psl_onehot.vhdl b/testsuite/synth/issue662/tb_psl_onehot.vhdl new file mode 100644 index 000000000..10b5d8c73 --- /dev/null +++ b/testsuite/synth/issue662/tb_psl_onehot.vhdl @@ -0,0 +1,69 @@ +library ieee; + use ieee.std_logic_1164.all; + use ieee.numeric_std.all; + +entity tb_psl_onehot is +end entity tb_psl_onehot; + + +architecture psl of tb_psl_onehot is + + procedure seq (s : string; signal clk : std_logic; signal o : out std_logic) + is + begin + for i in s'range loop + wait until rising_edge(clk); + case s(i) is + when '0' | '_' => o <= '0'; + when '1' | '-' => o <= '1'; + when others => o <= 'X'; + end case; + end loop; + wait; + end seq; + + procedure hseq (s : string; signal clk : std_logic; signal o : out std_logic_vector(3 downto 0)) + is + begin + for i in s'range loop + wait until rising_edge(clk); + case s(i) is + when '0' | '_' => o <= x"0"; + when '1' => o <= x"1"; + when '2' => o <= x"2"; + when '3' => o <= x"3"; + when '4' => o <= x"4"; + when '5' => o <= x"5"; + when '6' => o <= x"6"; + when '7' => o <= x"7"; + when '8' => o <= x"8"; + when '9' => o <= x"9"; + when 'a' | 'A' => o <= x"A"; + when 'b' | 'B' => o <= x"B"; + when 'c' | 'C' => o <= x"C"; + when 'd' | 'D' => o <= x"D"; + when 'e' | 'E' => o <= x"E"; + when 'f' | 'F' | '-' => o <= x"F"; + when others => o <= x"X"; + end case; + end loop; + wait; + end hseq; + + signal a, b : std_logic_vector(3 downto 0) := x"0"; + signal c : natural range 0 to 15 := 0; + signal clk : std_logic := '1'; + +begin + + dut: entity work.psl_onehot port map (clk, a, b, c); + + clk <= not clk after 500 ps; + + -- 012345678901234 + SEQ_A : hseq ("111222444888888", clk, a); + SEQ_B : hseq ("111222444888999", clk, b); + + c <= to_integer(unsigned(b)); + +end architecture psl; diff --git a/testsuite/synth/issue662/tb_psl_onehot0.vhdl b/testsuite/synth/issue662/tb_psl_onehot0.vhdl new file mode 100644 index 000000000..2f51ba020 --- /dev/null +++ b/testsuite/synth/issue662/tb_psl_onehot0.vhdl @@ -0,0 +1,69 @@ +library ieee; + use ieee.std_logic_1164.all; + use ieee.numeric_std.all; + +entity tb_psl_onehot0 is +end entity tb_psl_onehot0; + + +architecture psl of tb_psl_onehot0 is + + procedure seq (s : string; signal clk : std_logic; signal o : out std_logic) + is + begin + for i in s'range loop + wait until rising_edge(clk); + case s(i) is + when '0' | '_' => o <= '0'; + when '1' | '-' => o <= '1'; + when others => o <= 'X'; + end case; + end loop; + wait; + end seq; + + procedure hseq (s : string; signal clk : std_logic; signal o : out std_logic_vector(3 downto 0)) + is + begin + for i in s'range loop + wait until rising_edge(clk); + case s(i) is + when '0' | '_' => o <= x"0"; + when '1' => o <= x"1"; + when '2' => o <= x"2"; + when '3' => o <= x"3"; + when '4' => o <= x"4"; + when '5' => o <= x"5"; + when '6' => o <= x"6"; + when '7' => o <= x"7"; + when '8' => o <= x"8"; + when '9' => o <= x"9"; + when 'a' | 'A' => o <= x"A"; + when 'b' | 'B' => o <= x"B"; + when 'c' | 'C' => o <= x"C"; + when 'd' | 'D' => o <= x"D"; + when 'e' | 'E' => o <= x"E"; + when 'f' | 'F' | '-' => o <= x"F"; + when others => o <= x"X"; + end case; + end loop; + wait; + end hseq; + + signal a, b : std_logic_vector(3 downto 0) := x"0"; + signal c : natural range 0 to 15 := 0; + signal clk : std_logic := '1'; + +begin + + dut: entity work.psl_onehot0 port map (clk, a, b, c); + + clk <= not clk after 500 ps; + + -- 012345678901234567 + SEQ_A : hseq ("000111222444888888", clk, a); + SEQ_B : hseq ("000111222444888fff", clk, b); + + c <= to_integer(unsigned(b)); + +end architecture psl; diff --git a/testsuite/synth/issue662/testsuite.sh b/testsuite/synth/issue662/testsuite.sh index 5186799d1..cf8647e76 100755 --- a/testsuite/synth/issue662/testsuite.sh +++ b/testsuite/synth/issue662/testsuite.sh @@ -4,7 +4,7 @@ GHDL_STD_FLAGS=--std=08 -for test in psl_prev psl_stable psl_rose psl_fell; do +for test in psl_prev psl_stable psl_rose psl_fell psl_onehot psl_onehot0; do synth_analyze $test analyze tb_${test}.vhdl elab_simulate_failure tb_${test} --stop-time=20ns --asserts=disable-at-0 --assert-level=error |