Fix implicit dtype numbering to be per-module.

Internals: Remove use of parser in implicit dtype numbering.
This commit is contained in:
Wilson Snyder 2025-05-06 20:39:17 -04:00
parent d5f773f385
commit b099d6fe63
6 changed files with 27 additions and 22 deletions

View File

@ -666,16 +666,12 @@ class AstDefImplicitDType final : public AstNodeDType {
// After link, these become typedefs
// @astgen op1 := childDTypep : Optional[AstNodeDType]
string m_name;
void* m_containerp; // In what scope is the name unique, so we can know what are duplicate
// definitions (arbitrary value)
const int m_uniqueNum;
public:
AstDefImplicitDType(FileLine* fl, const string& name, void* containerp, VFlagChildDType,
AstNodeDType* dtp)
AstDefImplicitDType(FileLine* fl, const string& name, VFlagChildDType, AstNodeDType* dtp)
: ASTGEN_SUPER_DefImplicitDType(fl)
, m_name{name}
, m_containerp{containerp}
, m_uniqueNum{uniqueNumInc()} {
childDTypep(dtp); // Only for parser
dtypep(nullptr); // V3Width will resolve
@ -683,7 +679,6 @@ public:
AstDefImplicitDType(const AstDefImplicitDType& other)
: AstNodeDType(other)
, m_name(other.m_name)
, m_containerp(other.m_containerp)
, m_uniqueNum(uniqueNumInc()) {}
ASTGEN_MEMBERS_AstDefImplicitDType;
int uniqueNum() const { return m_uniqueNum; }
@ -696,7 +691,6 @@ public:
AstNodeDType* subDTypep() const override VL_MT_STABLE {
return dtypep() ? dtypep() : childDTypep();
}
void* containerp() const { return m_containerp; }
// METHODS
// op1 = Range of variable
AstNodeDType* dtypeSkipRefp() const { return dtypep()->skipRefp(); }

View File

@ -42,7 +42,7 @@ class LinkParseVisitor final : public VNVisitor {
const VNUser2InUse m_inuser2;
// TYPES
using ImplTypedefMap = std::map<const std::pair<void*, std::string>, AstTypedef*>;
using ImplTypedefMap = std::map<std::string, AstTypedef*>;
// STATE
AstVar* m_varp = nullptr; // Variable we're under
@ -498,14 +498,14 @@ class LinkParseVisitor final : public VNVisitor {
cleanFileline(nodep);
UINFO(8, " DEFIMPLICIT " << nodep << endl);
// Must remember what names we've already created, and combine duplicates
// so that for "var enum {...} a,b" a & b will share a common typedef
// Unique name space under each containerp() so that an addition of
// so that for "var enum {...} a,b" a & b will share a common typedef.
// Change to unique name space per module so that an addition of
// a new type won't change every verilated module.
AstTypedef* defp = nullptr;
const ImplTypedefMap::iterator it
= m_implTypedef.find(std::make_pair(nodep->containerp(), nodep->name()));
const ImplTypedefMap::iterator it = m_implTypedef.find(nodep->name());
if (it != m_implTypedef.end()) {
defp = it->second;
UINFO(9, "Reused impltypedef " << nodep << " --> " << defp << endl);
} else {
// Definition must be inserted right after the variable (etc) that needed it
// AstVar, AstTypedef, AstNodeFTask are common containers
@ -526,7 +526,11 @@ class LinkParseVisitor final : public VNVisitor {
} else {
defp = new AstTypedef{nodep->fileline(), nodep->name(), nullptr, VFlagChildDType{},
dtypep};
m_implTypedef.emplace(std::make_pair(nodep->containerp(), defp->name()), defp);
m_implTypedef.emplace(defp->name(), defp);
// Rename so that name doesn't change if a type is added/removed elsewhere
// But the m_implTypedef is stil by old name so we can find it for next new lookups
defp->name("__typeimpmod" + cvtToStr(m_implTypedef.size()));
UINFO(9, "New impltypedef " << defp << endl);
backp->addNextHere(defp);
}
}
@ -618,6 +622,7 @@ class LinkParseVisitor final : public VNVisitor {
VL_RESTORER(m_genblkAbove);
VL_RESTORER(m_genblkNum);
VL_RESTORER(m_beginDepth);
VL_RESTORER(m_implTypedef);
VL_RESTORER(m_lifetime);
VL_RESTORER(m_lifetimeAllowed);
{
@ -630,6 +635,7 @@ class LinkParseVisitor final : public VNVisitor {
m_genblkAbove = 0;
m_genblkNum = 0;
m_beginDepth = 0;
m_implTypedef.clear();
m_valueModp = nodep;
m_lifetime = nodep->lifetime();
m_lifetimeAllowed = VN_IS(nodep, Class);

View File

@ -749,7 +749,12 @@ int V3ParseImp::tokenToBison() {
// V3ParseBisonYYSType functions
std::ostream& operator<<(std::ostream& os, const V3ParseBisonYYSType& rhs) {
os << "TOKEN {" << rhs.fl->filenameLetters() << rhs.fl->asciiLineCol() << "}";
os << "TOKEN {";
if (VL_UNCOVERABLE(!rhs.fl))
os << "%E-null-fileline";
else
os << rhs.fl->filenameLetters() << rhs.fl->asciiLineCol();
os << "}";
os << "=" << rhs.token << " " << V3ParseImp::tokenName(rhs.token);
if (rhs.token == yaID__ETC //
|| rhs.token == yaID__CC //

View File

@ -108,7 +108,7 @@ public:
int m_pinNum = -1; // Pin number currently parsing
std::stack<int> m_pinStack; // Queue of pin numbers being parsed
static int s_modTypeImpNum; // Implicit type number, incremented each module
static int s_typeImpNum; // Implicit type number, incremented each module
// CONSTRUCTORS
V3ParseGrammar() {}
@ -300,7 +300,7 @@ public:
const VBasicDTypeKwd LOGIC = VBasicDTypeKwd::LOGIC; // Shorthand "LOGIC"
const VBasicDTypeKwd LOGIC_IMPLICIT = VBasicDTypeKwd::LOGIC_IMPLICIT;
int V3ParseGrammar::s_modTypeImpNum = 0;
int V3ParseGrammar::s_typeImpNum = 0;
//======================================================================
// Macro functions
@ -2233,12 +2233,12 @@ data_typeNoRef<nodeDTypep>: // ==IEEE: data_type, excluding class_ty
| struct_unionDecl packed_dimensionListE
{ $$ = GRAMMARP->createArray(
new AstDefImplicitDType{$1->fileline(),
"__typeimpsu" + cvtToStr(GRAMMARP->s_modTypeImpNum++),
SYMP, VFlagChildDType{}, $1}, $2, true); }
"__typeimpsu" + cvtToStr(GRAMMARP->s_typeImpNum++),
VFlagChildDType{}, $1}, $2, true); }
| enumDecl
{ $$ = new AstDefImplicitDType{$1->fileline(),
"__typeimpenum" + cvtToStr(GRAMMARP->s_modTypeImpNum++),
SYMP, VFlagChildDType{}, $1}; }
"__typeimpenum" + cvtToStr(GRAMMARP->s_typeImpNum++),
VFlagChildDType{}, $1}; }
| ySTRING
{ $$ = new AstBasicDType{$1, VBasicDTypeKwd::STRING}; }
| yCHANDLE

View File

@ -20,7 +20,7 @@
"int$[$:3]" ==? "int$[$:3]"
"bit$[]" ==? "bit$[]"
"enum{A=32'h0;B=32'h1;C=32'h63;}A::__typeimpenum1" ==? "enum{A=32'sd0,B=32'sd1,C=32'sd99}A::<unspecified>"
"enum{A=32'h0;B=32'h1;C=32'h63;}A::__typeimpmod1" ==? "enum{A=32'sd0,B=32'sd1,C=32'sd99}A::<unspecified>"
"struct{bit A;bit B;}t.AB_t" ==? "struct{bit A;bit B;}<some_have_typename>"
"struct{bit A;bit B;}t.AB_t$[0:9]" ==? "struct{bit A;bit B;}top.AB_t$[0:9]"
"union{bit A;bit B;}t.UAB_t" ==? "union{bit A;bit B;}"

View File

@ -9,7 +9,7 @@
import vltest_bootstrap
test.scenarios('simulator')
test.scenarios('simulator_st')
test.compile()