Fix elaboration displays with some `%p` (#6451).
This commit is contained in:
parent
92f30dd28f
commit
46e56ca6fc
2
Changes
2
Changes
|
|
@ -50,7 +50,7 @@ Verilator 5.041 devel
|
|||
* Fix external function declarations with class typedef references (#6433).
|
||||
* Fix internal error on out-of-bounds real array access.
|
||||
* Fix pre/post increments in assertions (#6434).
|
||||
* Fix elaboration displays with `%m` (#6445). [Alex Solomatnikov]
|
||||
* Fix elaboration displays with `%m` and some `%p` (#6445) (#6451). [Alex Solomatnikov]
|
||||
* Fix false unique assertions on `else ;` (#6450). [Don Owen]
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -3606,6 +3606,7 @@ class ConstVisitor final : public VNVisitor {
|
|||
// $accessor_name, ...
|
||||
// # .castFoo is the test VN_IS(object,Foo)
|
||||
// # ,, gets replaced with a , rather than &&
|
||||
// DISABLE_BASE # Turnes off checking Ast's base class treeops
|
||||
// }" # bracket not paren
|
||||
// ,"what to call"
|
||||
//
|
||||
|
|
@ -3920,6 +3921,7 @@ class ConstVisitor final : public VNVisitor {
|
|||
TREEOPA("AstPutcN{$lhsp.castConst, $rhsp.castConst, $thsp.castConst}", "replaceConst(nodep)");
|
||||
TREEOPA("AstSubstrN{$lhsp.castConst, $rhsp.castConst, $thsp.castConst}", "replaceConst(nodep)");
|
||||
TREEOPA("AstCvtPackString{$lhsp.castConst}", "replaceConstString(nodep, VN_AS(nodep->lhsp(), Const)->num().toString())");
|
||||
TREEOP ("AstToStringN{DISABLE_BASE}", "DONE"); // Avoid uniop(const); use matchToStringNConst
|
||||
TREEOP ("AstToStringN{matchToStringNConst(nodep)}", "DONE");
|
||||
// Custom
|
||||
// Implied by AstIsUnbounded::numberOperate: V("AstIsUnbounded{$lhsp.castConst}", "replaceNum(nodep, 0)");
|
||||
|
|
|
|||
|
|
@ -4554,7 +4554,7 @@ class WidthVisitor final : public VNVisitor {
|
|||
} else if (nodep->name() == "atoreal") {
|
||||
fmt = AstAtoN::ATOREAL;
|
||||
} else {
|
||||
V3ERROR_NA;
|
||||
nodep->v3fatalSrc("Bad case");
|
||||
fmt = AstAtoN::ATOI;
|
||||
} // dummy assignment to suppress compiler warning
|
||||
methodOkArguments(nodep, 0, 0);
|
||||
|
|
|
|||
19
src/astgen
19
src/astgen
|
|
@ -21,6 +21,7 @@ class Node:
|
|||
self._subClasses = [] # Initially list, but tuple after completion
|
||||
self._allSuperClasses = None # Computed on demand after completion
|
||||
self._allSubClasses = None # Computed on demand after completion
|
||||
self._disableBase = False # Skip base class const checking
|
||||
self._typeId = None # Concrete type identifier number for leaf classes
|
||||
self._typeIdMin = None # Lowest type identifier number for class
|
||||
self._typeIdMax = None # Highest type identifier number for class
|
||||
|
|
@ -47,6 +48,13 @@ class Node:
|
|||
def isCompleted(self):
|
||||
return isinstance(self._subClasses, tuple)
|
||||
|
||||
@property
|
||||
def disableBase(self):
|
||||
return self._disableBase
|
||||
|
||||
def disableBaseSet(self):
|
||||
self._disableBase = True
|
||||
|
||||
@property
|
||||
def file(self):
|
||||
return self._file
|
||||
|
|
@ -301,11 +309,15 @@ class Cpt:
|
|||
mif = "m_doV"
|
||||
else:
|
||||
self.error("Unknown flag: " + doflag)
|
||||
|
||||
subnodes = re.sub(r',,', '__ESCAPEDCOMMA__', subnodes)
|
||||
for subnode in re.split(r'\s*,\s*', subnodes):
|
||||
subnode = re.sub(r'__ESCAPEDCOMMA__', ',', subnode)
|
||||
if re.match(r'^\$([a-zA-Z0-9]+)$', subnode):
|
||||
continue # "$lhs" is just a comment that this op has a lhs
|
||||
if re.search(r'DISABLE_BASE', subnode):
|
||||
AstNodes[typen].disableBaseSet()
|
||||
return
|
||||
subnodeif = subnode
|
||||
subnodeif = re.sub(r'\$([a-zA-Z0-9]+)\.cast([A-Z][A-Za-z0-9]+)$',
|
||||
r'VN_IS(nodep->\1(),\2)', subnodeif)
|
||||
|
|
@ -464,7 +476,12 @@ class Cpt:
|
|||
for node in AstNodeList:
|
||||
out_for_type_sc = []
|
||||
out_for_type = []
|
||||
classes = list(node.allSuperClasses)
|
||||
if node.disableBase:
|
||||
classes = []
|
||||
out_for_type.extend(" // DISABLE_BASE\n")
|
||||
else:
|
||||
classes = list(node.allSuperClasses)
|
||||
|
||||
classes.append(node)
|
||||
for base in classes:
|
||||
base = base.name
|
||||
|
|
|
|||
|
|
@ -0,0 +1,16 @@
|
|||
#!/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('simulator')
|
||||
|
||||
test.compile()
|
||||
|
||||
test.passes()
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
// 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
|
||||
|
||||
// verilator lint_off WIDTH
|
||||
|
||||
module pipe_id_match #(
|
||||
parameter type ID_T = logic [4:0],
|
||||
parameter ID_T STAGE_IDS[3:0][1:0] = '{default: 1}
|
||||
);
|
||||
generate
|
||||
$info("%m %s:%0d: 4=%0d 2=%0d STAGE_IDS=%p", "test.sv", 25, 4, 2, STAGE_IDS);
|
||||
endgenerate
|
||||
endmodule
|
||||
|
||||
module t #(
|
||||
parameter type ID_T = logic [4:0]
|
||||
);
|
||||
function automatic ID_T [3:0][1:0] gen_stage_ids();
|
||||
for (int unsigned st = 0; st < 4; st++) begin
|
||||
for (int unsigned id = 0; id < 2; id++) begin
|
||||
gen_stage_ids[st][id] = 3 + ((st + 1) * 2) + id - (3 + ((st + 1) * 2) + id < 18 ? 0 : 18);
|
||||
end
|
||||
end
|
||||
endfunction
|
||||
|
||||
localparam ID_T STAGE_IDS[3:0][1:0] = gen_stage_ids();
|
||||
|
||||
pipe_id_match #(
|
||||
.ID_T(ID_T),
|
||||
.STAGE_IDS(STAGE_IDS)
|
||||
) pipe (
|
||||
.*);
|
||||
|
||||
initial $finish;
|
||||
|
||||
endmodule
|
||||
Loading…
Reference in New Issue