aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--doc/using/ImplementationOfVHDL.rst2
-rw-r--r--pyGHDL/libghdl/std_names.py62
-rw-r--r--pyGHDL/libghdl/vhdl/nodes.py236
-rw-r--r--pyGHDL/libghdl/vhdl/tokens.py2
-rw-r--r--src/ghdldrv/ghdlprint.adb4
-rw-r--r--src/std_names.adb2
-rw-r--r--src/std_names.ads16
-rw-r--r--src/synth/synth-expr.adb92
-rw-r--r--src/vhdl/vhdl-elocations.adb2
-rw-r--r--src/vhdl/vhdl-elocations.ads2
-rw-r--r--src/vhdl/vhdl-errors.adb4
-rw-r--r--src/vhdl/vhdl-nodes.adb2
-rw-r--r--src/vhdl/vhdl-nodes.ads15
-rw-r--r--src/vhdl/vhdl-nodes_meta.adb252
-rw-r--r--src/vhdl/vhdl-parse.adb6
-rw-r--r--src/vhdl/vhdl-prints.adb20
-rw-r--r--src/vhdl/vhdl-scanner.adb8
-rw-r--r--src/vhdl/vhdl-sem_expr.adb10
-rw-r--r--src/vhdl/vhdl-sem_psl.adb32
-rw-r--r--src/vhdl/vhdl-sem_psl.ads2
-rw-r--r--src/vhdl/vhdl-tokens.adb4
-rw-r--r--src/vhdl/vhdl-tokens.ads4
-rw-r--r--src/vhdl/vhdl-utils.adb2
-rw-r--r--testsuite/synth/issue662/psl_onehot.vhdl28
-rw-r--r--testsuite/synth/issue662/psl_onehot0.vhdl27
-rw-r--r--testsuite/synth/issue662/tb_psl_onehot.vhdl69
-rw-r--r--testsuite/synth/issue662/tb_psl_onehot0.vhdl69
-rwxr-xr-xtestsuite/synth/issue662/testsuite.sh2
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