2012-04-13 03:08:20 +02:00
|
|
|
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
2006-08-26 13:35:28 +02:00
|
|
|
//*************************************************************************
|
|
|
|
|
// DESCRIPTION: Verilator: Emit C++ for tree
|
|
|
|
|
//
|
2019-11-08 04:33:59 +01:00
|
|
|
// Code available from: https://verilator.org
|
2006-08-26 13:35:28 +02:00
|
|
|
//
|
|
|
|
|
//*************************************************************************
|
|
|
|
|
//
|
2022-01-01 14:26:40 +01:00
|
|
|
// Copyright 2003-2022 by Wilson Snyder. This program is free software; you
|
2020-03-21 16:24:24 +01:00
|
|
|
// can redistribute it and/or modify it under the terms of either the GNU
|
2009-05-04 23:07:57 +02:00
|
|
|
// Lesser General Public License Version 3 or the Perl Artistic License
|
|
|
|
|
// Version 2.0.
|
2020-03-21 16:24:24 +01:00
|
|
|
// SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
2006-08-26 13:35:28 +02:00
|
|
|
//
|
|
|
|
|
//*************************************************************************
|
2019-10-05 02:17:11 +02:00
|
|
|
|
2006-12-18 20:20:45 +01:00
|
|
|
#include "config_build.h"
|
|
|
|
|
#include "verilatedos.h"
|
2018-10-14 19:43:24 +02:00
|
|
|
|
|
|
|
|
#include "V3EmitC.h"
|
|
|
|
|
#include "V3EmitCBase.h"
|
2022-08-05 11:56:57 +02:00
|
|
|
#include "V3Global.h"
|
2018-10-14 19:43:24 +02:00
|
|
|
#include "V3LanguageWords.h"
|
2021-09-27 04:51:11 +02:00
|
|
|
#include "V3PartitionGraph.h"
|
2018-10-14 19:43:24 +02:00
|
|
|
|
2018-10-14 13:04:18 +02:00
|
|
|
#include <algorithm>
|
2006-08-26 13:35:28 +02:00
|
|
|
#include <map>
|
|
|
|
|
#include <vector>
|
|
|
|
|
|
2022-09-18 21:53:42 +02:00
|
|
|
VL_DEFINE_DEBUG_FUNCTIONS;
|
|
|
|
|
|
2006-08-26 13:35:28 +02:00
|
|
|
//######################################################################
|
|
|
|
|
// Symbol table emitting
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class EmitCSyms final : EmitCBaseVisitor {
|
2008-12-05 16:54:14 +01:00
|
|
|
// NODE STATE
|
|
|
|
|
// Cleared on Netlist
|
2019-05-19 22:13:13 +02:00
|
|
|
// AstNodeModule::user1() -> bool. Set true __Vconfigure called
|
2022-01-02 19:56:40 +01:00
|
|
|
const VNUser1InUse m_inuser1;
|
2008-12-05 16:54:14 +01:00
|
|
|
|
2009-12-09 04:12:59 +01:00
|
|
|
// TYPES
|
2020-04-15 01:55:00 +02:00
|
|
|
struct ScopeData {
|
2021-11-26 23:55:36 +01:00
|
|
|
const string m_symName;
|
|
|
|
|
const string m_prettyName;
|
|
|
|
|
const int m_timeunit;
|
2020-04-15 01:55:00 +02:00
|
|
|
string m_type;
|
2020-04-16 01:39:03 +02:00
|
|
|
ScopeData(const string& symName, const string& prettyName, int timeunit,
|
|
|
|
|
const string& type)
|
2020-08-16 15:55:36 +02:00
|
|
|
: m_symName{symName}
|
|
|
|
|
, m_prettyName{prettyName}
|
|
|
|
|
, m_timeunit{timeunit}
|
|
|
|
|
, m_type{type} {}
|
2010-03-17 13:22:49 +01:00
|
|
|
};
|
2020-04-15 01:55:00 +02:00
|
|
|
struct ScopeFuncData {
|
2021-11-13 19:50:44 +01:00
|
|
|
AstScopeName* const m_scopep;
|
|
|
|
|
AstCFunc* const m_cfuncp;
|
|
|
|
|
AstNodeModule* const m_modp;
|
2019-05-19 22:13:13 +02:00
|
|
|
ScopeFuncData(AstScopeName* scopep, AstCFunc* funcp, AstNodeModule* modp)
|
2020-08-16 15:55:36 +02:00
|
|
|
: m_scopep{scopep}
|
2020-10-31 13:59:35 +01:00
|
|
|
, m_cfuncp{funcp}
|
2020-08-16 15:55:36 +02:00
|
|
|
, m_modp{modp} {}
|
2009-12-20 14:27:00 +01:00
|
|
|
};
|
2020-04-15 01:55:00 +02:00
|
|
|
struct ScopeVarData {
|
2021-11-26 23:55:36 +01:00
|
|
|
const string m_scopeName;
|
|
|
|
|
const string m_varBasePretty;
|
2021-11-13 19:50:44 +01:00
|
|
|
AstVar* const m_varp;
|
2021-11-26 23:55:36 +01:00
|
|
|
const AstNodeModule* const m_modp;
|
2021-11-13 19:50:44 +01:00
|
|
|
AstScope* const m_scopep;
|
2020-04-15 01:55:00 +02:00
|
|
|
ScopeVarData(const string& scopeName, const string& varBasePretty, AstVar* varp,
|
2021-11-26 23:55:36 +01:00
|
|
|
const AstNodeModule* modp, AstScope* scopep)
|
2020-08-16 15:55:36 +02:00
|
|
|
: m_scopeName{scopeName}
|
|
|
|
|
, m_varBasePretty{varBasePretty}
|
|
|
|
|
, m_varp{varp}
|
|
|
|
|
, m_modp{modp}
|
|
|
|
|
, m_scopep{scopep} {}
|
2010-03-17 13:22:49 +01:00
|
|
|
};
|
2021-03-13 00:10:45 +01:00
|
|
|
using ScopeNames = std::map<const std::string, ScopeData>;
|
|
|
|
|
using ScopeModPair = std::pair<AstScope*, AstNodeModule*>;
|
|
|
|
|
using ModVarPair = std::pair<AstNodeModule*, AstVar*>;
|
|
|
|
|
using ScopeNameList = std::vector<std::string>;
|
|
|
|
|
using ScopeNameHierarchy = std::map<const std::string, ScopeNameList>;
|
2009-12-09 04:12:59 +01:00
|
|
|
struct CmpName {
|
2020-12-02 00:49:03 +01:00
|
|
|
bool operator()(const ScopeModPair& lhsp, const ScopeModPair& rhsp) const {
|
2019-05-19 22:13:13 +02:00
|
|
|
return lhsp.first->name() < rhsp.first->name();
|
|
|
|
|
}
|
2009-12-09 04:12:59 +01:00
|
|
|
};
|
2009-12-20 14:27:00 +01:00
|
|
|
struct CmpDpi {
|
2020-12-02 00:49:03 +01:00
|
|
|
bool operator()(const AstCFunc* lhsp, const AstCFunc* rhsp) const {
|
2021-06-10 23:41:33 +02:00
|
|
|
if (lhsp->dpiImportPrototype() != rhsp->dpiImportPrototype()) {
|
2019-05-19 22:13:13 +02:00
|
|
|
// cppcheck-suppress comparisonOfFuncReturningBoolError
|
2021-06-10 23:41:33 +02:00
|
|
|
return lhsp->dpiImportPrototype() < rhsp->dpiImportPrototype();
|
2019-05-19 22:13:13 +02:00
|
|
|
}
|
|
|
|
|
return lhsp->name() < rhsp->name();
|
|
|
|
|
}
|
2009-12-20 14:27:00 +01:00
|
|
|
};
|
2009-12-05 16:38:49 +01:00
|
|
|
|
2006-08-26 13:35:28 +02:00
|
|
|
// STATE
|
2020-10-31 13:59:35 +01:00
|
|
|
AstCFunc* m_cfuncp = nullptr; // Current function
|
2020-08-16 15:55:36 +02:00
|
|
|
AstNodeModule* m_modp = nullptr; // Current module
|
2019-10-02 03:57:45 +02:00
|
|
|
std::vector<ScopeModPair> m_scopes; // Every scope by module
|
2020-04-15 01:55:00 +02:00
|
|
|
std::vector<AstCFunc*> m_dpis; // DPI functions
|
|
|
|
|
std::vector<ModVarPair> m_modVars; // Each public {mod,var}
|
|
|
|
|
ScopeNames m_scopeNames; // Each unique AstScopeName
|
2021-03-12 23:26:53 +01:00
|
|
|
std::map<const std::string, ScopeFuncData> m_scopeFuncs; // Each {scope,dpi-export-func}
|
|
|
|
|
std::map<const std::string, ScopeVarData> m_scopeVars; // Each {scope,public-var}
|
2020-04-15 01:55:00 +02:00
|
|
|
ScopeNames m_vpiScopeCandidates; // All scopes for VPI
|
|
|
|
|
ScopeNameHierarchy m_vpiScopeHierarchy; // The actual hierarchy of scopes
|
2020-08-16 15:55:36 +02:00
|
|
|
int m_coverBins = 0; // Coverage bin number
|
2021-11-26 23:55:36 +01:00
|
|
|
const bool m_dpiHdrOnly; // Only emit the DPI header
|
2020-08-16 15:55:36 +02:00
|
|
|
int m_numStmts = 0; // Number of statements output
|
|
|
|
|
int m_funcNum = 0; // CFunc split function number
|
|
|
|
|
V3OutCFile* m_ofpBase = nullptr; // Base (not split) C file
|
2020-11-26 02:57:30 +01:00
|
|
|
std::unordered_map<int, bool> m_usesVfinal; // Split method uses __Vfinal
|
2006-08-26 13:35:28 +02:00
|
|
|
|
|
|
|
|
// METHODS
|
2009-12-09 04:12:59 +01:00
|
|
|
void emitSymHdr();
|
2019-09-04 12:15:41 +02:00
|
|
|
void checkSplit(bool usesVfinal);
|
|
|
|
|
void closeSplit();
|
|
|
|
|
void emitSymImpPreamble();
|
2020-12-17 18:21:40 +01:00
|
|
|
void emitScopeHier(bool destroy);
|
2009-12-09 04:12:59 +01:00
|
|
|
void emitSymImp();
|
|
|
|
|
void emitDpiHdr();
|
|
|
|
|
void emitDpiImp();
|
2006-08-26 13:35:28 +02:00
|
|
|
|
2020-08-16 20:55:46 +02:00
|
|
|
static void nameCheck(AstNode* nodep) {
|
2019-05-19 22:13:13 +02:00
|
|
|
// Prevent GCC compile time error; name check all things that reach C++ code
|
2020-02-03 03:15:07 +01:00
|
|
|
if (nodep->name() != ""
|
|
|
|
|
&& !(VN_IS(nodep, CFunc)
|
2021-10-22 14:56:48 +02:00
|
|
|
&& (VN_AS(nodep, CFunc)->isConstructor()
|
|
|
|
|
|| VN_AS(nodep, CFunc)->isDestructor()))) {
|
2021-06-21 00:32:57 +02:00
|
|
|
const string rsvd = V3LanguageWords::isKeyword(nodep->name());
|
2019-05-19 22:13:13 +02:00
|
|
|
if (rsvd != "") {
|
|
|
|
|
// Generally V3Name should find all of these and throw SYMRSVDWORD.
|
|
|
|
|
// We'll still check here because the compiler errors
|
|
|
|
|
// resulting if we miss this warning are SO nasty
|
2020-04-15 01:55:00 +02:00
|
|
|
nodep->v3error("Symbol matching " + rsvd
|
|
|
|
|
+ " reserved word reached emitter,"
|
|
|
|
|
" should have hit SYMRSVDWORD: "
|
|
|
|
|
<< nodep->prettyNameQ());
|
2019-05-19 22:13:13 +02:00
|
|
|
}
|
|
|
|
|
}
|
2006-08-26 13:35:28 +02:00
|
|
|
}
|
|
|
|
|
|
2020-08-16 20:55:46 +02:00
|
|
|
static string scopeSymString(const string& scpname) {
|
2019-10-02 03:57:45 +02:00
|
|
|
string out = scpname;
|
|
|
|
|
string::size_type pos;
|
2020-04-15 01:55:00 +02:00
|
|
|
while ((pos = out.find("__PVT__")) != string::npos) out.replace(pos, 7, "");
|
2019-10-02 03:57:45 +02:00
|
|
|
if (out.substr(0, 10) == "TOP__DOT__") out.replace(0, 10, "");
|
|
|
|
|
if (out.substr(0, 4) == "TOP.") out.replace(0, 4, "");
|
2020-04-15 01:55:00 +02:00
|
|
|
while ((pos = out.find('.')) != string::npos) out.replace(pos, 1, "__");
|
|
|
|
|
while ((pos = out.find("__DOT__")) != string::npos) out.replace(pos, 7, "__");
|
2019-10-02 03:57:45 +02:00
|
|
|
return out;
|
|
|
|
|
}
|
|
|
|
|
|
2020-08-16 20:55:46 +02:00
|
|
|
static string scopeDecodeIdentifier(const string& scpname) {
|
2019-10-02 03:57:45 +02:00
|
|
|
string out = scpname;
|
|
|
|
|
// Remove hierarchy
|
2020-04-04 04:31:54 +02:00
|
|
|
string::size_type pos = out.rfind('.');
|
2019-10-02 03:57:45 +02:00
|
|
|
if (pos != std::string::npos) out.erase(0, pos + 1);
|
|
|
|
|
// Decode all escaped characters
|
|
|
|
|
while ((pos = out.find("__0")) != string::npos) {
|
|
|
|
|
unsigned int x;
|
|
|
|
|
std::stringstream ss;
|
2020-04-15 01:55:00 +02:00
|
|
|
ss << std::hex << out.substr(pos + 3, 2);
|
2019-10-02 03:57:45 +02:00
|
|
|
ss >> x;
|
2020-04-15 01:55:00 +02:00
|
|
|
out.replace(pos, 5, 1, (char)x);
|
2019-10-02 03:57:45 +02:00
|
|
|
}
|
|
|
|
|
return out;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void varHierarchyScopes(string scp) {
|
|
|
|
|
while (!scp.empty()) {
|
2020-08-16 17:43:49 +02:00
|
|
|
const auto scpit = m_vpiScopeCandidates.find(scp);
|
2019-10-02 03:57:45 +02:00
|
|
|
if ((scpit != m_vpiScopeCandidates.end())
|
2020-04-15 01:55:00 +02:00
|
|
|
&& (m_scopeNames.find(scp) == m_scopeNames.end())) {
|
2021-06-21 00:32:57 +02:00
|
|
|
const auto scopeNameit = m_scopeNames.find(scpit->second.m_symName);
|
2021-04-26 15:50:25 +02:00
|
|
|
if (scopeNameit == m_scopeNames.end()) {
|
|
|
|
|
m_scopeNames.emplace(scpit->second.m_symName, scpit->second);
|
|
|
|
|
} else {
|
|
|
|
|
scopeNameit->second.m_type = scpit->second.m_type;
|
|
|
|
|
}
|
2019-10-02 03:57:45 +02:00
|
|
|
}
|
|
|
|
|
string::size_type pos = scp.rfind("__DOT__");
|
|
|
|
|
if (pos == string::npos) {
|
2020-04-04 04:31:54 +02:00
|
|
|
pos = scp.rfind('.');
|
|
|
|
|
if (pos == string::npos) break;
|
2019-10-02 03:57:45 +02:00
|
|
|
}
|
|
|
|
|
scp.resize(pos);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2010-03-17 13:22:49 +01:00
|
|
|
void varsExpand() {
|
2019-09-09 13:50:21 +02:00
|
|
|
// We didn't have all m_scopes loaded when we encountered variables, so expand them now
|
2019-05-19 22:13:13 +02:00
|
|
|
// It would be less code if each module inserted its own variables.
|
|
|
|
|
// Someday. For now public isn't common.
|
2020-04-15 01:55:00 +02:00
|
|
|
for (std::vector<ScopeModPair>::iterator itsc = m_scopes.begin(); itsc != m_scopes.end();
|
|
|
|
|
++itsc) {
|
2021-11-13 19:50:44 +01:00
|
|
|
AstScope* const scopep = itsc->first;
|
|
|
|
|
const AstNodeModule* const smodp = itsc->second;
|
2020-04-15 01:55:00 +02:00
|
|
|
for (std::vector<ModVarPair>::iterator it = m_modVars.begin(); it != m_modVars.end();
|
|
|
|
|
++it) {
|
2021-11-26 23:55:36 +01:00
|
|
|
const AstNodeModule* const modp = it->first;
|
2021-11-13 19:50:44 +01:00
|
|
|
AstVar* const varp = it->second;
|
2019-05-19 22:13:13 +02:00
|
|
|
if (modp == smodp) {
|
|
|
|
|
// Need to split the module + var name into the
|
|
|
|
|
// original-ish full scope and variable name under that scope.
|
|
|
|
|
// The module instance name is included later, when we
|
|
|
|
|
// know the scopes this module is under
|
2020-04-15 01:55:00 +02:00
|
|
|
string whole = scopep->name() + "__DOT__" + varp->name();
|
2019-05-19 22:13:13 +02:00
|
|
|
string scpName;
|
|
|
|
|
string varBase;
|
|
|
|
|
if (whole.substr(0, 10) == "__DOT__TOP") whole.replace(0, 10, "");
|
2021-11-26 23:55:36 +01:00
|
|
|
const string::size_type dpos = whole.rfind("__DOT__");
|
2019-05-19 22:13:13 +02:00
|
|
|
if (dpos != string::npos) {
|
|
|
|
|
scpName = whole.substr(0, dpos);
|
2022-09-15 03:10:19 +02:00
|
|
|
varBase = whole.substr(dpos + std::strlen("__DOT__"));
|
2019-05-19 22:13:13 +02:00
|
|
|
} else {
|
|
|
|
|
varBase = whole;
|
|
|
|
|
}
|
2021-09-02 14:54:14 +02:00
|
|
|
// UINFO(9, "For " << scopep->name() << " - " << varp->name() << " Scp "
|
|
|
|
|
// << scpName << "Var " << varBase << endl);
|
2021-06-21 00:32:57 +02:00
|
|
|
const string varBasePretty = AstNode::prettyName(varBase);
|
|
|
|
|
const string scpPretty = AstNode::prettyName(scpName);
|
|
|
|
|
const string scpSym = scopeSymString(scpName);
|
2021-09-02 14:54:14 +02:00
|
|
|
// UINFO(9, " scnameins sp " << scpName << " sp " << scpPretty << " ss "
|
|
|
|
|
// << scpSym << endl);
|
2020-04-15 01:55:00 +02:00
|
|
|
if (v3Global.opt.vpi()) varHierarchyScopes(scpName);
|
2019-05-19 22:13:13 +02:00
|
|
|
if (m_scopeNames.find(scpSym) == m_scopeNames.end()) {
|
2021-03-13 00:17:49 +01:00
|
|
|
m_scopeNames.insert(std::make_pair(
|
|
|
|
|
scpSym, ScopeData(scpSym, scpPretty, 0, "SCOPE_OTHER")));
|
2019-05-19 22:13:13 +02:00
|
|
|
}
|
|
|
|
|
m_scopeVars.insert(
|
2021-03-13 00:17:49 +01:00
|
|
|
std::make_pair(scpSym + " " + varp->name(),
|
|
|
|
|
ScopeVarData(scpSym, varBasePretty, varp, modp, scopep)));
|
2019-05-19 22:13:13 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2010-03-17 13:22:49 +01:00
|
|
|
}
|
|
|
|
|
|
2019-10-02 03:57:45 +02:00
|
|
|
void buildVpiHierarchy() {
|
2020-04-15 01:55:00 +02:00
|
|
|
for (ScopeNames::const_iterator it = m_scopeNames.begin(); it != m_scopeNames.end();
|
|
|
|
|
++it) {
|
2019-10-02 03:57:45 +02:00
|
|
|
if (it->second.m_type != "SCOPE_MODULE") continue;
|
|
|
|
|
|
2021-06-21 00:32:57 +02:00
|
|
|
const string symName = it->second.m_symName;
|
2021-04-26 15:50:25 +02:00
|
|
|
string above = symName;
|
|
|
|
|
if (above.substr(0, 4) == "TOP.") above.replace(0, 4, "");
|
2019-10-02 03:57:45 +02:00
|
|
|
|
|
|
|
|
while (!above.empty()) {
|
2021-11-26 23:55:36 +01:00
|
|
|
const string::size_type pos = above.rfind("__");
|
2020-04-04 04:31:54 +02:00
|
|
|
if (pos == string::npos) break;
|
2019-10-02 03:57:45 +02:00
|
|
|
above.resize(pos);
|
|
|
|
|
if (m_vpiScopeHierarchy.find(above) != m_vpiScopeHierarchy.end()) {
|
2021-04-26 15:50:25 +02:00
|
|
|
m_vpiScopeHierarchy[above].push_back(symName);
|
2019-10-02 03:57:45 +02:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
2021-04-26 15:50:25 +02:00
|
|
|
m_vpiScopeHierarchy[symName] = std::vector<string>();
|
2019-10-02 03:57:45 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2006-08-26 13:35:28 +02:00
|
|
|
// VISITORS
|
2022-09-16 12:22:11 +02:00
|
|
|
void visit(AstNetlist* nodep) override {
|
2019-05-19 22:13:13 +02:00
|
|
|
// Collect list of scopes
|
2018-05-11 02:55:37 +02:00
|
|
|
iterateChildren(nodep);
|
2019-05-19 22:13:13 +02:00
|
|
|
varsExpand();
|
|
|
|
|
|
2020-04-15 01:55:00 +02:00
|
|
|
if (v3Global.opt.vpi()) buildVpiHierarchy();
|
2019-10-02 03:57:45 +02:00
|
|
|
|
2019-05-19 22:13:13 +02:00
|
|
|
// Sort by names, so line/process order matters less
|
|
|
|
|
stable_sort(m_scopes.begin(), m_scopes.end(), CmpName());
|
|
|
|
|
stable_sort(m_dpis.begin(), m_dpis.end(), CmpDpi());
|
|
|
|
|
|
|
|
|
|
// Output
|
2019-08-28 03:36:59 +02:00
|
|
|
if (!m_dpiHdrOnly) {
|
2019-09-04 12:15:41 +02:00
|
|
|
// Must emit implementation first to determine number of splits
|
2019-08-28 03:36:59 +02:00
|
|
|
emitSymImp();
|
2019-09-04 12:15:41 +02:00
|
|
|
emitSymHdr();
|
2019-08-28 03:36:59 +02:00
|
|
|
}
|
2019-05-19 22:13:13 +02:00
|
|
|
if (v3Global.dpi()) {
|
|
|
|
|
emitDpiHdr();
|
2019-08-28 03:36:59 +02:00
|
|
|
if (!m_dpiHdrOnly) emitDpiImp();
|
2019-05-19 22:13:13 +02:00
|
|
|
}
|
2006-08-26 13:35:28 +02:00
|
|
|
}
|
2022-09-16 12:22:11 +02:00
|
|
|
void visit(AstConstPool* nodep) override {} // Ignore
|
|
|
|
|
void visit(AstNodeModule* nodep) override {
|
2019-05-19 22:13:13 +02:00
|
|
|
nameCheck(nodep);
|
2020-08-25 03:10:43 +02:00
|
|
|
VL_RESTORER(m_modp);
|
2020-01-20 19:27:27 +01:00
|
|
|
{
|
|
|
|
|
m_modp = nodep;
|
|
|
|
|
iterateChildren(nodep);
|
|
|
|
|
}
|
2006-08-26 13:35:28 +02:00
|
|
|
}
|
2022-09-16 12:22:11 +02:00
|
|
|
void visit(AstCellInline* nodep) override {
|
2019-10-02 03:57:45 +02:00
|
|
|
if (v3Global.opt.vpi()) {
|
2021-06-21 00:32:57 +02:00
|
|
|
const string type
|
|
|
|
|
= (nodep->origModName() == "__BEGIN__") ? "SCOPE_OTHER" : "SCOPE_MODULE";
|
|
|
|
|
const string name = nodep->scopep()->name() + "__DOT__" + nodep->name();
|
|
|
|
|
const string name_dedot = AstNode::dedotName(name);
|
|
|
|
|
const int timeunit = m_modp->timeunit().powerOfTen();
|
2020-04-15 01:55:00 +02:00
|
|
|
m_vpiScopeCandidates.insert(
|
2021-03-13 00:17:49 +01:00
|
|
|
std::make_pair(name, ScopeData(scopeSymString(name), name_dedot, timeunit, type)));
|
2019-10-02 03:57:45 +02:00
|
|
|
}
|
|
|
|
|
}
|
2022-09-16 12:22:11 +02:00
|
|
|
void visit(AstScope* nodep) override {
|
2020-04-05 15:30:23 +02:00
|
|
|
if (VN_IS(m_modp, Class)) return; // The ClassPackage is what is visible
|
2019-05-19 22:13:13 +02:00
|
|
|
nameCheck(nodep);
|
2019-10-02 03:57:45 +02:00
|
|
|
|
2021-03-13 00:17:49 +01:00
|
|
|
m_scopes.emplace_back(std::make_pair(nodep, m_modp));
|
2019-10-02 03:57:45 +02:00
|
|
|
|
|
|
|
|
if (v3Global.opt.vpi() && !nodep->isTop()) {
|
2021-06-21 00:32:57 +02:00
|
|
|
const string type = VN_IS(nodep->modp(), Package) ? "SCOPE_OTHER" : "SCOPE_MODULE";
|
|
|
|
|
const string name_dedot = AstNode::dedotName(nodep->shortName());
|
|
|
|
|
const int timeunit = m_modp->timeunit().powerOfTen();
|
2020-04-15 01:55:00 +02:00
|
|
|
m_vpiScopeCandidates.insert(
|
2021-03-13 00:17:49 +01:00
|
|
|
std::make_pair(nodep->name(), ScopeData(scopeSymString(nodep->name()), name_dedot,
|
2021-04-12 21:00:36 +02:00
|
|
|
timeunit, type)));
|
2019-10-02 03:57:45 +02:00
|
|
|
}
|
2006-08-26 13:35:28 +02:00
|
|
|
}
|
2022-09-16 12:22:11 +02:00
|
|
|
void visit(AstScopeName* nodep) override {
|
2021-06-21 00:32:57 +02:00
|
|
|
const string name = nodep->scopeSymName();
|
2020-04-16 01:39:03 +02:00
|
|
|
// UINFO(9,"scnameins sp "<<nodep->name()<<" sp "<<nodep->scopePrettySymName()
|
|
|
|
|
// <<" ss"<<name<<endl);
|
2021-06-21 00:32:57 +02:00
|
|
|
const int timeunit = m_modp ? m_modp->timeunit().powerOfTen() : 0;
|
2019-05-19 22:13:13 +02:00
|
|
|
if (m_scopeNames.find(name) == m_scopeNames.end()) {
|
2020-12-19 00:24:47 +01:00
|
|
|
m_scopeNames.emplace(
|
|
|
|
|
name, ScopeData(name, nodep->scopePrettySymName(), timeunit, "SCOPE_OTHER"));
|
2019-05-19 22:13:13 +02:00
|
|
|
}
|
|
|
|
|
if (nodep->dpiExport()) {
|
2020-10-31 13:59:35 +01:00
|
|
|
UASSERT_OBJ(m_cfuncp, nodep, "ScopeName not under DPI function");
|
2021-03-13 00:17:49 +01:00
|
|
|
m_scopeFuncs.insert(std::make_pair(name + " " + m_cfuncp->name(),
|
|
|
|
|
ScopeFuncData(nodep, m_cfuncp, m_modp)));
|
2019-05-19 22:13:13 +02:00
|
|
|
} else {
|
|
|
|
|
if (m_scopeNames.find(nodep->scopeDpiName()) == m_scopeNames.end()) {
|
2020-04-16 01:39:03 +02:00
|
|
|
m_scopeNames.insert(
|
2021-03-13 00:17:49 +01:00
|
|
|
std::make_pair(nodep->scopeDpiName(),
|
|
|
|
|
ScopeData(nodep->scopeDpiName(), nodep->scopePrettyDpiName(),
|
|
|
|
|
timeunit, "SCOPE_OTHER")));
|
2019-05-19 22:13:13 +02:00
|
|
|
}
|
|
|
|
|
}
|
2009-12-05 16:38:49 +01:00
|
|
|
}
|
2022-09-16 12:22:11 +02:00
|
|
|
void visit(AstVar* nodep) override {
|
2019-05-19 22:13:13 +02:00
|
|
|
nameCheck(nodep);
|
2018-05-11 02:55:37 +02:00
|
|
|
iterateChildren(nodep);
|
2021-03-26 23:24:31 +01:00
|
|
|
if (nodep->isSigUserRdPublic() && !m_cfuncp)
|
|
|
|
|
m_modVars.emplace_back(std::make_pair(m_modp, nodep));
|
2010-03-17 13:22:49 +01:00
|
|
|
}
|
2022-09-16 12:22:11 +02:00
|
|
|
void visit(AstCoverDecl* nodep) override {
|
2019-05-19 22:13:13 +02:00
|
|
|
// Assign numbers to all bins, so we know how big of an array to use
|
|
|
|
|
if (!nodep->dataDeclNullp()) { // else duplicate we don't need code for
|
|
|
|
|
nodep->binNum(m_coverBins++);
|
|
|
|
|
}
|
2008-12-05 16:54:14 +01:00
|
|
|
}
|
2022-09-16 12:22:11 +02:00
|
|
|
void visit(AstCFunc* nodep) override {
|
2019-05-19 22:13:13 +02:00
|
|
|
nameCheck(nodep);
|
2021-06-10 23:41:33 +02:00
|
|
|
if (nodep->dpiImportPrototype() || nodep->dpiExportDispatcher()) m_dpis.push_back(nodep);
|
2020-10-31 13:59:35 +01:00
|
|
|
VL_RESTORER(m_cfuncp);
|
|
|
|
|
{
|
|
|
|
|
m_cfuncp = nodep;
|
|
|
|
|
iterateChildren(nodep);
|
|
|
|
|
}
|
2009-12-09 04:12:59 +01:00
|
|
|
}
|
2020-04-04 14:31:14 +02:00
|
|
|
|
2006-08-26 13:35:28 +02:00
|
|
|
//---------------------------------------
|
2022-09-16 12:22:11 +02:00
|
|
|
void visit(AstConst*) override {}
|
|
|
|
|
void visit(AstNode* nodep) override { iterateChildren(nodep); }
|
2020-04-04 14:31:14 +02:00
|
|
|
|
2006-08-26 13:35:28 +02:00
|
|
|
public:
|
2020-04-04 14:31:14 +02:00
|
|
|
explicit EmitCSyms(AstNetlist* nodep, bool dpiHdrOnly)
|
2020-08-16 15:55:36 +02:00
|
|
|
: m_dpiHdrOnly{dpiHdrOnly} {
|
2018-05-11 02:55:37 +02:00
|
|
|
iterate(nodep);
|
2006-08-26 13:35:28 +02:00
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
2009-12-09 04:12:59 +01:00
|
|
|
void EmitCSyms::emitSymHdr() {
|
2020-04-15 01:55:00 +02:00
|
|
|
UINFO(6, __FUNCTION__ << ": " << endl);
|
2021-06-21 00:32:57 +02:00
|
|
|
const string filename = v3Global.opt.makeDir() + "/" + symClassName() + ".h";
|
2020-04-15 01:55:00 +02:00
|
|
|
newCFile(filename, true /*slow*/, false /*source*/);
|
2020-04-10 05:03:28 +02:00
|
|
|
|
|
|
|
|
if (v3Global.opt.systemC()) {
|
|
|
|
|
m_ofp = new V3OutScFile(filename);
|
|
|
|
|
} else {
|
|
|
|
|
m_ofp = new V3OutCFile(filename);
|
|
|
|
|
}
|
2006-08-26 13:35:28 +02:00
|
|
|
|
|
|
|
|
ofp()->putsHeader();
|
Introduce model interface class, make $root part or Syms (#3036)
This patch implements #3032. Verilator creates a module representing the
SystemVerilog $root scope (V3LinkLevel::wrapTop). Until now, this was
called the "TOP" module, which also acted as the user instantiated model
class. Syms used to hold a pointer to this root module, but hold
instances of any submodule. This patch renames this root scope module
from "TOP" to "$root", and introduces a separate model class which is
now an interface class. As the root module is no longer the user
interface class, it can now be made an instance of Syms, just like any
other submodule. This allows absolute references into the root module to
avoid an additional pointer indirection resulting in a potential speedup
(about 1.5% on OpenTitan). The model class now also contains all non
design specific generated code (e.g.: eval loops, trace config, etc),
which additionally simplifies Verilator internals.
Please see the updated documentation for the model interface changes.
2021-06-21 16:30:20 +02:00
|
|
|
puts("// DESCRIPTION: Verilator output: Symbol table internal header\n");
|
2009-12-03 02:09:13 +01:00
|
|
|
puts("//\n");
|
2019-07-07 15:00:57 +02:00
|
|
|
puts("// Internal details; most calling programs do not need this header,\n");
|
|
|
|
|
puts("// unless using verilator public meta comments.\n");
|
2009-12-03 02:09:13 +01:00
|
|
|
|
2019-12-24 01:00:17 +01:00
|
|
|
ofp()->putsGuard();
|
2006-08-26 13:35:28 +02:00
|
|
|
|
2019-12-24 01:00:17 +01:00
|
|
|
puts("\n");
|
2017-02-09 13:43:43 +01:00
|
|
|
ofp()->putsIntTopInclude();
|
2021-07-24 16:00:33 +02:00
|
|
|
puts("#include \"verilated.h\"\n");
|
Introduce model interface class, make $root part or Syms (#3036)
This patch implements #3032. Verilator creates a module representing the
SystemVerilog $root scope (V3LinkLevel::wrapTop). Until now, this was
called the "TOP" module, which also acted as the user instantiated model
class. Syms used to hold a pointer to this root module, but hold
instances of any submodule. This patch renames this root scope module
from "TOP" to "$root", and introduces a separate model class which is
now an interface class. As the root module is no longer the user
interface class, it can now be made an instance of Syms, just like any
other submodule. This allows absolute references into the root module to
avoid an additional pointer indirection resulting in a potential speedup
(about 1.5% on OpenTitan). The model class now also contains all non
design specific generated code (e.g.: eval loops, trace config, etc),
which additionally simplifies Verilator internals.
Please see the updated documentation for the model interface changes.
2021-06-21 16:30:20 +02:00
|
|
|
if (v3Global.needTraceDumper()) {
|
|
|
|
|
puts("#include \"" + v3Global.opt.traceSourceLang() + ".h\"\n");
|
|
|
|
|
}
|
2022-03-25 20:46:50 +01:00
|
|
|
if (v3Global.opt.usesProfiler()) puts("#include \"verilated_profiler.h\"\n");
|
Introduce model interface class, make $root part or Syms (#3036)
This patch implements #3032. Verilator creates a module representing the
SystemVerilog $root scope (V3LinkLevel::wrapTop). Until now, this was
called the "TOP" module, which also acted as the user instantiated model
class. Syms used to hold a pointer to this root module, but hold
instances of any submodule. This patch renames this root scope module
from "TOP" to "$root", and introduces a separate model class which is
now an interface class. As the root module is no longer the user
interface class, it can now be made an instance of Syms, just like any
other submodule. This allows absolute references into the root module to
avoid an additional pointer indirection resulting in a potential speedup
(about 1.5% on OpenTitan). The model class now also contains all non
design specific generated code (e.g.: eval loops, trace config, etc),
which additionally simplifies Verilator internals.
Please see the updated documentation for the model interface changes.
2021-06-21 16:30:20 +02:00
|
|
|
|
|
|
|
|
puts("\n// INCLUDE MODEL CLASS\n");
|
|
|
|
|
puts("\n#include \"" + topClassName() + ".h\"\n");
|
2010-01-17 21:10:37 +01:00
|
|
|
|
2006-08-26 13:35:28 +02:00
|
|
|
puts("\n// INCLUDE MODULE CLASSES\n");
|
2020-02-03 03:15:07 +01:00
|
|
|
for (AstNodeModule* nodep = v3Global.rootp()->modulesp(); nodep;
|
2021-10-22 14:56:48 +02:00
|
|
|
nodep = VN_AS(nodep->nextp(), NodeModule)) {
|
2020-04-05 15:30:23 +02:00
|
|
|
if (VN_IS(nodep, Class)) continue; // Class included earlier
|
2020-01-25 15:16:00 +01:00
|
|
|
puts("#include \"" + prefixNameProtect(nodep) + ".h\"\n");
|
2006-08-26 13:35:28 +02:00
|
|
|
}
|
|
|
|
|
|
2009-12-20 14:27:00 +01:00
|
|
|
if (v3Global.dpi()) {
|
2018-08-25 15:52:45 +02:00
|
|
|
puts("\n// DPI TYPES for DPI Export callbacks (Internal use)\n");
|
2020-10-30 23:00:40 +01:00
|
|
|
std::map<const string, int> types; // Remove duplicates and sort
|
2020-11-11 04:10:38 +01:00
|
|
|
for (const auto& itr : m_scopeFuncs) {
|
2021-11-13 19:50:44 +01:00
|
|
|
const AstCFunc* const funcp = itr.second.m_cfuncp;
|
2021-06-10 23:41:33 +02:00
|
|
|
if (funcp->dpiExportImpl()) {
|
2021-06-21 00:32:57 +02:00
|
|
|
const string cbtype
|
|
|
|
|
= protect(v3Global.opt.prefix() + "__Vcb_" + funcp->cname() + "_t");
|
2021-03-13 00:10:45 +01:00
|
|
|
types["using " + cbtype + " = void (*) (" + cFuncArgs(funcp) + ");\n"] = 1;
|
2019-05-19 22:13:13 +02:00
|
|
|
}
|
|
|
|
|
}
|
2020-10-30 23:00:40 +01:00
|
|
|
for (const auto& i : types) puts(i.first);
|
2009-12-20 14:27:00 +01:00
|
|
|
}
|
|
|
|
|
|
Introduce model interface class, make $root part or Syms (#3036)
This patch implements #3032. Verilator creates a module representing the
SystemVerilog $root scope (V3LinkLevel::wrapTop). Until now, this was
called the "TOP" module, which also acted as the user instantiated model
class. Syms used to hold a pointer to this root module, but hold
instances of any submodule. This patch renames this root scope module
from "TOP" to "$root", and introduces a separate model class which is
now an interface class. As the root module is no longer the user
interface class, it can now be made an instance of Syms, just like any
other submodule. This allows absolute references into the root module to
avoid an additional pointer indirection resulting in a potential speedup
(about 1.5% on OpenTitan). The model class now also contains all non
design specific generated code (e.g.: eval loops, trace config, etc),
which additionally simplifies Verilator internals.
Please see the updated documentation for the model interface changes.
2021-06-21 16:30:20 +02:00
|
|
|
puts("\n// SYMS CLASS (contains all model state)\n");
|
|
|
|
|
puts("class " + symClassName() + " final : public VerilatedSyms {\n");
|
2006-08-30 23:07:55 +02:00
|
|
|
ofp()->putsPrivate(false); // public:
|
2006-08-26 13:35:28 +02:00
|
|
|
|
Introduce model interface class, make $root part or Syms (#3036)
This patch implements #3032. Verilator creates a module representing the
SystemVerilog $root scope (V3LinkLevel::wrapTop). Until now, this was
called the "TOP" module, which also acted as the user instantiated model
class. Syms used to hold a pointer to this root module, but hold
instances of any submodule. This patch renames this root scope module
from "TOP" to "$root", and introduces a separate model class which is
now an interface class. As the root module is no longer the user
interface class, it can now be made an instance of Syms, just like any
other submodule. This allows absolute references into the root module to
avoid an additional pointer indirection resulting in a potential speedup
(about 1.5% on OpenTitan). The model class now also contains all non
design specific generated code (e.g.: eval loops, trace config, etc),
which additionally simplifies Verilator internals.
Please see the updated documentation for the model interface changes.
2021-06-21 16:30:20 +02:00
|
|
|
puts("// INTERNAL STATE\n");
|
|
|
|
|
puts(topClassName() + "* const __Vm_modelp;\n");
|
2020-04-15 01:55:00 +02:00
|
|
|
|
2020-03-02 03:39:23 +01:00
|
|
|
if (v3Global.needTraceDumper()) {
|
|
|
|
|
// __Vm_dumperp is local, otherwise we wouldn't know what design's eval()
|
|
|
|
|
// should call a global dumpperp
|
Introduce model interface class, make $root part or Syms (#3036)
This patch implements #3032. Verilator creates a module representing the
SystemVerilog $root scope (V3LinkLevel::wrapTop). Until now, this was
called the "TOP" module, which also acted as the user instantiated model
class. Syms used to hold a pointer to this root module, but hold
instances of any submodule. This patch renames this root scope module
from "TOP" to "$root", and introduces a separate model class which is
now an interface class. As the root module is no longer the user
interface class, it can now be made an instance of Syms, just like any
other submodule. This allows absolute references into the root module to
avoid an additional pointer indirection resulting in a potential speedup
(about 1.5% on OpenTitan). The model class now also contains all non
design specific generated code (e.g.: eval loops, trace config, etc),
which additionally simplifies Verilator internals.
Please see the updated documentation for the model interface changes.
2021-06-21 16:30:20 +02:00
|
|
|
puts("bool __Vm_dumping = false; // Dumping is active\n");
|
2020-03-02 03:39:23 +01:00
|
|
|
puts("VerilatedMutex __Vm_dumperMutex; // Protect __Vm_dumperp\n");
|
|
|
|
|
puts(v3Global.opt.traceClassLang()
|
Introduce model interface class, make $root part or Syms (#3036)
This patch implements #3032. Verilator creates a module representing the
SystemVerilog $root scope (V3LinkLevel::wrapTop). Until now, this was
called the "TOP" module, which also acted as the user instantiated model
class. Syms used to hold a pointer to this root module, but hold
instances of any submodule. This patch renames this root scope module
from "TOP" to "$root", and introduces a separate model class which is
now an interface class. As the root module is no longer the user
interface class, it can now be made an instance of Syms, just like any
other submodule. This allows absolute references into the root module to
avoid an additional pointer indirection resulting in a potential speedup
(about 1.5% on OpenTitan). The model class now also contains all non
design specific generated code (e.g.: eval loops, trace config, etc),
which additionally simplifies Verilator internals.
Please see the updated documentation for the model interface changes.
2021-06-21 16:30:20 +02:00
|
|
|
+ "* __Vm_dumperp VL_GUARDED_BY(__Vm_dumperMutex) = nullptr;"
|
|
|
|
|
" /// Trace class for $dump*\n");
|
2020-03-02 03:39:23 +01:00
|
|
|
}
|
2017-09-23 04:27:03 +02:00
|
|
|
if (v3Global.opt.trace()) {
|
Introduce model interface class, make $root part or Syms (#3036)
This patch implements #3032. Verilator creates a module representing the
SystemVerilog $root scope (V3LinkLevel::wrapTop). Until now, this was
called the "TOP" module, which also acted as the user instantiated model
class. Syms used to hold a pointer to this root module, but hold
instances of any submodule. This patch renames this root scope module
from "TOP" to "$root", and introduces a separate model class which is
now an interface class. As the root module is no longer the user
interface class, it can now be made an instance of Syms, just like any
other submodule. This allows absolute references into the root module to
avoid an additional pointer indirection resulting in a potential speedup
(about 1.5% on OpenTitan). The model class now also contains all non
design specific generated code (e.g.: eval loops, trace config, etc),
which additionally simplifies Verilator internals.
Please see the updated documentation for the model interface changes.
2021-06-21 16:30:20 +02:00
|
|
|
puts("bool __Vm_activity = false;"
|
|
|
|
|
" ///< Used by trace routines to determine change occurred\n");
|
|
|
|
|
puts("uint32_t __Vm_baseCode = 0;"
|
|
|
|
|
" ///< Used by trace routines when tracing multiple models\n");
|
|
|
|
|
}
|
2022-05-15 17:03:32 +02:00
|
|
|
if (v3Global.hasEvents()) puts("std::vector<VlEvent*> __Vm_triggeredEvents;\n");
|
2022-09-29 00:54:18 +02:00
|
|
|
if (v3Global.hasClasses()) puts("VlDeleter __Vm_deleter;\n");
|
Introduce model interface class, make $root part or Syms (#3036)
This patch implements #3032. Verilator creates a module representing the
SystemVerilog $root scope (V3LinkLevel::wrapTop). Until now, this was
called the "TOP" module, which also acted as the user instantiated model
class. Syms used to hold a pointer to this root module, but hold
instances of any submodule. This patch renames this root scope module
from "TOP" to "$root", and introduces a separate model class which is
now an interface class. As the root module is no longer the user
interface class, it can now be made an instance of Syms, just like any
other submodule. This allows absolute references into the root module to
avoid an additional pointer indirection resulting in a potential speedup
(about 1.5% on OpenTitan). The model class now also contains all non
design specific generated code (e.g.: eval loops, trace config, etc),
which additionally simplifies Verilator internals.
Please see the updated documentation for the model interface changes.
2021-06-21 16:30:20 +02:00
|
|
|
puts("bool __Vm_didInit = false;\n");
|
|
|
|
|
|
|
|
|
|
if (v3Global.opt.mtasks()) {
|
2022-03-25 20:46:50 +01:00
|
|
|
puts("\n// MULTI-THREADING\n");
|
Introduce model interface class, make $root part or Syms (#3036)
This patch implements #3032. Verilator creates a module representing the
SystemVerilog $root scope (V3LinkLevel::wrapTop). Until now, this was
called the "TOP" module, which also acted as the user instantiated model
class. Syms used to hold a pointer to this root module, but hold
instances of any submodule. This patch renames this root scope module
from "TOP" to "$root", and introduces a separate model class which is
now an interface class. As the root module is no longer the user
interface class, it can now be made an instance of Syms, just like any
other submodule. This allows absolute references into the root module to
avoid an additional pointer indirection resulting in a potential speedup
(about 1.5% on OpenTitan). The model class now also contains all non
design specific generated code (e.g.: eval loops, trace config, etc),
which additionally simplifies Verilator internals.
Please see the updated documentation for the model interface changes.
2021-06-21 16:30:20 +02:00
|
|
|
puts("VlThreadPool* const __Vm_threadPoolp;\n");
|
2022-09-06 15:59:40 +02:00
|
|
|
puts("bool __Vm_even_cycle__ico = false;\n");
|
|
|
|
|
puts("bool __Vm_even_cycle__act = false;\n");
|
|
|
|
|
puts("bool __Vm_even_cycle__nba = false;\n");
|
2017-09-23 04:27:03 +02:00
|
|
|
}
|
2006-08-30 03:14:29 +02:00
|
|
|
|
2022-07-12 12:41:15 +02:00
|
|
|
if (v3Global.opt.profExec()) {
|
|
|
|
|
puts("\n// EXECUTION PROFILING\n");
|
|
|
|
|
puts("VlExecutionProfiler* const __Vm_executionProfilerp;\n");
|
|
|
|
|
}
|
|
|
|
|
|
Introduce model interface class, make $root part or Syms (#3036)
This patch implements #3032. Verilator creates a module representing the
SystemVerilog $root scope (V3LinkLevel::wrapTop). Until now, this was
called the "TOP" module, which also acted as the user instantiated model
class. Syms used to hold a pointer to this root module, but hold
instances of any submodule. This patch renames this root scope module
from "TOP" to "$root", and introduces a separate model class which is
now an interface class. As the root module is no longer the user
interface class, it can now be made an instance of Syms, just like any
other submodule. This allows absolute references into the root module to
avoid an additional pointer indirection resulting in a potential speedup
(about 1.5% on OpenTitan). The model class now also contains all non
design specific generated code (e.g.: eval loops, trace config, etc),
which additionally simplifies Verilator internals.
Please see the updated documentation for the model interface changes.
2021-06-21 16:30:20 +02:00
|
|
|
puts("\n// MODULE INSTANCE STATE\n");
|
2020-10-30 23:00:40 +01:00
|
|
|
for (const auto& i : m_scopes) {
|
2021-11-13 19:50:44 +01:00
|
|
|
const AstScope* const scopep = i.first;
|
|
|
|
|
const AstNodeModule* const modp = i.second;
|
2020-04-05 15:30:23 +02:00
|
|
|
if (VN_IS(modp, Class)) continue;
|
Introduce model interface class, make $root part or Syms (#3036)
This patch implements #3032. Verilator creates a module representing the
SystemVerilog $root scope (V3LinkLevel::wrapTop). Until now, this was
called the "TOP" module, which also acted as the user instantiated model
class. Syms used to hold a pointer to this root module, but hold
instances of any submodule. This patch renames this root scope module
from "TOP" to "$root", and introduces a separate model class which is
now an interface class. As the root module is no longer the user
interface class, it can now be made an instance of Syms, just like any
other submodule. This allows absolute references into the root module to
avoid an additional pointer indirection resulting in a potential speedup
(about 1.5% on OpenTitan). The model class now also contains all non
design specific generated code (e.g.: eval loops, trace config, etc),
which additionally simplifies Verilator internals.
Please see the updated documentation for the model interface changes.
2021-06-21 16:30:20 +02:00
|
|
|
const string name = prefixNameProtect(modp);
|
|
|
|
|
ofp()->printf("%-30s ", name.c_str());
|
|
|
|
|
puts(protectIf(scopep->nameDotless(), scopep->protect()) + ";\n");
|
2006-08-26 13:35:28 +02:00
|
|
|
}
|
|
|
|
|
|
2008-12-05 16:54:14 +01:00
|
|
|
if (m_coverBins) {
|
2019-05-19 22:13:13 +02:00
|
|
|
puts("\n// COVERAGE\n");
|
2020-02-04 00:43:41 +01:00
|
|
|
puts(v3Global.opt.threads() ? "std::atomic<uint32_t>" : "uint32_t");
|
|
|
|
|
puts(" __Vcoverage[");
|
|
|
|
|
puts(cvtToStr(m_coverBins));
|
|
|
|
|
puts("];\n");
|
2008-12-05 16:54:14 +01:00
|
|
|
}
|
|
|
|
|
|
2022-03-25 20:46:50 +01:00
|
|
|
if (v3Global.opt.profPgo()) {
|
|
|
|
|
puts("\n// PGO PROFILING\n");
|
2022-04-10 12:37:41 +02:00
|
|
|
const uint32_t usedMTaskProfilingIDs = v3Global.rootp()->usedMTaskProfilingIDs();
|
|
|
|
|
puts("VlPgoProfiler<" + cvtToStr(usedMTaskProfilingIDs) + "> _vm_pgoProfiler;\n");
|
2021-09-27 04:51:11 +02:00
|
|
|
}
|
|
|
|
|
|
2019-10-02 03:57:45 +02:00
|
|
|
if (!m_scopeNames.empty()) { // Scope names
|
|
|
|
|
puts("\n// SCOPE NAMES\n");
|
2020-11-11 04:10:38 +01:00
|
|
|
for (const auto& itr : m_scopeNames) {
|
|
|
|
|
puts("VerilatedScope " + protect("__Vscope_" + itr.second.m_symName) + ";\n");
|
2019-05-19 22:13:13 +02:00
|
|
|
}
|
2009-12-05 16:38:49 +01:00
|
|
|
}
|
|
|
|
|
|
2019-10-02 03:57:45 +02:00
|
|
|
if (v3Global.opt.vpi()) {
|
|
|
|
|
puts("\n// SCOPE HIERARCHY\n");
|
|
|
|
|
puts("VerilatedHierarchy __Vhier;\n");
|
|
|
|
|
}
|
|
|
|
|
|
Introduce model interface class, make $root part or Syms (#3036)
This patch implements #3032. Verilator creates a module representing the
SystemVerilog $root scope (V3LinkLevel::wrapTop). Until now, this was
called the "TOP" module, which also acted as the user instantiated model
class. Syms used to hold a pointer to this root module, but hold
instances of any submodule. This patch renames this root scope module
from "TOP" to "$root", and introduces a separate model class which is
now an interface class. As the root module is no longer the user
interface class, it can now be made an instance of Syms, just like any
other submodule. This allows absolute references into the root module to
avoid an additional pointer indirection resulting in a potential speedup
(about 1.5% on OpenTitan). The model class now also contains all non
design specific generated code (e.g.: eval loops, trace config, etc),
which additionally simplifies Verilator internals.
Please see the updated documentation for the model interface changes.
2021-06-21 16:30:20 +02:00
|
|
|
puts("\n// CONSTRUCTORS\n");
|
|
|
|
|
puts(symClassName() + "(VerilatedContext* contextp, const char* namep, " + topClassName()
|
|
|
|
|
+ "* modelp);\n");
|
2020-12-17 18:21:40 +01:00
|
|
|
puts(string("~") + symClassName() + "();\n");
|
2006-08-30 23:07:55 +02:00
|
|
|
|
2020-10-30 23:00:40 +01:00
|
|
|
for (const auto& i : m_usesVfinal) {
|
|
|
|
|
puts("void " + symClassName() + "_" + cvtToStr(i.first) + "(");
|
Introduce model interface class, make $root part or Syms (#3036)
This patch implements #3032. Verilator creates a module representing the
SystemVerilog $root scope (V3LinkLevel::wrapTop). Until now, this was
called the "TOP" module, which also acted as the user instantiated model
class. Syms used to hold a pointer to this root module, but hold
instances of any submodule. This patch renames this root scope module
from "TOP" to "$root", and introduces a separate model class which is
now an interface class. As the root module is no longer the user
interface class, it can now be made an instance of Syms, just like any
other submodule. This allows absolute references into the root module to
avoid an additional pointer indirection resulting in a potential speedup
(about 1.5% on OpenTitan). The model class now also contains all non
design specific generated code (e.g.: eval loops, trace config, etc),
which additionally simplifies Verilator internals.
Please see the updated documentation for the model interface changes.
2021-06-21 16:30:20 +02:00
|
|
|
if (i.second) { puts("int __Vfinal"); }
|
2019-09-04 12:15:41 +02:00
|
|
|
puts(");\n");
|
|
|
|
|
}
|
|
|
|
|
|
2006-08-30 03:14:29 +02:00
|
|
|
puts("\n// METHODS\n");
|
Introduce model interface class, make $root part or Syms (#3036)
This patch implements #3032. Verilator creates a module representing the
SystemVerilog $root scope (V3LinkLevel::wrapTop). Until now, this was
called the "TOP" module, which also acted as the user instantiated model
class. Syms used to hold a pointer to this root module, but hold
instances of any submodule. This patch renames this root scope module
from "TOP" to "$root", and introduces a separate model class which is
now an interface class. As the root module is no longer the user
interface class, it can now be made an instance of Syms, just like any
other submodule. This allows absolute references into the root module to
avoid an additional pointer indirection resulting in a potential speedup
(about 1.5% on OpenTitan). The model class now also contains all non
design specific generated code (e.g.: eval loops, trace config, etc),
which additionally simplifies Verilator internals.
Please see the updated documentation for the model interface changes.
2021-06-21 16:30:20 +02:00
|
|
|
puts("const char* name() { return TOP.name(); }\n");
|
|
|
|
|
|
2022-05-15 17:03:32 +02:00
|
|
|
if (v3Global.hasEvents()) {
|
|
|
|
|
puts("void enqueueTriggeredEventForClearing(VlEvent& event) {\n");
|
|
|
|
|
puts("#ifdef VL_DEBUG\n");
|
|
|
|
|
puts("if (VL_UNLIKELY(!event.isTriggered())) {\n");
|
|
|
|
|
puts("VL_FATAL_MT(__FILE__, __LINE__, __FILE__, \"event passed to "
|
|
|
|
|
"'enqueueTriggeredEventForClearing' was not triggered\");\n");
|
|
|
|
|
puts("}\n");
|
|
|
|
|
puts("#endif\n");
|
|
|
|
|
puts("__Vm_triggeredEvents.push_back(&event);\n");
|
|
|
|
|
puts("}\n");
|
|
|
|
|
puts("void clearTriggeredEvents() {\n");
|
|
|
|
|
puts("for (const auto eventp : __Vm_triggeredEvents) eventp->clearTriggered();\n");
|
|
|
|
|
puts("__Vm_triggeredEvents.clear();\n");
|
|
|
|
|
puts("}\n");
|
|
|
|
|
}
|
|
|
|
|
|
Introduce model interface class, make $root part or Syms (#3036)
This patch implements #3032. Verilator creates a module representing the
SystemVerilog $root scope (V3LinkLevel::wrapTop). Until now, this was
called the "TOP" module, which also acted as the user instantiated model
class. Syms used to hold a pointer to this root module, but hold
instances of any submodule. This patch renames this root scope module
from "TOP" to "$root", and introduces a separate model class which is
now an interface class. As the root module is no longer the user
interface class, it can now be made an instance of Syms, just like any
other submodule. This allows absolute references into the root module to
avoid an additional pointer indirection resulting in a potential speedup
(about 1.5% on OpenTitan). The model class now also contains all non
design specific generated code (e.g.: eval loops, trace config, etc),
which additionally simplifies Verilator internals.
Please see the updated documentation for the model interface changes.
2021-06-21 16:30:20 +02:00
|
|
|
if (v3Global.needTraceDumper()) {
|
|
|
|
|
if (!optSystemC()) puts("void _traceDump();\n");
|
|
|
|
|
puts("void _traceDumpOpen();\n");
|
|
|
|
|
puts("void _traceDumpClose();\n");
|
|
|
|
|
}
|
|
|
|
|
|
2020-04-15 01:55:00 +02:00
|
|
|
if (v3Global.opt.savable()) {
|
|
|
|
|
puts("void " + protect("__Vserialize") + "(VerilatedSerialize& os);\n");
|
|
|
|
|
puts("void " + protect("__Vdeserialize") + "(VerilatedDeserialize& os);\n");
|
2012-08-27 03:13:47 +02:00
|
|
|
}
|
2020-02-02 02:28:03 +01:00
|
|
|
puts("} VL_ATTR_ALIGNED(VL_CACHE_LINE_BYTES);\n");
|
2019-12-24 01:00:17 +01:00
|
|
|
|
|
|
|
|
ofp()->putsEndGuard();
|
2020-08-15 16:12:55 +02:00
|
|
|
VL_DO_CLEAR(delete m_ofp, m_ofp = nullptr);
|
2006-08-26 13:35:28 +02:00
|
|
|
}
|
|
|
|
|
|
2019-09-04 12:15:41 +02:00
|
|
|
void EmitCSyms::closeSplit() {
|
|
|
|
|
if (!m_ofp || m_ofp == m_ofpBase) return;
|
|
|
|
|
|
|
|
|
|
puts("}\n");
|
2020-08-15 16:12:55 +02:00
|
|
|
VL_DO_CLEAR(delete m_ofp, m_ofp = nullptr);
|
2019-09-04 12:15:41 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void EmitCSyms::checkSplit(bool usesVfinal) {
|
2020-04-15 01:55:00 +02:00
|
|
|
if (m_ofp
|
|
|
|
|
&& (!v3Global.opt.outputSplitCFuncs() || m_numStmts < v3Global.opt.outputSplitCFuncs())) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
2019-09-04 12:15:41 +02:00
|
|
|
|
2020-05-25 22:12:34 +02:00
|
|
|
// Splitting file, so using parallel build.
|
|
|
|
|
v3Global.useParallelBuild(true);
|
|
|
|
|
|
2019-09-04 12:15:41 +02:00
|
|
|
m_numStmts = 0;
|
2021-11-26 23:55:36 +01:00
|
|
|
const string filename
|
2020-04-15 01:55:00 +02:00
|
|
|
= v3Global.opt.makeDir() + "/" + symClassName() + "__" + cvtToStr(++m_funcNum) + ".cpp";
|
2021-11-13 19:50:44 +01:00
|
|
|
AstCFile* const cfilep = newCFile(filename, true /*slow*/, true /*source*/);
|
2006-08-26 13:35:28 +02:00
|
|
|
cfilep->support(true);
|
2019-09-04 12:15:41 +02:00
|
|
|
m_usesVfinal[m_funcNum] = usesVfinal;
|
|
|
|
|
closeSplit();
|
|
|
|
|
|
2020-04-10 05:03:28 +02:00
|
|
|
if (v3Global.opt.systemC()) {
|
|
|
|
|
m_ofp = new V3OutScFile(filename);
|
|
|
|
|
} else {
|
|
|
|
|
m_ofp = new V3OutCFile(filename);
|
|
|
|
|
}
|
2019-09-04 12:15:41 +02:00
|
|
|
|
2020-04-15 01:55:00 +02:00
|
|
|
m_ofpBase->puts(symClassName() + "_" + cvtToStr(m_funcNum) + "(");
|
Introduce model interface class, make $root part or Syms (#3036)
This patch implements #3032. Verilator creates a module representing the
SystemVerilog $root scope (V3LinkLevel::wrapTop). Until now, this was
called the "TOP" module, which also acted as the user instantiated model
class. Syms used to hold a pointer to this root module, but hold
instances of any submodule. This patch renames this root scope module
from "TOP" to "$root", and introduces a separate model class which is
now an interface class. As the root module is no longer the user
interface class, it can now be made an instance of Syms, just like any
other submodule. This allows absolute references into the root module to
avoid an additional pointer indirection resulting in a potential speedup
(about 1.5% on OpenTitan). The model class now also contains all non
design specific generated code (e.g.: eval loops, trace config, etc),
which additionally simplifies Verilator internals.
Please see the updated documentation for the model interface changes.
2021-06-21 16:30:20 +02:00
|
|
|
if (usesVfinal) { m_ofpBase->puts("__Vfinal"); }
|
2019-09-04 12:15:41 +02:00
|
|
|
m_ofpBase->puts(");\n");
|
|
|
|
|
|
|
|
|
|
emitSymImpPreamble();
|
2020-04-15 01:55:00 +02:00
|
|
|
puts("void " + symClassName() + "::" + symClassName() + "_" + cvtToStr(m_funcNum) + "(");
|
Introduce model interface class, make $root part or Syms (#3036)
This patch implements #3032. Verilator creates a module representing the
SystemVerilog $root scope (V3LinkLevel::wrapTop). Until now, this was
called the "TOP" module, which also acted as the user instantiated model
class. Syms used to hold a pointer to this root module, but hold
instances of any submodule. This patch renames this root scope module
from "TOP" to "$root", and introduces a separate model class which is
now an interface class. As the root module is no longer the user
interface class, it can now be made an instance of Syms, just like any
other submodule. This allows absolute references into the root module to
avoid an additional pointer indirection resulting in a potential speedup
(about 1.5% on OpenTitan). The model class now also contains all non
design specific generated code (e.g.: eval loops, trace config, etc),
which additionally simplifies Verilator internals.
Please see the updated documentation for the model interface changes.
2021-06-21 16:30:20 +02:00
|
|
|
if (usesVfinal) { puts("int __Vfinal"); }
|
2019-09-04 12:15:41 +02:00
|
|
|
puts(") {\n");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void EmitCSyms::emitSymImpPreamble() {
|
2006-08-26 13:35:28 +02:00
|
|
|
ofp()->putsHeader();
|
2020-04-15 01:55:00 +02:00
|
|
|
puts("// DESCR"
|
|
|
|
|
"IPTION: Verilator output: Symbol table implementation internals\n");
|
2006-08-26 13:35:28 +02:00
|
|
|
puts("\n");
|
|
|
|
|
|
|
|
|
|
// Includes
|
2020-04-15 01:55:00 +02:00
|
|
|
puts("#include \"" + symClassName() + ".h\"\n");
|
Introduce model interface class, make $root part or Syms (#3036)
This patch implements #3032. Verilator creates a module representing the
SystemVerilog $root scope (V3LinkLevel::wrapTop). Until now, this was
called the "TOP" module, which also acted as the user instantiated model
class. Syms used to hold a pointer to this root module, but hold
instances of any submodule. This patch renames this root scope module
from "TOP" to "$root", and introduces a separate model class which is
now an interface class. As the root module is no longer the user
interface class, it can now be made an instance of Syms, just like any
other submodule. This allows absolute references into the root module to
avoid an additional pointer indirection resulting in a potential speedup
(about 1.5% on OpenTitan). The model class now also contains all non
design specific generated code (e.g.: eval loops, trace config, etc),
which additionally simplifies Verilator internals.
Please see the updated documentation for the model interface changes.
2021-06-21 16:30:20 +02:00
|
|
|
puts("#include \"" + topClassName() + ".h\"\n");
|
2020-01-25 13:59:25 +01:00
|
|
|
for (AstNodeModule* nodep = v3Global.rootp()->modulesp(); nodep;
|
2021-10-22 14:56:48 +02:00
|
|
|
nodep = VN_AS(nodep->nextp(), NodeModule)) {
|
2020-04-05 15:30:23 +02:00
|
|
|
if (VN_IS(nodep, Class)) continue; // Class included earlier
|
2020-01-25 15:16:00 +01:00
|
|
|
puts("#include \"" + prefixNameProtect(nodep) + ".h\"\n");
|
2006-08-26 13:35:28 +02:00
|
|
|
}
|
2021-06-10 23:41:33 +02:00
|
|
|
puts("\n");
|
|
|
|
|
// Declarations for DPI Export implementation functions
|
|
|
|
|
bool needsNewLine = false;
|
|
|
|
|
for (const auto& pair : m_scopeFuncs) {
|
|
|
|
|
const AstCFunc* const funcp = pair.second.m_cfuncp;
|
|
|
|
|
if (!funcp->dpiExportImpl()) continue;
|
|
|
|
|
emitCFuncDecl(funcp, pair.second.m_modp);
|
|
|
|
|
needsNewLine = true;
|
|
|
|
|
}
|
|
|
|
|
if (needsNewLine) puts("\n");
|
2019-09-04 12:15:41 +02:00
|
|
|
}
|
|
|
|
|
|
2020-12-17 18:21:40 +01:00
|
|
|
void EmitCSyms::emitScopeHier(bool destroy) {
|
|
|
|
|
if (v3Global.opt.vpi()) {
|
2021-06-21 00:32:57 +02:00
|
|
|
const string verb = destroy ? "Tear down" : "Set up";
|
|
|
|
|
const string method = destroy ? "remove" : "add";
|
2020-12-17 18:21:40 +01:00
|
|
|
puts("\n// " + verb + " scope hierarchy\n");
|
|
|
|
|
for (ScopeNames::const_iterator it = m_scopeNames.begin(); it != m_scopeNames.end();
|
|
|
|
|
++it) {
|
2021-06-21 00:32:57 +02:00
|
|
|
const string name = it->second.m_prettyName;
|
2020-12-17 18:21:40 +01:00
|
|
|
if (it->first == "TOP") continue;
|
|
|
|
|
if ((name.find('.') == string::npos) && (it->second.m_type == "SCOPE_MODULE")) {
|
|
|
|
|
puts("__Vhier." + method + "(0, &" + protect("__Vscope_" + it->second.m_symName)
|
|
|
|
|
+ ");\n");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-03-12 23:26:53 +01:00
|
|
|
for (auto it = m_vpiScopeHierarchy.cbegin(); it != m_vpiScopeHierarchy.cend(); ++it) {
|
2020-12-17 18:21:40 +01:00
|
|
|
for (ScopeNameList::const_iterator lit = it->second.begin(); lit != it->second.end();
|
|
|
|
|
++lit) {
|
2021-06-21 00:32:57 +02:00
|
|
|
const string fromname = scopeSymString(it->first);
|
|
|
|
|
const string toname = scopeSymString(*lit);
|
2020-12-17 18:21:40 +01:00
|
|
|
const auto from = vlstd::as_const(m_scopeNames).find(fromname);
|
|
|
|
|
const auto to = vlstd::as_const(m_scopeNames).find(toname);
|
|
|
|
|
UASSERT(from != m_scopeNames.end(), fromname + " not in m_scopeNames");
|
|
|
|
|
UASSERT(to != m_scopeNames.end(), toname + " not in m_scopeNames");
|
|
|
|
|
puts("__Vhier." + method + "(");
|
|
|
|
|
puts("&" + protect("__Vscope_" + from->second.m_symName) + ", ");
|
|
|
|
|
puts("&" + protect("__Vscope_" + to->second.m_symName) + ");\n");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
puts("\n");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-09-04 12:15:41 +02:00
|
|
|
void EmitCSyms::emitSymImp() {
|
2020-04-15 01:55:00 +02:00
|
|
|
UINFO(6, __FUNCTION__ << ": " << endl);
|
2021-06-21 00:32:57 +02:00
|
|
|
const string filename = v3Global.opt.makeDir() + "/" + symClassName() + ".cpp";
|
2021-11-26 23:55:36 +01:00
|
|
|
AstCFile* const cfilep = newCFile(filename, true /*slow*/, true /*source*/);
|
2019-09-04 12:15:41 +02:00
|
|
|
cfilep->support(true);
|
2020-04-10 05:03:28 +02:00
|
|
|
|
|
|
|
|
if (v3Global.opt.systemC()) {
|
|
|
|
|
m_ofp = new V3OutScFile(filename);
|
|
|
|
|
} else {
|
|
|
|
|
m_ofp = new V3OutCFile(filename);
|
|
|
|
|
}
|
|
|
|
|
|
2019-09-04 12:15:41 +02:00
|
|
|
m_ofpBase = m_ofp;
|
|
|
|
|
emitSymImpPreamble();
|
2006-08-26 13:35:28 +02:00
|
|
|
|
2020-04-15 01:55:00 +02:00
|
|
|
if (v3Global.opt.savable()) {
|
2021-07-11 16:42:32 +02:00
|
|
|
for (const bool& de : {false, true}) {
|
2021-06-21 00:32:57 +02:00
|
|
|
const string classname = de ? "VerilatedDeserialize" : "VerilatedSerialize";
|
|
|
|
|
const string funcname = de ? "__Vdeserialize" : "__Vserialize";
|
|
|
|
|
const string op = de ? ">>" : "<<";
|
2019-09-04 12:15:41 +02:00
|
|
|
// NOLINTNEXTLINE(performance-inefficient-string-concatenation)
|
2020-04-15 01:55:00 +02:00
|
|
|
puts("void " + symClassName() + "::" + protect(funcname) + "(" + classname
|
|
|
|
|
+ "& os) {\n");
|
Introduce model interface class, make $root part or Syms (#3036)
This patch implements #3032. Verilator creates a module representing the
SystemVerilog $root scope (V3LinkLevel::wrapTop). Until now, this was
called the "TOP" module, which also acted as the user instantiated model
class. Syms used to hold a pointer to this root module, but hold
instances of any submodule. This patch renames this root scope module
from "TOP" to "$root", and introduces a separate model class which is
now an interface class. As the root module is no longer the user
interface class, it can now be made an instance of Syms, just like any
other submodule. This allows absolute references into the root module to
avoid an additional pointer indirection resulting in a potential speedup
(about 1.5% on OpenTitan). The model class now also contains all non
design specific generated code (e.g.: eval loops, trace config, etc),
which additionally simplifies Verilator internals.
Please see the updated documentation for the model interface changes.
2021-06-21 16:30:20 +02:00
|
|
|
puts("// Internal state\n");
|
2021-02-22 03:25:21 +01:00
|
|
|
if (v3Global.opt.trace()) puts("os" + op + "__Vm_activity;\n");
|
Introduce model interface class, make $root part or Syms (#3036)
This patch implements #3032. Verilator creates a module representing the
SystemVerilog $root scope (V3LinkLevel::wrapTop). Until now, this was
called the "TOP" module, which also acted as the user instantiated model
class. Syms used to hold a pointer to this root module, but hold
instances of any submodule. This patch renames this root scope module
from "TOP" to "$root", and introduces a separate model class which is
now an interface class. As the root module is no longer the user
interface class, it can now be made an instance of Syms, just like any
other submodule. This allows absolute references into the root module to
avoid an additional pointer indirection resulting in a potential speedup
(about 1.5% on OpenTitan). The model class now also contains all non
design specific generated code (e.g.: eval loops, trace config, etc),
which additionally simplifies Verilator internals.
Please see the updated documentation for the model interface changes.
2021-06-21 16:30:20 +02:00
|
|
|
puts("os " + op + " __Vm_didInit;\n");
|
|
|
|
|
puts("// Module instance state\n");
|
|
|
|
|
for (const auto& pair : m_scopes) {
|
|
|
|
|
const AstScope* const scopep = pair.first;
|
|
|
|
|
puts(protectIf(scopep->nameDotless(), scopep->protect()) + "." + protect(funcname)
|
|
|
|
|
+ "(os);\n");
|
2019-09-04 12:15:41 +02:00
|
|
|
}
|
|
|
|
|
puts("}\n");
|
|
|
|
|
}
|
2021-06-10 23:41:33 +02:00
|
|
|
puts("\n");
|
2019-09-04 12:15:41 +02:00
|
|
|
}
|
|
|
|
|
|
2021-06-10 23:41:33 +02:00
|
|
|
puts("// FUNCTIONS\n");
|
2021-09-27 04:51:11 +02:00
|
|
|
|
Introduce model interface class, make $root part or Syms (#3036)
This patch implements #3032. Verilator creates a module representing the
SystemVerilog $root scope (V3LinkLevel::wrapTop). Until now, this was
called the "TOP" module, which also acted as the user instantiated model
class. Syms used to hold a pointer to this root module, but hold
instances of any submodule. This patch renames this root scope module
from "TOP" to "$root", and introduces a separate model class which is
now an interface class. As the root module is no longer the user
interface class, it can now be made an instance of Syms, just like any
other submodule. This allows absolute references into the root module to
avoid an additional pointer indirection resulting in a potential speedup
(about 1.5% on OpenTitan). The model class now also contains all non
design specific generated code (e.g.: eval loops, trace config, etc),
which additionally simplifies Verilator internals.
Please see the updated documentation for the model interface changes.
2021-06-21 16:30:20 +02:00
|
|
|
// Destructor
|
2020-12-17 18:21:40 +01:00
|
|
|
puts(symClassName() + "::~" + symClassName() + "()\n");
|
|
|
|
|
puts("{\n");
|
|
|
|
|
emitScopeHier(true);
|
2020-03-04 01:19:50 +01:00
|
|
|
if (v3Global.needTraceDumper()) {
|
Introduce model interface class, make $root part or Syms (#3036)
This patch implements #3032. Verilator creates a module representing the
SystemVerilog $root scope (V3LinkLevel::wrapTop). Until now, this was
called the "TOP" module, which also acted as the user instantiated model
class. Syms used to hold a pointer to this root module, but hold
instances of any submodule. This patch renames this root scope module
from "TOP" to "$root", and introduces a separate model class which is
now an interface class. As the root module is no longer the user
interface class, it can now be made an instance of Syms, just like any
other submodule. This allows absolute references into the root module to
avoid an additional pointer indirection resulting in a potential speedup
(about 1.5% on OpenTitan). The model class now also contains all non
design specific generated code (e.g.: eval loops, trace config, etc),
which additionally simplifies Verilator internals.
Please see the updated documentation for the model interface changes.
2021-06-21 16:30:20 +02:00
|
|
|
puts("#ifdef VM_TRACE\n");
|
|
|
|
|
puts("if (__Vm_dumping) _traceDumpClose();\n");
|
|
|
|
|
puts("#endif // VM_TRACE\n");
|
2020-05-09 00:42:34 +02:00
|
|
|
}
|
2022-03-25 20:46:50 +01:00
|
|
|
if (v3Global.opt.profPgo()) {
|
|
|
|
|
puts("_vm_pgoProfiler.write(\"" + topClassName()
|
2021-09-27 04:51:11 +02:00
|
|
|
+ "\", _vm_contextp__->profVltFilename());\n");
|
|
|
|
|
}
|
2022-08-26 01:29:11 +02:00
|
|
|
puts("}\n");
|
|
|
|
|
|
|
|
|
|
if (v3Global.needTraceDumper()) {
|
|
|
|
|
if (!optSystemC()) {
|
|
|
|
|
puts("\nvoid " + symClassName() + "::_traceDump() {\n");
|
|
|
|
|
// Caller checked for __Vm_dumperp non-nullptr
|
|
|
|
|
puts("const VerilatedLockGuard lock(__Vm_dumperMutex);\n");
|
|
|
|
|
puts("__Vm_dumperp->dump(VL_TIME_Q());\n");
|
|
|
|
|
puts("}\n");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
puts("\nvoid " + symClassName() + "::_traceDumpOpen() {\n");
|
|
|
|
|
puts("const VerilatedLockGuard lock(__Vm_dumperMutex);\n");
|
|
|
|
|
puts("if (VL_UNLIKELY(!__Vm_dumperp)) {\n");
|
|
|
|
|
puts("__Vm_dumperp = new " + v3Global.opt.traceClassLang() + "();\n");
|
|
|
|
|
puts("__Vm_modelp->trace(__Vm_dumperp, 0, 0);\n");
|
|
|
|
|
puts("std::string dumpfile = _vm_contextp__->dumpfileCheck();\n");
|
|
|
|
|
puts("__Vm_dumperp->open(dumpfile.c_str());\n");
|
|
|
|
|
puts("__Vm_dumping = true;\n");
|
|
|
|
|
puts("}\n");
|
|
|
|
|
puts("}\n");
|
|
|
|
|
|
|
|
|
|
puts("\nvoid " + symClassName() + "::_traceDumpClose() {\n");
|
|
|
|
|
puts("const VerilatedLockGuard lock(__Vm_dumperMutex);\n");
|
|
|
|
|
puts("__Vm_dumping = false;\n");
|
|
|
|
|
puts("VL_DO_CLEAR(delete __Vm_dumperp, __Vm_dumperp = nullptr);\n");
|
|
|
|
|
puts("}\n");
|
|
|
|
|
}
|
|
|
|
|
puts("\n");
|
Introduce model interface class, make $root part or Syms (#3036)
This patch implements #3032. Verilator creates a module representing the
SystemVerilog $root scope (V3LinkLevel::wrapTop). Until now, this was
called the "TOP" module, which also acted as the user instantiated model
class. Syms used to hold a pointer to this root module, but hold
instances of any submodule. This patch renames this root scope module
from "TOP" to "$root", and introduces a separate model class which is
now an interface class. As the root module is no longer the user
interface class, it can now be made an instance of Syms, just like any
other submodule. This allows absolute references into the root module to
avoid an additional pointer indirection resulting in a potential speedup
(about 1.5% on OpenTitan). The model class now also contains all non
design specific generated code (e.g.: eval loops, trace config, etc),
which additionally simplifies Verilator internals.
Please see the updated documentation for the model interface changes.
2021-06-21 16:30:20 +02:00
|
|
|
|
|
|
|
|
// Constructor
|
2022-06-23 02:06:23 +02:00
|
|
|
puts(symClassName() + "::" + symClassName()
|
|
|
|
|
+ "(VerilatedContext* contextp, const char* namep, " + topClassName() + "* modelp)\n");
|
Introduce model interface class, make $root part or Syms (#3036)
This patch implements #3032. Verilator creates a module representing the
SystemVerilog $root scope (V3LinkLevel::wrapTop). Until now, this was
called the "TOP" module, which also acted as the user instantiated model
class. Syms used to hold a pointer to this root module, but hold
instances of any submodule. This patch renames this root scope module
from "TOP" to "$root", and introduces a separate model class which is
now an interface class. As the root module is no longer the user
interface class, it can now be made an instance of Syms, just like any
other submodule. This allows absolute references into the root module to
avoid an additional pointer indirection resulting in a potential speedup
(about 1.5% on OpenTitan). The model class now also contains all non
design specific generated code (e.g.: eval loops, trace config, etc),
which additionally simplifies Verilator internals.
Please see the updated documentation for the model interface changes.
2021-06-21 16:30:20 +02:00
|
|
|
puts(" : VerilatedSyms{contextp}\n");
|
|
|
|
|
puts(" // Setup internal state of the Syms class\n");
|
2021-07-12 00:42:01 +02:00
|
|
|
puts(" , __Vm_modelp{modelp}\n");
|
Introduce model interface class, make $root part or Syms (#3036)
This patch implements #3032. Verilator creates a module representing the
SystemVerilog $root scope (V3LinkLevel::wrapTop). Until now, this was
called the "TOP" module, which also acted as the user instantiated model
class. Syms used to hold a pointer to this root module, but hold
instances of any submodule. This patch renames this root scope module
from "TOP" to "$root", and introduces a separate model class which is
now an interface class. As the root module is no longer the user
interface class, it can now be made an instance of Syms, just like any
other submodule. This allows absolute references into the root module to
avoid an additional pointer indirection resulting in a potential speedup
(about 1.5% on OpenTitan). The model class now also contains all non
design specific generated code (e.g.: eval loops, trace config, etc),
which additionally simplifies Verilator internals.
Please see the updated documentation for the model interface changes.
2021-06-21 16:30:20 +02:00
|
|
|
|
|
|
|
|
if (v3Global.opt.mtasks()) {
|
|
|
|
|
// TODO -- For now each model creates its own ThreadPool here,
|
|
|
|
|
// and deletes it in the destructor. If A and B are each top level
|
|
|
|
|
// modules, each creates a separate thread pool. This allows
|
|
|
|
|
// A.eval() and B.eval() to run concurrently without any
|
|
|
|
|
// interference -- so long as the physical machine has enough cores
|
|
|
|
|
// to support both pools and all testbench threads.
|
|
|
|
|
//
|
|
|
|
|
// In the future, we might want to let the client provide a
|
|
|
|
|
// threadpool to the constructor. This would allow two or more
|
|
|
|
|
// models to share a single threadpool.
|
|
|
|
|
//
|
|
|
|
|
// For example: suppose models A and B are each compiled to run on
|
|
|
|
|
// 4 threads. The client might create a single thread pool with 3
|
|
|
|
|
// threads and pass it to both models. If the client can ensure that
|
|
|
|
|
// A.eval() and B.eval() do NOT run concurrently, there will be no
|
|
|
|
|
// contention for the threads. This mode is missing for now. (Is
|
|
|
|
|
// there demand for such a setup?)
|
|
|
|
|
//
|
|
|
|
|
// Note we create N-1 threads in the thread pool. The thread
|
|
|
|
|
// that calls eval() becomes the final Nth thread for the
|
|
|
|
|
// duration of the eval call.
|
2022-07-12 12:41:15 +02:00
|
|
|
puts(" , __Vm_threadPoolp{static_cast<VlThreadPool*>(contextp->threadPoolp())}\n");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (v3Global.opt.profExec()) {
|
|
|
|
|
puts(" , "
|
|
|
|
|
"__Vm_executionProfilerp{static_cast<VlExecutionProfiler*>(contextp->"
|
|
|
|
|
"enableExecutionProfiler(&VlExecutionProfiler::construct))}\n");
|
Introduce model interface class, make $root part or Syms (#3036)
This patch implements #3032. Verilator creates a module representing the
SystemVerilog $root scope (V3LinkLevel::wrapTop). Until now, this was
called the "TOP" module, which also acted as the user instantiated model
class. Syms used to hold a pointer to this root module, but hold
instances of any submodule. This patch renames this root scope module
from "TOP" to "$root", and introduces a separate model class which is
now an interface class. As the root module is no longer the user
interface class, it can now be made an instance of Syms, just like any
other submodule. This allows absolute references into the root module to
avoid an additional pointer indirection resulting in a potential speedup
(about 1.5% on OpenTitan). The model class now also contains all non
design specific generated code (e.g.: eval loops, trace config, etc),
which additionally simplifies Verilator internals.
Please see the updated documentation for the model interface changes.
2021-06-21 16:30:20 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
puts(" // Setup module instances\n");
|
2020-10-30 23:00:40 +01:00
|
|
|
for (const auto& i : m_scopes) {
|
Introduce model interface class, make $root part or Syms (#3036)
This patch implements #3032. Verilator creates a module representing the
SystemVerilog $root scope (V3LinkLevel::wrapTop). Until now, this was
called the "TOP" module, which also acted as the user instantiated model
class. Syms used to hold a pointer to this root module, but hold
instances of any submodule. This patch renames this root scope module
from "TOP" to "$root", and introduces a separate model class which is
now an interface class. As the root module is no longer the user
interface class, it can now be made an instance of Syms, just like any
other submodule. This allows absolute references into the root module to
avoid an additional pointer indirection resulting in a potential speedup
(about 1.5% on OpenTitan). The model class now also contains all non
design specific generated code (e.g.: eval loops, trace config, etc),
which additionally simplifies Verilator internals.
Please see the updated documentation for the model interface changes.
2021-06-21 16:30:20 +02:00
|
|
|
const AstScope* const scopep = i.first;
|
|
|
|
|
const AstNodeModule* const modp = i.second;
|
|
|
|
|
puts(" , ");
|
|
|
|
|
puts(protect(scopep->nameDotless()));
|
2022-03-27 16:05:24 +02:00
|
|
|
puts("{this");
|
2019-05-19 22:13:13 +02:00
|
|
|
if (modp->isTop()) {
|
2022-03-27 16:05:24 +02:00
|
|
|
puts(", namep");
|
2019-05-19 22:13:13 +02:00
|
|
|
} else {
|
|
|
|
|
// The "." is added by catName
|
2022-03-27 16:05:24 +02:00
|
|
|
puts(", Verilated::catName(namep, ");
|
2019-10-06 19:24:21 +02:00
|
|
|
putsQuoted(protectWordsIf(scopep->prettyName(), scopep->protect()));
|
2022-03-27 16:05:24 +02:00
|
|
|
puts(")");
|
2019-05-19 22:13:13 +02:00
|
|
|
}
|
2022-03-27 16:05:24 +02:00
|
|
|
puts("}\n");
|
Introduce model interface class, make $root part or Syms (#3036)
This patch implements #3032. Verilator creates a module representing the
SystemVerilog $root scope (V3LinkLevel::wrapTop). Until now, this was
called the "TOP" module, which also acted as the user instantiated model
class. Syms used to hold a pointer to this root module, but hold
instances of any submodule. This patch renames this root scope module
from "TOP" to "$root", and introduces a separate model class which is
now an interface class. As the root module is no longer the user
interface class, it can now be made an instance of Syms, just like any
other submodule. This allows absolute references into the root module to
avoid an additional pointer indirection resulting in a potential speedup
(about 1.5% on OpenTitan). The model class now also contains all non
design specific generated code (e.g.: eval loops, trace config, etc),
which additionally simplifies Verilator internals.
Please see the updated documentation for the model interface changes.
2021-06-21 16:30:20 +02:00
|
|
|
++m_numStmts;
|
2006-08-26 13:35:28 +02:00
|
|
|
}
|
|
|
|
|
puts("{\n");
|
|
|
|
|
|
2022-03-25 20:46:50 +01:00
|
|
|
if (v3Global.opt.profPgo()) {
|
|
|
|
|
puts("// Configure profiling for PGO\n");
|
2021-09-27 04:51:11 +02:00
|
|
|
if (v3Global.opt.mtasks()) {
|
2022-04-10 12:37:41 +02:00
|
|
|
v3Global.rootp()->topModulep()->foreach<AstExecGraph>(
|
|
|
|
|
[&](const AstExecGraph* execGraphp) {
|
|
|
|
|
for (const V3GraphVertex* vxp = execGraphp->depGraphp()->verticesBeginp(); vxp;
|
|
|
|
|
vxp = vxp->verticesNextp()) {
|
|
|
|
|
const ExecMTask* const mtp = static_cast<const ExecMTask*>(vxp);
|
|
|
|
|
puts("_vm_pgoProfiler.addCounter(" + cvtToStr(mtp->profilerId()) + ", \""
|
|
|
|
|
+ mtp->hashName() + "\");\n");
|
|
|
|
|
}
|
|
|
|
|
});
|
2021-09-27 04:51:11 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-06-19 18:12:56 +02:00
|
|
|
puts("// Configure time unit / time precision\n");
|
|
|
|
|
if (!v3Global.rootp()->timeunit().isNone()) {
|
|
|
|
|
puts("_vm_contextp__->timeunit(");
|
|
|
|
|
puts(cvtToStr(v3Global.rootp()->timeunit().powerOfTen()));
|
|
|
|
|
puts(");\n");
|
|
|
|
|
}
|
|
|
|
|
if (!v3Global.rootp()->timeprecision().isNone()) {
|
|
|
|
|
puts("_vm_contextp__->timeprecision(");
|
|
|
|
|
puts(cvtToStr(v3Global.rootp()->timeprecision().powerOfTen()));
|
|
|
|
|
puts(");\n");
|
|
|
|
|
}
|
|
|
|
|
|
Introduce model interface class, make $root part or Syms (#3036)
This patch implements #3032. Verilator creates a module representing the
SystemVerilog $root scope (V3LinkLevel::wrapTop). Until now, this was
called the "TOP" module, which also acted as the user instantiated model
class. Syms used to hold a pointer to this root module, but hold
instances of any submodule. This patch renames this root scope module
from "TOP" to "$root", and introduces a separate model class which is
now an interface class. As the root module is no longer the user
interface class, it can now be made an instance of Syms, just like any
other submodule. This allows absolute references into the root module to
avoid an additional pointer indirection resulting in a potential speedup
(about 1.5% on OpenTitan). The model class now also contains all non
design specific generated code (e.g.: eval loops, trace config, etc),
which additionally simplifies Verilator internals.
Please see the updated documentation for the model interface changes.
2021-06-21 16:30:20 +02:00
|
|
|
puts("// Setup each module's pointers to their submodules\n");
|
2020-10-30 23:00:40 +01:00
|
|
|
for (const auto& i : m_scopes) {
|
Introduce model interface class, make $root part or Syms (#3036)
This patch implements #3032. Verilator creates a module representing the
SystemVerilog $root scope (V3LinkLevel::wrapTop). Until now, this was
called the "TOP" module, which also acted as the user instantiated model
class. Syms used to hold a pointer to this root module, but hold
instances of any submodule. This patch renames this root scope module
from "TOP" to "$root", and introduces a separate model class which is
now an interface class. As the root module is no longer the user
interface class, it can now be made an instance of Syms, just like any
other submodule. This allows absolute references into the root module to
avoid an additional pointer indirection resulting in a potential speedup
(about 1.5% on OpenTitan). The model class now also contains all non
design specific generated code (e.g.: eval loops, trace config, etc),
which additionally simplifies Verilator internals.
Please see the updated documentation for the model interface changes.
2021-06-21 16:30:20 +02:00
|
|
|
const AstScope* const scopep = i.first;
|
|
|
|
|
const AstNodeModule* const modp = i.second;
|
|
|
|
|
if (const AstScope* const aboveScopep = scopep->aboveScopep()) {
|
2019-09-04 12:15:41 +02:00
|
|
|
checkSplit(false);
|
Introduce model interface class, make $root part or Syms (#3036)
This patch implements #3032. Verilator creates a module representing the
SystemVerilog $root scope (V3LinkLevel::wrapTop). Until now, this was
called the "TOP" module, which also acted as the user instantiated model
class. Syms used to hold a pointer to this root module, but hold
instances of any submodule. This patch renames this root scope module
from "TOP" to "$root", and introduces a separate model class which is
now an interface class. As the root module is no longer the user
interface class, it can now be made an instance of Syms, just like any
other submodule. This allows absolute references into the root module to
avoid an additional pointer indirection resulting in a potential speedup
(about 1.5% on OpenTitan). The model class now also contains all non
design specific generated code (e.g.: eval loops, trace config, etc),
which additionally simplifies Verilator internals.
Please see the updated documentation for the model interface changes.
2021-06-21 16:30:20 +02:00
|
|
|
const string protName = protectWordsIf(scopep->name(), scopep->protect());
|
|
|
|
|
if (VN_IS(modp, ClassPackage)) {
|
|
|
|
|
// ClassPackage modules seem to be a bit out of place, so hard code...
|
|
|
|
|
puts("TOP");
|
|
|
|
|
} else {
|
|
|
|
|
puts(protectIf(aboveScopep->nameDotless(), aboveScopep->protect()));
|
|
|
|
|
}
|
|
|
|
|
puts(".");
|
2022-07-30 16:01:25 +02:00
|
|
|
puts(protName.substr(protName.rfind('.') + 1));
|
Introduce model interface class, make $root part or Syms (#3036)
This patch implements #3032. Verilator creates a module representing the
SystemVerilog $root scope (V3LinkLevel::wrapTop). Until now, this was
called the "TOP" module, which also acted as the user instantiated model
class. Syms used to hold a pointer to this root module, but hold
instances of any submodule. This patch renames this root scope module
from "TOP" to "$root", and introduces a separate model class which is
now an interface class. As the root module is no longer the user
interface class, it can now be made an instance of Syms, just like any
other submodule. This allows absolute references into the root module to
avoid an additional pointer indirection resulting in a potential speedup
(about 1.5% on OpenTitan). The model class now also contains all non
design specific generated code (e.g.: eval loops, trace config, etc),
which additionally simplifies Verilator internals.
Please see the updated documentation for the model interface changes.
2021-06-21 16:30:20 +02:00
|
|
|
puts(" = &");
|
|
|
|
|
puts(protectIf(scopep->nameDotless(), scopep->protect()) + ";\n");
|
2019-09-04 12:15:41 +02:00
|
|
|
++m_numStmts;
|
2019-05-19 22:13:13 +02:00
|
|
|
}
|
2006-08-26 13:35:28 +02:00
|
|
|
}
|
|
|
|
|
|
Introduce model interface class, make $root part or Syms (#3036)
This patch implements #3032. Verilator creates a module representing the
SystemVerilog $root scope (V3LinkLevel::wrapTop). Until now, this was
called the "TOP" module, which also acted as the user instantiated model
class. Syms used to hold a pointer to this root module, but hold
instances of any submodule. This patch renames this root scope module
from "TOP" to "$root", and introduces a separate model class which is
now an interface class. As the root module is no longer the user
interface class, it can now be made an instance of Syms, just like any
other submodule. This allows absolute references into the root module to
avoid an additional pointer indirection resulting in a potential speedup
(about 1.5% on OpenTitan). The model class now also contains all non
design specific generated code (e.g.: eval loops, trace config, etc),
which additionally simplifies Verilator internals.
Please see the updated documentation for the model interface changes.
2021-06-21 16:30:20 +02:00
|
|
|
puts("// Setup each module's pointer back to symbol table (for public functions)\n");
|
|
|
|
|
for (const auto& i : m_scopes) {
|
2021-11-26 23:55:36 +01:00
|
|
|
AstScope* const scopep = i.first;
|
|
|
|
|
AstNodeModule* const modp = i.second;
|
Introduce model interface class, make $root part or Syms (#3036)
This patch implements #3032. Verilator creates a module representing the
SystemVerilog $root scope (V3LinkLevel::wrapTop). Until now, this was
called the "TOP" module, which also acted as the user instantiated model
class. Syms used to hold a pointer to this root module, but hold
instances of any submodule. This patch renames this root scope module
from "TOP" to "$root", and introduces a separate model class which is
now an interface class. As the root module is no longer the user
interface class, it can now be made an instance of Syms, just like any
other submodule. This allows absolute references into the root module to
avoid an additional pointer indirection resulting in a potential speedup
(about 1.5% on OpenTitan). The model class now also contains all non
design specific generated code (e.g.: eval loops, trace config, etc),
which additionally simplifies Verilator internals.
Please see the updated documentation for the model interface changes.
2021-06-21 16:30:20 +02:00
|
|
|
checkSplit(false);
|
|
|
|
|
// first is used by AstCoverDecl's call to __vlCoverInsert
|
|
|
|
|
const bool first = !modp->user1();
|
|
|
|
|
modp->user1(true);
|
|
|
|
|
puts(protectIf(scopep->nameDotless(), scopep->protect()) + "." + protect("__Vconfigure")
|
2022-03-27 16:05:24 +02:00
|
|
|
+ "(" + (first ? "true" : "false") + ");\n");
|
Introduce model interface class, make $root part or Syms (#3036)
This patch implements #3032. Verilator creates a module representing the
SystemVerilog $root scope (V3LinkLevel::wrapTop). Until now, this was
called the "TOP" module, which also acted as the user instantiated model
class. Syms used to hold a pointer to this root module, but hold
instances of any submodule. This patch renames this root scope module
from "TOP" to "$root", and introduces a separate model class which is
now an interface class. As the root module is no longer the user
interface class, it can now be made an instance of Syms, just like any
other submodule. This allows absolute references into the root module to
avoid an additional pointer indirection resulting in a potential speedup
(about 1.5% on OpenTitan). The model class now also contains all non
design specific generated code (e.g.: eval loops, trace config, etc),
which additionally simplifies Verilator internals.
Please see the updated documentation for the model interface changes.
2021-06-21 16:30:20 +02:00
|
|
|
++m_numStmts;
|
|
|
|
|
}
|
|
|
|
|
|
2019-10-02 03:57:45 +02:00
|
|
|
if (!m_scopeNames.empty()) { // Setup scope names
|
|
|
|
|
puts("// Setup scopes\n");
|
2019-05-19 22:13:13 +02:00
|
|
|
for (ScopeNames::iterator it = m_scopeNames.begin(); it != m_scopeNames.end(); ++it) {
|
2019-09-04 12:15:41 +02:00
|
|
|
checkSplit(false);
|
2020-04-15 01:55:00 +02:00
|
|
|
puts(protect("__Vscope_" + it->second.m_symName) + ".configure(this, name(), ");
|
2019-10-06 19:24:21 +02:00
|
|
|
putsQuoted(protectWordsIf(it->second.m_prettyName, true));
|
2019-10-02 03:57:45 +02:00
|
|
|
puts(", ");
|
2019-10-06 19:24:21 +02:00
|
|
|
putsQuoted(protect(scopeDecodeIdentifier(it->second.m_prettyName)));
|
2020-04-16 01:39:03 +02:00
|
|
|
puts(", ");
|
|
|
|
|
puts(cvtToStr(it->second.m_timeunit));
|
2020-04-15 01:55:00 +02:00
|
|
|
puts(", VerilatedScope::" + it->second.m_type + ");\n");
|
2019-09-04 12:15:41 +02:00
|
|
|
++m_numStmts;
|
2019-05-19 22:13:13 +02:00
|
|
|
}
|
2009-12-05 16:38:49 +01:00
|
|
|
}
|
|
|
|
|
|
2020-12-17 18:21:40 +01:00
|
|
|
emitScopeHier(false);
|
2019-10-02 03:57:45 +02:00
|
|
|
|
2019-09-04 12:15:41 +02:00
|
|
|
// Everything past here is in the __Vfinal loop, so start a new split file if needed
|
|
|
|
|
closeSplit();
|
|
|
|
|
|
2009-12-20 14:27:00 +01:00
|
|
|
if (v3Global.dpi()) {
|
2019-09-04 12:15:41 +02:00
|
|
|
m_ofpBase->puts("// Setup export functions\n");
|
|
|
|
|
m_ofpBase->puts("for (int __Vfinal=0; __Vfinal<2; __Vfinal++) {\n");
|
2021-03-12 23:26:53 +01:00
|
|
|
for (auto it = m_scopeFuncs.begin(); it != m_scopeFuncs.end(); ++it) {
|
2021-11-26 23:55:36 +01:00
|
|
|
AstScopeName* const scopep = it->second.m_scopep;
|
|
|
|
|
AstCFunc* const funcp = it->second.m_cfuncp;
|
|
|
|
|
AstNodeModule* const modp = it->second.m_modp;
|
2021-06-10 23:41:33 +02:00
|
|
|
if (funcp->dpiExportImpl()) {
|
2019-09-04 12:15:41 +02:00
|
|
|
checkSplit(true);
|
2020-04-15 01:55:00 +02:00
|
|
|
puts(protect("__Vscope_" + scopep->scopeSymName()) + ".exportInsert(__Vfinal, ");
|
2019-10-06 19:24:21 +02:00
|
|
|
putsQuoted(funcp->cname()); // Not protected - user asked for import/export
|
2019-05-19 22:13:13 +02:00
|
|
|
puts(", (void*)(&");
|
2020-01-25 15:16:00 +01:00
|
|
|
puts(prefixNameProtect(modp));
|
2021-06-10 23:41:33 +02:00
|
|
|
puts("__");
|
2019-10-06 19:24:21 +02:00
|
|
|
puts(funcp->nameProtect());
|
2019-05-19 22:13:13 +02:00
|
|
|
puts("));\n");
|
2019-09-04 12:15:41 +02:00
|
|
|
++m_numStmts;
|
2019-05-19 22:13:13 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
// It would be less code if each module inserted its own variables.
|
|
|
|
|
// Someday. For now public isn't common.
|
2021-03-12 23:26:53 +01:00
|
|
|
for (auto it = m_scopeVars.begin(); it != m_scopeVars.end(); ++it) {
|
2019-09-04 12:15:41 +02:00
|
|
|
checkSplit(true);
|
2021-11-26 23:55:36 +01:00
|
|
|
AstScope* const scopep = it->second.m_scopep;
|
|
|
|
|
AstVar* const varp = it->second.m_varp;
|
2019-05-19 22:13:13 +02:00
|
|
|
//
|
2021-05-07 13:17:54 +02:00
|
|
|
int pwidth = 1;
|
2019-05-19 22:13:13 +02:00
|
|
|
int pdim = 0;
|
|
|
|
|
int udim = 0;
|
|
|
|
|
string bounds;
|
2021-11-26 23:55:36 +01:00
|
|
|
if (AstBasicDType* const basicp = varp->basicp()) {
|
2019-05-19 22:13:13 +02:00
|
|
|
// Range is always first, it's not in "C" order
|
|
|
|
|
if (basicp->isRanged()) {
|
2020-04-15 01:55:00 +02:00
|
|
|
bounds += " ,";
|
2020-12-07 03:13:56 +01:00
|
|
|
bounds += cvtToStr(basicp->hi());
|
2020-04-15 01:55:00 +02:00
|
|
|
bounds += ",";
|
2020-12-07 03:13:56 +01:00
|
|
|
bounds += cvtToStr(basicp->lo());
|
2019-05-19 22:13:13 +02:00
|
|
|
pdim++;
|
2021-05-07 13:17:54 +02:00
|
|
|
pwidth *= basicp->elements();
|
2019-05-19 22:13:13 +02:00
|
|
|
}
|
2020-04-15 01:55:00 +02:00
|
|
|
for (AstNodeDType* dtypep = varp->dtypep(); dtypep;) {
|
|
|
|
|
dtypep
|
|
|
|
|
= dtypep->skipRefp(); // Skip AstRefDType/AstTypedef, or return same node
|
2021-11-26 23:55:36 +01:00
|
|
|
if (const AstNodeArrayDType* const adtypep = VN_CAST(dtypep, NodeArrayDType)) {
|
2020-04-15 01:55:00 +02:00
|
|
|
bounds += " ,";
|
2021-01-03 04:00:13 +01:00
|
|
|
bounds += cvtToStr(adtypep->left());
|
2020-04-15 01:55:00 +02:00
|
|
|
bounds += ",";
|
2021-01-03 04:00:13 +01:00
|
|
|
bounds += cvtToStr(adtypep->right());
|
2020-04-15 01:55:00 +02:00
|
|
|
if (VN_IS(dtypep, PackArrayDType)) {
|
|
|
|
|
pdim++;
|
2021-05-07 13:17:54 +02:00
|
|
|
pwidth *= adtypep->elementsConst();
|
2020-04-15 01:55:00 +02:00
|
|
|
} else {
|
|
|
|
|
udim++;
|
|
|
|
|
}
|
2019-05-19 22:13:13 +02:00
|
|
|
dtypep = adtypep->subDTypep();
|
2020-04-15 01:55:00 +02:00
|
|
|
} else {
|
|
|
|
|
break; // AstBasicDType - nothing below, 1
|
2019-05-19 22:13:13 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2021-05-07 13:17:54 +02:00
|
|
|
// TODO: actually expose packed arrays as vpiRegArray
|
|
|
|
|
if (pdim > 1 && udim == 0) {
|
|
|
|
|
bounds = ", ";
|
|
|
|
|
bounds += cvtToStr(pwidth - 1);
|
|
|
|
|
bounds += ",0";
|
|
|
|
|
pdim = 1;
|
|
|
|
|
}
|
|
|
|
|
if (pdim > 1 || udim > 1) {
|
2019-05-19 22:13:13 +02:00
|
|
|
puts("//UNSUP "); // VerilatedImp can't deal with >2d or packed arrays
|
|
|
|
|
}
|
2020-04-15 01:55:00 +02:00
|
|
|
puts(protect("__Vscope_" + it->second.m_scopeName) + ".varInsert(__Vfinal,");
|
2019-10-06 19:24:21 +02:00
|
|
|
putsQuoted(protect(it->second.m_varBasePretty));
|
2020-06-13 00:38:01 +02:00
|
|
|
|
|
|
|
|
std::string varName;
|
2021-07-22 19:59:03 +02:00
|
|
|
varName += protectIf(scopep->nameDotless(), scopep->protect()) + ".";
|
|
|
|
|
varName += protect(varp->name());
|
2020-06-13 00:38:01 +02:00
|
|
|
|
2020-06-16 13:07:59 +02:00
|
|
|
if (varp->isParam()) {
|
|
|
|
|
if (varp->vlEnumType() == "VLVT_STRING") {
|
|
|
|
|
puts(", const_cast<void*>(static_cast<const void*>(");
|
2020-08-16 20:55:46 +02:00
|
|
|
puts(varName);
|
2020-06-16 13:07:59 +02:00
|
|
|
puts(".c_str())), ");
|
|
|
|
|
} else {
|
|
|
|
|
puts(", const_cast<void*>(static_cast<const void*>(&(");
|
2020-08-16 20:55:46 +02:00
|
|
|
puts(varName);
|
2020-06-16 13:07:59 +02:00
|
|
|
puts("))), ");
|
|
|
|
|
}
|
2020-06-13 00:38:01 +02:00
|
|
|
} else {
|
2020-06-16 13:07:59 +02:00
|
|
|
puts(", &(");
|
2020-08-16 20:55:46 +02:00
|
|
|
puts(varName);
|
2020-06-16 13:07:59 +02:00
|
|
|
puts("), ");
|
2020-06-13 00:38:01 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
puts(varp->isParam() ? "true" : "false");
|
|
|
|
|
puts(", ");
|
2019-05-19 22:13:13 +02:00
|
|
|
puts(varp->vlEnumType()); // VLVT_UINT32 etc
|
|
|
|
|
puts(",");
|
|
|
|
|
puts(varp->vlEnumDir()); // VLVD_IN etc
|
|
|
|
|
puts(",");
|
2020-04-15 01:55:00 +02:00
|
|
|
puts(cvtToStr(pdim + udim));
|
2019-05-19 22:13:13 +02:00
|
|
|
puts(bounds);
|
|
|
|
|
puts(");\n");
|
2019-09-04 12:15:41 +02:00
|
|
|
++m_numStmts;
|
2019-05-19 22:13:13 +02:00
|
|
|
}
|
2019-09-04 12:15:41 +02:00
|
|
|
m_ofpBase->puts("}\n");
|
2009-12-20 14:27:00 +01:00
|
|
|
}
|
|
|
|
|
|
2019-09-04 12:15:41 +02:00
|
|
|
m_ofpBase->puts("}\n");
|
Introduce model interface class, make $root part or Syms (#3036)
This patch implements #3032. Verilator creates a module representing the
SystemVerilog $root scope (V3LinkLevel::wrapTop). Until now, this was
called the "TOP" module, which also acted as the user instantiated model
class. Syms used to hold a pointer to this root module, but hold
instances of any submodule. This patch renames this root scope module
from "TOP" to "$root", and introduces a separate model class which is
now an interface class. As the root module is no longer the user
interface class, it can now be made an instance of Syms, just like any
other submodule. This allows absolute references into the root module to
avoid an additional pointer indirection resulting in a potential speedup
(about 1.5% on OpenTitan). The model class now also contains all non
design specific generated code (e.g.: eval loops, trace config, etc),
which additionally simplifies Verilator internals.
Please see the updated documentation for the model interface changes.
2021-06-21 16:30:20 +02:00
|
|
|
|
2019-09-04 12:15:41 +02:00
|
|
|
closeSplit();
|
2022-07-04 16:23:31 +02:00
|
|
|
m_ofp = nullptr;
|
|
|
|
|
VL_DO_CLEAR(delete m_ofpBase, m_ofpBase = nullptr);
|
2006-08-26 13:35:28 +02:00
|
|
|
}
|
|
|
|
|
|
2009-12-09 04:12:59 +01:00
|
|
|
//######################################################################
|
|
|
|
|
|
|
|
|
|
void EmitCSyms::emitDpiHdr() {
|
2020-04-15 01:55:00 +02:00
|
|
|
UINFO(6, __FUNCTION__ << ": " << endl);
|
2021-06-21 00:32:57 +02:00
|
|
|
const string filename = v3Global.opt.makeDir() + "/" + topClassName() + "__Dpi.h";
|
2021-11-26 23:55:36 +01:00
|
|
|
AstCFile* const cfilep = newCFile(filename, false /*slow*/, false /*source*/);
|
2009-12-09 04:12:59 +01:00
|
|
|
cfilep->support(true);
|
2020-04-15 01:55:00 +02:00
|
|
|
V3OutCFile hf(filename);
|
2009-12-09 04:12:59 +01:00
|
|
|
m_ofp = &hf;
|
|
|
|
|
|
|
|
|
|
m_ofp->putsHeader();
|
2020-04-15 01:55:00 +02:00
|
|
|
puts("// DESCR"
|
|
|
|
|
"IPTION: Verilator output: Prototypes for DPI import and export functions.\n");
|
2009-12-09 04:12:59 +01:00
|
|
|
puts("//\n");
|
|
|
|
|
puts("// Verilator includes this file in all generated .cpp files that use DPI functions.\n");
|
2020-01-25 02:10:44 +01:00
|
|
|
puts("// Manually include this file where DPI .c import functions are declared to ensure\n");
|
2009-12-09 04:12:59 +01:00
|
|
|
puts("// the C functions match the expectations of the DPI imports.\n");
|
2021-08-24 03:43:54 +02:00
|
|
|
|
|
|
|
|
ofp()->putsGuard();
|
|
|
|
|
|
2009-12-09 04:12:59 +01:00
|
|
|
puts("\n");
|
2011-05-12 12:32:29 +02:00
|
|
|
puts("#include \"svdpi.h\"\n");
|
|
|
|
|
puts("\n");
|
2009-12-09 04:12:59 +01:00
|
|
|
puts("#ifdef __cplusplus\n");
|
|
|
|
|
puts("extern \"C\" {\n");
|
|
|
|
|
puts("#endif\n");
|
|
|
|
|
puts("\n");
|
2012-03-20 21:01:53 +01:00
|
|
|
|
2011-08-05 03:58:45 +02:00
|
|
|
int firstExp = 0;
|
|
|
|
|
int firstImp = 0;
|
2020-08-16 17:43:49 +02:00
|
|
|
for (AstCFunc* nodep : m_dpis) {
|
2021-06-10 23:41:33 +02:00
|
|
|
if (nodep->dpiExportDispatcher()) {
|
2019-05-19 22:13:13 +02:00
|
|
|
if (!firstExp++) puts("\n// DPI EXPORTS\n");
|
2020-12-13 02:22:28 +01:00
|
|
|
putsDecoration("// DPI export" + ifNoProtect(" at " + nodep->fileline()->ascii())
|
|
|
|
|
+ "\n");
|
2020-04-15 01:55:00 +02:00
|
|
|
puts("extern " + nodep->rtnTypeVoid() + " " + nodep->nameProtect() + "("
|
|
|
|
|
+ cFuncArgs(nodep) + ");\n");
|
2021-06-10 23:41:33 +02:00
|
|
|
} else if (nodep->dpiImportPrototype()) {
|
2019-05-19 22:13:13 +02:00
|
|
|
if (!firstImp++) puts("\n// DPI IMPORTS\n");
|
2020-12-13 02:22:28 +01:00
|
|
|
putsDecoration("// DPI import" + ifNoProtect(" at " + nodep->fileline()->ascii())
|
|
|
|
|
+ "\n");
|
2020-04-15 01:55:00 +02:00
|
|
|
puts("extern " + nodep->rtnTypeVoid() + " " + nodep->nameProtect() + "("
|
|
|
|
|
+ cFuncArgs(nodep) + ");\n");
|
2019-05-19 22:13:13 +02:00
|
|
|
}
|
2009-12-09 04:12:59 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
puts("\n");
|
|
|
|
|
puts("#ifdef __cplusplus\n");
|
|
|
|
|
puts("}\n");
|
|
|
|
|
puts("#endif\n");
|
2021-08-24 03:43:54 +02:00
|
|
|
|
|
|
|
|
ofp()->putsEndGuard();
|
2009-12-09 04:12:59 +01:00
|
|
|
}
|
|
|
|
|
|
2009-12-20 14:27:00 +01:00
|
|
|
//######################################################################
|
|
|
|
|
|
|
|
|
|
void EmitCSyms::emitDpiImp() {
|
2020-04-15 01:55:00 +02:00
|
|
|
UINFO(6, __FUNCTION__ << ": " << endl);
|
2021-06-21 00:32:57 +02:00
|
|
|
const string filename = v3Global.opt.makeDir() + "/" + topClassName() + "__Dpi.cpp";
|
2021-11-26 23:55:36 +01:00
|
|
|
AstCFile* const cfilep = newCFile(filename, false /*slow*/, true /*source*/);
|
2009-12-20 14:27:00 +01:00
|
|
|
cfilep->support(true);
|
2020-04-15 01:55:00 +02:00
|
|
|
V3OutCFile hf(filename);
|
2009-12-20 14:27:00 +01:00
|
|
|
m_ofp = &hf;
|
|
|
|
|
|
|
|
|
|
m_ofp->putsHeader();
|
2020-04-15 01:55:00 +02:00
|
|
|
puts("// DESCR"
|
|
|
|
|
"IPTION: Verilator output: Implementation of DPI export functions.\n");
|
2009-12-20 14:27:00 +01:00
|
|
|
puts("//\n");
|
|
|
|
|
puts("// Verilator compiles this file in when DPI functions are used.\n");
|
|
|
|
|
puts("// If you have multiple Verilated designs with the same DPI exported\n");
|
|
|
|
|
puts("// function names, you will get multiple definition link errors from here.\n");
|
|
|
|
|
puts("// This is an unfortunate result of the DPI specification.\n");
|
|
|
|
|
puts("// To solve this, either\n");
|
2020-04-15 01:55:00 +02:00
|
|
|
puts("// 1. Call " + topClassName() + "::{export_function} instead,\n");
|
2009-12-20 14:27:00 +01:00
|
|
|
puts("// and do not even bother to compile this file\n");
|
|
|
|
|
puts("// or 2. Compile all __Dpi.cpp files in the same compiler run,\n");
|
|
|
|
|
puts("// and #ifdefs already inserted here will sort everything out.\n");
|
|
|
|
|
puts("\n");
|
2012-03-20 21:01:53 +01:00
|
|
|
|
2020-04-15 01:55:00 +02:00
|
|
|
puts("#include \"" + topClassName() + "__Dpi.h\"\n");
|
|
|
|
|
puts("#include \"" + topClassName() + ".h\"\n");
|
2009-12-20 14:27:00 +01:00
|
|
|
puts("\n");
|
|
|
|
|
|
2020-08-16 17:43:49 +02:00
|
|
|
for (AstCFunc* nodep : m_dpis) {
|
2021-06-10 23:41:33 +02:00
|
|
|
if (nodep->dpiExportDispatcher()) {
|
2021-03-04 04:53:50 +01:00
|
|
|
// Prevent multi-definition if used by multiple models
|
|
|
|
|
puts("#ifndef VL_DPIDECL_" + nodep->name() + "_\n");
|
|
|
|
|
puts("#define VL_DPIDECL_" + nodep->name() + "_\n");
|
2020-04-15 01:55:00 +02:00
|
|
|
puts(nodep->rtnTypeVoid() + " " + nodep->name() + "(" + cFuncArgs(nodep) + ") {\n");
|
|
|
|
|
puts("// DPI export" + ifNoProtect(" at " + nodep->fileline()->ascii()) + "\n");
|
|
|
|
|
puts("return " + topClassName() + "::" + nodep->name() + "(");
|
2019-05-19 22:13:13 +02:00
|
|
|
string args;
|
2020-04-15 01:55:00 +02:00
|
|
|
for (AstNode* stmtp = nodep->argsp(); stmtp; stmtp = stmtp->nextp()) {
|
2021-11-26 23:55:36 +01:00
|
|
|
if (const AstVar* const portp = VN_CAST(stmtp, Var)) {
|
2019-05-19 22:13:13 +02:00
|
|
|
if (portp->isIO() && !portp->isFuncReturn()) {
|
2020-04-15 01:55:00 +02:00
|
|
|
if (args != "") args += ", ";
|
2019-05-19 22:13:13 +02:00
|
|
|
args += portp->name();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2020-04-15 01:55:00 +02:00
|
|
|
puts(args + ");\n");
|
2019-05-19 22:13:13 +02:00
|
|
|
puts("}\n");
|
|
|
|
|
puts("#endif\n");
|
|
|
|
|
puts("\n");
|
|
|
|
|
}
|
2009-12-20 14:27:00 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2006-08-26 13:35:28 +02:00
|
|
|
//######################################################################
|
|
|
|
|
// EmitC class functions
|
|
|
|
|
|
2019-08-28 03:36:59 +02:00
|
|
|
void V3EmitC::emitcSyms(bool dpiHdrOnly) {
|
2020-04-05 02:08:58 +02:00
|
|
|
UINFO(2, __FUNCTION__ << ": " << endl);
|
|
|
|
|
EmitCSyms(v3Global.rootp(), dpiHdrOnly);
|
2006-08-26 13:35:28 +02:00
|
|
|
}
|