mirror of
https://github.com/verilator/verilator.git
synced 2025-07-31 07:56:10 +00:00
Add public enums, bug833.
This commit is contained in:
parent
e9c46afcf7
commit
3f82fd2f37
2
Changes
2
Changes
@ -9,6 +9,8 @@ indicates the contributor was also the author of the fix; Thanks!
|
|||||||
|
|
||||||
*** Add optimization of operators between concats, msg1447. [Jie Xu]
|
*** Add optimization of operators between concats, msg1447. [Jie Xu]
|
||||||
|
|
||||||
|
*** Add public enums, bug833. [Jonathon Donaldson]
|
||||||
|
|
||||||
**** Fix public parameters in unused packages, bug804. [Jonathon Donaldson]
|
**** Fix public parameters in unused packages, bug804. [Jonathon Donaldson]
|
||||||
|
|
||||||
**** Fix generate unrolling with function call, bug830. [Steven Slatter]
|
**** Fix generate unrolling with function call, bug830. [Steven Slatter]
|
||||||
|
@ -2251,6 +2251,14 @@ reduce the size of the final executable when a task is used a very large
|
|||||||
number of times. For this flag to work, the task and tasks below it must
|
number of times. For this flag to work, the task and tasks below it must
|
||||||
be pure; they cannot reference any variables outside the task itself.
|
be pure; they cannot reference any variables outside the task itself.
|
||||||
|
|
||||||
|
=item /*verilator public*/ (typedef enum)
|
||||||
|
|
||||||
|
Used after an enum typedef declaration to indicate the emitted C code
|
||||||
|
should have the enum values visible. Due to C++ language restrictions, this
|
||||||
|
may only be used on 64-bit or narrower integral enumerations.
|
||||||
|
|
||||||
|
typedef enum logic [2:0] { ZERO = 3'b0 } pub_t /*verilator public*/;
|
||||||
|
|
||||||
=item /*verilator public*/ (variable)
|
=item /*verilator public*/ (variable)
|
||||||
|
|
||||||
Used after an input, output, register, or wire declaration to indicate the
|
Used after an input, output, register, or wire declaration to indicate the
|
||||||
|
@ -236,6 +236,8 @@ public:
|
|||||||
DIM_SIZE, // V3Width processes
|
DIM_SIZE, // V3Width processes
|
||||||
DIM_UNPK_DIMENSIONS, // V3Width converts to constant
|
DIM_UNPK_DIMENSIONS, // V3Width converts to constant
|
||||||
//
|
//
|
||||||
|
DT_PUBLIC, // V3LinkParse moves to AstTypedef::attrPublic
|
||||||
|
//
|
||||||
MEMBER_BASE, // V3LinkResolve creates for AstPreSel, V3LinkParam removes
|
MEMBER_BASE, // V3LinkResolve creates for AstPreSel, V3LinkParam removes
|
||||||
//
|
//
|
||||||
VAR_BASE, // V3LinkResolve creates for AstPreSel, V3LinkParam removes
|
VAR_BASE, // V3LinkResolve creates for AstPreSel, V3LinkParam removes
|
||||||
@ -255,6 +257,7 @@ public:
|
|||||||
"%E-AT",
|
"%E-AT",
|
||||||
"DIM_BITS", "DIM_DIMENSIONS", "DIM_HIGH", "DIM_INCREMENT", "DIM_LEFT",
|
"DIM_BITS", "DIM_DIMENSIONS", "DIM_HIGH", "DIM_INCREMENT", "DIM_LEFT",
|
||||||
"DIM_LOW", "DIM_RIGHT", "DIM_SIZE", "DIM_UNPK_DIMENSIONS",
|
"DIM_LOW", "DIM_RIGHT", "DIM_SIZE", "DIM_UNPK_DIMENSIONS",
|
||||||
|
"DT_PUBLIC",
|
||||||
"MEMBER_BASE",
|
"MEMBER_BASE",
|
||||||
"VAR_BASE", "VAR_CLOCK", "VAR_CLOCK_ENABLE", "VAR_PUBLIC",
|
"VAR_BASE", "VAR_CLOCK", "VAR_CLOCK_ENABLE", "VAR_PUBLIC",
|
||||||
"VAR_PUBLIC_FLAT", "VAR_PUBLIC_FLAT_RD","VAR_PUBLIC_FLAT_RW",
|
"VAR_PUBLIC_FLAT", "VAR_PUBLIC_FLAT_RD","VAR_PUBLIC_FLAT_RW",
|
||||||
@ -1565,8 +1568,9 @@ public:
|
|||||||
virtual void dumpSmall(ostream& str);
|
virtual void dumpSmall(ostream& str);
|
||||||
virtual bool hasDType() const { return true; }
|
virtual bool hasDType() const { return true; }
|
||||||
virtual AstBasicDType* basicp() const = 0; // (Slow) recurse down to find basic data type
|
virtual AstBasicDType* basicp() const = 0; // (Slow) recurse down to find basic data type
|
||||||
virtual AstNodeDType* skipRefp() const = 0; // recurses over typedefs to next non-typeref type
|
virtual AstNodeDType* skipRefp() const = 0; // recurses over typedefs/const/enum to next non-typeref type
|
||||||
virtual AstNodeDType* skipRefToConstp() const = 0; // recurses over typedefs to next non-typeref-or-const type
|
virtual AstNodeDType* skipRefToConstp() const = 0; // recurses over typedefs to next non-typeref-or-const type
|
||||||
|
virtual AstNodeDType* skipRefToEnump() const = 0; // recurses over typedefs/const to next non-typeref-or-enum/struct type
|
||||||
virtual int widthAlignBytes() const = 0; // (Slow) recurses - Structure alignment 1,2,4 or 8 bytes (arrays affect this)
|
virtual int widthAlignBytes() const = 0; // (Slow) recurses - Structure alignment 1,2,4 or 8 bytes (arrays affect this)
|
||||||
virtual int widthTotalBytes() const = 0; // (Slow) recurses - Width in bytes rounding up 1,2,4,8,12,...
|
virtual int widthTotalBytes() const = 0; // (Slow) recurses - Width in bytes rounding up 1,2,4,8,12,...
|
||||||
virtual bool maybePointedTo() const { return true; }
|
virtual bool maybePointedTo() const { return true; }
|
||||||
@ -1617,6 +1621,7 @@ public:
|
|||||||
virtual AstBasicDType* basicp() const { return findLogicDType(width(),width(),numeric())->castBasicDType(); }
|
virtual AstBasicDType* basicp() const { return findLogicDType(width(),width(),numeric())->castBasicDType(); }
|
||||||
virtual AstNodeDType* skipRefp() const { return (AstNodeDType*)this; }
|
virtual AstNodeDType* skipRefp() const { return (AstNodeDType*)this; }
|
||||||
virtual AstNodeDType* skipRefToConstp() const { return (AstNodeDType*)this; }
|
virtual AstNodeDType* skipRefToConstp() const { return (AstNodeDType*)this; }
|
||||||
|
virtual AstNodeDType* skipRefToEnump() const { return (AstNodeDType*)this; }
|
||||||
virtual int widthAlignBytes() const; // (Slow) recurses - Structure alignment 1,2,4 or 8 bytes (arrays affect this)
|
virtual int widthAlignBytes() const; // (Slow) recurses - Structure alignment 1,2,4 or 8 bytes (arrays affect this)
|
||||||
virtual int widthTotalBytes() const; // (Slow) recurses - Width in bytes rounding up 1,2,4,8,12,...
|
virtual int widthTotalBytes() const; // (Slow) recurses - Width in bytes rounding up 1,2,4,8,12,...
|
||||||
// op1 = members
|
// op1 = members
|
||||||
@ -1673,6 +1678,7 @@ public:
|
|||||||
virtual AstBasicDType* basicp() const { return subDTypep()->basicp(); } // (Slow) recurse down to find basic data type
|
virtual AstBasicDType* basicp() const { return subDTypep()->basicp(); } // (Slow) recurse down to find basic data type
|
||||||
virtual AstNodeDType* skipRefp() const { return (AstNodeDType*)this; }
|
virtual AstNodeDType* skipRefp() const { return (AstNodeDType*)this; }
|
||||||
virtual AstNodeDType* skipRefToConstp() const { return (AstNodeDType*)this; }
|
virtual AstNodeDType* skipRefToConstp() const { return (AstNodeDType*)this; }
|
||||||
|
virtual AstNodeDType* skipRefToEnump() const { return (AstNodeDType*)this; }
|
||||||
virtual int widthAlignBytes() const { return subDTypep()->widthAlignBytes(); }
|
virtual int widthAlignBytes() const { return subDTypep()->widthAlignBytes(); }
|
||||||
virtual int widthTotalBytes() const { return elementsConst() * subDTypep()->widthTotalBytes(); }
|
virtual int widthTotalBytes() const { return elementsConst() * subDTypep()->widthTotalBytes(); }
|
||||||
int msb() const;
|
int msb() const;
|
||||||
|
@ -819,6 +819,10 @@ void AstPin::dump(ostream& str) {
|
|||||||
else { str<<" ->UNLINKED"; }
|
else { str<<" ->UNLINKED"; }
|
||||||
if (svImplicit()) str<<" [.SV]";
|
if (svImplicit()) str<<" [.SV]";
|
||||||
}
|
}
|
||||||
|
void AstTypedef::dump(ostream& str) {
|
||||||
|
this->AstNode::dump(str);
|
||||||
|
if (attrPublic()) str<<" [PUBLIC]";
|
||||||
|
}
|
||||||
void AstRange::dump(ostream& str) {
|
void AstRange::dump(ostream& str) {
|
||||||
this->AstNode::dump(str);
|
this->AstNode::dump(str);
|
||||||
if (littleEndian()) str<<" [LITTLE]";
|
if (littleEndian()) str<<" [LITTLE]";
|
||||||
|
@ -183,22 +183,30 @@ public:
|
|||||||
class AstTypedef : public AstNode {
|
class AstTypedef : public AstNode {
|
||||||
private:
|
private:
|
||||||
string m_name;
|
string m_name;
|
||||||
|
bool m_attrPublic;
|
||||||
public:
|
public:
|
||||||
AstTypedef(FileLine* fl, const string& name, VFlagChildDType, AstNodeDType* dtp)
|
AstTypedef(FileLine* fl, const string& name, AstNode* attrsp, VFlagChildDType, AstNodeDType* dtp)
|
||||||
: AstNode(fl), m_name(name) {
|
: AstNode(fl), m_name(name) {
|
||||||
childDTypep(dtp); // Only for parser
|
childDTypep(dtp); // Only for parser
|
||||||
|
addAttrsp(attrsp);
|
||||||
dtypep(NULL); // V3Width will resolve
|
dtypep(NULL); // V3Width will resolve
|
||||||
|
m_attrPublic = false;
|
||||||
}
|
}
|
||||||
ASTNODE_NODE_FUNCS(Typedef, TYPEDEF)
|
ASTNODE_NODE_FUNCS(Typedef, TYPEDEF)
|
||||||
|
virtual void dump(ostream& str);
|
||||||
AstNodeDType* getChildDTypep() const { return childDTypep(); }
|
AstNodeDType* getChildDTypep() const { return childDTypep(); }
|
||||||
AstNodeDType* childDTypep() const { return op1p()->castNodeDType(); } // op1 = Type assigning to
|
AstNodeDType* childDTypep() const { return op1p()->castNodeDType(); } // op1 = Type assigning to
|
||||||
void childDTypep(AstNodeDType* nodep) { setOp1p(nodep); }
|
void childDTypep(AstNodeDType* nodep) { setOp1p(nodep); }
|
||||||
AstNodeDType* subDTypep() const { return dtypep() ? dtypep() : childDTypep(); }
|
AstNodeDType* subDTypep() const { return dtypep() ? dtypep() : childDTypep(); }
|
||||||
|
void addAttrsp(AstNode* nodep) { addNOp4p(nodep); }
|
||||||
|
AstNode* attrsp() const { return op4p()->castNode(); } // op4 = Attributes during early parse
|
||||||
// METHODS
|
// METHODS
|
||||||
virtual string name() const { return m_name; }
|
virtual string name() const { return m_name; }
|
||||||
virtual bool maybePointedTo() const { return true; }
|
virtual bool maybePointedTo() const { return true; }
|
||||||
virtual bool hasDType() const { return true; }
|
virtual bool hasDType() const { return true; }
|
||||||
void name(const string& flag) { m_name = flag; }
|
void name(const string& flag) { m_name = flag; }
|
||||||
|
bool attrPublic() const { return m_attrPublic; }
|
||||||
|
void attrPublic(bool flag) { m_attrPublic = flag; }
|
||||||
};
|
};
|
||||||
|
|
||||||
class AstTypedefFwd : public AstNode {
|
class AstTypedefFwd : public AstNode {
|
||||||
@ -242,6 +250,7 @@ public:
|
|||||||
virtual AstBasicDType* basicp() const { return subDTypep()->basicp(); } // (Slow) recurse down to find basic data type
|
virtual AstBasicDType* basicp() const { return subDTypep()->basicp(); } // (Slow) recurse down to find basic data type
|
||||||
virtual AstNodeDType* skipRefp() const { return (AstNodeDType*)this; }
|
virtual AstNodeDType* skipRefp() const { return (AstNodeDType*)this; }
|
||||||
virtual AstNodeDType* skipRefToConstp() const { return (AstNodeDType*)this; }
|
virtual AstNodeDType* skipRefToConstp() const { return (AstNodeDType*)this; }
|
||||||
|
virtual AstNodeDType* skipRefToEnump() const { return (AstNodeDType*)this; }
|
||||||
virtual int widthAlignBytes() const { return dtypep()->widthAlignBytes(); }
|
virtual int widthAlignBytes() const { return dtypep()->widthAlignBytes(); }
|
||||||
virtual int widthTotalBytes() const { return dtypep()->widthTotalBytes(); }
|
virtual int widthTotalBytes() const { return dtypep()->widthTotalBytes(); }
|
||||||
virtual string name() const { return m_name; }
|
virtual string name() const { return m_name; }
|
||||||
@ -384,6 +393,7 @@ public:
|
|||||||
virtual AstBasicDType* basicp() const { return (AstBasicDType*)this; } // (Slow) recurse down to find basic data type
|
virtual AstBasicDType* basicp() const { return (AstBasicDType*)this; } // (Slow) recurse down to find basic data type
|
||||||
virtual AstNodeDType* skipRefp() const { return (AstNodeDType*)this; }
|
virtual AstNodeDType* skipRefp() const { return (AstNodeDType*)this; }
|
||||||
virtual AstNodeDType* skipRefToConstp() const { return (AstNodeDType*)this; }
|
virtual AstNodeDType* skipRefToConstp() const { return (AstNodeDType*)this; }
|
||||||
|
virtual AstNodeDType* skipRefToEnump() const { return (AstNodeDType*)this; }
|
||||||
virtual int widthAlignBytes() const; // (Slow) recurses - Structure alignment 1,2,4 or 8 bytes (arrays affect this)
|
virtual int widthAlignBytes() const; // (Slow) recurses - Structure alignment 1,2,4 or 8 bytes (arrays affect this)
|
||||||
virtual int widthTotalBytes() const; // (Slow) recurses - Width in bytes rounding up 1,2,4,8,12,...
|
virtual int widthTotalBytes() const; // (Slow) recurses - Width in bytes rounding up 1,2,4,8,12,...
|
||||||
AstBasicDTypeKwd keyword() const { return m.m_keyword; } // Avoid using - use isSomething accessors instead
|
AstBasicDTypeKwd keyword() const { return m.m_keyword; } // Avoid using - use isSomething accessors instead
|
||||||
@ -445,6 +455,7 @@ public:
|
|||||||
virtual AstBasicDType* basicp() const { return subDTypep()->basicp(); } // (Slow) recurse down to find basic data type
|
virtual AstBasicDType* basicp() const { return subDTypep()->basicp(); } // (Slow) recurse down to find basic data type
|
||||||
virtual AstNodeDType* skipRefp() const { return subDTypep()->skipRefp(); }
|
virtual AstNodeDType* skipRefp() const { return subDTypep()->skipRefp(); }
|
||||||
virtual AstNodeDType* skipRefToConstp() const { return (AstNodeDType*)this; }
|
virtual AstNodeDType* skipRefToConstp() const { return (AstNodeDType*)this; }
|
||||||
|
virtual AstNodeDType* skipRefToEnump() const { return (AstNodeDType*)this; }
|
||||||
virtual int widthAlignBytes() const { return subDTypep()->widthAlignBytes(); }
|
virtual int widthAlignBytes() const { return subDTypep()->widthAlignBytes(); }
|
||||||
virtual int widthTotalBytes() const { return subDTypep()->widthTotalBytes(); }
|
virtual int widthTotalBytes() const { return subDTypep()->widthTotalBytes(); }
|
||||||
};
|
};
|
||||||
@ -474,6 +485,7 @@ public:
|
|||||||
virtual AstBasicDType* basicp() const { return NULL; }
|
virtual AstBasicDType* basicp() const { return NULL; }
|
||||||
virtual AstNodeDType* skipRefp() const { return (AstNodeDType*)this; }
|
virtual AstNodeDType* skipRefp() const { return (AstNodeDType*)this; }
|
||||||
virtual AstNodeDType* skipRefToConstp() const { return (AstNodeDType*)this; }
|
virtual AstNodeDType* skipRefToConstp() const { return (AstNodeDType*)this; }
|
||||||
|
virtual AstNodeDType* skipRefToEnump() const { return (AstNodeDType*)this; }
|
||||||
virtual int widthAlignBytes() const { return 1; }
|
virtual int widthAlignBytes() const { return 1; }
|
||||||
virtual int widthTotalBytes() const { return 1; }
|
virtual int widthTotalBytes() const { return 1; }
|
||||||
string cellName() const { return m_cellName; }
|
string cellName() const { return m_cellName; }
|
||||||
@ -528,6 +540,10 @@ public:
|
|||||||
if (defp()) return defp()->skipRefToConstp();
|
if (defp()) return defp()->skipRefToConstp();
|
||||||
else { v3fatalSrc("Typedef not linked"); return NULL; }
|
else { v3fatalSrc("Typedef not linked"); return NULL; }
|
||||||
}
|
}
|
||||||
|
virtual AstNodeDType* skipRefToEnump() const {
|
||||||
|
if (defp()) return defp()->skipRefToEnump();
|
||||||
|
else { v3fatalSrc("Typedef not linked"); return NULL; }
|
||||||
|
}
|
||||||
virtual int widthAlignBytes() const { return dtypeSkipRefp()->widthAlignBytes(); }
|
virtual int widthAlignBytes() const { return dtypeSkipRefp()->widthAlignBytes(); }
|
||||||
virtual int widthTotalBytes() const { return dtypeSkipRefp()->widthTotalBytes(); }
|
virtual int widthTotalBytes() const { return dtypeSkipRefp()->widthTotalBytes(); }
|
||||||
void name(const string& flag) { m_name = flag; }
|
void name(const string& flag) { m_name = flag; }
|
||||||
@ -599,6 +615,7 @@ public:
|
|||||||
AstNodeDType* dtypeSkipRefp() const { return subDTypep()->skipRefp(); } // op1 = Range of variable (Note don't need virtual - AstVar isn't a NodeDType)
|
AstNodeDType* dtypeSkipRefp() const { return subDTypep()->skipRefp(); } // op1 = Range of variable (Note don't need virtual - AstVar isn't a NodeDType)
|
||||||
virtual AstNodeDType* skipRefp() const { return subDTypep()->skipRefp(); }
|
virtual AstNodeDType* skipRefp() const { return subDTypep()->skipRefp(); }
|
||||||
virtual AstNodeDType* skipRefToConstp() const { return subDTypep()->skipRefToConstp(); }
|
virtual AstNodeDType* skipRefToConstp() const { return subDTypep()->skipRefToConstp(); }
|
||||||
|
virtual AstNodeDType* skipRefToEnump() const { return (AstNodeDType*)this; }
|
||||||
virtual int widthAlignBytes() const { return subDTypep()->widthAlignBytes(); } // (Slow) recurses - Structure alignment 1,2,4 or 8 bytes (arrays affect this)
|
virtual int widthAlignBytes() const { return subDTypep()->widthAlignBytes(); } // (Slow) recurses - Structure alignment 1,2,4 or 8 bytes (arrays affect this)
|
||||||
virtual int widthTotalBytes() const { return subDTypep()->widthTotalBytes(); } // (Slow) recurses - Width in bytes rounding up 1,2,4,8,12,...
|
virtual int widthTotalBytes() const { return subDTypep()->widthTotalBytes(); } // (Slow) recurses - Width in bytes rounding up 1,2,4,8,12,...
|
||||||
// METHODS
|
// METHODS
|
||||||
@ -688,6 +705,7 @@ public:
|
|||||||
virtual AstBasicDType* basicp() const { return subDTypep()->basicp(); } // (Slow) recurse down to find basic data type
|
virtual AstBasicDType* basicp() const { return subDTypep()->basicp(); } // (Slow) recurse down to find basic data type
|
||||||
virtual AstNodeDType* skipRefp() const { return subDTypep()->skipRefp(); }
|
virtual AstNodeDType* skipRefp() const { return subDTypep()->skipRefp(); }
|
||||||
virtual AstNodeDType* skipRefToConstp() const { return subDTypep()->skipRefToConstp(); }
|
virtual AstNodeDType* skipRefToConstp() const { return subDTypep()->skipRefToConstp(); }
|
||||||
|
virtual AstNodeDType* skipRefToEnump() const { return (AstNodeDType*)this; }
|
||||||
virtual int widthAlignBytes() const { return subDTypep()->widthAlignBytes(); }
|
virtual int widthAlignBytes() const { return subDTypep()->widthAlignBytes(); }
|
||||||
virtual int widthTotalBytes() const { return subDTypep()->widthTotalBytes(); }
|
virtual int widthTotalBytes() const { return subDTypep()->widthTotalBytes(); }
|
||||||
};
|
};
|
||||||
|
@ -238,6 +238,10 @@ private:
|
|||||||
nodep->iterateChildren(*this);
|
nodep->iterateChildren(*this);
|
||||||
insureCleanAndNext (nodep->valuep());
|
insureCleanAndNext (nodep->valuep());
|
||||||
}
|
}
|
||||||
|
virtual void visit(AstTypedef* nodep, AstNUser*) {
|
||||||
|
// No cleaning, or would loose pointer to enum
|
||||||
|
nodep->iterateChildren(*this);
|
||||||
|
}
|
||||||
|
|
||||||
// Control flow operators
|
// Control flow operators
|
||||||
virtual void visit(AstNodeCond* nodep, AstNUser*) {
|
virtual void visit(AstNodeCond* nodep, AstNUser*) {
|
||||||
|
@ -165,6 +165,13 @@ private:
|
|||||||
nodep->packagep()->user1Inc();
|
nodep->packagep()->user1Inc();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
virtual void visit(AstTypedef* nodep, AstNUser*) {
|
||||||
|
nodep->iterateChildren(*this);
|
||||||
|
checkAll(nodep);
|
||||||
|
// Don't let packages with only public variables disappear
|
||||||
|
// Normal modules may disappear, e.g. if they are parameterized then removed
|
||||||
|
if (nodep->attrPublic() && m_modp && m_modp->castPackage()) m_modp->user1Inc();
|
||||||
|
}
|
||||||
virtual void visit(AstVarScope* nodep, AstNUser*) {
|
virtual void visit(AstVarScope* nodep, AstNUser*) {
|
||||||
nodep->iterateChildren(*this);
|
nodep->iterateChildren(*this);
|
||||||
checkAll(nodep);
|
checkAll(nodep);
|
||||||
|
@ -96,6 +96,38 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void emitTypedefs(AstNode* firstp) {
|
||||||
|
bool first = true;
|
||||||
|
for (AstNode* loopp=firstp; loopp; loopp = loopp->nextp()) {
|
||||||
|
if (AstTypedef* nodep = loopp->castTypedef()) {
|
||||||
|
if (nodep->attrPublic()) {
|
||||||
|
if (first) {
|
||||||
|
first = false;
|
||||||
|
puts("\n// TYPEDEFS\n");
|
||||||
|
puts("// That were declared public\n");
|
||||||
|
} else {
|
||||||
|
puts("\n");
|
||||||
|
}
|
||||||
|
if (AstEnumDType* adtypep = nodep->dtypep()->skipRefToEnump()->castEnumDType()) {
|
||||||
|
if (adtypep->width()>64) {
|
||||||
|
puts("// enum "+nodep->name()+" // Ignored: Too wide for C++\n");
|
||||||
|
} else {
|
||||||
|
puts("enum "+nodep->name()+" {\n");
|
||||||
|
for (AstEnumItem* itemp = adtypep->itemsp(); itemp; itemp=itemp->nextp()->castEnumItem()) {
|
||||||
|
puts(itemp->name());
|
||||||
|
puts(" = ");
|
||||||
|
itemp->valuep()->iterateAndNext(*this);
|
||||||
|
if (nodep->nextp()) puts(",");
|
||||||
|
puts("\n");
|
||||||
|
}
|
||||||
|
puts("};\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// VISITORS
|
// VISITORS
|
||||||
virtual void visit(AstNodeAssign* nodep, AstNUser*) {
|
virtual void visit(AstNodeAssign* nodep, AstNUser*) {
|
||||||
bool paren = true; bool decind = false;
|
bool paren = true; bool decind = false;
|
||||||
@ -663,6 +695,7 @@ public:
|
|||||||
nodep->iterateChildren(*this);
|
nodep->iterateChildren(*this);
|
||||||
}
|
}
|
||||||
// NOPs
|
// NOPs
|
||||||
|
virtual void visit(AstTypedef*, AstNUser*) {}
|
||||||
virtual void visit(AstPragma*, AstNUser*) {}
|
virtual void visit(AstPragma*, AstNUser*) {}
|
||||||
virtual void visit(AstCell*, AstNUser*) {} // Handled outside the Visit class
|
virtual void visit(AstCell*, AstNUser*) {} // Handled outside the Visit class
|
||||||
virtual void visit(AstVar*, AstNUser*) {} // Handled outside the Visit class
|
virtual void visit(AstVar*, AstNUser*) {} // Handled outside the Visit class
|
||||||
@ -670,7 +703,6 @@ public:
|
|||||||
virtual void visit(AstTraceDecl*, AstNUser*) {} // Handled outside the Visit class
|
virtual void visit(AstTraceDecl*, AstNUser*) {} // Handled outside the Visit class
|
||||||
virtual void visit(AstTraceInc*, AstNUser*) {} // Handled outside the Visit class
|
virtual void visit(AstTraceInc*, AstNUser*) {} // Handled outside the Visit class
|
||||||
virtual void visit(AstCFile*, AstNUser*) {} // Handled outside the Visit class
|
virtual void visit(AstCFile*, AstNUser*) {} // Handled outside the Visit class
|
||||||
virtual void visit(AstTypedef*, AstNUser*) {} // Nothing needed presently
|
|
||||||
// Default
|
// Default
|
||||||
virtual void visit(AstNode* nodep, AstNUser*) {
|
virtual void visit(AstNode* nodep, AstNUser*) {
|
||||||
puts((string)"\n???? // "+nodep->prettyTypeName()+"\n");
|
puts((string)"\n???? // "+nodep->prettyTypeName()+"\n");
|
||||||
@ -1845,6 +1877,8 @@ void EmitCImp::emitInt(AstNodeModule* modp) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
emitTypedefs(modp->stmtsp());
|
||||||
|
|
||||||
puts("\n// PORTS\n");
|
puts("\n// PORTS\n");
|
||||||
if (modp->isTop()) puts("// The application code writes and reads these signals to\n");
|
if (modp->isTop()) puts("// The application code writes and reads these signals to\n");
|
||||||
if (modp->isTop()) puts("// propagate new values into/out from the Verilated model.\n");
|
if (modp->isTop()) puts("// propagate new values into/out from the Verilated model.\n");
|
||||||
|
@ -62,6 +62,7 @@ private:
|
|||||||
AstNodeModule* m_valueModp; // If set, move AstVar->valuep() initial values to this module
|
AstNodeModule* m_valueModp; // If set, move AstVar->valuep() initial values to this module
|
||||||
AstNodeModule* m_modp; // Current module
|
AstNodeModule* m_modp; // Current module
|
||||||
AstNodeFTask* m_ftaskp; // Current task
|
AstNodeFTask* m_ftaskp; // Current task
|
||||||
|
AstNodeDType* m_dtypep; // Current data type
|
||||||
|
|
||||||
// METHODS
|
// METHODS
|
||||||
static int debug() {
|
static int debug() {
|
||||||
@ -104,6 +105,15 @@ private:
|
|||||||
m_valueModp = upperValueModp;
|
m_valueModp = upperValueModp;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
virtual void visit(AstNodeDType* nodep, AstNUser*) {
|
||||||
|
if (!nodep->user1SetOnce()) { // Process only once.
|
||||||
|
cleanFileline(nodep);
|
||||||
|
AstNodeDType* upperDtypep = m_dtypep;
|
||||||
|
m_dtypep = nodep;
|
||||||
|
nodep->iterateChildren(*this);
|
||||||
|
m_dtypep = upperDtypep;
|
||||||
|
}
|
||||||
|
}
|
||||||
virtual void visit(AstEnumItem* nodep, AstNUser*) {
|
virtual void visit(AstEnumItem* nodep, AstNUser*) {
|
||||||
// Expand ranges
|
// Expand ranges
|
||||||
cleanFileline(nodep);
|
cleanFileline(nodep);
|
||||||
@ -176,7 +186,13 @@ private:
|
|||||||
virtual void visit(AstAttrOf* nodep, AstNUser*) {
|
virtual void visit(AstAttrOf* nodep, AstNUser*) {
|
||||||
cleanFileline(nodep);
|
cleanFileline(nodep);
|
||||||
nodep->iterateChildren(*this);
|
nodep->iterateChildren(*this);
|
||||||
if (nodep->attrType() == AstAttrType::VAR_CLOCK) {
|
if (nodep->attrType() == AstAttrType::DT_PUBLIC) {
|
||||||
|
AstTypedef* typep = nodep->backp()->castTypedef();
|
||||||
|
if (!typep) nodep->v3fatalSrc("Attribute not attached to typedef");
|
||||||
|
typep->attrPublic(true);
|
||||||
|
nodep->unlinkFrBack()->deleteTree(); nodep=NULL;
|
||||||
|
}
|
||||||
|
else if (nodep->attrType() == AstAttrType::VAR_CLOCK) {
|
||||||
if (!m_varp) nodep->v3fatalSrc("Attribute not attached to variable");
|
if (!m_varp) nodep->v3fatalSrc("Attribute not attached to variable");
|
||||||
m_varp->attrScClocked(true);
|
m_varp->attrScClocked(true);
|
||||||
nodep->unlinkFrBack()->deleteTree(); nodep=NULL;
|
nodep->unlinkFrBack()->deleteTree(); nodep=NULL;
|
||||||
@ -265,7 +281,7 @@ private:
|
|||||||
nodep->deleteTree(); nodep=NULL;
|
nodep->deleteTree(); nodep=NULL;
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
defp = new AstTypedef(nodep->fileline(), nodep->name(), VFlagChildDType(), dtypep);
|
defp = new AstTypedef(nodep->fileline(), nodep->name(), NULL, VFlagChildDType(), dtypep);
|
||||||
m_implTypedef.insert(make_pair(make_pair(nodep->containerp(), defp->name()), defp));
|
m_implTypedef.insert(make_pair(make_pair(nodep->containerp(), defp->name()), defp));
|
||||||
backp->addNextHere(defp);
|
backp->addNextHere(defp);
|
||||||
}
|
}
|
||||||
@ -327,6 +343,7 @@ public:
|
|||||||
m_varp = NULL;
|
m_varp = NULL;
|
||||||
m_modp = NULL;
|
m_modp = NULL;
|
||||||
m_ftaskp = NULL;
|
m_ftaskp = NULL;
|
||||||
|
m_dtypep = NULL;
|
||||||
m_inAlways = false;
|
m_inAlways = false;
|
||||||
m_inGenerate = false;
|
m_inGenerate = false;
|
||||||
m_needStart = false;
|
m_needStart = false;
|
||||||
|
@ -1600,8 +1600,9 @@ implicit_typeE<dtypep>: // IEEE: part of *data_type_or_implicit
|
|||||||
|
|
||||||
type_declaration<nodep>: // ==IEEE: type_declaration
|
type_declaration<nodep>: // ==IEEE: type_declaration
|
||||||
// // Use idAny, as we can redeclare a typedef on an existing typedef
|
// // Use idAny, as we can redeclare a typedef on an existing typedef
|
||||||
yTYPEDEF data_type idAny variable_dimensionListE ';' { $$ = new AstTypedef($<fl>1, *$3, VFlagChildDType(), GRAMMARP->createArray($2,$4,false));
|
yTYPEDEF data_type idAny variable_dimensionListE dtypeAttrListE ';'
|
||||||
SYMP->reinsert($$); }
|
/**/ { $$ = new AstTypedef($<fl>1, *$3, $5, VFlagChildDType(), GRAMMARP->createArray($2,$4,false));
|
||||||
|
SYMP->reinsert($$); }
|
||||||
//UNSUP yTYPEDEF id/*interface*/ '.' idAny/*type*/ idAny/*type*/ ';' { $$ = NULL; $1->v3error("Unsupported: SystemVerilog 2005 typedef in this context"); } //UNSUP
|
//UNSUP yTYPEDEF id/*interface*/ '.' idAny/*type*/ idAny/*type*/ ';' { $$ = NULL; $1->v3error("Unsupported: SystemVerilog 2005 typedef in this context"); } //UNSUP
|
||||||
// // Combines into above "data_type id" rule
|
// // Combines into above "data_type id" rule
|
||||||
// // Verilator: Not important what it is in the AST, just need to make sure the yaID__aTYPE gets returned
|
// // Verilator: Not important what it is in the AST, just need to make sure the yaID__aTYPE gets returned
|
||||||
@ -1612,6 +1613,20 @@ type_declaration<nodep>: // ==IEEE: type_declaration
|
|||||||
//UNSUP yTYPEDEF yCLASS idAny ';' { $$ = NULL; $$ = new AstTypedefFwd($<fl>1, *$3); SYMP->reinsert($$); }
|
//UNSUP yTYPEDEF yCLASS idAny ';' { $$ = NULL; $$ = new AstTypedefFwd($<fl>1, *$3); SYMP->reinsert($$); }
|
||||||
;
|
;
|
||||||
|
|
||||||
|
dtypeAttrListE<nodep>:
|
||||||
|
/* empty */ { $$ = NULL; }
|
||||||
|
| dtypeAttrList { $$ = $1; }
|
||||||
|
;
|
||||||
|
|
||||||
|
dtypeAttrList<nodep>:
|
||||||
|
dtypeAttr { $$ = $1; }
|
||||||
|
| dtypeAttrList dtypeAttr { $$ = $1->addNextNull($2); }
|
||||||
|
;
|
||||||
|
|
||||||
|
dtypeAttr<nodep>:
|
||||||
|
yVL_PUBLIC { $$ = new AstAttrOf($1,AstAttrType::DT_PUBLIC); }
|
||||||
|
;
|
||||||
|
|
||||||
//************************************************
|
//************************************************
|
||||||
// Module Items
|
// Module Items
|
||||||
|
|
||||||
|
26
test_regress/t/t_enum_public.cpp
Normal file
26
test_regress/t/t_enum_public.cpp
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||||
|
//
|
||||||
|
// DESCRIPTION: Verilator: Verilog Test module
|
||||||
|
//
|
||||||
|
// This file ONLY is placed into the Public Domain, for any use,
|
||||||
|
// without warranty, 2006 by Wilson Snyder.
|
||||||
|
|
||||||
|
#include <verilated.h>
|
||||||
|
#include "Vt_enum_public.h"
|
||||||
|
|
||||||
|
#include "Vt_enum_public_p3.h"
|
||||||
|
#include "Vt_enum_public_p62.h"
|
||||||
|
|
||||||
|
int main (int argc, char *argv[]) {
|
||||||
|
Vt_enum_public *topp = new Vt_enum_public;
|
||||||
|
|
||||||
|
Verilated::debug(0);
|
||||||
|
|
||||||
|
// Make sure public tag worked
|
||||||
|
if (Vt_enum_public_p3::ZERO || Vt_enum_public_p3::ONE) {}
|
||||||
|
if (Vt_enum_public_p62::ZERO || Vt_enum_public_p62::ALLONE) {}
|
||||||
|
|
||||||
|
for (int i = 0; i < 10; i++) {
|
||||||
|
topp->eval();
|
||||||
|
}
|
||||||
|
}
|
26
test_regress/t/t_enum_public.pl
Executable file
26
test_regress/t/t_enum_public.pl
Executable file
@ -0,0 +1,26 @@
|
|||||||
|
#!/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.
|
||||||
|
|
||||||
|
if ($Self->{vlt}) {
|
||||||
|
compile (
|
||||||
|
verilator_flags2 => ["--exe $Self->{t_dir}/$Self->{name}.cpp"],
|
||||||
|
make_top_shell => 0,
|
||||||
|
make_main => 0,
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
compile (
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
execute (
|
||||||
|
check_finished=>1,
|
||||||
|
);
|
||||||
|
|
||||||
|
ok(1);
|
||||||
|
1;
|
33
test_regress/t/t_enum_public.v
Normal file
33
test_regress/t/t_enum_public.v
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
// DESCRIPTION: Verilator: Verilog Test module
|
||||||
|
//
|
||||||
|
// This file ONLY is placed into the Public Domain, for any use,
|
||||||
|
// without warranty, 2009 by Wilson Snyder.
|
||||||
|
|
||||||
|
package p3;
|
||||||
|
typedef enum logic [2:0] {
|
||||||
|
ZERO = 3'b0,
|
||||||
|
ONE = 3'b1 } e3_t /*verilator public*/;
|
||||||
|
endpackage
|
||||||
|
|
||||||
|
package p62;
|
||||||
|
typedef enum logic [62:0] {
|
||||||
|
ZERO = '0,
|
||||||
|
ALLONE = '1 } e62_t /*verilator public*/;
|
||||||
|
endpackage
|
||||||
|
|
||||||
|
module t (/*AUTOARG*/);
|
||||||
|
|
||||||
|
enum integer {
|
||||||
|
EI_A,
|
||||||
|
EI_B,
|
||||||
|
EI_C
|
||||||
|
} m_state;
|
||||||
|
|
||||||
|
initial begin
|
||||||
|
m_state = EI_A;
|
||||||
|
$write("*-* All Finished *-*\n");
|
||||||
|
$finish;
|
||||||
|
end
|
||||||
|
|
||||||
|
endmodule
|
||||||
|
|
Loading…
Reference in New Issue
Block a user