mirror of
https://github.com/verilator/verilator.git
synced 2025-04-29 20:16:53 +00:00
Support --bbox-unsup parsing of event control expressions
This commit is contained in:
parent
933e796cc2
commit
5cd5c05c05
@ -3116,6 +3116,7 @@ public:
|
||||
//
|
||||
virtual void dump(std::ostream& str) const;
|
||||
AstSenTree* sensesp() const { return VN_CAST(op1p(), SenTree); } // op1 = Sensitivity list
|
||||
void sensesp(AstSenTree* nodep) { setOp1p(nodep); }
|
||||
VAlwaysKwd keyword() const { return m_keyword; }
|
||||
};
|
||||
|
||||
@ -4803,6 +4804,26 @@ public:
|
||||
virtual bool same(const AstNode* samep) const { return fileline() == samep->fileline(); }
|
||||
};
|
||||
|
||||
class AstTimingControl : public AstNodeStmt {
|
||||
// Parents: stmtlist
|
||||
public:
|
||||
AstTimingControl(FileLine* fl, AstSenTree* sensesp, AstNode* stmtsp)
|
||||
: ASTGEN_SUPER(fl) {
|
||||
setNOp1p(sensesp);
|
||||
setNOp2p(stmtsp);
|
||||
}
|
||||
ASTNODE_NODE_FUNCS(TimingControl)
|
||||
virtual string verilogKwd() const { return "@(%l) %r"; }
|
||||
virtual bool isGateOptimizable() const { return false; }
|
||||
virtual bool isPredictOptimizable() const { return false; }
|
||||
virtual bool isPure() const { return false; }
|
||||
virtual bool isOutputter() const { return false; }
|
||||
virtual int instrCount() const { return 0; }
|
||||
virtual V3Hash sameHash() const { return V3Hash(); }
|
||||
AstSenTree* sensesp() const { return VN_CAST(op1p(), SenTree); }
|
||||
AstNode* stmtsp() const { return op2p(); }
|
||||
};
|
||||
|
||||
class AstTimeFormat : public AstNodeStmt {
|
||||
// Parents: stmtlist
|
||||
public:
|
||||
|
@ -498,26 +498,57 @@ private:
|
||||
}
|
||||
virtual void visit(AstPrintTimeScale* nodep) VL_OVERRIDE {
|
||||
// Inlining may change hierarchy, so just save timescale where needed
|
||||
cleanFileline(nodep);
|
||||
iterateChildren(nodep);
|
||||
nodep->name(m_modp->name());
|
||||
nodep->timeunit(m_modp->timeunit());
|
||||
}
|
||||
virtual void visit(AstSFormatF* nodep) VL_OVERRIDE {
|
||||
cleanFileline(nodep);
|
||||
iterateChildren(nodep);
|
||||
nodep->timeunit(m_modp->timeunit());
|
||||
}
|
||||
virtual void visit(AstTime* nodep) VL_OVERRIDE {
|
||||
cleanFileline(nodep);
|
||||
iterateChildren(nodep);
|
||||
nodep->timeunit(m_modp->timeunit());
|
||||
}
|
||||
virtual void visit(AstTimeD* nodep) VL_OVERRIDE {
|
||||
cleanFileline(nodep);
|
||||
iterateChildren(nodep);
|
||||
nodep->timeunit(m_modp->timeunit());
|
||||
}
|
||||
virtual void visit(AstTimeImport* nodep) VL_OVERRIDE {
|
||||
cleanFileline(nodep);
|
||||
iterateChildren(nodep);
|
||||
nodep->timeunit(m_modp->timeunit());
|
||||
}
|
||||
virtual void visit(AstTimingControl* nodep) VL_OVERRIDE {
|
||||
cleanFileline(nodep);
|
||||
iterateChildren(nodep);
|
||||
AstAlways* alwaysp = VN_CAST(nodep->backp(), Always);
|
||||
if (alwaysp && alwaysp->keyword() == VAlwaysKwd::ALWAYS_COMB) {
|
||||
alwaysp->v3error("Timing control statements not legal under always_comb\n"
|
||||
<< nodep->warnMore() << "... Suggest use a normal 'always'");
|
||||
} else if (alwaysp && !alwaysp->sensesp()) {
|
||||
// Verilator is still ony supporting SenTrees under an always,
|
||||
// so allow the parser to handle everything and shim to
|
||||
// historical AST here
|
||||
if (AstSenTree* sensesp = nodep->sensesp()) {
|
||||
sensesp->unlinkFrBackWithNext();
|
||||
alwaysp->sensesp(sensesp);
|
||||
}
|
||||
if (nodep->stmtsp()) alwaysp->addStmtp(nodep->stmtsp()->unlinkFrBackWithNext());
|
||||
} else {
|
||||
if (!v3Global.opt.bboxUnsup()) {
|
||||
nodep->v3error("Unsupported: timing control statement in this location\n"
|
||||
<< nodep->warnMore()
|
||||
<< "... Suggest have one timing control statement "
|
||||
<< "per procedure, at the top of the procedure");
|
||||
}
|
||||
}
|
||||
VL_DO_DANGLING(nodep->unlinkFrBack()->deleteTree(), nodep);
|
||||
}
|
||||
|
||||
virtual void visit(AstNode* nodep) VL_OVERRIDE {
|
||||
// Default: Just iterate
|
||||
|
@ -2201,9 +2201,9 @@ module_common_item<nodep>: // ==IEEE: module_common_item
|
||||
| final_construct { $$ = $1; }
|
||||
// // IEEE: always_construct
|
||||
// // Verilator only - event_control attached to always
|
||||
| yALWAYS event_controlE stmtBlock { $$ = new AstAlways($1,VAlwaysKwd::ALWAYS, $2,$3); }
|
||||
| yALWAYS_FF event_controlE stmtBlock { $$ = new AstAlways($1,VAlwaysKwd::ALWAYS_FF, $2,$3); }
|
||||
| yALWAYS_LATCH event_controlE stmtBlock { $$ = new AstAlways($1,VAlwaysKwd::ALWAYS_LATCH, $2,$3); }
|
||||
| yALWAYS stmtBlock { $$ = new AstAlways($1,VAlwaysKwd::ALWAYS, NULL, $2); }
|
||||
| yALWAYS_FF stmtBlock { $$ = new AstAlways($1,VAlwaysKwd::ALWAYS_FF, NULL, $2); }
|
||||
| yALWAYS_LATCH stmtBlock { $$ = new AstAlways($1,VAlwaysKwd::ALWAYS_LATCH, NULL, $2); }
|
||||
| yALWAYS_COMB stmtBlock { $$ = new AstAlways($1,VAlwaysKwd::ALWAYS_COMB, NULL, $2); }
|
||||
//
|
||||
| loop_generate_construct { $$ = $1; }
|
||||
@ -2757,11 +2757,6 @@ attr_event_control<sentreep>: // ==IEEE: event_control
|
||||
| '@' '*' { $$ = NULL; }
|
||||
;
|
||||
|
||||
event_controlE<sentreep>:
|
||||
/* empty */ { $$ = NULL; }
|
||||
| event_control { $$ = $1; }
|
||||
;
|
||||
|
||||
event_control<sentreep>: // ==IEEE: event_control
|
||||
'@' '(' event_expression ')' { $$ = new AstSenTree($1,$3); }
|
||||
| '@' '(' '*' ')' { $$ = NULL; }
|
||||
@ -2776,7 +2771,7 @@ event_control<sentreep>: // ==IEEE: event_control
|
||||
// // 1995 delay with a sequence with parameters.
|
||||
// // Alternatively split this out of event_control, and delay_or_event_controlE
|
||||
// // and anywhere delay_or_event_controlE is called allow two expressions
|
||||
//| '@' idClassSel '(' list_of_argumentsE ')' { }
|
||||
//UNSUP '@' idClassSel '(' list_of_argumentsE ')' { }
|
||||
;
|
||||
|
||||
event_expression<senitemp>: // IEEE: event_expression - split over several
|
||||
@ -3023,7 +3018,7 @@ statement_item<nodep>: // IEEE: statement_item
|
||||
| par_block { $$ = $1; }
|
||||
// // IEEE: procedural_timing_control_statement + procedural_timing_control
|
||||
| delay_control stmtBlock { $$ = new AstDelay($1->fileline(), $1); $$->addNextNull($2); }
|
||||
//UNSUP event_control stmtBlock { UNSUP }
|
||||
| event_control stmtBlock { $$ = new AstTimingControl(FILELINE_OR_CRE($1), $1, $2); }
|
||||
//UNSUP cycle_delay stmtBlock { UNSUP }
|
||||
//
|
||||
| seq_block { $$ = $1; }
|
||||
|
9
test_regress/t/t_event_control_unsup.out
Normal file
9
test_regress/t/t_event_control_unsup.out
Normal file
@ -0,0 +1,9 @@
|
||||
%Error: t/t_event_control_unsup.v:14:7: Unsupported: timing control statement in this location
|
||||
: ... Suggest have one timing control statement per procedure, at the top of the procedure
|
||||
14 | @(clk);
|
||||
| ^
|
||||
%Error: t/t_event_control_unsup.v:16:7: Unsupported: timing control statement in this location
|
||||
: ... Suggest have one timing control statement per procedure, at the top of the procedure
|
||||
16 | @(clk);
|
||||
| ^
|
||||
%Error: Exiting due to
|
23
test_regress/t/t_event_control_unsup.pl
Executable file
23
test_regress/t/t_event_control_unsup.pl
Executable file
@ -0,0 +1,23 @@
|
||||
#!/usr/bin/env perl
|
||||
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 2003 by Wilson Snyder. This program is free software; you
|
||||
# can redistribute it and/or modify it under the terms of either the GNU
|
||||
# Lesser General Public License Version 3 or the Perl Artistic License
|
||||
# Version 2.0.
|
||||
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||
|
||||
scenarios(simulator => 1);
|
||||
|
||||
compile(
|
||||
fails => $Self->{vlt_all},
|
||||
expect_filename => $Self->{golden_filename},
|
||||
);
|
||||
|
||||
#execute(
|
||||
# check_finished => 1,
|
||||
# );
|
||||
|
||||
ok(1);
|
||||
1;
|
22
test_regress/t/t_event_control_unsup.v
Normal file
22
test_regress/t/t_event_control_unsup.v
Normal file
@ -0,0 +1,22 @@
|
||||
// DESCRIPTION: Verilator: Verilog Test module
|
||||
//
|
||||
// This file ONLY is placed under the Creative Commons Public Domain, for
|
||||
// any use, without warranty, 2003 by Wilson Snyder.
|
||||
// SPDX-License-Identifier: CC0-1.0
|
||||
|
||||
module t(/*AUTOARG*/
|
||||
// Inputs
|
||||
clk
|
||||
);
|
||||
input clk;
|
||||
|
||||
initial begin;
|
||||
@(clk);
|
||||
$write("[%0t] Got\n", $time);
|
||||
@(clk);
|
||||
$write("[%0t] Got\n", $time);
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
|
||||
endmodule
|
@ -1,4 +1,5 @@
|
||||
%Error: t/t_lint_comb_bad.v:14:16: syntax error, unexpected '@'
|
||||
%Error: t/t_lint_comb_bad.v:14:4: Timing control statements not legal under always_comb
|
||||
: ... Suggest use a normal 'always'
|
||||
14 | always_comb @(*) begin
|
||||
| ^
|
||||
%Error: Cannot continue
|
||||
| ^~~~~~~~~~~
|
||||
%Error: Exiting due to
|
||||
|
Loading…
Reference in New Issue
Block a user