mirror of
https://github.com/verilator/verilator.git
synced 2026-10-06 18:13:50 +02:00
Fix interface exposure with --public-depth or --trace-depth (#5758).
This commit is contained in:
@@ -293,7 +293,8 @@ class AstNodeModule VL_NOT_FINAL : public AstNode {
|
||||
string m_someInstanceName; // Hierarchical name of some arbitrary instance of this module.
|
||||
// Used for user messages only.
|
||||
string m_libname; // Work library
|
||||
int m_level = 0; // 1=top module, 2=cell off top module, ...
|
||||
int m_depth = 0; // 1=top module, 2=cell off top, shared things low, for -depth options
|
||||
int m_level = 0; // 1=top module, 2=cell off top, shared things have high number
|
||||
VLifetime m_lifetime; // Lifetime
|
||||
VTimescale m_timeunit; // Global time unit
|
||||
VOptionBool m_unconnectedDrive; // State of `unconnected_drive
|
||||
@@ -341,7 +342,9 @@ public:
|
||||
void someInstanceName(const string& name) { m_someInstanceName = name; }
|
||||
bool inLibrary() const { return m_inLibrary; }
|
||||
void inLibrary(bool flag) { m_inLibrary = flag; }
|
||||
void level(int level) { m_level = level; }
|
||||
void depth(int value) { m_depth = value; }
|
||||
int depth() const VL_MT_SAFE { return m_depth; }
|
||||
void level(int value) { m_level = value; }
|
||||
int level() const VL_MT_SAFE { return m_level; }
|
||||
string libname() const { return m_libname; }
|
||||
string prettyLibnameQ() const { return "'" + prettyName(libname()) + "'"; }
|
||||
|
||||
@@ -2419,6 +2419,7 @@ void AstNetlist::createTopScope(AstScope* scopep) {
|
||||
void AstNodeModule::dump(std::ostream& str) const {
|
||||
this->AstNode::dump(str);
|
||||
str << " L" << level();
|
||||
str << " D" << depth();
|
||||
if (modPublic()) str << " [P]";
|
||||
if (inLibrary()) str << " [LIB]";
|
||||
if (dead()) str << " [DEAD]";
|
||||
|
||||
@@ -201,6 +201,7 @@ class V3GraphVertex VL_NOT_FINAL {
|
||||
friend class V3GraphEdge;
|
||||
friend class GraphAcyc;
|
||||
friend class GraphAlgRank;
|
||||
friend class GraphAlgRankDepth;
|
||||
V3ListLinks<V3GraphVertex> m_links; // List links to store instances of this class
|
||||
V3GraphEdge::OList m_outs; // List of outbound edges
|
||||
V3GraphEdge::IList m_ins; // List of inbound edges
|
||||
@@ -382,11 +383,19 @@ public:
|
||||
void stronglyConnected(V3EdgeFuncP edgeFuncp) VL_MT_DISABLED;
|
||||
|
||||
/// Assign an ordering number to all vertexes in a tree.
|
||||
/// For multiple usages of a vertex, get the maximum of all inbound ranks + 1
|
||||
/// All nodes with no inputs will get rank 1
|
||||
/// Side-effect: changes user()
|
||||
void rank(V3EdgeFuncP edgeFuncp) VL_MT_DISABLED;
|
||||
void rank() VL_MT_DISABLED;
|
||||
|
||||
/// Assign an ordering number to all vertexes in a tree.
|
||||
/// For multiple usages of a vertex, get the minimu of all inbound ranks + 1
|
||||
/// All nodes with no inputs will get rank 1
|
||||
/// Side-effect: changes user()
|
||||
void rankMin(V3EdgeFuncP edgeFuncp) VL_MT_DISABLED;
|
||||
void rankMin() VL_MT_DISABLED;
|
||||
|
||||
/// Sort all vertices and edges using the V3GraphVertex::sortCmp() function
|
||||
void sortVertices() VL_MT_DISABLED;
|
||||
/// Sort all edges and edges using the V3GraphEdge::sortCmp() function
|
||||
|
||||
+56
-6
@@ -271,12 +271,9 @@ class GraphAlgRank final : GraphAlg<> {
|
||||
vertex.user(0);
|
||||
}
|
||||
for (V3GraphVertex& vertex : m_graphp->vertices()) {
|
||||
if (!vertex.user()) { //
|
||||
vertexIterate(&vertex, 1);
|
||||
}
|
||||
if (!vertex.user()) vertexIterate(&vertex, 1);
|
||||
}
|
||||
}
|
||||
|
||||
void vertexIterate(V3GraphVertex* vertexp, uint32_t currentRank) {
|
||||
// Assign rank to each unvisited node
|
||||
// If larger rank is found, assign it and loop back through
|
||||
@@ -302,10 +299,63 @@ public:
|
||||
~GraphAlgRank() = default;
|
||||
};
|
||||
|
||||
void V3Graph::rank() { GraphAlgRank{this, &V3GraphEdge::followAlwaysTrue}; }
|
||||
|
||||
void V3Graph::rank() { rank(&V3GraphEdge::followAlwaysTrue); }
|
||||
void V3Graph::rank(V3EdgeFuncP edgeFuncp) { GraphAlgRank{this, edgeFuncp}; }
|
||||
|
||||
//######################################################################
|
||||
//######################################################################
|
||||
// Algorithms - ranking min
|
||||
// Changes user() and rank()
|
||||
|
||||
class GraphAlgRankMin final : GraphAlg<> {
|
||||
void main() {
|
||||
// Rank each vertex, ignoring cutable edges
|
||||
// Vertex::m_user begin: 1 indicates processing, 2 indicates completed
|
||||
// Clear existing ranks
|
||||
for (V3GraphVertex& vertex : m_graphp->vertices()) {
|
||||
vertex.rank(0);
|
||||
vertex.user(0);
|
||||
}
|
||||
for (V3GraphVertex& vertex : m_graphp->vertices()) {
|
||||
if (!vertex.user()) vertexIterate(&vertex);
|
||||
}
|
||||
}
|
||||
uint32_t vertexIterate(V3GraphVertex* vertexp) {
|
||||
// Assign rank to each unvisited node
|
||||
// If we hit a back node make a list of all loops
|
||||
if (vertexp->user() == 1) {
|
||||
m_graphp->loopsMessageCb(vertexp, m_edgeFuncp);
|
||||
return vertexp->rank();
|
||||
}
|
||||
if (vertexp->user()) return vertexp->rank(); // Done earlier
|
||||
vertexp->user(1);
|
||||
vertexp->rank(1); // In case loop
|
||||
// If no input edges, then rank 1 (+ adder)
|
||||
// Otherwise, get minimum from following all inputs.
|
||||
uint32_t minrank = ~0U;
|
||||
for (V3GraphEdge& edge : vertexp->inEdges()) {
|
||||
if (followEdge(&edge)) {
|
||||
const uint32_t nrank = vertexIterate(edge.fromp());
|
||||
minrank = std::min(minrank, nrank);
|
||||
}
|
||||
}
|
||||
if (minrank == ~0U) minrank = 0;
|
||||
vertexp->rank(minrank + vertexp->rankAdder());
|
||||
vertexp->user(2);
|
||||
return vertexp->rank();
|
||||
}
|
||||
|
||||
public:
|
||||
GraphAlgRankMin(V3Graph* graphp, V3EdgeFuncP edgeFuncp)
|
||||
: GraphAlg<>{graphp, edgeFuncp} {
|
||||
main();
|
||||
}
|
||||
~GraphAlgRankMin() = default;
|
||||
};
|
||||
|
||||
void V3Graph::rankMin() { rankMin(&V3GraphEdge::followAlwaysTrue); }
|
||||
void V3Graph::rankMin(V3EdgeFuncP edgeFuncp) { GraphAlgRankMin{this, edgeFuncp}; }
|
||||
|
||||
//######################################################################
|
||||
//######################################################################
|
||||
// Algorithms - report loops
|
||||
|
||||
@@ -205,6 +205,14 @@ class LinkCellsVisitor final : public VNVisitor {
|
||||
modp->level(vvertexp->rank() + 1);
|
||||
}
|
||||
}
|
||||
m_graph.rankMin();
|
||||
for (V3GraphVertex& vtx : m_graph.vertices()) {
|
||||
if (const LinkCellsVertex* const vvertexp = vtx.cast<LinkCellsVertex>()) {
|
||||
// +1 so we leave level 1 for the new wrapper we'll make in a moment
|
||||
AstNodeModule* const modp = vvertexp->modp();
|
||||
modp->depth(vvertexp->rank() + 1);
|
||||
}
|
||||
}
|
||||
if (v3Global.opt.topModule() != "" && !m_topVertexp) {
|
||||
v3error("Specified --top-module '" << v3Global.opt.topModule()
|
||||
<< "' was not found in design.");
|
||||
|
||||
@@ -173,6 +173,7 @@ void V3LinkLevel::wrapTop(AstNetlist* rootp) {
|
||||
// Make the new module first in the list
|
||||
oldmodp->unlinkFrBackWithNext();
|
||||
newmodp->addNext(oldmodp);
|
||||
newmodp->depth(1);
|
||||
newmodp->level(1);
|
||||
newmodp->modPublic(true);
|
||||
newmodp->protect(false);
|
||||
|
||||
+2
-2
@@ -354,7 +354,7 @@ class LinkParseVisitor final : public VNVisitor {
|
||||
} else if (v3Global.opt.publicParams() && nodep->isParam()) {
|
||||
nodep->sigUserRWPublic(true);
|
||||
} else if (m_modp && v3Global.opt.publicDepth()) {
|
||||
if ((m_modp->level() - 1) <= v3Global.opt.publicDepth()) {
|
||||
if ((m_modp->depth() - 1) <= v3Global.opt.publicDepth()) {
|
||||
nodep->sigUserRWPublic(true);
|
||||
} else if (VN_IS(m_modp, Package) && nodep->isParam()) {
|
||||
nodep->sigUserRWPublic(true);
|
||||
@@ -365,7 +365,7 @@ class LinkParseVisitor final : public VNVisitor {
|
||||
// We used modTrace before leveling, and we may now
|
||||
// want to turn it off now that we know the levelizations
|
||||
if (v3Global.opt.traceDepth() && m_modp
|
||||
&& (m_modp->level() - 1) > v3Global.opt.traceDepth()) {
|
||||
&& (m_modp->depth() - 1) > v3Global.opt.traceDepth()) {
|
||||
m_modp->modTrace(false);
|
||||
nodep->trace(false);
|
||||
}
|
||||
|
||||
@@ -1761,6 +1761,9 @@ class ParamTop final : VNDeleter {
|
||||
maxParentLevel = std::max(maxParentLevel, parentp->level());
|
||||
}
|
||||
if (modp->level() <= maxParentLevel) modp->level(maxParentLevel + 1);
|
||||
// Not correct fixup of depth(), as it should be mininum. But depth() is unused
|
||||
// past V3LinkParse, so just do something sane in case this code doesn't get updated
|
||||
modp->depth(modp->level());
|
||||
}
|
||||
|
||||
void resortNetlistModules(AstNetlist* netlistp) {
|
||||
|
||||
Reference in New Issue
Block a user