Internals: Refactor file handling in EmitC* (#6667)

Combined the 3 various APIs used in EmitC* passes to handle file
opening/splitting into a single one. This removes a lot of copy paste
and makes everything consistent.

All C++ file handling goes through `EmitCBaseVisitor` using the
`openNewOutputHeaderFile`, `openNewOutputSourceFile` and
`closOutputFile` methods.

To emit a new kind of file, always derive a new class from
`EmitCBaseVisitor`, and use the above APIs, they will take care of
everything else in a consistent matter.

Subsequently also removed V3OutSCFile, and instead included
verilated_sc.h (which included the systemc header itself) in the two
files that need it (the primary model header, and the root module
header).

Functional changes:
- The PCH header did not use to have a corresponding AstCFile. Now it
  does, though this makes no difference in the output
- All 'slow' sources now have '__Slow' in the name automatically (the
  only one missing was for the ConstPool files)

Rest of the output is identical except for the header line now being
present in all generated C++ files.
This commit is contained in:
Geza Lore
2025-11-09 17:41:13 +00:00
committed by GitHub
parent aaafa6e8df
commit f4086496cb
14 changed files with 414 additions and 511 deletions
+13 -33
View File
@@ -53,15 +53,7 @@ class EmitCModel final : public EmitCFunc {
}
void emitHeader(AstNodeModule* modp) {
UASSERT(!ofp(), "Output file should not be open");
const string filename = v3Global.opt.makeDir() + "/" + EmitCUtil::topClassName() + ".h";
setOutputFile(v3Global.opt.systemC() ? new V3OutScFile{filename}
: new V3OutCFile{filename},
newCFile(filename, /* slow: */ false, /* source: */ false));
ofp()->putsHeader();
puts("// DESCRIPTION: Verilator output: Primary model header\n");
openNewOutputHeaderFile(EmitCUtil::topClassName(), "Primary model header");
puts("//\n");
puts("// This header should be included by all source files instantiating the design.\n");
puts("// The class here is then constructed to instantiate the design.\n");
@@ -72,7 +64,9 @@ class EmitCModel final : public EmitCFunc {
// Include files
puts("\n");
ofp()->putsIntTopInclude();
puts("#include \"verilated.h\"\n");
if (v3Global.opt.systemC()) puts("#include \"verilated_sc.h\"\n");
if (v3Global.opt.mtasks()) puts("#include \"verilated_threads.h\"\n");
if (v3Global.opt.savable()) puts("#include \"verilated_save.h\"\n");
if (v3Global.opt.coverage()) puts("#include \"verilated_cov.h\"\n");
@@ -614,17 +608,8 @@ class EmitCModel final : public EmitCFunc {
}
void emitImplementation(AstNodeModule* modp) {
UASSERT(!ofp(), "Output file should not be open");
const string filename = v3Global.opt.makeDir() + "/" + EmitCUtil::topClassName() + ".cpp";
setOutputFile(v3Global.opt.systemC() ? new V3OutScFile{filename}
: new V3OutCFile{filename},
newCFile(filename, /* slow: */ false, /* source: */ true));
ofp()->putsHeader();
puts("// DESCRIPTION: Verilator output: "
"Model implementation (design independent parts)\n");
openNewOutputSourceFile(EmitCUtil::topClassName(), false, false,
"Model implementation (design independent parts)");
puts("\n");
puts("#include \"" + EmitCUtil::pchClassName() + ".h\"\n");
for (const string& base : v3Global.opt.traceSourceLangs())
@@ -643,6 +628,10 @@ class EmitCModel final : public EmitCFunc {
void emitDpiExportDispatchers(AstNodeModule* modp) {
UASSERT(!ofp(), "Output file should not be open");
// File name utils
V3UniqueNames uniqueNames;
const std::string fileBaseName = EmitCUtil::topClassName() + "__Dpi_Export";
// Emit DPI Export dispatchers
for (AstNode* nodep = modp->stmtsp(); nodep; nodep = nodep->nextp()) {
AstCFunc* const funcp = VN_CAST(nodep, CFunc);
@@ -656,23 +645,14 @@ class EmitCModel final : public EmitCFunc {
}
if (!ofp()) {
string filename
= v3Global.opt.makeDir() + "/" + EmitCUtil::topClassName() + "__Dpi_Export";
filename = m_uniqueNames.get(filename);
filename += ".cpp";
setOutputFile(v3Global.opt.systemC() ? new V3OutScFile{filename}
: new V3OutCFile{filename},
newCFile(filename, /* slow: */ false, /* source: */ true));
splitSizeReset(); // Reset file size tracking
m_lazyDecls.reset();
ofp()->putsHeader();
puts(
"// DESCRIPTION: Verilator output: Implementation of DPI export functions.\n");
puts("//\n");
openNewOutputSourceFile(uniqueNames.get(fileBaseName), false, false,
"Implementation of DPI export functions.");
puts("\n");
puts("#include \"" + EmitCUtil::topClassName() + ".h\"\n");
puts("#include \"" + EmitCUtil::symClassName() + ".h\"\n");
puts("#include \"verilated_dpi.h\"\n");
puts("\n");
m_lazyDecls.reset();
}
iterateConst(funcp);