forked from github/verilator
Fix enum.next(0) and enum.prev(0).
This commit is contained in:
parent
4703fc39be
commit
c03affa544
1
Changes
1
Changes
@ -50,6 +50,7 @@ Verilator 5.007 devel
|
|||||||
* Fix build on HP PA architecture (#3954). [John David Anglin]
|
* Fix build on HP PA architecture (#3954). [John David Anglin]
|
||||||
* Fix missing error on negative replicate (#3963). [Benjamin Menküc]
|
* Fix missing error on negative replicate (#3963). [Benjamin Menküc]
|
||||||
* Fix packed array structure replication.
|
* Fix packed array structure replication.
|
||||||
|
* Fix enum.next(0) and enum.prev(0).
|
||||||
|
|
||||||
|
|
||||||
Verilator 5.006 2023-01-22
|
Verilator 5.006 2023-01-22
|
||||||
|
@ -2920,34 +2920,47 @@ private:
|
|||||||
VAttrType attrType;
|
VAttrType attrType;
|
||||||
if (nodep->name() == "name") {
|
if (nodep->name() == "name") {
|
||||||
attrType = VAttrType::ENUM_NAME;
|
attrType = VAttrType::ENUM_NAME;
|
||||||
|
methodOkArguments(nodep, 0, 0);
|
||||||
} else if (nodep->name() == "next") {
|
} else if (nodep->name() == "next") {
|
||||||
attrType = VAttrType::ENUM_NEXT;
|
attrType = VAttrType::ENUM_NEXT;
|
||||||
|
methodOkArguments(nodep, 0, 1);
|
||||||
} else if (nodep->name() == "prev") {
|
} else if (nodep->name() == "prev") {
|
||||||
attrType = VAttrType::ENUM_PREV;
|
attrType = VAttrType::ENUM_PREV;
|
||||||
|
methodOkArguments(nodep, 0, 1);
|
||||||
} else {
|
} else {
|
||||||
nodep->v3fatalSrc("Bad case");
|
nodep->v3fatalSrc("Bad case");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nodep->name() == "name") {
|
if (nodep->name() != "name" && nodep->pinsp()) {
|
||||||
methodOkArguments(nodep, 0, 0);
|
if (!VN_IS(VN_AS(nodep->pinsp(), Arg)->exprp(), Const)) {
|
||||||
} else if (nodep->pinsp() && !(VN_IS(VN_AS(nodep->pinsp(), Arg)->exprp(), Const))) {
|
nodep->pinsp()->v3fatalSrc(
|
||||||
nodep->pinsp()->v3fatalSrc("Unsupported: enum next/prev with non-const argument");
|
"Unsupported: enum next/prev with non-const argument");
|
||||||
} else if (nodep->pinsp()
|
} else {
|
||||||
&& !(VN_IS(VN_AS(nodep->pinsp(), Arg)->exprp(), Const)
|
const uint32_t stepWidth
|
||||||
&& VN_AS(VN_AS(nodep->pinsp(), Arg)->exprp(), Const)->toUInt() == 1
|
= VN_AS(VN_AS(nodep->pinsp(), Arg)->exprp(), Const)->toUInt();
|
||||||
&& !nodep->pinsp()->nextp())) {
|
if (stepWidth == 0) {
|
||||||
// Unroll of enumVar.next(k) to enumVar.next(1).next(k - 1)
|
// Step of 0 "legalizes" like $cast, use .next.prev
|
||||||
AstMethodCall* const clonep = nodep->cloneTree(false);
|
AstMethodCall* const newp = new AstMethodCall{
|
||||||
VN_AS(VN_AS(clonep->pinsp(), Arg)->exprp(), Const)->num().setLong(1);
|
nodep->fileline(),
|
||||||
const uint32_t stepWidth
|
new AstMethodCall{nodep->fileline(), nodep->fromp()->unlinkFrBack(),
|
||||||
= VN_AS(VN_AS(nodep->pinsp(), Arg)->exprp(), Const)->toUInt();
|
"next", nullptr},
|
||||||
AstConst* const constp = new AstConst(nodep->fileline(), stepWidth - 1);
|
"prev", nullptr};
|
||||||
AstArg* const argp = new AstArg{nodep->fileline(), "", constp};
|
nodep->replaceWith(newp);
|
||||||
AstMethodCall* const newp
|
VL_DO_DANGLING(nodep->deleteTree(), nodep);
|
||||||
= new AstMethodCall{nodep->fileline(), clonep, nodep->name(), argp};
|
return;
|
||||||
nodep->replaceWith(newp);
|
} else if (stepWidth != 1) {
|
||||||
VL_DO_DANGLING(nodep->deleteTree(), nodep);
|
// Unroll of enumVar.next(k) to enumVar.next(1).next(k - 1)
|
||||||
return;
|
AstMethodCall* const clonep = nodep->cloneTree(false);
|
||||||
|
VN_AS(VN_AS(clonep->pinsp(), Arg)->exprp(), Const)->num().setLong(1);
|
||||||
|
AstConst* const constp = new AstConst(nodep->fileline(), stepWidth - 1);
|
||||||
|
AstArg* const argp = new AstArg{nodep->fileline(), "", constp};
|
||||||
|
AstMethodCall* const newp
|
||||||
|
= new AstMethodCall{nodep->fileline(), clonep, nodep->name(), argp};
|
||||||
|
nodep->replaceWith(newp);
|
||||||
|
VL_DO_DANGLING(nodep->deleteTree(), nodep);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// Need a runtime lookup table. Yuk.
|
// Need a runtime lookup table. Yuk.
|
||||||
const uint64_t msbdim = enumMaxValue(nodep, adtypep);
|
const uint64_t msbdim = enumMaxValue(nodep, adtypep);
|
||||||
|
@ -34,12 +34,16 @@ module t (/*AUTOARG*/
|
|||||||
else if (cyc == 1) begin
|
else if (cyc == 1) begin
|
||||||
`checks(e.name, "E01");
|
`checks(e.name, "E01");
|
||||||
`checkh(e.next, ELARGE);
|
`checkh(e.next, ELARGE);
|
||||||
|
`checkh(e.next(0), E01);
|
||||||
|
`checkh(e.prev(0), E01);
|
||||||
e <= ELARGE;
|
e <= ELARGE;
|
||||||
end
|
end
|
||||||
else if (cyc == 3) begin
|
else if (cyc == 3) begin
|
||||||
`checks(e.name, "ELARGE");
|
`checks(e.name, "ELARGE");
|
||||||
`checkh(e.next, E01);
|
`checkh(e.next, E01);
|
||||||
`checkh(e.prev, E01);
|
`checkh(e.prev, E01);
|
||||||
|
`checkh(e.next(0), ELARGE);
|
||||||
|
`checkh(e.prev(0), ELARGE);
|
||||||
e <= E01;
|
e <= E01;
|
||||||
end
|
end
|
||||||
//
|
//
|
||||||
|
Loading…
Reference in New Issue
Block a user