Use AstDelay nodes for intra-assignment delays (#3672)

Also fix messy implementation of net delays.

Signed-off-by: Krzysztof Bieganski <kbieganski@antmicro.com>
This commit is contained in:
Krzysztof Bieganski 2022-10-14 09:35:26 +02:00 committed by GitHub
parent caed086516
commit 8a347248f5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 119 additions and 104 deletions

View File

@ -1,4 +1,4 @@
.. comment: generated by t_lint_stmtdly_bad
.. code-block::
%Warning-STMTDLY: example.v:1:8 Ignoring delay on this statement due to --no-timing
%Warning-STMTDLY: example.v:1:7 Ignoring delay on this statement due to --no-timing

View File

@ -525,9 +525,7 @@ private:
}
void visit(AstAssignAlias* nodep) override { moveUnderSpecial<AstSenItem::Combo>(nodep); }
void visit(AstCoverToggle* nodep) override { moveUnderSpecial<AstSenItem::Combo>(nodep); }
void visit(AstAssignW* nodep) override {
visitAlways(nodep, nullptr, VAlwaysKwd::ALWAYS_COMB);
}
void visit(AstAssignW* nodep) override { moveUnderSpecial<AstSenItem::Combo>(nodep); }
void visit(AstAlways* nodep) override {
if (!nodep->stmtsp()) { // Empty always. Remove it now.
VL_DO_DANGLING(nodep->unlinkFrBack()->deleteTree(), nodep);

View File

@ -1971,7 +1971,7 @@ class AstVar final : public AstNode {
// A variable (in/out/wire/reg/param) inside a module
//
// @astgen op1 := childDTypep : Optional[AstNodeDType]
// @astgen op2 := delayp : Optional[AstNode] // Net delay
// @astgen op2 := delayp : Optional[AstDelay] // Net delay
// Initial value that never changes (static const), or constructor argument for
// MTASKSTATE variables
// @astgen op3 := valuep : Optional[AstNode]
@ -3023,10 +3023,9 @@ class AstDelay final : public AstNodeStmt {
// @astgen op1 := lhsp : AstNode // Delay value
// @astgen op2 := stmtsp : List[AstNode] // Statements under delay
public:
AstDelay(FileLine* fl, AstNode* lhsp, AstNode* stmtsp)
AstDelay(FileLine* fl, AstNode* lhsp)
: ASTGEN_SUPER_Delay(fl) {
this->lhsp(lhsp);
this->addStmtsp(stmtsp);
}
ASTGEN_MEMBERS_AstDelay;
bool isTimingControl() const override { return true; }
@ -3827,6 +3826,12 @@ public:
AstNode* const controlp = timingControlp() ? timingControlp()->cloneTree(false) : nullptr;
return new AstAssignW{fileline(), lhsp, rhsp, controlp};
}
bool isTimingControl() const override {
return timingControlp()
|| lhsp()->exists<AstNodeVarRef>([](const AstNodeVarRef* const refp) {
return refp->access().isWriteOrRW() && refp->varp()->delayp();
});
}
bool brokeLhsMustBeLvalue() const override { return true; }
AstAlways* convertToAlways();
};

View File

@ -2243,12 +2243,13 @@ void AstCUse::dump(std::ostream& str) const {
}
AstAlways* AstAssignW::convertToAlways() {
const bool hasTimingControl = isTimingControl();
AstNode* const lhs1p = lhsp()->unlinkFrBack();
AstNode* const rhs1p = rhsp()->unlinkFrBack();
AstNode* const controlp = timingControlp() ? timingControlp()->unlinkFrBack() : nullptr;
FileLine* const flp = fileline();
AstNode* bodysp = new AstAssign{flp, lhs1p, rhs1p, controlp};
if (controlp) {
if (hasTimingControl) {
// If there's a timing control, put the assignment in a fork..join_none. This process won't
// get marked as suspendable and thus will be scheduled normally
auto* forkp = new AstFork{flp, "", bodysp};

View File

@ -135,14 +135,17 @@ private:
return nodep->user3u().to<DependencyVertex*>();
}
// Find net delay on the LHS of an assignment
AstNode* getLhsNetDelay(AstNodeAssign* nodep) const {
AstDelay* getLhsNetDelay(AstNodeAssign* nodep) const {
bool foundWrite = false;
AstNode* delayp = nullptr;
AstDelay* delayp = nullptr;
nodep->lhsp()->foreach<AstNodeVarRef>([&](const AstNodeVarRef* const refp) {
if (!refp->access().isWriteOrRW()) return;
UASSERT_OBJ(!foundWrite, nodep, "Should only be one variable written to on the LHS");
foundWrite = true;
if (refp->varp()->delayp()) delayp = refp->varp()->delayp()->cloneTree(false);
if (refp->varp()->delayp()) {
delayp = refp->varp()->delayp();
delayp->unlinkFrBack();
}
});
return delayp;
}
@ -150,20 +153,25 @@ private:
// assignment under it
AstNodeStmt* factorOutTimingControl(AstNodeAssign* nodep) const {
AstNodeStmt* stmtp = nodep;
AstNode* delayp = getLhsNetDelay(nodep);
AstDelay* delayp = getLhsNetDelay(nodep);
FileLine* const flp = nodep->fileline();
AstNode* const controlp = nodep->timingControlp();
if (controlp) {
controlp->unlinkFrBack();
if (!VN_IS(controlp, SenTree)) {
delayp = delayp ? new AstAdd{flp, delayp, controlp} : controlp;
if (auto* const assignDelayp = VN_CAST(controlp, Delay)) {
if (delayp) {
delayp->lhsp(new AstAdd{flp, delayp->lhsp()->unlinkFrBack(),
assignDelayp->lhsp()->unlinkFrBack()});
VL_DO_DANGLING(assignDelayp->deleteTree(), nodep);
} else {
delayp = assignDelayp;
}
}
}
if (delayp) {
auto* const delayStmtp = new AstDelay{flp, delayp, nullptr};
stmtp->replaceWith(delayStmtp);
delayStmtp->addStmtsp(stmtp);
stmtp = delayStmtp;
stmtp->replaceWith(delayp);
delayp->addStmtsp(stmtp);
stmtp = delayp;
}
if (auto* const sensesp = VN_CAST(controlp, SenTree)) {
auto* const eventControlp = new AstEventControl{flp, sensesp, nullptr};
@ -493,7 +501,6 @@ private:
VL_DO_DANGLING(nodep->deleteTree(), nodep);
}
void visit(AstNodeAssign* nodep) override {
iterateChildren(nodep);
// Only process once to avoid infinite loops (due to the net delay)
if (nodep->user1SetOnce()) return;
AstNode* const controlp = factorOutTimingControl(nodep);
@ -536,14 +543,14 @@ private:
replaceWithIntermediate(nodep->rhsp(), m_intraValueNames.get(nodep));
}
void visit(AstAssignW* nodep) override {
iterateChildren(nodep);
auto* const netDelayp = getLhsNetDelay(nodep);
AstDelay* const netDelayp = getLhsNetDelay(nodep);
if (!netDelayp && !nodep->timingControlp()) return;
// This assignment will be converted to an always. In some cases this may generate an
// UNOPTFLAT, e.g.: assign #1 clk = ~clk. We create a temp var for the LHS of this assign,
// to disable the UNOPTFLAT warning for it.
// TODO: Find a way to do this without introducing this var. Perhaps make V3SchedAcyclic
// recognize awaits and prevent it from treating this kind of logic as cyclic
// UNOPTFLAT, e.g.: assign #1 clk = ~clk. We create a temp var for the LHS of this
// assign, to disable the UNOPTFLAT warning for it.
// TODO: Find a way to do this without introducing this var. Perhaps make
// V3SchedAcyclic recognize awaits and prevent it from treating this kind of logic as
// cyclic
AstNode* const lhsp = nodep->lhsp()->unlinkFrBack();
std::string varname;
if (auto* const refp = VN_CAST(lhsp, VarRef)) {
@ -631,6 +638,7 @@ private:
//--------------------
void visit(AstNodeMath*) override {} // Accelerate
void visit(AstVar*) override {}
void visit(AstNode* nodep) override { iterateChildren(nodep); }
public:

View File

@ -85,7 +85,7 @@ public:
AstCase* m_caseAttrp = nullptr; // Current case statement for attribute adding
AstNodeDType* m_varDTypep = nullptr; // Pointer to data type for next signal declaration
AstNodeDType* m_memDTypep = nullptr; // Pointer to data type for next member declaration
AstNode* m_netDelayp = nullptr; // Pointer to delay for next signal declaration
AstDelay* m_netDelayp = nullptr; // Pointer to delay for next signal declaration
AstStrengthSpec* m_netStrengthp = nullptr; // Pointer to strength for next net declaration
AstNodeModule* m_modp = nullptr; // Last module for timeunits
bool m_pinAnsi = false; // In ANSI port list
@ -190,7 +190,7 @@ public:
if (m_varDTypep) VL_DO_CLEAR(m_varDTypep->deleteTree(), m_varDTypep = nullptr);
m_varDTypep = dtypep;
}
void setNetDelay(AstNode* netDelayp) { m_netDelayp = netDelayp; }
void setNetDelay(AstDelay* netDelayp) { m_netDelayp = netDelayp; }
void setNetStrength(AstStrengthSpec* netStrengthp) { m_netStrengthp = netStrengthp; }
void pinPush() {
m_pinStack.push(m_pinNum);
@ -1082,6 +1082,7 @@ BISONPRE_VERSION(3.7,%define api.header.include {"V3ParseBison.h"})
// Blank lines for type insertion
// Blank lines for type insertion
// Blank lines for type insertion
// Blank lines for type insertion
%start source_text
@ -2736,16 +2737,20 @@ delay_or_event_controlE<nodep>: // IEEE: delay_or_event_control plus empty
//UNSUP | yREPEAT '(' expr ')' event_control { }
;
delay_controlE<nodep>:
delay_controlE<delayp>:
/* empty */ { $$ = nullptr; }
| delay_control { $$ = $1; }
;
delay_control<nodep>: //== IEEE: delay_control
'#' delay_value { $$ = $2; }
| '#' '(' minTypMax ')' { $$ = $3; }
| '#' '(' minTypMax ',' minTypMax ')' { $$ = $3; RISEFALLDLYUNSUP($3); DEL($5); }
| '#' '(' minTypMax ',' minTypMax ',' minTypMax ')' { $$ = $3; RISEFALLDLYUNSUP($3); DEL($5); DEL($7); }
delay_control<delayp>: //== IEEE: delay_control
'#' delay_value
{ $$ = new AstDelay{$<fl>1, $2}; }
| '#' '(' minTypMax ')'
{ $$ = new AstDelay{$<fl>1, $3}; }
| '#' '(' minTypMax ',' minTypMax ')'
{ $$ = new AstDelay{$<fl>1, $3}; RISEFALLDLYUNSUP($3); DEL($5); }
| '#' '(' minTypMax ',' minTypMax ',' minTypMax ')'
{ $$ = new AstDelay{$<fl>1, $3}; RISEFALLDLYUNSUP($3); DEL($5); DEL($7); }
;
delay_value<nodep>: // ==IEEE:delay_value
@ -2777,7 +2782,6 @@ netSig<varp>: // IEEE: net_decl_assignment - one element from
{ $$ = VARDONEA($<fl>1, *$1, nullptr, $2);
auto* const assignp = new AstAssignW{$3, new AstVarRef{$<fl>1, *$1, VAccess::WRITE}, $4};
if (GRAMMARP->m_netStrengthp) assignp->strengthSpecp(GRAMMARP->m_netStrengthp->cloneTree(false));
if ($$->delayp()) assignp->timingControlp($$->delayp()->unlinkFrBack()); // IEEE 1800-2017 10.3.3
AstNode::addNext<AstNode, AstNode>($$, assignp); }
| netId variable_dimensionList sigAttrListE
{ $$ = VARDONEA($<fl>1,*$1, $2, $3); }
@ -3320,8 +3324,11 @@ statement_item<nodep>: // IEEE: statement_item
| par_block { $$ = $1; }
// // IEEE: procedural_timing_control_statement + procedural_timing_control
| delay_control stmtBlock { AstNode* nextp = nullptr;
if ($2 && $2->nextp()) nextp = $2->nextp()->unlinkFrBackWithNext();
$$ = new AstDelay{$1->fileline(), $1, $2};
if ($2) {
if ($2->nextp()) nextp = $2->nextp()->unlinkFrBackWithNext();
$1->addStmtsp($2);
}
$$ = $1;
addNextNull($$, nextp); }
| event_control stmtBlock { AstNode* nextp = nullptr;
if ($2 && $2->nextp()) nextp = $2->nextp()->unlinkFrBackWithNext();

View File

@ -1,25 +1,25 @@
%Warning-ASSIGNDLY: t/t_delay.v:24:13: Ignoring timing control on this assignment/primitive due to --no-timing
%Warning-ASSIGNDLY: t/t_delay.v:24:11: Ignoring timing control on this assignment/primitive due to --no-timing
: ... In instance t
24 | 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:29:19: Ignoring timing control on this assignment/primitive due to --no-timing
%Warning-ASSIGNDLY: t/t_delay.v:29:18: Ignoring timing control on this assignment/primitive due to --no-timing
: ... In instance t
29 | dly0 <= #0 32'h11;
| ^
%Warning-ASSIGNDLY: t/t_delay.v:32:19: Ignoring timing control on this assignment/primitive due to --no-timing
| ^
%Warning-ASSIGNDLY: t/t_delay.v:32:18: Ignoring timing control on this assignment/primitive due to --no-timing
: ... In instance t
32 | dly0 <= #0.12 dly0 + 32'h12;
| ^~~~
%Warning-ASSIGNDLY: t/t_delay.v:40:26: Ignoring timing control on this assignment/primitive due to --no-timing
| ^
%Warning-ASSIGNDLY: t/t_delay.v:40:18: Ignoring timing control on this assignment/primitive due to --no-timing
: ... In instance t
40 | dly0 <= #(dly_s.dly) 32'h55;
| ^~~
%Warning-STMTDLY: t/t_delay.v:45:11: Ignoring delay on this statement due to --no-timing
| ^
%Warning-STMTDLY: t/t_delay.v:45:10: Ignoring delay on this statement due to --no-timing
: ... In instance t
45 | #100 $finish;
| ^~~
| ^
%Warning-UNUSED: t/t_delay.v:22:12: Signal is not used: 'dly_s'
: ... In instance t
22 | dly_s_t dly_s;

View File

@ -1,7 +1,7 @@
%Warning-STMTDLY: t/t_lint_stmtdly_bad.v:10:8: Ignoring delay on this statement due to --no-timing
%Warning-STMTDLY: t/t_lint_stmtdly_bad.v:10:7: Ignoring delay on this statement due to --no-timing
: ... In instance t
10 | #100 $finish;
| ^~~
| ^
... For warning description see https://verilator.org/warn/STMTDLY?v=latest
... Use "/* verilator lint_off STMTDLY */" and lint_on around source to disable this message.
%Error: Exiting due to

View File

@ -1,11 +1,7 @@
%Warning-ASSIGNDLY: t/t_net_delay.v:13:15: Ignoring timing control on this assignment/primitive due to --no-timing
: ... In instance t
13 | wire[3:0] #4 val1 = cyc;
| ^
... 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_net_delay.v:17:12: Ignoring timing control on this assignment/primitive due to --no-timing
%Warning-ASSIGNDLY: t/t_net_delay.v:17:11: Ignoring timing control on this assignment/primitive due to --no-timing
: ... In instance t
17 | assign #4 val2 = cyc;
| ^
| ^
... 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.
%Error: Exiting due to

View File

@ -1,7 +1,7 @@
%Warning-STMTDLY: t/t_notiming.v:12:9: Ignoring delay on this statement due to --no-timing
%Warning-STMTDLY: t/t_notiming.v:12:8: Ignoring delay on this statement due to --no-timing
: ... In instance t
12 | #1
| ^
| ^
... For warning description see https://verilator.org/warn/STMTDLY?v=latest
... Use "/* verilator lint_off STMTDLY */" and lint_on around source to disable this message.
%Error-NOTIMING: t/t_notiming.v:13:8: Fork statements require --timing
@ -22,12 +22,12 @@
: ... With --no-timing, suggest have one event control statement per procedure, at the top of the procedure
19 | @e
| ^
%Warning-STMTDLY: t/t_notiming.v:26:13: Ignoring delay on this statement due to --no-timing
%Warning-STMTDLY: t/t_notiming.v:26:12: Ignoring delay on this statement due to --no-timing
: ... In instance t
26 | initial #1 ->e;
| ^
%Warning-STMTDLY: t/t_notiming.v:27:13: Ignoring delay on this statement due to --no-timing
| ^
%Warning-STMTDLY: t/t_notiming.v:27:12: Ignoring delay on this statement due to --no-timing
: ... In instance t
27 | initial #2 $stop;
| ^
| ^
%Error: Exiting due to

View File

@ -4,26 +4,26 @@
25 | @e1;
| ^
... For error description see https://verilator.org/warn/NOTIMING?v=latest
%Warning-STMTDLY: t/t_timing_off.v:33:13: Ignoring delay on this statement due to --no-timing
%Warning-STMTDLY: t/t_timing_off.v:33:12: Ignoring delay on this statement due to --no-timing
: ... In instance t
33 | initial #2 ->e1;
| ^
| ^
... Use "/* verilator lint_off STMTDLY */" and lint_on around source to disable this message.
%Warning-STMTDLY: t/t_timing_off.v:37:13: Ignoring delay on this statement due to --no-timing
%Warning-STMTDLY: t/t_timing_off.v:37:12: Ignoring delay on this statement due to --no-timing
: ... In instance t
37 | initial #3 $stop;
| ^
%Warning-STMTDLY: t/t_timing_off.v:38:13: Ignoring delay on this statement due to --no-timing
| ^
%Warning-STMTDLY: t/t_timing_off.v:38:12: Ignoring delay on this statement due to --no-timing
: ... In instance t
38 | initial #1 @(e1, e2) #1 $stop;
| ^
| ^
%Error-NOTIMING: t/t_timing_off.v:38:15: Event control statement in this location requires --timing
: ... In instance t
: ... With --no-timing, suggest have one event control statement per procedure, at the top of the procedure
38 | initial #1 @(e1, e2) #1 $stop;
| ^
%Warning-STMTDLY: t/t_timing_off.v:38:26: Ignoring delay on this statement due to --no-timing
%Warning-STMTDLY: t/t_timing_off.v:38:25: Ignoring delay on this statement due to --no-timing
: ... In instance t
38 | initial #1 @(e1, e2) #1 $stop;
| ^
| ^
%Error: Exiting due to

View File

@ -1,11 +1,11 @@
%Error: t/t_timing_func_bad.v:10:8: Delays are not legal in functions. Suggest use a task (IEEE 1800-2017 13.4.4)
%Error: t/t_timing_func_bad.v:10:7: Delays are not legal in functions. Suggest use a task (IEEE 1800-2017 13.4.4)
: ... In instance t
10 | #1 $stop;
| ^
%Error: t/t_timing_func_bad.v:15:13: Timing controls are not legal in functions. Suggest use a task (IEEE 1800-2017 13.4.4)
| ^
%Error: t/t_timing_func_bad.v:15:12: Timing controls are not legal in functions. Suggest use a task (IEEE 1800-2017 13.4.4)
: ... In instance t
15 | f2 = #5 0; $stop;
| ^
| ^
%Error: t/t_timing_func_bad.v:20:7: Event controls are not legal in functions. Suggest use a task (IEEE 1800-2017 13.4.4)
: ... In instance t
20 | @e $stop;
@ -18,8 +18,8 @@
: ... In instance t
31 | wait(i == 0) $stop;
| ^~~~
%Error: t/t_timing_func_bad.v:42:8: Delays are not legal in final blocks (IEEE 1800-2017 9.2.3)
%Error: t/t_timing_func_bad.v:42:7: Delays are not legal in final blocks (IEEE 1800-2017 9.2.3)
: ... In instance t
42 | #1;
| ^
| ^
%Error: Exiting due to

View File

@ -1,7 +1,7 @@
%Error-NEEDTIMINGOPT: t/t_notiming.v:12:9: Use --timing or --no-timing to specify how delays should be handled
%Error-NEEDTIMINGOPT: t/t_notiming.v:12:8: Use --timing or --no-timing to specify how delays should be handled
: ... In instance t
12 | #1
| ^
| ^
... For error description see https://verilator.org/warn/NEEDTIMINGOPT?v=latest
%Error-NEEDTIMINGOPT: t/t_notiming.v:13:8: Use --timing or --no-timing to specify how forks should be handled
: ... In instance t
@ -15,20 +15,20 @@
: ... In instance t
15 | wait(x == 4)
| ^~~~
%Error-NEEDTIMINGOPT: t/t_notiming.v:16:13: Use --timing or --no-timing to specify how timing controls should be handled
%Error-NEEDTIMINGOPT: t/t_notiming.v:16:12: Use --timing or --no-timing to specify how timing controls should be handled
: ... In instance t
16 | x = #1 8;
| ^
| ^
%Error-NEEDTIMINGOPT: t/t_notiming.v:19:8: Use --timing or --no-timing to specify how event controls should be handled
: ... In instance t
19 | @e
| ^
%Error-NEEDTIMINGOPT: t/t_notiming.v:26:13: Use --timing or --no-timing to specify how delays should be handled
%Error-NEEDTIMINGOPT: t/t_notiming.v:26:12: Use --timing or --no-timing to specify how delays should be handled
: ... In instance t
26 | initial #1 ->e;
| ^
%Error-NEEDTIMINGOPT: t/t_notiming.v:27:13: Use --timing or --no-timing to specify how delays should be handled
| ^
%Error-NEEDTIMINGOPT: t/t_notiming.v:27:12: Use --timing or --no-timing to specify how delays should be handled
: ... In instance t
27 | initial #2 $stop;
| ^
| ^
%Error: Exiting due to

View File

@ -3,24 +3,24 @@
25 | @e1;
| ^
... For error description see https://verilator.org/warn/NEEDTIMINGOPT?v=latest
%Error-NEEDTIMINGOPT: t/t_timing_off.v:33:13: Use --timing or --no-timing to specify how delays should be handled
%Error-NEEDTIMINGOPT: t/t_timing_off.v:33:12: Use --timing or --no-timing to specify how delays should be handled
: ... In instance t
33 | initial #2 ->e1;
| ^
%Error-NEEDTIMINGOPT: t/t_timing_off.v:37:13: Use --timing or --no-timing to specify how delays should be handled
| ^
%Error-NEEDTIMINGOPT: t/t_timing_off.v:37:12: Use --timing or --no-timing to specify how delays should be handled
: ... In instance t
37 | initial #3 $stop;
| ^
%Error-NEEDTIMINGOPT: t/t_timing_off.v:38:13: Use --timing or --no-timing to specify how delays should be handled
| ^
%Error-NEEDTIMINGOPT: t/t_timing_off.v:38:12: Use --timing or --no-timing to specify how delays should be handled
: ... In instance t
38 | initial #1 @(e1, e2) #1 $stop;
| ^
| ^
%Error-NEEDTIMINGOPT: t/t_timing_off.v:38:15: Use --timing or --no-timing to specify how event controls should be handled
: ... In instance t
38 | initial #1 @(e1, e2) #1 $stop;
| ^
%Error-NEEDTIMINGOPT: t/t_timing_off.v:38:26: Use --timing or --no-timing to specify how delays should be handled
%Error-NEEDTIMINGOPT: t/t_timing_off.v:38:25: Use --timing or --no-timing to specify how delays should be handled
: ... In instance t
38 | initial #1 @(e1, e2) #1 $stop;
| ^
| ^
%Error: Exiting due to

View File

@ -1,5 +1,5 @@
%Error-ZERODLY: t/t_timing_zerodly_unsup.v:12:14: Unsupported: #0 delays do not schedule process resumption in the Inactive region
%Error-ZERODLY: t/t_timing_zerodly_unsup.v:12:13: Unsupported: #0 delays do not schedule process resumption in the Inactive region
12 | #0 if (v) $finish;
| ^
| ^
... For error description see https://verilator.org/warn/ZERODLY?v=latest
%Error: Exiting due to

View File

@ -15,25 +15,25 @@
: ... In instance t
20 | wait (value == 3) if (value != 3) $stop;
| ^~~~
%Warning-STMTDLY: t/t_wait.v:25:8: Ignoring delay on this statement due to --no-timing
%Warning-STMTDLY: t/t_wait.v:25:7: Ignoring delay on this statement due to --no-timing
: ... In instance t
25 | #10;
| ^~
| ^
... Use "/* verilator lint_off STMTDLY */" and lint_on around source to disable this message.
%Warning-STMTDLY: t/t_wait.v:27:8: Ignoring delay on this statement due to --no-timing
%Warning-STMTDLY: t/t_wait.v:27:7: Ignoring delay on this statement due to --no-timing
: ... In instance t
27 | #10;
| ^~
%Warning-STMTDLY: t/t_wait.v:29:8: Ignoring delay on this statement due to --no-timing
| ^
%Warning-STMTDLY: t/t_wait.v:29:7: Ignoring delay on this statement due to --no-timing
: ... In instance t
29 | #10;
| ^~
%Warning-STMTDLY: t/t_wait.v:31:8: Ignoring delay on this statement due to --no-timing
| ^
%Warning-STMTDLY: t/t_wait.v:31:7: Ignoring delay on this statement due to --no-timing
: ... In instance t
31 | #10;
| ^~
%Warning-STMTDLY: t/t_wait.v:33:8: Ignoring delay on this statement due to --no-timing
| ^
%Warning-STMTDLY: t/t_wait.v:33:7: Ignoring delay on this statement due to --no-timing
: ... In instance t
33 | #10;
| ^~
| ^
%Error: Exiting due to