Support systemc_interface and related inside class`.

This commit is contained in:
Wilson Snyder
2025-03-28 22:40:21 -04:00
parent 6edf2f80a2
commit b4ef6ce860
13 changed files with 175 additions and 52 deletions
+13 -1
View File
@@ -137,7 +137,17 @@ class CCtorsVisitor final : public VNVisitor {
AstCFunc* m_cfuncp = nullptr; // Current function
V3CCtorsBuilder* m_varResetp = nullptr; // Builder of _ctor_var_reset
// VISITs
// METHODS
static void insertSc(AstCFunc* cfuncp, const AstNodeModule* modp, VNType type) {
auto textAndFileline = EmitCBaseVisitorConst::textSection(modp, type);
if (!textAndFileline.first.empty()) {
AstTextBlock* const newp
= new AstTextBlock{textAndFileline.second, textAndFileline.first, false, false};
cfuncp->addStmtsp(newp);
}
}
// VISITORS
void visit(AstNodeModule* nodep) override {
VL_RESTORER(m_modp);
VL_RESTORER(m_varResetp);
@@ -167,6 +177,7 @@ class CCtorsVisitor final : public VNVisitor {
// If can be referred to by base pointer, need virtual delete
funcp->isVirtual(classp->isExtended());
funcp->slow(false);
insertSc(funcp, classp, VNType::atScDtor);
classp->addStmtsp(funcp);
}
}
@@ -177,6 +188,7 @@ class CCtorsVisitor final : public VNVisitor {
m_varResetp = nullptr;
m_cfuncp = nodep;
iterateChildren(nodep);
if (nodep->name() == "new") insertSc(nodep, m_modp, VNType::atScCtor);
}
void visit(AstVar* nodep) override {
if (nodep->needsCReset()) {
+36 -20
View File
@@ -285,27 +285,43 @@ void EmitCBaseVisitorConst::emitModCUse(const AstNodeModule* modp, VUseType useT
if (nl) puts("\n");
}
std::pair<string, FileLine*> EmitCBaseVisitorConst::textSection(const AstNodeModule* modp,
VNType type) {
if (!v3Global.hasSCTextSections()) return std::make_pair("", nullptr);
string text;
FileLine* fl = nullptr;
int last_line = -999;
for (AstNode* nodep = modp->stmtsp(); nodep; nodep = nodep->nextp()) {
if (nodep->type() != type) continue;
if (const AstNodeText* const textp = VN_CAST(nodep, NodeText)) {
if (text.empty()) {
fl = textp->fileline();
text += "\n";
if (v3Global.opt.decoration())
text += "\n//*** Below code from `systemc in Verilog file\n";
}
if (last_line + 1 != nodep->fileline()->lineno() && v3Global.opt.decoration())
text += "// From `systemc at " + nodep->fileline()->ascii() + "\n";
last_line = textp->fileline()->lineno();
text += textp->text();
}
}
if (!text.empty()) {
if (v3Global.opt.decoration()) text += "//*** Above code from `systemc in Verilog file\n";
text += "\n";
// Substitute `systemc_class_name
string::size_type pos;
while ((pos = text.find("`systemc_class_name")) != string::npos) {
text.replace(pos, std::strlen("`systemc_class_name"),
EmitCBase::prefixNameProtect(modp));
}
}
return std::make_pair(text, fl);
}
void EmitCBaseVisitorConst::emitTextSection(const AstNodeModule* modp, VNType type) {
// Short circuit if nothing to do. This can save a lot of time on large designs as this
// function needs to traverse the entire module linearly.
if (!v3Global.hasSCTextSections()) return;
int last_line = -999;
for (AstNode* nodep = modp->stmtsp(); nodep; nodep = nodep->nextp()) {
if (const AstNodeText* const textp = VN_CAST(nodep, NodeText)) {
if (nodep->type() == type) {
if (last_line != nodep->fileline()->lineno()) {
if (last_line < 0) {
putns(nodep, "\n//*** Below code from `systemc in Verilog file\n");
}
putsDecoration(nodep, ifNoProtect("// From `systemc at "
+ nodep->fileline()->ascii() + "\n"));
last_line = nodep->fileline()->lineno();
}
ofp()->putsNoTracking(textp->text());
last_line++;
}
}
}
if (last_line > 0) puts("//*** Above code from `systemc in Verilog file\n\n");
auto textAndFileline = textSection(modp, type);
if (!textAndFileline.first.empty()) ofp()->putsNoTracking(textAndFileline.first);
}
+1
View File
@@ -164,6 +164,7 @@ public:
}
void emitModCUse(const AstNodeModule* modp, VUseType useType);
void emitTextSection(const AstNodeModule* modp, VNType type);
static std::pair<string, FileLine*> textSection(const AstNodeModule* modp, VNType type);
// CONSTRUCTORS
EmitCBaseVisitorConst() = default;
+1 -1
View File
@@ -162,7 +162,7 @@ class LinkCellsVisitor final : public VNVisitor {
return modp;
}
// VISITs
// VISITORS
void visit(AstNetlist* nodep) override {
readModNames();
iterateChildren(nodep);
+5 -5
View File
@@ -846,7 +846,7 @@ class LinkDotFindVisitor final : public VNVisitor {
return hierBlocks.find(name) != hierBlocks.end();
}
// VISITs
// VISITORS
void visit(AstNetlist* nodep) override {
// Process $unit or other packages
// Not needed - dotted references not allowed from inside packages
@@ -1791,7 +1791,7 @@ class LinkDotParamVisitor final : public VNVisitor {
}
}
// VISITs
// VISITORS
void visit(AstTypeTable*) override {}
void visit(AstConstPool*) override {}
void visit(AstNodeModule* nodep) override {
@@ -1967,7 +1967,7 @@ class LinkDotScopeVisitor final : public VNVisitor {
const AstScope* m_scopep = nullptr; // The current scope
VSymEnt* m_modSymp = nullptr; // Symbol entry for current module
// VISITs
// VISITORS
void visit(AstNetlist* nodep) override {
// Recurse..., backward as must do packages before using packages
iterateChildrenBackwardsConst(nodep);
@@ -2131,7 +2131,7 @@ class LinkDotIfaceVisitor final : public VNVisitor {
LinkDotState* const m_statep; // State to pass between visitors, including symbol table
VSymEnt* m_curSymp; // Symbol Entry for current table, where to lookup/insert
// VISITs
// VISITORS
void visit(AstModport* nodep) override {
// Modport: Remember its name for later resolution
UINFO(5, " fiv: " << nodep << endl);
@@ -2543,7 +2543,7 @@ class LinkDotResolveVisitor final : public VNVisitor {
return result + " ";
}
// VISITs
// VISITORS
void visit(AstNetlist* nodep) override {
// Recurse..., backward as must do packages before using packages
iterateChildrenBackwardsConst(nodep);
+1 -1
View File
@@ -41,7 +41,7 @@ class LinkLValueVisitor final : public VNVisitor {
bool m_inInitialStatic = false; // Set if inside AstInitialStatic
VAccess m_setRefLvalue; // Set VarRefs to lvalues for pin assignments
// VISITs
// VISITORS
// Result handing
void visit(AstNodeVarRef* nodep) override {
// VarRef: LValue its reference
+1 -1
View File
@@ -175,7 +175,7 @@ class LinkParseVisitor final : public VNVisitor {
<< nodep->warnContextSecondary());
}
// VISITs
// VISITORS
void visit(AstNodeFTask* nodep) override {
if (!nodep->user1SetOnce()) { // Process only once.
// Mark class methods
+2 -2
View File
@@ -55,7 +55,7 @@ class LinkResolveVisitor final : public VNVisitor {
bool m_underGenFor = false; // Under GenFor
bool m_underGenerate = false; // Under GenFor/GenIf
// VISITs
// VISITORS
// TODO: Most of these visitors are here for historical reasons.
// TODO: ExpectDescriptor can move to data type resolution, and the rest
// TODO: could move to V3LinkParse to get them out of the way of elaboration
@@ -531,7 +531,7 @@ class LinkBotupVisitor final : public VNVisitorConst {
// STATE
AstNodeModule* m_modp = nullptr; // Current module
// VISITs
// VISITORS
void visit(AstNetlist* nodep) override {
// Iterate modules backwards, in bottom-up order.
iterateChildrenBackwardsConst(nodep);
+13 -6
View File
@@ -2729,18 +2729,23 @@ non_port_module_item<nodep>: // ==IEEE: non_port_module_item
{ $$ = nullptr; BBUNSUP(CRELINE(), "Unsupported: interface decls within module decls"); }
| timeunits_declaration { $$ = $1; }
// // Verilator specific
| yaSCHDR { $$ = new AstScHdr{$<fl>1, *$1}; v3Global.setHasSCTextSections(); }
| yaSCINT { $$ = new AstScInt{$<fl>1, *$1}; v3Global.setHasSCTextSections(); }
| yaSCIMP { $$ = new AstScImp{$<fl>1, *$1}; v3Global.setHasSCTextSections(); }
| yaSCIMPH { $$ = new AstScImpHdr{$<fl>1, *$1}; v3Global.setHasSCTextSections(); }
| yaSCCTOR { $$ = new AstScCtor{$<fl>1, *$1}; v3Global.setHasSCTextSections(); }
| yaSCDTOR { $$ = new AstScDtor{$<fl>1, *$1}; v3Global.setHasSCTextSections(); }
| vlScBlock { $$ = $1; }
| yVL_HIER_BLOCK { $$ = new AstPragma{$1, VPragmaType::HIER_BLOCK}; }
| yVL_INLINE_MODULE { $$ = new AstPragma{$1, VPragmaType::INLINE_MODULE}; }
| yVL_NO_INLINE_MODULE { $$ = new AstPragma{$1, VPragmaType::NO_INLINE_MODULE}; }
| yVL_PUBLIC_MODULE { $$ = new AstPragma{$1, VPragmaType::PUBLIC_MODULE}; v3Global.dpi(true); }
;
vlScBlock<nodep>: // Verilator-specific `systemc_* blocks
yaSCHDR { $$ = new AstScHdr{$<fl>1, *$1}; v3Global.setHasSCTextSections(); }
| yaSCINT { $$ = new AstScInt{$<fl>1, *$1}; v3Global.setHasSCTextSections(); }
| yaSCIMP { $$ = new AstScImp{$<fl>1, *$1}; v3Global.setHasSCTextSections(); }
| yaSCIMPH { $$ = new AstScImpHdr{$<fl>1, *$1}; v3Global.setHasSCTextSections(); }
| yaSCCTOR { $$ = new AstScCtor{$<fl>1, *$1}; v3Global.setHasSCTextSections(); }
| yaSCDTOR { $$ = new AstScDtor{$<fl>1, *$1}; v3Global.setHasSCTextSections(); }
;
module_or_generate_item<nodep>: // ==IEEE: module_or_generate_item
// // IEEE: parameter_override
yDEFPARAM list_of_defparam_assignments ';' { $$ = $2; }
@@ -7372,6 +7377,8 @@ class_item<nodep>: // ==IEEE: class_item
// // local_parameter_declaration under parameter_declaration
| parameter_declaration ';' { $$ = $1; }
| ';' { $$ = nullptr; }
// // Verilator specific
| vlScBlock { $$ = $1; }
//
| error ';' { $$ = nullptr; }
;