Fix interface exposure with `--public-depth` or `--trace-depth` (#5758).
This commit is contained in:
parent
d972b7465a
commit
fd12ab3413
1
Changes
1
Changes
|
|
@ -35,6 +35,7 @@ Verilator 5.041 devel
|
||||||
* Optimize constant folding in wide expression expansion (#6381). [Geza Lore]
|
* Optimize constant folding in wide expression expansion (#6381). [Geza Lore]
|
||||||
* Fix missing BLKSEQ when connecting module port to array (#2973).
|
* Fix missing BLKSEQ when connecting module port to array (#2973).
|
||||||
* Fix false CONSTVAR error on initializers (#4992).
|
* Fix false CONSTVAR error on initializers (#4992).
|
||||||
|
* Fix interface exposure with `--public-depth` or `--trace-depth` (#5758).
|
||||||
* Fix cell scoping performance (#6059). [Jerry Tianchen]
|
* Fix cell scoping performance (#6059). [Jerry Tianchen]
|
||||||
* Fix hierarchical `--prof-pgo` (#6213). [Bartłomiej Chmiel, Antmicro Ltd.]
|
* Fix hierarchical `--prof-pgo` (#6213). [Bartłomiej Chmiel, Antmicro Ltd.]
|
||||||
* Fix while loop hang on timing-delayed assignment (#6343) (#6354). [Krzysztof Bieganski, Antmicro Ltd.]
|
* Fix while loop hang on timing-delayed assignment (#6343) (#6354). [Krzysztof Bieganski, Antmicro Ltd.]
|
||||||
|
|
|
||||||
|
|
@ -293,7 +293,8 @@ class AstNodeModule VL_NOT_FINAL : public AstNode {
|
||||||
string m_someInstanceName; // Hierarchical name of some arbitrary instance of this module.
|
string m_someInstanceName; // Hierarchical name of some arbitrary instance of this module.
|
||||||
// Used for user messages only.
|
// Used for user messages only.
|
||||||
string m_libname; // Work library
|
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
|
VLifetime m_lifetime; // Lifetime
|
||||||
VTimescale m_timeunit; // Global time unit
|
VTimescale m_timeunit; // Global time unit
|
||||||
VOptionBool m_unconnectedDrive; // State of `unconnected_drive
|
VOptionBool m_unconnectedDrive; // State of `unconnected_drive
|
||||||
|
|
@ -341,7 +342,9 @@ public:
|
||||||
void someInstanceName(const string& name) { m_someInstanceName = name; }
|
void someInstanceName(const string& name) { m_someInstanceName = name; }
|
||||||
bool inLibrary() const { return m_inLibrary; }
|
bool inLibrary() const { return m_inLibrary; }
|
||||||
void inLibrary(bool flag) { m_inLibrary = flag; }
|
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; }
|
int level() const VL_MT_SAFE { return m_level; }
|
||||||
string libname() const { return m_libname; }
|
string libname() const { return m_libname; }
|
||||||
string prettyLibnameQ() const { return "'" + prettyName(libname()) + "'"; }
|
string prettyLibnameQ() const { return "'" + prettyName(libname()) + "'"; }
|
||||||
|
|
|
||||||
|
|
@ -2419,6 +2419,7 @@ void AstNetlist::createTopScope(AstScope* scopep) {
|
||||||
void AstNodeModule::dump(std::ostream& str) const {
|
void AstNodeModule::dump(std::ostream& str) const {
|
||||||
this->AstNode::dump(str);
|
this->AstNode::dump(str);
|
||||||
str << " L" << level();
|
str << " L" << level();
|
||||||
|
str << " D" << depth();
|
||||||
if (modPublic()) str << " [P]";
|
if (modPublic()) str << " [P]";
|
||||||
if (inLibrary()) str << " [LIB]";
|
if (inLibrary()) str << " [LIB]";
|
||||||
if (dead()) str << " [DEAD]";
|
if (dead()) str << " [DEAD]";
|
||||||
|
|
|
||||||
|
|
@ -201,6 +201,7 @@ class V3GraphVertex VL_NOT_FINAL {
|
||||||
friend class V3GraphEdge;
|
friend class V3GraphEdge;
|
||||||
friend class GraphAcyc;
|
friend class GraphAcyc;
|
||||||
friend class GraphAlgRank;
|
friend class GraphAlgRank;
|
||||||
|
friend class GraphAlgRankDepth;
|
||||||
V3ListLinks<V3GraphVertex> m_links; // List links to store instances of this class
|
V3ListLinks<V3GraphVertex> m_links; // List links to store instances of this class
|
||||||
V3GraphEdge::OList m_outs; // List of outbound edges
|
V3GraphEdge::OList m_outs; // List of outbound edges
|
||||||
V3GraphEdge::IList m_ins; // List of inbound edges
|
V3GraphEdge::IList m_ins; // List of inbound edges
|
||||||
|
|
@ -382,11 +383,19 @@ public:
|
||||||
void stronglyConnected(V3EdgeFuncP edgeFuncp) VL_MT_DISABLED;
|
void stronglyConnected(V3EdgeFuncP edgeFuncp) VL_MT_DISABLED;
|
||||||
|
|
||||||
/// Assign an ordering number to all vertexes in a tree.
|
/// 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
|
/// All nodes with no inputs will get rank 1
|
||||||
/// Side-effect: changes user()
|
/// Side-effect: changes user()
|
||||||
void rank(V3EdgeFuncP edgeFuncp) VL_MT_DISABLED;
|
void rank(V3EdgeFuncP edgeFuncp) VL_MT_DISABLED;
|
||||||
void rank() 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
|
/// Sort all vertices and edges using the V3GraphVertex::sortCmp() function
|
||||||
void sortVertices() VL_MT_DISABLED;
|
void sortVertices() VL_MT_DISABLED;
|
||||||
/// Sort all edges and edges using the V3GraphEdge::sortCmp() function
|
/// Sort all edges and edges using the V3GraphEdge::sortCmp() function
|
||||||
|
|
|
||||||
|
|
@ -271,12 +271,9 @@ class GraphAlgRank final : GraphAlg<> {
|
||||||
vertex.user(0);
|
vertex.user(0);
|
||||||
}
|
}
|
||||||
for (V3GraphVertex& vertex : m_graphp->vertices()) {
|
for (V3GraphVertex& vertex : m_graphp->vertices()) {
|
||||||
if (!vertex.user()) { //
|
if (!vertex.user()) vertexIterate(&vertex, 1);
|
||||||
vertexIterate(&vertex, 1);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void vertexIterate(V3GraphVertex* vertexp, uint32_t currentRank) {
|
void vertexIterate(V3GraphVertex* vertexp, uint32_t currentRank) {
|
||||||
// Assign rank to each unvisited node
|
// Assign rank to each unvisited node
|
||||||
// If larger rank is found, assign it and loop back through
|
// If larger rank is found, assign it and loop back through
|
||||||
|
|
@ -302,10 +299,63 @@ public:
|
||||||
~GraphAlgRank() = default;
|
~GraphAlgRank() = default;
|
||||||
};
|
};
|
||||||
|
|
||||||
void V3Graph::rank() { GraphAlgRank{this, &V3GraphEdge::followAlwaysTrue}; }
|
void V3Graph::rank() { rank(&V3GraphEdge::followAlwaysTrue); }
|
||||||
|
|
||||||
void V3Graph::rank(V3EdgeFuncP edgeFuncp) { GraphAlgRank{this, edgeFuncp}; }
|
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
|
// Algorithms - report loops
|
||||||
|
|
|
||||||
|
|
@ -205,6 +205,14 @@ class LinkCellsVisitor final : public VNVisitor {
|
||||||
modp->level(vvertexp->rank() + 1);
|
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) {
|
if (v3Global.opt.topModule() != "" && !m_topVertexp) {
|
||||||
v3error("Specified --top-module '" << v3Global.opt.topModule()
|
v3error("Specified --top-module '" << v3Global.opt.topModule()
|
||||||
<< "' was not found in design.");
|
<< "' was not found in design.");
|
||||||
|
|
|
||||||
|
|
@ -173,6 +173,7 @@ void V3LinkLevel::wrapTop(AstNetlist* rootp) {
|
||||||
// Make the new module first in the list
|
// Make the new module first in the list
|
||||||
oldmodp->unlinkFrBackWithNext();
|
oldmodp->unlinkFrBackWithNext();
|
||||||
newmodp->addNext(oldmodp);
|
newmodp->addNext(oldmodp);
|
||||||
|
newmodp->depth(1);
|
||||||
newmodp->level(1);
|
newmodp->level(1);
|
||||||
newmodp->modPublic(true);
|
newmodp->modPublic(true);
|
||||||
newmodp->protect(false);
|
newmodp->protect(false);
|
||||||
|
|
|
||||||
|
|
@ -354,7 +354,7 @@ class LinkParseVisitor final : public VNVisitor {
|
||||||
} else if (v3Global.opt.publicParams() && nodep->isParam()) {
|
} else if (v3Global.opt.publicParams() && nodep->isParam()) {
|
||||||
nodep->sigUserRWPublic(true);
|
nodep->sigUserRWPublic(true);
|
||||||
} else if (m_modp && v3Global.opt.publicDepth()) {
|
} 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);
|
nodep->sigUserRWPublic(true);
|
||||||
} else if (VN_IS(m_modp, Package) && nodep->isParam()) {
|
} else if (VN_IS(m_modp, Package) && nodep->isParam()) {
|
||||||
nodep->sigUserRWPublic(true);
|
nodep->sigUserRWPublic(true);
|
||||||
|
|
@ -365,7 +365,7 @@ class LinkParseVisitor final : public VNVisitor {
|
||||||
// We used modTrace before leveling, and we may now
|
// We used modTrace before leveling, and we may now
|
||||||
// want to turn it off now that we know the levelizations
|
// want to turn it off now that we know the levelizations
|
||||||
if (v3Global.opt.traceDepth() && m_modp
|
if (v3Global.opt.traceDepth() && m_modp
|
||||||
&& (m_modp->level() - 1) > v3Global.opt.traceDepth()) {
|
&& (m_modp->depth() - 1) > v3Global.opt.traceDepth()) {
|
||||||
m_modp->modTrace(false);
|
m_modp->modTrace(false);
|
||||||
nodep->trace(false);
|
nodep->trace(false);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1761,6 +1761,9 @@ class ParamTop final : VNDeleter {
|
||||||
maxParentLevel = std::max(maxParentLevel, parentp->level());
|
maxParentLevel = std::max(maxParentLevel, parentp->level());
|
||||||
}
|
}
|
||||||
if (modp->level() <= maxParentLevel) modp->level(maxParentLevel + 1);
|
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) {
|
void resortNetlistModules(AstNetlist* netlistp) {
|
||||||
|
|
|
||||||
|
|
@ -2285,7 +2285,7 @@ class VlTest:
|
||||||
#######################################################################
|
#######################################################################
|
||||||
# File utilities
|
# File utilities
|
||||||
|
|
||||||
def files_identical(self, fn1: str, fn2: str, is_logfile=False) -> None:
|
def files_identical(self, fn1: str, fn2: str, is_logfile=False, strip_hex=False) -> None:
|
||||||
"""Test if two files have identical contents"""
|
"""Test if two files have identical contents"""
|
||||||
delay = 0.25
|
delay = 0.25
|
||||||
for tryn in range(Args.log_retries, -1, -1):
|
for tryn in range(Args.log_retries, -1, -1):
|
||||||
|
|
@ -2294,10 +2294,11 @@ class VlTest:
|
||||||
delay = min(1, delay * 2)
|
delay = min(1, delay * 2)
|
||||||
moretry = tryn != 0
|
moretry = tryn != 0
|
||||||
if not self._files_identical_try(
|
if not self._files_identical_try(
|
||||||
fn1=fn1, fn2=fn2, is_logfile=is_logfile, moretry=moretry):
|
fn1=fn1, fn2=fn2, is_logfile=is_logfile, strip_hex=strip_hex, moretry=moretry):
|
||||||
break
|
break
|
||||||
|
|
||||||
def _files_identical_try(self, fn1: str, fn2: str, is_logfile: bool, moretry: bool) -> bool:
|
def _files_identical_try(self, fn1: str, fn2: str, is_logfile: bool, strip_hex: bool,
|
||||||
|
moretry: bool) -> bool:
|
||||||
# If moretry, then return true to try again
|
# If moretry, then return true to try again
|
||||||
try:
|
try:
|
||||||
f1 = open( # pylint: disable=consider-using-with
|
f1 = open( # pylint: disable=consider-using-with
|
||||||
|
|
@ -2321,6 +2322,7 @@ class VlTest:
|
||||||
fn1=fn1,
|
fn1=fn1,
|
||||||
fn2=fn2,
|
fn2=fn2,
|
||||||
is_logfile=is_logfile,
|
is_logfile=is_logfile,
|
||||||
|
strip_hex=strip_hex,
|
||||||
moretry=moretry)
|
moretry=moretry)
|
||||||
if f1:
|
if f1:
|
||||||
f1.close()
|
f1.close()
|
||||||
|
|
@ -2329,7 +2331,7 @@ class VlTest:
|
||||||
return again
|
return again
|
||||||
|
|
||||||
def _files_identical_reader(self, f1, f2, fn1: str, fn2: str, is_logfile: bool,
|
def _files_identical_reader(self, f1, f2, fn1: str, fn2: str, is_logfile: bool,
|
||||||
moretry: bool) -> None:
|
strip_hex: bool, moretry: bool) -> None:
|
||||||
# If moretry, then return true to try again
|
# If moretry, then return true to try again
|
||||||
l1s = f1.readlines()
|
l1s = f1.readlines()
|
||||||
l2s = f2.readlines() if f2 else []
|
l2s = f2.readlines() if f2 else []
|
||||||
|
|
@ -2377,6 +2379,13 @@ class VlTest:
|
||||||
#
|
#
|
||||||
l1s = l1o
|
l1s = l1o
|
||||||
|
|
||||||
|
if strip_hex:
|
||||||
|
l1o = []
|
||||||
|
for line in l1s:
|
||||||
|
line = re.sub(r'\b0x[0-9a-f]+', '0x#', line)
|
||||||
|
l1o.append(line)
|
||||||
|
l1s = l1o
|
||||||
|
|
||||||
for lineno_m1 in range(0, max(len(l1s), len(l2s))):
|
for lineno_m1 in range(0, max(len(l1s), len(l2s))):
|
||||||
l1 = l1s[lineno_m1] if lineno_m1 < len(l1s) else "*EOF*\n"
|
l1 = l1s[lineno_m1] if lineno_m1 < len(l1s) else "*EOF*\n"
|
||||||
l2 = l2s[lineno_m1] if lineno_m1 < len(l2s) else "*EOF*\n"
|
l2 = l2s[lineno_m1] if lineno_m1 < len(l2s) else "*EOF*\n"
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,43 @@
|
||||||
|
// DESCRIPTION: Verilator: Verilog Test module
|
||||||
|
//
|
||||||
|
// This file ONLY is placed under the Creative Commons Public Domain, for
|
||||||
|
// any use, without warranty, 2025 by Wilson Snyder.
|
||||||
|
// SPDX-License-Identifier: CC0-1.0
|
||||||
|
|
||||||
|
interface AXIS_IF (
|
||||||
|
input logic aclk
|
||||||
|
);
|
||||||
|
logic [127:0] tdata;
|
||||||
|
logic [ 31:0] tuser;
|
||||||
|
logic tvalid, tready;
|
||||||
|
modport master(input aclk, output tdata, tuser, tvalid, input tready);
|
||||||
|
modport slave(input aclk, input tdata, tuser, tvalid, output tready);
|
||||||
|
endinterface : AXIS_IF
|
||||||
|
|
||||||
|
module sub (
|
||||||
|
input clk,
|
||||||
|
AXIS_IF.slave s_axis_if
|
||||||
|
);
|
||||||
|
assign s_axis_if.tready = s_axis_if.tdata[0];
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
module dut (
|
||||||
|
input clk,
|
||||||
|
AXIS_IF.slave s_axis_if
|
||||||
|
);
|
||||||
|
sub u_sub(.*);
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
module t(/*AUTOARG*/
|
||||||
|
// Inputs
|
||||||
|
clk
|
||||||
|
);
|
||||||
|
input clk;
|
||||||
|
AXIS_IF s_axis_if (.aclk(clk));
|
||||||
|
dut u_dut (.clk, .s_axis_if(s_axis_if));
|
||||||
|
initial begin
|
||||||
|
$c("Verilated::scopesDump();");
|
||||||
|
$write("*-* All Finished *-*\n");
|
||||||
|
$finish;
|
||||||
|
end
|
||||||
|
endmodule
|
||||||
|
|
@ -0,0 +1,5 @@
|
||||||
|
scopesDump:
|
||||||
|
SCOPE 0x#: top.TOP
|
||||||
|
SCOPE 0x#: top.t
|
||||||
|
|
||||||
|
*-* All Finished *-*
|
||||||
|
|
@ -0,0 +1,21 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||||
|
#
|
||||||
|
# Copyright 2025 by Wilson Snyder. This program is free software; you
|
||||||
|
# can redistribute it and/or modify it under the terms of either the GNU
|
||||||
|
# Lesser General Public License Version 3 or the Perl Artistic License
|
||||||
|
# Version 2.0.
|
||||||
|
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||||
|
|
||||||
|
import vltest_bootstrap
|
||||||
|
|
||||||
|
test.scenarios('vlt')
|
||||||
|
test.top_filename = "t/t_vpi_public_depthn.v"
|
||||||
|
|
||||||
|
test.compile(verilator_flags2=['--public-depth 1'])
|
||||||
|
|
||||||
|
test.execute()
|
||||||
|
|
||||||
|
test.files_identical(test.run_log_filename, test.golden_filename, is_logfile=True, strip_hex=True)
|
||||||
|
|
||||||
|
test.passes()
|
||||||
|
|
@ -0,0 +1,7 @@
|
||||||
|
scopesDump:
|
||||||
|
SCOPE 0x#: top.TOP
|
||||||
|
SCOPE 0x#: top.t
|
||||||
|
SCOPE 0x#: top.t.s_axis_if
|
||||||
|
SCOPE 0x#: top.t.u_dut
|
||||||
|
|
||||||
|
*-* All Finished *-*
|
||||||
|
|
@ -0,0 +1,21 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||||
|
#
|
||||||
|
# Copyright 2025 by Wilson Snyder. This program is free software; you
|
||||||
|
# can redistribute it and/or modify it under the terms of either the GNU
|
||||||
|
# Lesser General Public License Version 3 or the Perl Artistic License
|
||||||
|
# Version 2.0.
|
||||||
|
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||||
|
|
||||||
|
import vltest_bootstrap
|
||||||
|
|
||||||
|
test.scenarios('vlt')
|
||||||
|
test.top_filename = "t/t_vpi_public_depthn.v"
|
||||||
|
|
||||||
|
test.compile(verilator_flags2=['--public-depth 2'])
|
||||||
|
|
||||||
|
test.execute()
|
||||||
|
|
||||||
|
test.files_identical(test.run_log_filename, test.golden_filename, is_logfile=True, strip_hex=True)
|
||||||
|
|
||||||
|
test.passes()
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
scopesDump:
|
||||||
|
SCOPE 0x#: top.TOP
|
||||||
|
SCOPE 0x#: top.t
|
||||||
|
SCOPE 0x#: top.t.s_axis_if
|
||||||
|
SCOPE 0x#: top.t.u_dut
|
||||||
|
SCOPE 0x#: top.t.u_dut.u_sub
|
||||||
|
|
||||||
|
*-* All Finished *-*
|
||||||
|
|
@ -0,0 +1,21 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||||
|
#
|
||||||
|
# Copyright 2025 by Wilson Snyder. This program is free software; you
|
||||||
|
# can redistribute it and/or modify it under the terms of either the GNU
|
||||||
|
# Lesser General Public License Version 3 or the Perl Artistic License
|
||||||
|
# Version 2.0.
|
||||||
|
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||||
|
|
||||||
|
import vltest_bootstrap
|
||||||
|
|
||||||
|
test.scenarios('vlt')
|
||||||
|
test.top_filename = "t/t_vpi_public_depthn.v"
|
||||||
|
|
||||||
|
test.compile(verilator_flags2=['--public-depth 3'])
|
||||||
|
|
||||||
|
test.execute()
|
||||||
|
|
||||||
|
test.files_identical(test.run_log_filename, test.golden_filename, is_logfile=True, strip_hex=True)
|
||||||
|
|
||||||
|
test.passes()
|
||||||
Loading…
Reference in New Issue