forked from github/verilator
Add BOUNDED warning and promote bounded queues to unbounded.
This commit is contained in:
parent
3be0eea995
commit
cda5c53cf9
2
Changes
2
Changes
@ -4,6 +4,8 @@ The contributors that suggested a given feature are shown in []. Thanks!
|
||||
|
||||
* Verilator 4.025 devel
|
||||
|
||||
*** Add BOUNDED warning and promote bounded queues to unbounded.
|
||||
|
||||
|
||||
* Verilator 4.024 2019-12-08
|
||||
|
||||
|
@ -3743,6 +3743,14 @@ generally unrolls small loops. You may want to try increasing
|
||||
--unroll-count (and occasionally --unroll-stmts) which will raise the small
|
||||
loop bar to avoid this error.
|
||||
|
||||
=item BOUNDED
|
||||
|
||||
This indicates that bounded queues (e.g. "var name[$ : 3]") are
|
||||
unsupported.
|
||||
|
||||
Ignoring this warning may make Verilator simulations differ from other
|
||||
simulators.
|
||||
|
||||
=item BSSPACE
|
||||
|
||||
Warns that a backslash is followed by a space then a newline. Likely the
|
||||
|
@ -105,6 +105,7 @@ public:
|
||||
SYMRSVDWORD, // Symbol is Reserved Word
|
||||
SYNCASYNCNET, // Mixed sync + async reset
|
||||
TICKCOUNT, // Too large tick count
|
||||
UNBOUNDED, // Unbounded queue
|
||||
UNDRIVEN, // No drivers
|
||||
UNOPT, // Unoptimizable block
|
||||
UNOPTFLAT, // Unoptimizable block after flattening
|
||||
@ -154,7 +155,7 @@ public:
|
||||
"REALCVT", "REDEFMACRO",
|
||||
"SELRANGE", "SHORTREAL", "STMTDLY", "SYMRSVDWORD", "SYNCASYNCNET",
|
||||
"TICKCOUNT",
|
||||
"UNDRIVEN", "UNOPT", "UNOPTFLAT", "UNOPTTHREADS",
|
||||
"UNBOUNDED", "UNDRIVEN", "UNOPT", "UNOPTFLAT", "UNOPTTHREADS",
|
||||
"UNPACKED", "UNSIGNED", "UNUSED",
|
||||
"USERERROR", "USERFATAL", "USERINFO", "USERWARN",
|
||||
"VARHIDDEN", "WIDTH", "WIDTHCONCAT",
|
||||
|
@ -116,11 +116,17 @@ AstNodeDType* V3ParseGrammar::createArray(AstNodeDType* basep,
|
||||
if (rangep && isPacked) {
|
||||
arrayp = new AstPackArrayDType
|
||||
(rangep->fileline(), VFlagChildDType(), arrayp, rangep);
|
||||
} else if (rangep) {
|
||||
if (VN_IS(rangep->leftp(), Unbounded)
|
||||
|| VN_IS(rangep->rightp(), Unbounded)) {
|
||||
rangep->v3error("Unsupported: Bounded queues. Suggest use unbounded.");
|
||||
} else if (VN_IS(nrangep, QueueRange)) {
|
||||
arrayp = new AstQueueDType
|
||||
(nrangep->fileline(), VFlagChildDType(), arrayp);
|
||||
} else if (rangep && (VN_IS(rangep->leftp(), Unbounded)
|
||||
|| VN_IS(rangep->rightp(), Unbounded))) {
|
||||
if (!VN_IS(rangep->rightp(), Unbounded)) {
|
||||
rangep->v3warn(UNBOUNDED,
|
||||
"Unsupported: Bounded queues. Converting to unbounded.");
|
||||
}
|
||||
arrayp = new AstQueueDType(nrangep->fileline(), VFlagChildDType(), arrayp);
|
||||
} else if (rangep) {
|
||||
arrayp = new AstUnpackArrayDType
|
||||
(rangep->fileline(), VFlagChildDType(), arrayp, rangep);
|
||||
} else if (VN_IS(nrangep, UnsizedRange)) {
|
||||
@ -131,9 +137,6 @@ AstNodeDType* V3ParseGrammar::createArray(AstNodeDType* basep,
|
||||
AstNodeDType* keyp = arangep->keyDTypep(); keyp->unlinkFrBack();
|
||||
arrayp = new AstAssocArrayDType
|
||||
(nrangep->fileline(), VFlagChildDType(), arrayp, keyp);
|
||||
} else if (VN_IS(nrangep, QueueRange)) {
|
||||
arrayp = new AstQueueDType
|
||||
(nrangep->fileline(), VFlagChildDType(), arrayp);
|
||||
} else {
|
||||
UASSERT_OBJ(0, nrangep, "Expected range or unsized range");
|
||||
}
|
||||
|
@ -1935,28 +1935,46 @@ private:
|
||||
newp->protect(false);
|
||||
newp->makeStatement();
|
||||
} else {
|
||||
nodep->v3error("Unsupported: Queue .delete(index) method, as is O(n) complexity and slow.");
|
||||
AstNode* index_exprp = methodCallQueueIndexExpr(nodep);
|
||||
newp = new AstCMethodCall(nodep->fileline(),
|
||||
nodep->fromp()->unlinkFrBack(),
|
||||
"erase", index_exprp->unlinkFrBack());
|
||||
newp->protect(false);
|
||||
newp->makeStatement();
|
||||
if (index_exprp->isZero()) { // delete(0) is a pop_front
|
||||
newp = new AstCMethodCall(nodep->fileline(),
|
||||
nodep->fromp()->unlinkFrBack(),
|
||||
"pop_front", NULL);
|
||||
newp->dtypeFrom(adtypep->subDTypep());
|
||||
newp->protect(false);
|
||||
newp->didWidth(true);
|
||||
newp->makeStatement();
|
||||
} else {
|
||||
nodep->v3error("Unsupported: Queue .delete(index) method, as is O(n) complexity and slow.");
|
||||
newp = new AstCMethodCall(nodep->fileline(),
|
||||
nodep->fromp()->unlinkFrBack(),
|
||||
"erase", index_exprp->unlinkFrBack());
|
||||
newp->protect(false);
|
||||
newp->makeStatement();
|
||||
}
|
||||
}
|
||||
} else if (nodep->name() == "insert") {
|
||||
nodep->v3error("Unsupported: Queue .insert method, as is O(n) complexity and slow.");
|
||||
methodOkArguments(nodep, 2, 2);
|
||||
methodCallLValue(nodep, nodep->fromp(), true);
|
||||
AstNode* index_exprp = methodCallQueueIndexExpr(nodep);
|
||||
AstArg* argp = VN_CAST(nodep->pinsp()->nextp(), Arg);
|
||||
iterateCheckTyped(nodep, "insert value", argp->exprp(), adtypep->subDTypep(), BOTH);
|
||||
newp = new AstCMethodCall(nodep->fileline(),
|
||||
nodep->fromp()->unlinkFrBack(),
|
||||
nodep->name(),
|
||||
index_exprp->unlinkFrBack());
|
||||
newp->addPinsp(argp->exprp()->unlinkFrBack());
|
||||
newp->protect(false);
|
||||
newp->makeStatement();
|
||||
if (index_exprp->isZero()) { // insert(0, ...) is a push_front
|
||||
newp = new AstCMethodCall(nodep->fileline(),
|
||||
nodep->fromp()->unlinkFrBack(),
|
||||
"push_front", argp->exprp()->unlinkFrBack());
|
||||
newp->protect(false);
|
||||
newp->makeStatement();
|
||||
} else {
|
||||
nodep->v3error("Unsupported: Queue .insert method, as is O(n) complexity and slow.");
|
||||
newp = new AstCMethodCall(nodep->fileline(),
|
||||
nodep->fromp()->unlinkFrBack(),
|
||||
nodep->name(),
|
||||
index_exprp->unlinkFrBack());
|
||||
newp->addPinsp(argp->exprp()->unlinkFrBack());
|
||||
newp->protect(false);
|
||||
newp->makeStatement();
|
||||
}
|
||||
} else if (nodep->name() == "pop_front"
|
||||
|| nodep->name() == "pop_back") {
|
||||
methodOkArguments(nodep, 0, 0);
|
||||
|
@ -72,6 +72,15 @@ module t (/*AUTOARG*/
|
||||
i = q.size(); `checkh(i, 0);
|
||||
v = q.pop_front(); `checks(v, ""); // Was empty, optional warning
|
||||
v = q.pop_back(); `checks(v, ""); // Was empty, optional warning
|
||||
|
||||
// COnversion of insert/delete with zero to operator
|
||||
q.push_front("front");
|
||||
q.insert(0, "newfront");
|
||||
i = q.size(); `checkh(i, 2);
|
||||
q.delete(0);
|
||||
i = q.size(); `checkh(i, 1);
|
||||
`checks(q[0], "front");
|
||||
|
||||
end
|
||||
|
||||
// See t_queue_unsup_bad for more unsupported stuff
|
||||
|
20
test_regress/t/t_queue_bounded.pl
Executable file
20
test_regress/t/t_queue_bounded.pl
Executable file
@ -0,0 +1,20 @@
|
||||
#!/usr/bin/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.
|
||||
|
||||
scenarios(simulator => 1);
|
||||
|
||||
compile(
|
||||
);
|
||||
|
||||
execute(
|
||||
check_finished => 1,
|
||||
);
|
||||
|
||||
ok(1);
|
||||
1;
|
23
test_regress/t/t_queue_bounded.v
Normal file
23
test_regress/t/t_queue_bounded.v
Normal file
@ -0,0 +1,23 @@
|
||||
// DESCRIPTION: Verilator: Verilog Test module
|
||||
//
|
||||
// This file ONLY is placed into the Public Domain, for any use,
|
||||
// without warranty, 2019 by Wilson Snyder.
|
||||
|
||||
module t (/*AUTOARG*/);
|
||||
|
||||
// verilator lint_off UNBOUNDED
|
||||
int q[$ : 3];
|
||||
|
||||
initial begin
|
||||
q.push_front(1);
|
||||
q.push_front(1);
|
||||
q.push_front(1);
|
||||
if (q.size() != 3) $stop;
|
||||
q.push_front(1);
|
||||
// TODO correct answer when supported:
|
||||
//if (q.size() != 3) $stop;
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
|
||||
endmodule
|
@ -1,4 +1,5 @@
|
||||
%Error: t/t_queue_bounded_unsup_bad.v:7: Unsupported: Bounded queues. Suggest use unbounded.
|
||||
%Warning-UNBOUNDED: t/t_queue_bounded_unsup_bad.v:7: Unsupported: Bounded queues. Converting to unbounded.
|
||||
int q[$ : 3];
|
||||
^
|
||||
... Use "/* verilator lint_off UNBOUNDED */" and lint_on around source to disable this message.
|
||||
%Error: Exiting due to
|
||||
|
@ -6,10 +6,6 @@
|
||||
: ... In instance t
|
||||
q.delete(1);
|
||||
^~~~~~
|
||||
%Error: t/t_queue_unsup_bad.v:26: Unsupported: Queue .insert method, as is O(n) complexity and slow.
|
||||
: ... In instance t
|
||||
q.insert(0, "ins0");
|
||||
^~~~~~
|
||||
%Error: t/t_queue_unsup_bad.v:27: Unsupported: Queue .insert method, as is O(n) complexity and slow.
|
||||
: ... In instance t
|
||||
q.insert(2, "ins2");
|
||||
|
Loading…
Reference in New Issue
Block a user