From 7f1aae640f10394916945bceb3d8b539acea7ba0 Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Sun, 10 Nov 2024 10:23:29 -0500 Subject: [PATCH] Fix dotted reference in delay value (#2410). --- Changes | 1 + src/verilog.y | 30 ++++++++++++++--- test_regress/t/t_delay.v | 2 ++ test_regress/t/t_delay_stmtdly_bad.out | 46 +++++++++++++++----------- 4 files changed, 56 insertions(+), 23 deletions(-) diff --git a/Changes b/Changes index acf36fcbd..a5effd1d4 100644 --- a/Changes +++ b/Changes @@ -21,6 +21,7 @@ Verilator 5.031 devel * Add error when improperly storing to parameter (#5147). [Gökçe Aydos] * Add coverage point hierarchy to coverage reports (#5575) (#5576). [Andrew Nolte] * Add error on `solve before` or soft constraints of `randc` variable. +* Fix dotted reference in delay value (#2410). * Fix can't locate scope error in interface task delayed assignment (#5462) (#5568). [Zhou Shen] * Fix BLKANDNBLK for for VARXREFs (#5569). [Todd Strader] * Fix VPI error instead of fatal for vpi_get_value() on large signals (#5571). [Todd Strader] diff --git a/src/verilog.y b/src/verilog.y index c91609894..17e484999 100644 --- a/src/verilog.y +++ b/src/verilog.y @@ -3075,7 +3075,7 @@ delay_control: //== IEEE: delay_control delay_value: // ==IEEE:delay_value // // IEEE: ps_identifier - packageClassScopeE varRefBase { $$ = AstDot::newIfPkg($2, $1, $2); } + idClass { $$ = $1; } | yaINTNUM { $$ = new AstConst{$1, *$1}; } | yaFLOATNUM { $$ = new AstConst{$1, AstConst::RealDouble{}, $1}; } | timeNumAdjusted { $$ = $1; } @@ -5810,7 +5810,7 @@ idSVKwd: // Warn about non-forward compatible Verilog 200 { static string s = "final"; $$ = &s; ERRSVKWD($1, *$$); $$ = $1; } ; -variable_lvalue: // IEEE: variable_lvalue or net_lvalue +variable_lvalue: // IEEE: variable_lvalue or net_lvalue // // Note many variable_lvalue's must use exprOkLvalue when arbitrary expressions may also exist idClassSel { $$ = $1; } | '{' variable_lvalueConcList '}' { $$ = $2; } @@ -5832,8 +5832,19 @@ variable_lvalueConcList: // IEEE: part of variable_lvalue: '{' variab //UNSUP | variable_lvalueList ',' variable_lvalue { $$ = addNextNull($1, $3); } //UNSUP ; -// VarRef to dotted, and/or arrayed, and/or bit-ranged variable -idClassSel: // Misc Ref to dotted, and/or arrayed, and/or bit-ranged variable +idClass: // Misc Ref to dotted, and/or arrayed, and/or bit-ranged variable + idDotted { $$ = $1; } + // // IEEE: [ implicit_class_handle . | package_scope ] hierarchical_variable_identifier select + | yTHIS '.' idDotted + { $$ = new AstDot{$2, false, new AstParseRef{$1, VParseRefExp::PX_ROOT, "this"}, $3}; } + | ySUPER '.' idDotted + { $$ = new AstDot{$2, false, new AstParseRef{$1, VParseRefExp::PX_ROOT, "super"}, $3}; } + | yTHIS '.' ySUPER '.' idDotted { $$ = $5; BBUNSUP($1, "Unsupported: this.super"); } + // // Expanded: package_scope idDottedSel + | packageClassScope idDotted { $$ = new AstDot{$2, true, $1, $2}; } + ; + +idClassSel: // Misc Ref to dotted, and/or arrayed, and/or bit-ranged variable idDottedSel { $$ = $1; } // // IEEE: [ implicit_class_handle . | package_scope ] hierarchical_variable_identifier select | yTHIS '.' idDottedSel @@ -5857,6 +5868,12 @@ idClassSelForeach: | packageClassScope idDottedForeach { $$ = new AstDot{$2, true, $1, $2}; } ; +idDotted: + yD_ROOT '.' idDottedMore + { $$ = new AstDot{$2, false, new AstParseRef{$1, VParseRefExp::PX_ROOT, "$root"}, $3}; } + | idDottedMore { $$ = $1; } + ; + idDottedSel: yD_ROOT '.' idDottedSelMore { $$ = new AstDot{$2, false, new AstParseRef{$1, VParseRefExp::PX_ROOT, "$root"}, $3}; } @@ -5869,6 +5886,11 @@ idDottedForeach: | idDottedMoreForeach { $$ = $1; } ; +idDottedMore: + varRefBase { $$ = $1; } + | idDottedMore '.' varRefBase { $$ = new AstDot{$2, false, $1, $3}; } + ; + idDottedSelMore: idArrayed { $$ = $1; } | idDottedSelMore '.' idArrayed { $$ = new AstDot{$2, false, $1, $3}; } diff --git a/test_regress/t/t_delay.v b/test_regress/t/t_delay.v index 4b01e9eb8..e541a10d0 100644 --- a/test_regress/t/t_delay.v +++ b/test_regress/t/t_delay.v @@ -18,12 +18,14 @@ module t (/*AUTOARG*/ wire [31:0] dly1; wire [31:0] dly2 = dly1 + 32'h1; wire [31:0] dly3; + wire [31:0] dly4; typedef struct packed { int dly; } dly_s_t; dly_s_t dly_s; assign #(1.2000000000000000) dly1 = dly0 + 32'h1; assign #(sub.delay) dly3 = dly1 + 1; + assign #sub.delay dly4 = dly1 + 1; sub sub(); diff --git a/test_regress/t/t_delay_stmtdly_bad.out b/test_regress/t/t_delay_stmtdly_bad.out index 40b0b31a3..441588a9c 100644 --- a/test_regress/t/t_delay_stmtdly_bad.out +++ b/test_regress/t/t_delay_stmtdly_bad.out @@ -1,39 +1,47 @@ -%Warning-ASSIGNDLY: t/t_delay.v:25:11: Ignoring timing control on this assignment/primitive due to --no-timing +%Warning-ASSIGNDLY: t/t_delay.v:26:11: Ignoring timing control on this assignment/primitive due to --no-timing : ... note: In instance 't' - 25 | assign #(1.2000000000000000) dly1 = dly0 + 32'h1; + 26 | assign #(1.2000000000000000) dly1 = dly0 + 32'h1; | ^ ... For warning description see https://verilator.org/warn/ASSIGNDLY?v=latest ... Use "/* verilator lint_off ASSIGNDLY */" and lint_on around source to disable this message. -%Warning-ASSIGNDLY: t/t_delay.v:26:11: Ignoring timing control on this assignment/primitive due to --no-timing +%Warning-ASSIGNDLY: t/t_delay.v:27:11: Ignoring timing control on this assignment/primitive due to --no-timing : ... note: In instance 't' - 26 | assign #(sub.delay) dly3 = dly1 + 1; + 27 | assign #(sub.delay) dly3 = dly1 + 1; | ^ -%Warning-ASSIGNDLY: t/t_delay.v:33:18: Ignoring timing control on this assignment/primitive due to --no-timing +%Warning-ASSIGNDLY: t/t_delay.v:28:11: Ignoring timing control on this assignment/primitive due to --no-timing : ... note: In instance 't' - 33 | dly0 <= #0 32'h11; - | ^ -%Warning-ASSIGNDLY: t/t_delay.v:36:18: Ignoring timing control on this assignment/primitive due to --no-timing + 28 | assign #sub.delay dly4 = dly1 + 1; + | ^ +%Warning-ASSIGNDLY: t/t_delay.v:35:18: Ignoring timing control on this assignment/primitive due to --no-timing : ... note: In instance 't' - 36 | dly0 <= #0.12 dly0 + 32'h12; + 35 | dly0 <= #0 32'h11; | ^ -%Warning-ASSIGNDLY: t/t_delay.v:44:18: Ignoring timing control on this assignment/primitive due to --no-timing +%Warning-ASSIGNDLY: t/t_delay.v:38:18: Ignoring timing control on this assignment/primitive due to --no-timing : ... note: In instance 't' - 44 | dly0 <= #(dly_s.dly) 32'h55; + 38 | dly0 <= #0.12 dly0 + 32'h12; | ^ -%Warning-STMTDLY: t/t_delay.v:50:10: Ignoring delay on this statement due to --no-timing +%Warning-ASSIGNDLY: t/t_delay.v:46:18: Ignoring timing control on this assignment/primitive due to --no-timing + : ... note: In instance 't' + 46 | dly0 <= #(dly_s.dly) 32'h55; + | ^ +%Warning-STMTDLY: t/t_delay.v:52:10: Ignoring delay on this statement due to --no-timing : ... note: In instance 't' - 50 | #100 $finish; + 52 | #100 $finish; | ^ -%Warning-UNUSEDSIGNAL: t/t_delay.v:23:12: Signal is not used: 'dly_s' +%Warning-UNUSEDSIGNAL: t/t_delay.v:21:16: Signal is not used: 'dly4' : ... note: In instance 't' - 23 | dly_s_t dly_s; + 21 | wire [31:0] dly4; + | ^~~~ +%Warning-UNUSEDSIGNAL: t/t_delay.v:24:12: Signal is not used: 'dly_s' + : ... note: In instance 't' + 24 | dly_s_t dly_s; | ^~~~~ -%Warning-UNUSEDSIGNAL: t/t_delay.v:57:13: Signal is not used: 'delay' +%Warning-UNUSEDSIGNAL: t/t_delay.v:59:13: Signal is not used: 'delay' : ... note: In instance 't.sub' - 57 | realtime delay = 2.3; + 59 | realtime delay = 2.3; | ^~~~~ -%Warning-BLKSEQ: t/t_delay.v:43:20: Blocking assignment '=' in sequential logic process +%Warning-BLKSEQ: t/t_delay.v:45:20: Blocking assignment '=' in sequential logic process : ... Suggest using delayed assignment '<=' - 43 | dly_s.dly = 55; + 45 | dly_s.dly = 55; | ^ %Error: Exiting due to