Support dotted access to ports of a direct hier_block instance. (#6595)
Accessing the ports of hier_block instances directly under the current hier_block (or top level) work just fine (the heir stub .sv has them), and this can simplify hooking up dotted references into hier blocks: push part of the reference under the hier block into the hier block, and wire it to a port, then resolve the rest of the reference to the port of the instance.
This commit is contained in:
parent
68b227065e
commit
0ead54b17e
|
|
@ -143,8 +143,11 @@ Limitations
|
|||
|
||||
Hierarchy blocks have some limitations, including:
|
||||
|
||||
* The hierarchy block cannot be accessed using dot (.) from the upper
|
||||
module(s) or other hierarchy blocks.
|
||||
* Internals of the hierarchy block cannot be accessed using dot (.) from
|
||||
the upper module(s) or other hierarchy blocks, except that ports of a
|
||||
hierarchy block instance can be accessed from the directly enclosing
|
||||
nested hierarchy block, or from the top level non-hierarchical portions
|
||||
of the design if not a nested hierarchy block.
|
||||
|
||||
* Modport cannot be used at the hierarchical block boundary.
|
||||
|
||||
|
|
|
|||
|
|
@ -729,8 +729,8 @@ public:
|
|||
if (lookupSymp) {
|
||||
if (const AstCell* const cellp = VN_CAST(lookupSymp->nodep(), Cell)) {
|
||||
if (const AstNodeModule* const modp = cellp->modp()) {
|
||||
if (modp->hierBlock()) {
|
||||
refLocationp->v3error("Cannot access inside hierarchical block");
|
||||
if (modp->hierBlock() && !leftname.empty()) {
|
||||
refLocationp->v3error("Cannot access scope inside hierarchical block");
|
||||
} else if (VN_IS(modp, NotFoundModule)) {
|
||||
refLocationp->v3error("Dotted reference to instance that refers to "
|
||||
"missing module/interface: "
|
||||
|
|
@ -3004,6 +3004,22 @@ class LinkDotResolveVisitor final : public VNVisitor {
|
|||
}
|
||||
}
|
||||
|
||||
// Returns true and issues error iff 'varp' cannot be accesed with a VarXRef
|
||||
// in a hier_block given by 'scopeSymp'
|
||||
bool errorHierNonPort(AstVarXRef* refp, AstVar* varp, VSymEnt* scopeSymp) {
|
||||
// OK to access ports on hier_block
|
||||
if (varp->isIO()) return false;
|
||||
// OK if not an instance
|
||||
const AstCell* const cellp = VN_CAST(scopeSymp->nodep(), Cell);
|
||||
if (!cellp) return false;
|
||||
// Ok if not a hier_block
|
||||
const AstNodeModule* const modp = cellp->modp();
|
||||
if (!modp->hierBlock()) return false;
|
||||
// Bad
|
||||
refp->v3error("Cannot access non-port symbols inside hierarchical block");
|
||||
return true;
|
||||
}
|
||||
|
||||
#define LINKDOT_VISIT_START() \
|
||||
VL_RESTORER(m_indent); \
|
||||
++m_indent;
|
||||
|
|
@ -4104,6 +4120,8 @@ class LinkDotResolveVisitor final : public VNVisitor {
|
|||
nodep->varp(varp);
|
||||
updateVarUse(nodep->varp());
|
||||
UINFO(7, indent() << "Resolved " << nodep); // Also prints varp
|
||||
// If found, check if it's ok to access in case it's in a hier_block
|
||||
if (nodep->varp() && errorHierNonPort(nodep, nodep->varp(), dotSymp)) return;
|
||||
if (!nodep->varp()) {
|
||||
nodep->v3error("Can't find definition of "
|
||||
<< AstNode::prettyNameQ(baddot) << " in dotted signal: '"
|
||||
|
|
@ -4130,6 +4148,8 @@ class LinkDotResolveVisitor final : public VNVisitor {
|
|||
VSymEnt* const foundp
|
||||
= m_statep->findSymPrefixed(dotSymp, nodep->name(), baddot, true);
|
||||
AstVarScope* vscp = foundp ? VN_AS(foundp->nodep(), VarScope) : nullptr;
|
||||
// If found, check if it's ok to access in case it's in a hier_block
|
||||
if (vscp && errorHierNonPort(nodep, vscp->varp(), dotSymp)) return;
|
||||
if (!vscp) {
|
||||
nodep->v3error("Can't find varpin scope of "
|
||||
<< AstNode::prettyNameQ(baddot) << " in dotted signal: '"
|
||||
|
|
|
|||
|
|
@ -55,7 +55,9 @@ module t (/*AUTOARG*/
|
|||
|
||||
always_ff @(posedge clk) begin
|
||||
if (out3 != out3_2) $stop;
|
||||
$display("%d out0:%d %d %d %d %d", count, out0, out1, out2, out3, out5, out6);
|
||||
$display("%d %m out0:%d %d %d %d %d", count, out0, out1, out2, out3, out5, out6);
|
||||
$display("%d %m child input ports: %d %d %d", count, i_sub1.in, i_sub2.in, i_sub3.in);
|
||||
$display("%d %m child output ports: %d %d %d", count, i_sub1.out, i_sub2.out, i_sub3.out);
|
||||
if (count == 16) begin
|
||||
if (out6 == 19) begin
|
||||
$write("*-* All Finished *-*\n");
|
||||
|
|
@ -192,8 +194,16 @@ module sub3 #(
|
|||
assign out = out4;
|
||||
/* verilator lint_off REALCVT */
|
||||
sub4 #(.P0(1.6), .P1(3.1), .P3(4.1)) i_sub4_0(.clk(clk), .in(ff), .out(out4)); // incr 2
|
||||
sub4 #(.P0(2.4), .P1(3.1), .P3(5)) i_sub4_1(.clk(clk), .in(ff), .out(out4_2));
|
||||
sub4 #(.P0(2.4), .P1(3.1), .P3(5)) i_sub4_1(.clk(clk), .in(), .out(out4_2));
|
||||
/* verilator lint_on REALCVT */
|
||||
/* verilator lint_off ASSIGNIN */
|
||||
assign i_sub4_1.in = ff; // Hierarchical reference to port of hier_block is OK
|
||||
/* verilator lint_off ASSIGNIN */
|
||||
|
||||
always @(posedge clk) begin
|
||||
$display("%d %m child input ports: %d %d", $time, i_sub4_0.in, i_sub4_1.in);
|
||||
$display("%d %m child output ports: %d %d", $time, i_sub4_0.out, i_sub4_1.out);
|
||||
end
|
||||
endmodule
|
||||
|
||||
module sub4 #(
|
||||
|
|
@ -248,6 +258,10 @@ module sub4 #(
|
|||
$display("in[%d][%d] act:%d exp:%d", i, j, sub5_out[i][j], exp);
|
||||
$stop;
|
||||
end
|
||||
if (i_sub5.out[i][j] != exp) begin
|
||||
$display("in[%d][%d] act:%d exp:%d", i, j, i_sub5.out[i][j], exp);
|
||||
$stop;
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -3,7 +3,15 @@
|
|||
21 | sub0 #(UNPACKED) i_sub0(.clk(clk), .in(8'(count)), .out(out0));
|
||||
| ^~~~~~~~
|
||||
... See the manual at https://verilator.org/verilator_doc.html?v=latest for more assistance.
|
||||
%Error: t/t_hier_block0_bad.v:26:42: Cannot access inside hierarchical block
|
||||
26 | $display("%d %d %d", count, i_sub0.ff, out1);
|
||||
%Error: t/t_hier_block0_bad.v:62:41: Cannot access non-port symbols inside hierarchical block
|
||||
: ... note: In instance 't.i_sub0'
|
||||
62 | $display("%m: i_sub.x: %d", i_sub.x);
|
||||
| ^
|
||||
%Error: t/t_hier_block0_bad.v:26:50: Cannot access non-port symbols inside hierarchical block
|
||||
: ... note: In instance 't'
|
||||
26 | $display("%d i_sub0.ff: %d", count, i_sub0.ff);
|
||||
| ^~
|
||||
%Error: t/t_hier_block0_bad.v:27:63: Cannot access scope inside hierarchical block
|
||||
27 | $display("%d i_sub0.i_sub.out: %d", count, i_sub0.i_sub.out);
|
||||
| ^~~
|
||||
%Error: Exiting due to
|
||||
|
|
|
|||
|
|
@ -22,8 +22,12 @@ module t (/*AUTOARG*/
|
|||
sub1 #(.T(logic[7:0])) i_sub1(.in(out0), .out(out1));
|
||||
|
||||
always_ff @(posedge clk) begin
|
||||
// dotted access under hierarchical block is not allowed
|
||||
$display("%d %d %d", count, i_sub0.ff, out1);
|
||||
// dotted access under hierarchical block is not allowed ...
|
||||
$display("%d i_sub0.ff: %d", count, i_sub0.ff);
|
||||
$display("%d i_sub0.i_sub.out: %d", count, i_sub0.i_sub.out);
|
||||
// ... Except for ports on a dierct hierarchical child
|
||||
$display("%d i_sub0.out: %d", count, i_sub0.out);
|
||||
$display("%d out1: %d", count, out1);
|
||||
if (count == 16) begin
|
||||
if (out1 == 15) begin
|
||||
$write("*-* All Finished *-*\n");
|
||||
|
|
@ -49,6 +53,16 @@ module sub0 #(
|
|||
|
||||
always_ff @(posedge clk) ff <= in;
|
||||
assign out = ff;
|
||||
|
||||
logic [7:0] gg;
|
||||
sub0_sub0 i_sub(.in(ff), .out(gg));
|
||||
|
||||
always_ff @(posedge clk) begin
|
||||
// dotted access under hierarchical block is not allowed ...
|
||||
$display("%m: i_sub.x: %d", i_sub.x);
|
||||
// ... Except for ports on a direct hierarchical child
|
||||
$display("%m: i_sub.out: %d", i_sub.out);
|
||||
end
|
||||
endmodule
|
||||
|
||||
module sub1 #(
|
||||
|
|
@ -56,4 +70,15 @@ module sub1 #(
|
|||
) (
|
||||
input wire T in, output wire T out); `HIER_BLOCK
|
||||
assign out = in;
|
||||
|
||||
sub1_sub #(T) sub(in, out);
|
||||
endmodule
|
||||
|
||||
module sub0_sub0 (
|
||||
input wire [7:0] in,
|
||||
output wire [7:0] out
|
||||
);
|
||||
`HIER_BLOCK
|
||||
wire [7:0] x = in + 1;
|
||||
assign out = x;
|
||||
endmodule
|
||||
|
|
|
|||
Loading…
Reference in New Issue