Internals: Add AstStmtPragma (#6280)
Trivial adaptor node to put AstPragma in AstNodeStmt position, which will be required in various places. Also fix dumping of AstPragma.
This commit is contained in:
parent
43373010dc
commit
5ac345e09c
|
|
@ -1439,7 +1439,6 @@ inline std::ostream& operator<<(std::ostream& os, const VNumRange& rhs) {
|
|||
class VPragmaType final {
|
||||
public:
|
||||
enum en : uint8_t {
|
||||
ILLEGAL,
|
||||
COVERAGE_BLOCK_OFF,
|
||||
HIER_BLOCK,
|
||||
HIER_PARAMS,
|
||||
|
|
@ -1453,11 +1452,28 @@ public:
|
|||
UNROLL_FULL,
|
||||
FULL_CASE,
|
||||
PARALLEL_CASE,
|
||||
ENUM_SIZE
|
||||
_ENUM_SIZE
|
||||
};
|
||||
enum en m_e;
|
||||
VPragmaType()
|
||||
: m_e{ILLEGAL} {}
|
||||
const char* ascii() const {
|
||||
static const char* const names[] = {
|
||||
"COVERAGE_BLOCK_OFF", //
|
||||
"HIER_BLOCK", //
|
||||
"HIER_PARAMS", //
|
||||
"INLINE_MODULE", //
|
||||
"NO_INLINE_MODULE", //
|
||||
"NO_INLINE_TASK", //
|
||||
"PUBLIC_MODULE", //
|
||||
"PUBLIC_TASK", //
|
||||
"TIMEUNIT_SET", //
|
||||
"UNROLL_DISABLE", //
|
||||
"UNROLL_FULL", //
|
||||
"FULL_CASE", //
|
||||
"PARALLEL_CASE", //
|
||||
"_ENUM_SIZE" //
|
||||
};
|
||||
return names[m_e];
|
||||
}
|
||||
// cppcheck-suppress noExplicitConstructor
|
||||
constexpr VPragmaType(en _e)
|
||||
: m_e{_e} {}
|
||||
|
|
@ -1470,6 +1486,9 @@ constexpr bool operator==(const VPragmaType& lhs, const VPragmaType& rhs) {
|
|||
}
|
||||
constexpr bool operator==(const VPragmaType& lhs, VPragmaType::en rhs) { return lhs.m_e == rhs; }
|
||||
constexpr bool operator==(VPragmaType::en lhs, const VPragmaType& rhs) { return lhs == rhs.m_e; }
|
||||
inline std::ostream& operator<<(std::ostream& os, const VPragmaType& rhs) {
|
||||
return os << rhs.ascii();
|
||||
}
|
||||
|
||||
// ######################################################################
|
||||
// Defines what kind of randomization is done on a variable
|
||||
|
|
|
|||
|
|
@ -1388,12 +1388,16 @@ public:
|
|||
// other processing in verilator.
|
||||
AstPragma(FileLine* fl, VPragmaType pragType)
|
||||
: ASTGEN_SUPER_Pragma(fl)
|
||||
, m_pragType{pragType} {}
|
||||
AstPragma(FileLine* fl, VPragmaType pragType, const VTimescale& timescale)
|
||||
, m_pragType{pragType} {
|
||||
UASSERT_OBJ(pragType != VPragmaType::TIMEUNIT_SET, fl, "Should use other constructor");
|
||||
}
|
||||
AstPragma(FileLine* fl, const VTimescale& timescale)
|
||||
: ASTGEN_SUPER_Pragma(fl)
|
||||
, m_pragType{pragType}
|
||||
, m_pragType{VPragmaType::TIMEUNIT_SET}
|
||||
, m_timescale{timescale} {}
|
||||
ASTGEN_MEMBERS_AstPragma;
|
||||
void dump(std::ostream& str) const override;
|
||||
void dumpJson(std::ostream& str) const override;
|
||||
VPragmaType pragType() const { return m_pragType; } // *=type of the pragma
|
||||
bool isPredictOptimizable() const override { return false; }
|
||||
bool sameNode(const AstNode* samep) const override {
|
||||
|
|
|
|||
|
|
@ -1097,6 +1097,16 @@ public:
|
|||
// cppcheck-suppress uselessOverride
|
||||
bool isPure() override { return exprp()->isPure(); }
|
||||
};
|
||||
class AstStmtPragma final : public AstNodeStmt {
|
||||
// Pragma in statement position
|
||||
// @astgen op1 := pragp : AstPragma
|
||||
public:
|
||||
AstStmtPragma(FileLine* fl, AstPragma* pragp)
|
||||
: ASTGEN_SUPER_StmtPragma(fl) {
|
||||
this->pragp(pragp);
|
||||
}
|
||||
ASTGEN_MEMBERS_AstStmtPragma;
|
||||
};
|
||||
class AstStop final : public AstNodeStmt {
|
||||
const bool m_isFatal; // $fatal not $stop
|
||||
public:
|
||||
|
|
|
|||
|
|
@ -2179,6 +2179,20 @@ string AstPin::prettyOperatorName() const {
|
|||
+ "port connection " + modVarp()->prettyNameQ())
|
||||
: "port connection";
|
||||
}
|
||||
void AstPragma::dump(std::ostream& str) const {
|
||||
this->AstNode::dump(str);
|
||||
str << " " << pragType();
|
||||
if (pragType() == VPragmaType::TIMEUNIT_SET) { //
|
||||
str << " timescale=" << timescale();
|
||||
}
|
||||
}
|
||||
void AstPragma::dumpJson(std::ostream& str) const {
|
||||
dumpJsonStr(str, "pragType", pragType().ascii());
|
||||
if (pragType() == VPragmaType::TIMEUNIT_SET) {
|
||||
dumpJsonStr(str, "timescale", timescale().ascii());
|
||||
}
|
||||
dumpJsonGen(str);
|
||||
}
|
||||
void AstPrintTimeScale::dump(std::ostream& str) const {
|
||||
this->AstNodeStmt::dump(str);
|
||||
str << " " << timeunit();
|
||||
|
|
|
|||
|
|
@ -272,10 +272,11 @@ public:
|
|||
|
||||
void applyBlock(AstNodeBlock* nodep) {
|
||||
const VPragmaType pragma = VPragmaType::COVERAGE_BLOCK_OFF;
|
||||
FileLine* const flp = nodep->fileline();
|
||||
if (!nodep->unnamed()) {
|
||||
for (const string& i : m_coverageOffBlocks) {
|
||||
if (VString::wildmatch(nodep->prettyDehashOrigOrName(), i)) {
|
||||
nodep->addStmtsp(new AstPragma{nodep->fileline(), pragma});
|
||||
nodep->addStmtsp(new AstStmtPragma{flp, new AstPragma{flp, pragma}});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -316,7 +317,7 @@ std::ostream& operator<<(std::ostream& os, const V3ControlIgnoresLine& rhs) {
|
|||
|
||||
// Some attributes are attached to entities of the occur on a fileline
|
||||
// and multiple attributes can be attached to a line
|
||||
using V3ControlLineAttribute = std::bitset<VPragmaType::ENUM_SIZE>;
|
||||
using V3ControlLineAttribute = std::bitset<VPragmaType::_ENUM_SIZE>;
|
||||
|
||||
class WaiverSetting final {
|
||||
public:
|
||||
|
|
@ -396,8 +397,9 @@ public:
|
|||
void applyBlock(AstNodeBlock* nodep) {
|
||||
// Apply to block at this line
|
||||
const VPragmaType pragma = VPragmaType::COVERAGE_BLOCK_OFF;
|
||||
if (lineMatch(nodep->fileline()->lineno(), pragma)) {
|
||||
nodep->addStmtsp(new AstPragma{nodep->fileline(), pragma});
|
||||
FileLine* const flp = nodep->fileline();
|
||||
if (lineMatch(flp->lineno(), pragma)) {
|
||||
nodep->addStmtsp(new AstStmtPragma{flp, new AstPragma{flp, pragma}});
|
||||
}
|
||||
}
|
||||
void applyCase(AstCase* nodep) {
|
||||
|
|
|
|||
|
|
@ -710,8 +710,8 @@ class CoverageVisitor final : public VNVisitor {
|
|||
UINFO(4, " STOP: " << nodep);
|
||||
m_state.m_on = false;
|
||||
}
|
||||
void visit(AstPragma* nodep) override {
|
||||
if (nodep->pragType() == VPragmaType::COVERAGE_BLOCK_OFF) {
|
||||
void visit(AstStmtPragma* nodep) override {
|
||||
if (nodep->pragp()->pragType() == VPragmaType::COVERAGE_BLOCK_OFF) {
|
||||
// Skip all NEXT nodes under this block, and skip this if/case branch
|
||||
UINFO(4, " OFF: h" << m_state.m_handle << " " << nodep);
|
||||
m_state.m_on = false;
|
||||
|
|
|
|||
|
|
@ -1145,6 +1145,7 @@ class EmitVBaseVisitorConst VL_NOT_FINAL : public VNVisitorConst {
|
|||
void visit(AstTraceInc*) override {}
|
||||
// NOPs
|
||||
void visit(AstPragma*) override {}
|
||||
void visit(AstStmtPragma*) override {}
|
||||
void visit(AstCell*) override {} // Handled outside the Visit class
|
||||
// Default
|
||||
void visit(AstNode* nodep) override {
|
||||
|
|
|
|||
|
|
@ -267,11 +267,11 @@ class LinkJumpVisitor final : public VNVisitor {
|
|||
}
|
||||
m_blockStack.pop_back();
|
||||
}
|
||||
void visit(AstPragma* nodep) override {
|
||||
if (nodep->pragType() == VPragmaType::UNROLL_DISABLE) {
|
||||
void visit(AstStmtPragma* nodep) override {
|
||||
if (nodep->pragp()->pragType() == VPragmaType::UNROLL_DISABLE) {
|
||||
m_unrollFull = VOptionBool::OPT_FALSE;
|
||||
VL_DO_DANGLING(pushDeletep(nodep->unlinkFrBack()), nodep);
|
||||
} else if (nodep->pragType() == VPragmaType::UNROLL_FULL) {
|
||||
} else if (nodep->pragp()->pragType() == VPragmaType::UNROLL_FULL) {
|
||||
m_unrollFull = VOptionBool::OPT_TRUE;
|
||||
VL_DO_DANGLING(pushDeletep(nodep->unlinkFrBack()), nodep);
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -269,6 +269,17 @@ class LinkResolveVisitor final : public VNVisitor {
|
|||
VL_DO_DANGLING(pushDeletep(nodep), nodep);
|
||||
}
|
||||
|
||||
void visit(AstStmtPragma* nodep) override {
|
||||
if (nodep->pragp()->pragType() == VPragmaType::COVERAGE_BLOCK_OFF) {
|
||||
// Strip pragma if not needed, may optimize better without
|
||||
if (!v3Global.opt.coverageLine()) {
|
||||
VL_DO_DANGLING(pushDeletep(nodep->unlinkFrBack()), nodep);
|
||||
return;
|
||||
}
|
||||
}
|
||||
iterateChildren(nodep);
|
||||
}
|
||||
|
||||
void visit(AstPragma* nodep) override {
|
||||
if (nodep->pragType() == VPragmaType::HIER_BLOCK) {
|
||||
UASSERT_OBJ(m_modp, nodep, "HIER_BLOCK not under a module");
|
||||
|
|
@ -291,12 +302,6 @@ class LinkResolveVisitor final : public VNVisitor {
|
|||
m_modp->modPublic(true); // Need to get to the task...
|
||||
nodep->unlinkFrBack();
|
||||
VL_DO_DANGLING(pushDeletep(nodep), nodep);
|
||||
} else if (nodep->pragType() == VPragmaType::COVERAGE_BLOCK_OFF) {
|
||||
if (!v3Global.opt.coverageLine()) { // No need for block statements; may optimize
|
||||
// better without
|
||||
nodep->unlinkFrBack();
|
||||
VL_DO_DANGLING(pushDeletep(nodep), nodep);
|
||||
}
|
||||
} else {
|
||||
iterateChildren(nodep);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -146,7 +146,7 @@ AstPragma* V3ParseImp::createTimescale(FileLine* fl, bool unitSet, double unitVa
|
|||
return nullptr;
|
||||
} else {
|
||||
unit = v3Global.opt.timeComputeUnit(unit);
|
||||
return new AstPragma{fl, VPragmaType::TIMEUNIT_SET, unit};
|
||||
return new AstPragma{fl, unit};
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -994,6 +994,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
|
||||
|
||||
|
|
@ -3553,7 +3554,7 @@ statement_item<nodep>: // IEEE: statement_item
|
|||
//
|
||||
| task_subroutine_callNoSemi ';' { $$ = $1; }
|
||||
//
|
||||
| statementVerilatorPragmas { $$ = $1; }
|
||||
| statementVerilatorPragmas { $$ = new AstStmtPragma{$<fl>1, $1}; }
|
||||
//
|
||||
// // IEEE: disable_statement
|
||||
| yDISABLE yFORK ';' { $$ = new AstDisableFork{$1}; }
|
||||
|
|
@ -3654,7 +3655,7 @@ statement_item<nodep>: // IEEE: statement_item
|
|||
{ $$ = nullptr; BBUNSUP($1, "Unsupported: expect"); DEL($3, $6); }
|
||||
;
|
||||
|
||||
statementVerilatorPragmas<nodep>:
|
||||
statementVerilatorPragmas<pragmap>:
|
||||
yVL_COVERAGE_BLOCK_OFF
|
||||
{ $$ = new AstPragma{$1, VPragmaType::COVERAGE_BLOCK_OFF}; }
|
||||
| yVL_UNROLL_DISABLE
|
||||
|
|
|
|||
Loading…
Reference in New Issue