parent
7e55c62cac
commit
d0a5da2445
|
|
@ -1177,7 +1177,6 @@ class AstRefDType final : public AstNodeDType {
|
|||
// @astgen ptr := m_refDTypep : Optional[AstNodeDType] // Data type references
|
||||
// @astgen ptr := m_classOrPackagep : Optional[AstNodeModule] // Class/package defined in
|
||||
string m_name; // Name of an AstTypedef
|
||||
string m_ifacePortName; // Name of pre-dot interface port identifier
|
||||
public:
|
||||
AstRefDType(FileLine* fl, const string& name)
|
||||
: ASTGEN_SUPER_RefDType(fl)
|
||||
|
|
@ -1194,11 +1193,6 @@ public:
|
|||
this->typeofp(typeofp);
|
||||
if (AstNodeDType* const dtp = VN_CAST(typeofp, NodeDType)) refDTypep(dtp);
|
||||
}
|
||||
class FlagIfaceTypedef {};
|
||||
AstRefDType(FileLine* fl, FlagIfaceTypedef, const string& ifc, const string& name)
|
||||
: ASTGEN_SUPER_RefDType(fl)
|
||||
, m_name{name}
|
||||
, m_ifacePortName{ifc} {}
|
||||
ASTGEN_MEMBERS_AstRefDType;
|
||||
// METHODS
|
||||
bool sameNode(const AstNode* samep) const override {
|
||||
|
|
@ -1213,7 +1207,6 @@ public:
|
|||
void dumpJson(std::ostream& str = std::cout) const override;
|
||||
void dumpSmall(std::ostream& str) const override;
|
||||
string name() const override VL_MT_STABLE { return m_name; }
|
||||
string ifacePortName() const { return m_ifacePortName; }
|
||||
string prettyDTypeName(bool full) const override {
|
||||
return subDTypep() ? prettyName(subDTypep()->prettyDTypeName(full)) : prettyName();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2328,14 +2328,10 @@ void AstRefDType::dump(std::ostream& str) const {
|
|||
s_recursing = false;
|
||||
}
|
||||
} else {
|
||||
if (!ifacePortName().empty()) str << " ifcPort=" << ifacePortName();
|
||||
str << " -> UNLINKED";
|
||||
}
|
||||
}
|
||||
void AstRefDType::dumpJson(std::ostream& str) const {
|
||||
if (!ifacePortName().empty()) dumpJsonStr(str, "ifcPortName", ifacePortName());
|
||||
dumpJsonGen(str);
|
||||
}
|
||||
void AstRefDType::dumpJson(std::ostream& str) const { dumpJsonGen(str); }
|
||||
|
||||
void AstRefDType::dumpSmall(std::ostream& str) const {
|
||||
this->AstNodeDType::dumpSmall(str);
|
||||
|
|
|
|||
|
|
@ -5309,18 +5309,18 @@ class LinkDotResolveVisitor final : public VNVisitor {
|
|||
const VSymEnt* foundp;
|
||||
if (nodep->classOrPackagep()) {
|
||||
foundp = m_statep->getNodeSym(nodep->classOrPackagep())->findIdFlat(nodep->name());
|
||||
} else if (!nodep->ifacePortName().empty()) { // Interface typedef
|
||||
nodep->v3error("Unsupported: SystemVerilog 2005 interface typedef");
|
||||
return;
|
||||
} else if (m_ds.m_dotPos == DP_FIRST || m_ds.m_dotPos == DP_NONE) {
|
||||
foundp = m_curSymp->findIdFallback(nodep->name());
|
||||
} else {
|
||||
//foundp = m_curSymp->findIdFlat(nodep->name());
|
||||
// Use dotSymp if set (e.g., for captured interface typedefs), else curSymp
|
||||
VSymEnt* const lookupSymp = m_ds.m_dotSymp ? m_ds.m_dotSymp : m_curSymp;
|
||||
foundp = lookupSymp->findIdFlat(nodep->name());
|
||||
}
|
||||
if (!foundp && ifaceCaptured && capturedTypedefp) {
|
||||
if (ifaceCaptured && capturedTypedefp) {
|
||||
// When we have a captured interface typedef context, use the captured typedef
|
||||
// instead of any local lookup result. This handles the case where the local
|
||||
// typedef has the same name as the interface typedef (e.g., `typedef if0.rq_t
|
||||
// rq_t;`)
|
||||
UINFO(9, indent() << "iface capture binding via captured typedef fallback name="
|
||||
<< nodep->name() << " typedef=" << capturedTypedefp);
|
||||
nodep->typedefp(capturedTypedefp);
|
||||
|
|
|
|||
|
|
@ -390,9 +390,36 @@ class LinkParseVisitor final : public VNVisitor {
|
|||
AstNode* dtypep = nodep->valuep();
|
||||
if (dtypep) {
|
||||
dtypep->unlinkFrBack();
|
||||
// Transform right-associative Dot tree to left-associative
|
||||
// This handles typedef with arrayed interface on first component:
|
||||
// typedef if0[0].x_if0.rq_t my_t;
|
||||
// Grammar produces: DOT(SELBIT, DOT(x_if0, rq_t))
|
||||
// We need: DOT(DOT(SELBIT, x_if0), rq_t)
|
||||
if (AstNodeExpr* exprp = VN_CAST(dtypep, NodeExpr)) {
|
||||
AstDot* dotp = VN_CAST(exprp, Dot);
|
||||
while (dotp) {
|
||||
AstDot* rhsDotp = VN_CAST(dotp->rhsp(), Dot);
|
||||
if (!rhsDotp) break;
|
||||
FileLine* const fl = dotp->fileline();
|
||||
const bool colon = dotp->colon();
|
||||
AstNodeExpr* const lhs = VN_AS(dotp->lhsp()->unlinkFrBack(), NodeExpr);
|
||||
AstNodeExpr* const rhsLhs
|
||||
= VN_AS(rhsDotp->lhsp()->unlinkFrBack(), NodeExpr);
|
||||
AstNodeExpr* const rhsRhs
|
||||
= VN_AS(rhsDotp->rhsp()->unlinkFrBack(), NodeExpr);
|
||||
FileLine* const rhsFl = rhsDotp->fileline();
|
||||
const bool rhsColon = rhsDotp->colon();
|
||||
AstDot* const newLhs = new AstDot{fl, colon, lhs, rhsLhs};
|
||||
exprp = new AstDot{rhsFl, rhsColon, newLhs, rhsRhs};
|
||||
VL_DO_DANGLING(dotp->deleteTree(), dotp);
|
||||
dotp = VN_CAST(exprp, Dot);
|
||||
}
|
||||
dtypep = exprp;
|
||||
}
|
||||
} else {
|
||||
dtypep = new AstVoidDType{nodep->fileline()};
|
||||
}
|
||||
|
||||
AstNode* const newp = new AstParamTypeDType{
|
||||
nodep->fileline(), nodep->varType(),
|
||||
ptypep->fwdType(), nodep->name(),
|
||||
|
|
|
|||
|
|
@ -2495,6 +2495,32 @@ type_declaration<nodep>: // ==IEEE: type_declaration
|
|||
/*cont*/ idAny variable_dimensionListE dtypeAttrListE ';'
|
||||
{ AstNodeDType* const dtp = $2;
|
||||
$$ = GRAMMARP->createTypedef($<fl>3, *$3, $5, dtp, $4); }
|
||||
|
||||
// IEEE 1800-2017 6.18 typedef: dotted or arrayed type identifier
|
||||
// Handles interface typedef references like if0.rq_t and if0[0].rq_t (arrays allowed after first component)
|
||||
| yTYPEDEF idDottedOrArrayed
|
||||
/*cont*/ idAny variable_dimensionListE dtypeAttrListE ';'
|
||||
{ VARRESET_NONLIST(LPARAM);
|
||||
AstParseTypeDType* const ptypep = new AstParseTypeDType{$<fl>2, VFwdType::NONE};
|
||||
VARDTYPE(ptypep);
|
||||
AstVar* const varp = VARDONEA($<fl>3, *$3, $4, $5);
|
||||
// idDottedOrArrayed produces Dot/SelBit tree for hierarchical refs like if0[0].rq_t
|
||||
varp->valuep($2);
|
||||
$$ = varp; }
|
||||
|
||||
// IEEE 1800-2017 6.18 typedef with hierarchical type identifier
|
||||
// Special-case array on first component requiring a '.' after ']' to disambiguate from packed dims
|
||||
// Examples: typedef if0[0].rq_t my_t; typedef if0[0].x_if.rq_t my_t;
|
||||
| yTYPEDEF id '[' expr ']' '.' idDottedSelMore
|
||||
/*cont*/ idAny variable_dimensionListE dtypeAttrListE ';'
|
||||
{ VARRESET_NONLIST(LPARAM);
|
||||
AstParseTypeDType* const ptypep = new AstParseTypeDType{$<fl>2, VFwdType::NONE};
|
||||
VARDTYPE(ptypep);
|
||||
AstVar* const varp = VARDONEA($<fl>8, *$8, $9, $10);
|
||||
AstNodeExpr* const arrp = new AstSelBit{$3, new AstParseRef{$<fl>2, *$2, nullptr, nullptr}, $4};
|
||||
varp->valuep(new AstDot{$6, false, arrp, $7});
|
||||
$$ = varp; }
|
||||
|
||||
| yTYPEDEF packageClassScope idAny packed_dimensionListE
|
||||
/*cont*/ idAny variable_dimensionListE dtypeAttrListE ';'
|
||||
{ AstRefDType* const refp = new AstRefDType{$<fl>3, *$3, $2, nullptr};
|
||||
|
|
@ -2505,20 +2531,36 @@ type_declaration<nodep>: // ==IEEE: type_declaration
|
|||
{ AstRefDType* const refp = new AstRefDType{$<fl>3, *$3, $2, $4};
|
||||
AstNodeDType* const dtp = GRAMMARP->createArray(refp, $5, true);
|
||||
$$ = GRAMMARP->createTypedef($<fl>6, *$6, $8, dtp, $7); }
|
||||
| yTYPEDEF idAny packed_dimensionListE
|
||||
|
||||
// Type alias without packed dimensions: typedef existing_t new_t;
|
||||
| yTYPEDEF idAny idAny variable_dimensionListE dtypeAttrListE ';'
|
||||
{ AstRefDType* const refp = new AstRefDType{$<fl>2, *$2, nullptr, nullptr};
|
||||
$$ = GRAMMARP->createTypedef($<fl>3, *$3, $5, refp, $4); }
|
||||
|
||||
// IEEE 1800-2017 6.18.2 typedef with packed dimensions on an existing type identifier
|
||||
// Disambiguated from interface array access by requiring ':' inside the brackets
|
||||
// (applies to both plain identifiers and type identifiers)
|
||||
| yTYPEDEF id '[' constExpr ':' constExpr ']' packed_dimensionListE
|
||||
/*cont*/ idAny variable_dimensionListE dtypeAttrListE ';'
|
||||
{ AstRefDType* const refp = new AstRefDType{$<fl>2, *$2, nullptr, nullptr};
|
||||
AstNodeDType* const dtp = GRAMMARP->createArray(refp, $3, true);
|
||||
$$ = GRAMMARP->createTypedef($<fl>4, *$4, $6, dtp, $5); }
|
||||
AstNodeRange* const rangep = new AstRange{$3, $4, $6};
|
||||
AstNodeDType* const dtp = GRAMMARP->createArray(refp, addNextNull(rangep, $8), true);
|
||||
$$ = GRAMMARP->createTypedef($<fl>9, *$9, $11, dtp, $10); }
|
||||
|
||||
// Same as above but for type identifiers (parameter types, etc.)
|
||||
| yTYPEDEF idType '[' constExpr ':' constExpr ']' packed_dimensionListE
|
||||
/*cont*/ idAny variable_dimensionListE dtypeAttrListE ';'
|
||||
{ AstRefDType* const refp = new AstRefDType{$<fl>2, *$2, nullptr, nullptr};
|
||||
AstNodeRange* const rangep = new AstRange{$3, $4, $6};
|
||||
AstNodeDType* const dtp = GRAMMARP->createArray(refp, addNextNull(rangep, $8), true);
|
||||
$$ = GRAMMARP->createTypedef($<fl>9, *$9, $11, dtp, $10); }
|
||||
|
||||
| yTYPEDEF idAny parameter_value_assignmentClass packed_dimensionListE
|
||||
/*cont*/ idAny variable_dimensionListE dtypeAttrListE ';'
|
||||
{ AstRefDType* const refp = new AstRefDType{$<fl>2, *$2, nullptr, $3};
|
||||
AstNodeDType* const dtp = GRAMMARP->createArray(refp, $4, true);
|
||||
$$ = GRAMMARP->createTypedef($<fl>5, *$5, $7, dtp, $6); }
|
||||
// //
|
||||
| yTYPEDEF idAny/*interface_port*/ '.' idAny/*type*/ idAny/*type*/ dtypeAttrListE ';'
|
||||
{ AstRefDType* const refp = new AstRefDType{$<fl>2, AstRefDType::FlagIfaceTypedef{}, *$2, *$4};
|
||||
$$ = GRAMMARP->createTypedef($<fl>5, *$5, $6, refp, nullptr); }
|
||||
|
||||
// // idAny as also allows redeclaring same typedef again
|
||||
| yTYPEDEF idAny ';' { $$ = GRAMMARP->createTypedefFwd($<fl>2, *$2, VFwdType::NONE); }
|
||||
// // IEEE: expanded forward_type to prevent conflict
|
||||
|
|
@ -5995,6 +6037,16 @@ idClassSelForeach<nodeExprp>:
|
|||
| packageClassScope idDottedForeach { $$ = new AstDot{$<fl>2, true, $1, $2}; }
|
||||
;
|
||||
|
||||
|
||||
// Dotted identifier for typedef - must have at least one '.'
|
||||
// First component is plain id or id with array index, subsequent components can have arrays
|
||||
idDottedOrArrayed<nodeExprp>:
|
||||
id '.' idArrayed
|
||||
{ $$ = new AstDot{$2, false, new AstParseRef{$<fl>1, *$1, nullptr, nullptr}, $3}; }
|
||||
| idDottedOrArrayed '.' idArrayed
|
||||
{ $$ = new AstDot{$2, false, $1, $3}; }
|
||||
;
|
||||
|
||||
idDotted<nodeExprp>:
|
||||
yD_ROOT '.' idDottedMore
|
||||
{ $$ = new AstDot{$2, false, new AstParseRef{$<fl>1, "$root"}, $3}; }
|
||||
|
|
|
|||
|
|
@ -11,9 +11,7 @@ import vltest_bootstrap
|
|||
|
||||
test.scenarios('simulator_st')
|
||||
|
||||
test.compile(verilator_flags2=['--binary'],
|
||||
fails=test.vlt_all,
|
||||
expect_filename=test.golden_filename)
|
||||
test.compile(verilator_flags2=['--binary'])
|
||||
|
||||
if not test.vlt_all:
|
||||
test.execute()
|
||||
|
|
|
|||
|
|
@ -11,9 +11,7 @@ import vltest_bootstrap
|
|||
|
||||
test.scenarios('simulator_st')
|
||||
|
||||
test.compile(verilator_flags2=['--binary'],
|
||||
fails=test.vlt_all,
|
||||
expect_filename=test.golden_filename)
|
||||
test.compile(verilator_flags2=['--binary'])
|
||||
|
||||
if not test.vlt_all:
|
||||
test.execute()
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
%Error: t/t_interface_typedef3.v:22:11: Unsupported: SystemVerilog 2005 interface typedef
|
||||
%Error: t/t_interface_typedef3.v:22:19: Expecting a data type, not DOT: ''
|
||||
22 | typedef iface_mp.choice_t tdef_t;
|
||||
| ^~~~~~~~
|
||||
| ^
|
||||
... See the manual at https://verilator.org/verilator_doc.html?v=latest for more assistance.
|
||||
%Error: Exiting due to
|
||||
|
|
|
|||
|
|
@ -1,11 +1,14 @@
|
|||
%Error: t/t_interface_typedef_bad.v:15:11: Unsupported: SystemVerilog 2005 interface typedef
|
||||
%Error: t/t_interface_typedef_bad.v:15:11: Can't find definition of scope/variable: 'not_found'
|
||||
15 | typedef not_found.choice_t choice1_t;
|
||||
| ^~~~~~~~~
|
||||
... See the manual at https://verilator.org/verilator_doc.html?v=latest for more assistance.
|
||||
%Error: t/t_interface_typedef_bad.v:16:11: Unsupported: SystemVerilog 2005 interface typedef
|
||||
%Error: t/t_interface_typedef_bad.v:15:20: Expecting a data type, not a constant: 0
|
||||
15 | typedef not_found.choice_t choice1_t;
|
||||
| ^
|
||||
%Error: t/t_interface_typedef_bad.v:16:12: Expecting a data type, not DOT: ''
|
||||
16 | typedef i.not_found_t choice2_t;
|
||||
| ^
|
||||
%Error: t/t_interface_typedef_bad.v:17:11: Unsupported: SystemVerilog 2005 interface typedef
|
||||
| ^
|
||||
%Error: t/t_interface_typedef_bad.v:17:19: Expecting a data type, not MEMBERSEL: 'x_t'
|
||||
17 | typedef not_ifc.x_t choice3_t;
|
||||
| ^~~~~~~
|
||||
| ^~~
|
||||
%Error: Exiting due to
|
||||
|
|
|
|||
|
|
@ -0,0 +1,18 @@
|
|||
#!/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(verilator_flags2=["--binary"])
|
||||
|
||||
test.execute()
|
||||
|
||||
test.passes()
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
// 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
|
||||
//
|
||||
// assign localparam from nested interface typedef
|
||||
//
|
||||
|
||||
interface x_if #(
|
||||
parameter int p_awidth = 4
|
||||
)();
|
||||
typedef struct packed {
|
||||
logic [p_awidth-1:0] addr;
|
||||
} rq_t;
|
||||
endinterface
|
||||
|
||||
interface y_if #(
|
||||
parameter int p_dwidth = 7
|
||||
)();
|
||||
typedef struct packed {
|
||||
logic [p_dwidth-1:0] data;
|
||||
} rs_t;
|
||||
endinterface
|
||||
|
||||
interface z_if #(
|
||||
parameter int p_awidth = 3
|
||||
,parameter int p_dwidth = 9
|
||||
);
|
||||
x_if #(p_awidth) x_if0();
|
||||
y_if #(p_dwidth) y_if0();
|
||||
endinterface
|
||||
|
||||
module top();
|
||||
|
||||
z_if #(.p_awidth(16) ,.p_dwidth(8)) if0();
|
||||
|
||||
localparam type rq_t = if0.x_if0.rq_t;
|
||||
|
||||
rq_t rq;
|
||||
|
||||
initial begin
|
||||
#1;
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
#!/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(verilator_flags2=["--binary"])
|
||||
|
||||
test.execute()
|
||||
|
||||
test.passes()
|
||||
|
|
@ -0,0 +1,55 @@
|
|||
// 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
|
||||
//
|
||||
// assign localparam from interface typedef, single level nesting
|
||||
//
|
||||
|
||||
`define stop $stop
|
||||
`define checkh(gotv,expv) \
|
||||
do if ((gotv) !== (expv)) begin \
|
||||
$write("%%Error: %s:%0d: got=%0h exp=%0h\n", \
|
||||
`__FILE__,`__LINE__, (gotv), (expv)); \
|
||||
`stop; \
|
||||
end while(0);
|
||||
|
||||
interface x_if #(
|
||||
parameter int p_awidth = 4
|
||||
,parameter int p_dwidth = 7
|
||||
)();
|
||||
typedef struct packed {
|
||||
logic [p_awidth-1:0] addr;
|
||||
logic [p_dwidth-1:0] data;
|
||||
} rq_t;
|
||||
|
||||
typedef struct packed {
|
||||
logic [p_dwidth-1:0] data;
|
||||
} rs_t;
|
||||
endinterface
|
||||
|
||||
module top();
|
||||
x_if #(
|
||||
.p_awidth(16)
|
||||
,.p_dwidth(8)
|
||||
) if0();
|
||||
|
||||
typedef if0.rq_t p0_rq_t;
|
||||
|
||||
p0_rq_t rq;
|
||||
|
||||
always_comb begin
|
||||
rq.addr = 'h1234;
|
||||
rq.data = 'h37;
|
||||
end
|
||||
|
||||
initial begin
|
||||
#1;
|
||||
`checkh(rq.addr, 16'h1234);
|
||||
`checkh(rq.data, 8'h37);
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
#!/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(verilator_flags2=["--binary"])
|
||||
|
||||
test.execute()
|
||||
|
||||
test.passes()
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
// 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 x_if #(
|
||||
parameter int a_width = 3
|
||||
)();
|
||||
|
||||
typedef struct packed {
|
||||
logic [a_width-1:0] addr;
|
||||
} rq_t;
|
||||
endinterface
|
||||
|
||||
module top();
|
||||
x_if #(
|
||||
.a_width(8)
|
||||
) if0();
|
||||
|
||||
typedef if0.rq_t p0_t;
|
||||
|
||||
initial begin
|
||||
#1;
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
#!/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(verilator_flags2=["--binary"])
|
||||
|
||||
test.execute()
|
||||
|
||||
test.passes()
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
// 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
|
||||
//
|
||||
// assign localparam from interface typedef, single level nesting
|
||||
//
|
||||
|
||||
`define stop $stop
|
||||
`define checkd(gotv,expv) \
|
||||
do if ((gotv) !== (expv)) begin \
|
||||
$write("%%Error: %s:%0d: got=%0d exp=%0d\n", \
|
||||
`__FILE__,`__LINE__, (gotv), (expv)); \
|
||||
`stop; \
|
||||
end while(0);
|
||||
|
||||
`define checkh(gotv,expv) \
|
||||
do if ((gotv) !== (expv)) begin \
|
||||
$write("%%Error: %s:%0d: got=%0h exp=%0h\n", \
|
||||
`__FILE__,`__LINE__, (gotv), (expv)); \
|
||||
`stop; \
|
||||
end while(0);
|
||||
|
||||
interface x_if #(
|
||||
parameter int p_awidth = 4
|
||||
,parameter int p_dwidth = 7
|
||||
)();
|
||||
localparam int Bits = p_awidth + p_dwidth;
|
||||
typedef struct packed {
|
||||
logic [p_awidth-1:0] addr;
|
||||
logic [p_dwidth-1:0] data;
|
||||
} rq_t;
|
||||
endinterface
|
||||
|
||||
interface y_if #(
|
||||
parameter int p_awidth = 4
|
||||
,parameter int p_dwidth = 7
|
||||
)();
|
||||
x_if #(.p_awidth(p_awidth), .p_dwidth(p_dwidth)) x_if_a[2] ();
|
||||
endinterface
|
||||
|
||||
module top();
|
||||
y_if #(
|
||||
.p_awidth(16)
|
||||
,.p_dwidth(8)
|
||||
) y_if0 ();
|
||||
|
||||
typedef y_if0.x_if_a[0].rq_t rq_t;
|
||||
|
||||
rq_t rq;
|
||||
|
||||
always_comb begin
|
||||
rq.addr = 'h1234;
|
||||
rq.data = 'h37;
|
||||
end
|
||||
|
||||
initial begin
|
||||
#1;
|
||||
`checkh(rq.addr,16'h1234);
|
||||
`checkh(rq.data,8'h37);
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
#!/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(verilator_flags2=["--binary"])
|
||||
|
||||
test.execute()
|
||||
|
||||
test.passes()
|
||||
|
|
@ -0,0 +1,82 @@
|
|||
// 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
|
||||
//
|
||||
// assign localparam from interface typedef, single level nesting
|
||||
//
|
||||
|
||||
`define stop $stop
|
||||
`define checkd(gotv,expv) \
|
||||
do if ((gotv) !== (expv)) begin \
|
||||
$write("%%Error: %s:%0d: got=%0d exp=%0d\n", \
|
||||
`__FILE__,`__LINE__, (gotv), (expv)); \
|
||||
`stop; \
|
||||
end while(0);
|
||||
|
||||
`define checkh(gotv,expv) \
|
||||
do if ((gotv) !== (expv)) begin \
|
||||
$write("%%Error: %s:%0d: got=%0h exp=%0h\n", \
|
||||
`__FILE__,`__LINE__, (gotv), (expv)); \
|
||||
`stop; \
|
||||
end while(0);
|
||||
|
||||
interface x_if #(
|
||||
parameter int p_awidth = 4
|
||||
)();
|
||||
typedef struct packed {
|
||||
logic [p_awidth-1:0] addr;
|
||||
} rq_t;
|
||||
endinterface
|
||||
|
||||
interface y_if #(
|
||||
parameter int p_dwidth = 7
|
||||
)();
|
||||
typedef struct packed {
|
||||
logic [p_dwidth-1:0] data;
|
||||
} rs_t;
|
||||
endinterface
|
||||
|
||||
interface z_if #(
|
||||
parameter int p_awidth = 3
|
||||
,parameter int p_dwidth = 9
|
||||
);
|
||||
x_if #(p_awidth) x_if0();
|
||||
y_if #(p_dwidth) y_if0();
|
||||
endinterface
|
||||
|
||||
module a_top(
|
||||
z_if z_if0
|
||||
);
|
||||
typedef z_if0.x_if0.rq_t rq_t;
|
||||
typedef z_if0.y_if0.rs_t rs_t;
|
||||
|
||||
rq_t rq;
|
||||
rs_t rs;
|
||||
|
||||
always_comb begin
|
||||
rq.addr = 'h1234;
|
||||
rs.data = 'ha5;
|
||||
end
|
||||
|
||||
initial begin
|
||||
#1;
|
||||
`checkh(rq.addr,16'h1234);
|
||||
`checkh(rs.data,8'ha5);
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
||||
module top();
|
||||
z_if #(.p_awidth(16) ,.p_dwidth(8)) z_if0();
|
||||
|
||||
a_top a_top(z_if0);
|
||||
|
||||
initial begin
|
||||
#1;
|
||||
#1;
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
#!/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(verilator_flags2=["--binary"])
|
||||
|
||||
test.execute()
|
||||
|
||||
test.passes()
|
||||
|
|
@ -0,0 +1,70 @@
|
|||
// 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
|
||||
//
|
||||
// assign localparam from interface typedef, single level nesting
|
||||
//
|
||||
|
||||
`define stop $stop
|
||||
`define checkd(gotv,expv) \
|
||||
do if ((gotv) !== (expv)) begin \
|
||||
$write("%%Error: %s:%0d: got=%0d exp=%0d\n", \
|
||||
`__FILE__,`__LINE__, (gotv), (expv)); \
|
||||
`stop; \
|
||||
end while(0);
|
||||
|
||||
`define checkh(gotv,expv) \
|
||||
do if ((gotv) !== (expv)) begin \
|
||||
$write("%%Error: %s:%0d: got=%0h exp=%0h\n", \
|
||||
`__FILE__,`__LINE__, (gotv), (expv)); \
|
||||
`stop; \
|
||||
end while(0);
|
||||
|
||||
interface x_if #(
|
||||
parameter int p_awidth = 4
|
||||
)();
|
||||
typedef struct packed {
|
||||
logic [p_awidth-1:0] addr;
|
||||
} rq_t;
|
||||
endinterface
|
||||
|
||||
interface y_if #(
|
||||
parameter int p_dwidth = 7
|
||||
)();
|
||||
typedef struct packed {
|
||||
logic [p_dwidth-1:0] data;
|
||||
} rs_t;
|
||||
endinterface
|
||||
|
||||
interface z_if #(
|
||||
parameter int p_awidth = 3
|
||||
,parameter int p_dwidth = 9
|
||||
);
|
||||
x_if #(p_awidth) x_if0();
|
||||
y_if #(p_dwidth) y_if0();
|
||||
endinterface
|
||||
|
||||
module top();
|
||||
z_if #(.p_awidth(16) ,.p_dwidth(8)) if0();
|
||||
|
||||
typedef if0.x_if0.rq_t rq_t;
|
||||
typedef if0.y_if0.rs_t rs_t;
|
||||
|
||||
rq_t rq;
|
||||
rs_t rs;
|
||||
|
||||
always_comb begin
|
||||
rq.addr = 'h1234;
|
||||
rs.data = 'ha5;
|
||||
end
|
||||
|
||||
initial begin
|
||||
#1;
|
||||
`checkh(rq.addr,16'h1234);
|
||||
`checkh(rs.data,8'ha5);
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
#!/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(verilator_flags2=["--binary"])
|
||||
|
||||
test.execute()
|
||||
|
||||
test.passes()
|
||||
|
|
@ -0,0 +1,66 @@
|
|||
// 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
|
||||
//
|
||||
// assign localparam from interface typedef, single level nesting
|
||||
//
|
||||
|
||||
`define stop $stop
|
||||
`define checkd(gotv,expv) \
|
||||
do if ((gotv) !== (expv)) begin \
|
||||
$write("%%Error: %s:%0d: got=%0d exp=%0d\n", \
|
||||
`__FILE__,`__LINE__, (gotv), (expv)); \
|
||||
`stop; \
|
||||
end while(0);
|
||||
|
||||
`define checkh(gotv,expv) \
|
||||
do if ((gotv) !== (expv)) begin \
|
||||
$write("%%Error: %s:%0d: got=%0h exp=%0h\n", \
|
||||
`__FILE__,`__LINE__, (gotv), (expv)); \
|
||||
`stop; \
|
||||
end while(0);
|
||||
|
||||
interface x_if #(
|
||||
parameter int p_awidth = 4
|
||||
)();
|
||||
typedef struct packed {
|
||||
logic [p_awidth-1:0] addr;
|
||||
} rq_t;
|
||||
endinterface
|
||||
|
||||
interface y_if #(
|
||||
parameter int p_dwidth = 7
|
||||
)();
|
||||
typedef struct packed {
|
||||
logic [p_dwidth-1:0] data;
|
||||
} rs_t;
|
||||
endinterface
|
||||
|
||||
interface z_if #(
|
||||
parameter int p_awidth = 3
|
||||
,parameter int p_dwidth = 9
|
||||
);
|
||||
x_if #(p_awidth) x_if0();
|
||||
y_if #(p_dwidth) y_if0();
|
||||
endinterface
|
||||
|
||||
module top();
|
||||
z_if #(.p_awidth(16) ,.p_dwidth(8)) if0 [2] ();
|
||||
|
||||
typedef if0[0].x_if0.rq_t rq_t;
|
||||
|
||||
rq_t rq;
|
||||
|
||||
always_comb begin
|
||||
rq.addr = 'h1234;
|
||||
end
|
||||
|
||||
initial begin
|
||||
#1;
|
||||
`checkh(rq.addr,16'h1234);
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
#!/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(verilator_flags2=["--binary"])
|
||||
|
||||
test.execute()
|
||||
|
||||
test.passes()
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
// 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
|
||||
//
|
||||
// Chained typedef aliases from an interface typedef
|
||||
|
||||
`define stop $stop
|
||||
`define checkh(gotv,expv) \
|
||||
do if ((gotv) !== (expv)) begin \
|
||||
$write("%%Error: %s:%0d: got=%0h exp=%0h\n", \
|
||||
`__FILE__,`__LINE__, (gotv), (expv)); \
|
||||
`stop; \
|
||||
end while(0);
|
||||
|
||||
interface x_if #(
|
||||
parameter int p_awidth = 4
|
||||
)();
|
||||
typedef struct packed {
|
||||
logic [p_awidth-1:0] addr;
|
||||
} rq_t;
|
||||
endinterface
|
||||
|
||||
module top();
|
||||
x_if #(.p_awidth(16)) if0();
|
||||
|
||||
// First alias of interface typedef
|
||||
typedef if0.rq_t my_rq_t;
|
||||
// Second alias of the alias
|
||||
typedef my_rq_t my_rq2_t;
|
||||
|
||||
my_rq2_t rq;
|
||||
|
||||
always_comb begin
|
||||
rq.addr = 'h1234;
|
||||
end
|
||||
|
||||
initial begin
|
||||
#1;
|
||||
`checkh(rq.addr,16'h1234);
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
endmodule
|
||||
Loading…
Reference in New Issue