mirror of
https://github.com/verilator/verilator.git
synced 2025-04-21 12:06:55 +00:00
Fix interface inside generate, bug1001, bug1003.
Signed-off-by: Wilson Snyder <wsnyder@wsnyder.org>
This commit is contained in:
parent
f0af8726e3
commit
5e54d3e41a
2
Changes
2
Changes
@ -15,7 +15,7 @@ indicates the contributor was also the author of the fix; Thanks!
|
||||
|
||||
**** Fix constant function assigned to packed structs, bug997. [Johan Bjork]
|
||||
|
||||
**** Fix interface inside generate, bug998. [Johan Bjork]
|
||||
**** Fix interface inside generate, bug998, bug1001, bug1003. [Johan Bjork]
|
||||
|
||||
**** Fix $signed casts under generates, bug999. [Clifford Wolf]
|
||||
|
||||
|
@ -186,6 +186,13 @@ private:
|
||||
}
|
||||
nodep->iterateChildren(*this);
|
||||
}
|
||||
virtual void visit(AstVarXRef* nodep, AstNUser*) {
|
||||
UINFO(9, " VARXREF "<<nodep<<endl);
|
||||
if (m_namedScope != "" && nodep->inlinedDots() == "") {
|
||||
nodep->inlinedDots(m_namedScope);
|
||||
UINFO(9, " rescope to "<<nodep<<endl);
|
||||
}
|
||||
}
|
||||
virtual void visit(AstScopeName* nodep, AstNUser*) {
|
||||
// If there's a %m in the display text, we add a special node that will contain the name()
|
||||
// Similar code in V3Inline
|
||||
@ -218,7 +225,7 @@ private:
|
||||
}
|
||||
nodep->iterateChildren(*this);
|
||||
m_ifDepth = prevIfDepth;
|
||||
}
|
||||
}
|
||||
virtual void visit(AstNode* nodep, AstNUser*) {
|
||||
nodep->iterateChildren(*this);
|
||||
}
|
||||
|
@ -106,7 +106,9 @@ private:
|
||||
exprp);
|
||||
m_modp->addStmtp(assp);
|
||||
if (debug()>=9) assp->dumpTree(cout," _new: ");
|
||||
} else if (nodep->modVarp()->isIfaceRef()) {
|
||||
} else if (nodep->modVarp()->isIfaceRef()
|
||||
|| (nodep->modVarp()->subDTypep()->castUnpackArrayDType()
|
||||
&& nodep->modVarp()->subDTypep()->castUnpackArrayDType()->subDTypep()->castIfaceRefDType())) {
|
||||
// Create an AstAssignVarScope for Vars to Cells so we can link with their scope later
|
||||
AstNode* lhsp = new AstVarXRef (exprp->fileline(), nodep->modVarp(), m_cellp->name(), false);
|
||||
AstVarRef* refp = exprp->castVarRef();
|
||||
@ -194,6 +196,8 @@ private:
|
||||
// the IfaceRef.
|
||||
if (isIface) {
|
||||
AstUnpackArrayDType* arrdtype = ifaceVarp->dtypep()->castUnpackArrayDType();
|
||||
AstIfaceRefDType* origIfaceRefp = arrdtype->subDTypep()->castIfaceRefDType();
|
||||
origIfaceRefp->cellp(NULL);
|
||||
AstVar* varNewp = ifaceVarp->cloneTree(false);
|
||||
AstIfaceRefDType* ifaceRefp = arrdtype->subDTypep()->castIfaceRefDType()->cloneTree(false);
|
||||
arrdtype->addNextHere(ifaceRefp);
|
||||
@ -220,6 +224,32 @@ private:
|
||||
nodep->iterateChildren(*this);
|
||||
}
|
||||
|
||||
virtual void visit(AstVar* nodep, AstNUser*) {
|
||||
bool isIface = nodep->dtypep()->castUnpackArrayDType()
|
||||
&& nodep->dtypep()->castUnpackArrayDType()->subDTypep()->castIfaceRefDType();
|
||||
if (isIface) {
|
||||
AstUnpackArrayDType* arrdtype = nodep->dtypep()->castUnpackArrayDType();
|
||||
AstNode* prev = NULL;
|
||||
for (int i = arrdtype->lsb(); i <= arrdtype->msb(); ++i) {
|
||||
AstVar* varNewp = nodep->cloneTree(false);
|
||||
AstIfaceRefDType* ifaceRefp = arrdtype->subDTypep()->castIfaceRefDType()->cloneTree(false);
|
||||
arrdtype->addNextHere(ifaceRefp);
|
||||
ifaceRefp->cellp(NULL);
|
||||
varNewp->name(varNewp->name() + "__BRA__" + cvtToStr(i) + "__KET__");
|
||||
varNewp->origName(varNewp->origName() + "__BRA__" + cvtToStr(i) + "__KET__");
|
||||
varNewp->dtypep(ifaceRefp);
|
||||
if (!prev) {
|
||||
prev = varNewp;
|
||||
} else {
|
||||
prev->addNextHere(varNewp);
|
||||
}
|
||||
}
|
||||
nodep->addNextHere(prev);
|
||||
if (debug()==9) { prev->dumpTree(cout, "newintf: "); cout << endl; }
|
||||
}
|
||||
nodep->iterateChildren(*this);
|
||||
}
|
||||
|
||||
virtual void visit(AstPin* nodep, AstNUser*) {
|
||||
// Any non-direct pins need reconnection with a part-select
|
||||
if (!nodep->exprp()) return; // No-connect
|
||||
@ -260,17 +290,55 @@ private:
|
||||
string index = AstNode::encodeNumber(constp->toSInt());
|
||||
AstVarRef* varrefp = arrselp->lhsp()->castVarRef();
|
||||
AstVarXRef* newp = new AstVarXRef(nodep->fileline(),varrefp->name () + "__BRA__" + index + "__KET__", "", true);
|
||||
AstVar* varp = varrefp->varp()->cloneTree(true);
|
||||
varp->name(varp->name() + "__TMP__" + "__BRA__" + index + "__KET__");
|
||||
if (!nodep->modVarp()->dtypep()) nodep->v3fatalSrc("No dtype for AstPin");
|
||||
varp->dtypep(nodep->modVarp()->dtypep());
|
||||
newp->addNextHere(varp);
|
||||
newp->varp(varp);
|
||||
newp->dtypep(nodep->modVarp()->dtypep());
|
||||
newp->packagep(varrefp->packagep());
|
||||
arrselp->addNextHere(newp);
|
||||
arrselp->unlinkFrBack()->deleteTree();
|
||||
}
|
||||
} else {
|
||||
AstVar* pinVarp = nodep->modVarp();
|
||||
AstUnpackArrayDType* pinArrp = pinVarp->dtypep()->castUnpackArrayDType();
|
||||
if (!pinArrp || !pinArrp->subDTypep()->castIfaceRefDType())
|
||||
return;
|
||||
AstNode* prevp = NULL;
|
||||
AstNode* prevPinp = NULL;
|
||||
// Clone the var referenced by the pin, and clone each var referenced by the varref
|
||||
// Clone pin varp:
|
||||
for (int i = pinArrp->lsb(); i <= pinArrp->msb(); ++i) {
|
||||
AstVar* varNewp = pinVarp->cloneTree(false);
|
||||
AstIfaceRefDType* ifaceRefp = pinArrp->subDTypep()->castIfaceRefDType();
|
||||
ifaceRefp->cellp(NULL);
|
||||
varNewp->name(varNewp->name() + "__BRA__" + cvtToStr(i) + "__KET__");
|
||||
varNewp->origName(varNewp->origName() + "__BRA__" + cvtToStr(i) + "__KET__");
|
||||
varNewp->dtypep(ifaceRefp);
|
||||
if (!prevp) {
|
||||
prevp = varNewp;
|
||||
} else {
|
||||
prevp->addNextHere(varNewp);
|
||||
}
|
||||
// Now also clone the pin itself and update its varref
|
||||
AstPin* newp = nodep->cloneTree(false);
|
||||
newp->modVarp(varNewp);
|
||||
newp->name(newp->name() + "__BRA__" + cvtToStr(i) + "__KET__");
|
||||
// And replace exprp with a new varxref
|
||||
AstVarRef* varrefp = newp->exprp()->castVarRef();
|
||||
string newname = varrefp->name () + "__BRA__" + cvtToStr(i) + "__KET__";
|
||||
AstVarXRef* newVarXRefp = new AstVarXRef (nodep->fileline(), newname, "", true);
|
||||
newVarXRefp->varp(newp->modVarp());
|
||||
newVarXRefp->dtypep(newp->modVarp()->dtypep());
|
||||
newp->exprp()->unlinkFrBack()->deleteTree();
|
||||
newp->exprp(newVarXRefp);
|
||||
if (!prevPinp) {
|
||||
prevPinp = newp;
|
||||
} else {
|
||||
prevPinp->addNextHere(newp);
|
||||
}
|
||||
}
|
||||
pinVarp->replaceWith(prevp);
|
||||
nodep->replaceWith(prevPinp);
|
||||
pushDeletep(pinVarp);
|
||||
pushDeletep(nodep);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -346,6 +414,7 @@ public:
|
||||
// Done. Interface
|
||||
} else if (!alwaysCvt
|
||||
&& connectXRefp
|
||||
&& connectXRefp->varp()
|
||||
&& connectXRefp->varp()->isIfaceRef()) {
|
||||
} else if (!alwaysCvt
|
||||
&& connBasicp
|
||||
|
@ -352,13 +352,14 @@ private:
|
||||
AstIfaceRefDType* idtypep = new AstIfaceRefDType(nodep->fileline(), nodep->name(),
|
||||
nodep->modp()->name());
|
||||
idtypep->ifacep(NULL); // cellp overrides
|
||||
// In the case of arrayed interfaces, we replace cellp when de-arraying in V3Inst
|
||||
idtypep->cellp(nodep); // Only set when real parent cell known.
|
||||
AstVar* varp;
|
||||
if (nodep->rangep()) {
|
||||
AstNodeArrayDType* arrp = new AstUnpackArrayDType(nodep->fileline(),VFlagChildDType(), idtypep, nodep->rangep()->cloneTree(true));
|
||||
varp = new AstVar(nodep->fileline(), AstVarType::IFACEREF, varName,
|
||||
VFlagChildDType(), arrp);
|
||||
} else {
|
||||
idtypep->cellp(nodep); // Only set when real parent cell known
|
||||
varp = new AstVar(nodep->fileline(), AstVarType::IFACEREF, varName,
|
||||
VFlagChildDType(), idtypep);
|
||||
}
|
||||
|
@ -365,12 +365,22 @@ public:
|
||||
void insertIfaceVarSym(VSymEnt* symp) { // Where sym is for a VAR of dtype IFACEREFDTYPE
|
||||
m_ifaceVarSyms.push_back(symp);
|
||||
}
|
||||
// Iface for a raw or arrayed iface
|
||||
static AstIfaceRefDType* ifaceRefFromArray(AstNodeDType* nodep) {
|
||||
AstIfaceRefDType* ifacerefp = nodep->castIfaceRefDType();
|
||||
if (!ifacerefp) {
|
||||
if (AstUnpackArrayDType* arrp = nodep->castUnpackArrayDType()) {
|
||||
ifacerefp = arrp->subDTypep()->castIfaceRefDType();
|
||||
}
|
||||
}
|
||||
return ifacerefp;
|
||||
}
|
||||
void computeIfaceVarSyms() {
|
||||
for (IfaceVarSyms::iterator it = m_ifaceVarSyms.begin(); it != m_ifaceVarSyms.end(); ++it) {
|
||||
VSymEnt* varSymp = *it;
|
||||
AstVar* varp = varSymp->nodep()->castVar();
|
||||
UINFO(9, " insAllIface se"<<(void*)varSymp<<" "<<varp<<endl);
|
||||
AstIfaceRefDType* ifacerefp = varp->subDTypep()->castIfaceRefDType();
|
||||
AstIfaceRefDType* ifacerefp = ifaceRefFromArray(varp->subDTypep());
|
||||
if (!ifacerefp) varp->v3fatalSrc("Non-ifacerefs on list!");
|
||||
if (!ifacerefp->ifaceViaCellp()) {
|
||||
if (!ifacerefp->cellp()) { // Probably a NotFoundModule, or a normal module if made mistake
|
||||
@ -408,6 +418,10 @@ public:
|
||||
// Track and later insert scope aliases; an interface referenced by a child cell connecting to that interface
|
||||
// Typically lhsp=VAR w/dtype IFACEREF, rhsp=IFACE cell
|
||||
UINFO(9," insertScopeAlias se"<<(void*)lhsp<<" se"<<(void*)rhsp<<endl);
|
||||
if (rhsp->nodep()->castCell()
|
||||
&& !rhsp->nodep()->castCell()->modp()->castIface()) {
|
||||
rhsp->nodep()->v3fatalSrc("Got a non-IFACE alias RHS");
|
||||
}
|
||||
m_scopeAliasMap[samn].insert(make_pair(lhsp, rhsp));
|
||||
}
|
||||
void computeScopeAliases() {
|
||||
@ -515,6 +529,17 @@ public:
|
||||
return lookupSymp;
|
||||
}
|
||||
|
||||
static string removeLastInlineScope(const string& name) {
|
||||
string out = name;
|
||||
string dot = "__DOT__";
|
||||
size_t dotPos = out.rfind(dot, out.size() - dot.length() - 2);
|
||||
if (dotPos == string::npos) {
|
||||
return "";
|
||||
} else {
|
||||
return out.erase(dotPos + dot.length(), string::npos);
|
||||
}
|
||||
}
|
||||
|
||||
VSymEnt* findSymPrefixed(VSymEnt* lookupSymp, const string& dotname, string& baddot) {
|
||||
// Find symbol in given point in hierarchy, allowing prefix (post-Inline)
|
||||
// For simplicity lookupSymp may be passed NULL result from findDotted
|
||||
@ -525,7 +550,15 @@ public:
|
||||
<<((lookupSymp->symPrefix()=="") ? "" : lookupSymp->symPrefix()+dotname)
|
||||
<<" at se"<<lookupSymp
|
||||
<<endl);
|
||||
VSymEnt* foundp = lookupSymp->findIdFallback(lookupSymp->symPrefix() + dotname); // Might be NULL
|
||||
string prefix = lookupSymp->symPrefix();
|
||||
VSymEnt* foundp = NULL;
|
||||
while (!foundp) {
|
||||
foundp = lookupSymp->findIdFallback(prefix + dotname); // Might be NULL
|
||||
if (prefix == "") {
|
||||
break;
|
||||
}
|
||||
prefix = removeLastInlineScope(prefix);
|
||||
}
|
||||
if (!foundp) baddot = dotname;
|
||||
return foundp;
|
||||
}
|
||||
@ -842,10 +875,12 @@ class LinkDotFindVisitor : public AstNVisitor {
|
||||
VSymEnt* insp = m_statep->insertSym(m_curSymp, nodep->name(), nodep, m_packagep);
|
||||
if (m_statep->forPrimary() && nodep->isGParam()) {
|
||||
m_paramNum++;
|
||||
VSymEnt* symp = m_statep->insertSym(m_curSymp, "__paramNumber"+cvtToStr(m_paramNum), nodep, m_packagep);
|
||||
VSymEnt* symp = m_statep->insertSym(m_curSymp, "__paramNumber" + cvtToStr(m_paramNum),
|
||||
nodep, m_packagep);
|
||||
symp->exported(false);
|
||||
}
|
||||
if (nodep->subDTypep()->castIfaceRefDType()) {
|
||||
AstIfaceRefDType* ifacerefp = LinkDotState::ifaceRefFromArray(nodep->subDTypep());
|
||||
if (ifacerefp) {
|
||||
// Can't resolve until interfaces and modport names are known; see notes at top
|
||||
m_statep->insertIfaceVarSym(insp);
|
||||
}
|
||||
@ -1111,7 +1146,7 @@ class LinkDotScopeVisitor : public AstNVisitor {
|
||||
&& nodep->varp()->isIfaceParent()) {
|
||||
UINFO(9,"Iface parent ref var "<<nodep->varp()->name()<<" "<<nodep<<endl);
|
||||
// Find the interface cell the var references
|
||||
AstIfaceRefDType* dtypep = nodep->varp()->dtypep()->castIfaceRefDType();
|
||||
AstIfaceRefDType* dtypep = LinkDotState::ifaceRefFromArray(nodep->varp()->dtypep());
|
||||
if (!dtypep) nodep->v3fatalSrc("Non AstIfaceRefDType on isIfaceRef() var");
|
||||
UINFO(9,"Iface parent dtype "<<dtypep<<endl);
|
||||
string ifcellname = dtypep->cellName();
|
||||
@ -1154,9 +1189,18 @@ class LinkDotScopeVisitor : public AstNVisitor {
|
||||
AstVarRef* refp = nodep->rhsp()->castVarRef();
|
||||
AstVarXRef* xrefp = nodep->rhsp()->castVarXRef();
|
||||
if (!refp && !xrefp) nodep->v3fatalSrc("Unsupported: Non Var(X)Ref attached to interface pin");
|
||||
string scopename = refp ? refp->name() : xrefp->name();
|
||||
string baddot; VSymEnt* okSymp;
|
||||
VSymEnt* symp = m_statep->findDotted(m_modSymp, scopename, baddot, okSymp);
|
||||
string inl = (xrefp && xrefp->inlinedDots().size()) ? (xrefp->inlinedDots() + "__DOT__") : "";
|
||||
VSymEnt* symp = NULL;
|
||||
string scopename;
|
||||
while (!symp) {
|
||||
scopename = refp ? refp->name() : (inl.size() ? (inl + xrefp->name()) : xrefp->name());
|
||||
string baddot; VSymEnt* okSymp;
|
||||
symp = m_statep->findDotted(m_modSymp, scopename, baddot, okSymp);
|
||||
if (inl == "")
|
||||
break;
|
||||
inl = LinkDotState::removeLastInlineScope(inl);
|
||||
}
|
||||
if (!symp) UINFO(9,"No symbol for interface alias rhs ("<<string(refp?"VARREF ":"VARXREF ")<<scopename<<")"<<endl);
|
||||
if (!symp) nodep->v3fatalSrc("No symbol for interface alias rhs");
|
||||
UINFO(5, " Found a linked scope RHS: "<<scopename<<" se"<<(void*)symp<<" "<<symp->nodep()<<endl);
|
||||
rhsSymp = symp;
|
||||
@ -1647,7 +1691,8 @@ private:
|
||||
}
|
||||
}
|
||||
else if (AstVar* varp = foundp->nodep()->castVar()) {
|
||||
if (AstIfaceRefDType* ifacerefp = varp->subDTypep()->castIfaceRefDType()) {
|
||||
AstIfaceRefDType* ifacerefp = LinkDotState::ifaceRefFromArray(varp->subDTypep());
|
||||
if (ifacerefp) {
|
||||
if (!ifacerefp->ifaceViaCellp()) ifacerefp->v3fatalSrc("Unlinked interface");
|
||||
// Really this is a scope reference into an interface
|
||||
UINFO(9,"varref-ifaceref "<<m_ds.m_dotText<<" "<<nodep<<endl);
|
||||
@ -2068,6 +2113,7 @@ private:
|
||||
UINFO(5," AstCellArrayRef: "<<nodep<<" "<<m_ds.ascii()<<endl);
|
||||
// No need to iterate, if we have a UnlinkedVarXRef, we're already done
|
||||
}
|
||||
|
||||
virtual void visit(AstNode* nodep, AstNUser*) {
|
||||
// Default: Just iterate
|
||||
checkNoDot(nodep);
|
||||
|
@ -495,6 +495,10 @@ void ParamVisitor::visitCell(AstCell* nodep) {
|
||||
AstVar* modvarp = pinp->modVarp();
|
||||
if (modvarp->isIfaceRef()) {
|
||||
AstIfaceRefDType* portIrefp = modvarp->subDTypep()->castIfaceRefDType();
|
||||
if (!portIrefp) {
|
||||
portIrefp = modvarp->subDTypep()->castUnpackArrayDType()->subDTypep()->castIfaceRefDType();
|
||||
}
|
||||
|
||||
AstIfaceRefDType* pinIrefp = NULL;
|
||||
AstNode* exprp = pinp->exprp();
|
||||
if (exprp
|
||||
@ -512,12 +516,23 @@ void ParamVisitor::visitCell(AstCell* nodep) {
|
||||
&& exprp->op1p()->castVarRef()->varp()->subDTypep()->castUnpackArrayDType()->subDTypep()
|
||||
&& exprp->op1p()->castVarRef()->varp()->subDTypep()->castUnpackArrayDType()->subDTypep()->castIfaceRefDType())
|
||||
pinIrefp = exprp->op1p()->castVarRef()->varp()->subDTypep()->castUnpackArrayDType()->subDTypep()->castIfaceRefDType();
|
||||
//UINFO(9," portIfaceRef "<<portIrefp<<endl);
|
||||
else if (exprp
|
||||
&& exprp->castVarRef()
|
||||
&& exprp->castVarRef()->varp()
|
||||
&& exprp->castVarRef()->varp()->subDTypep()
|
||||
&& exprp->castVarRef()->varp()->subDTypep()->castUnpackArrayDType()
|
||||
&& exprp->castVarRef()->varp()->subDTypep()->castUnpackArrayDType()->subDTypep()
|
||||
&& exprp->castVarRef()->varp()->subDTypep()->castUnpackArrayDType()->subDTypep()->castIfaceRefDType())
|
||||
pinIrefp = exprp->castVarRef()->varp()->subDTypep()->castUnpackArrayDType()->subDTypep()->castIfaceRefDType();
|
||||
|
||||
if (!pinIrefp) {
|
||||
UINFO(9," portIfaceRef "<<portIrefp<<endl);
|
||||
|
||||
if (!portIrefp) {
|
||||
pinp->v3error("Interface port '"<<modvarp->prettyName()<<"' is not an interface" << modvarp);
|
||||
} else if (!pinIrefp) {
|
||||
pinp->v3error("Interface port '"<<modvarp->prettyName()<<"' is not connected to interface/modport pin expression");
|
||||
} else {
|
||||
//UINFO(9," pinIfaceRef "<<pinIrefp<<endl);
|
||||
UINFO(9," pinIfaceRef "<<pinIrefp<<endl);
|
||||
if (portIrefp->ifaceViaCellp() != pinIrefp->ifaceViaCellp()) {
|
||||
UINFO(9," IfaceRefDType needs reconnect "<<pinIrefp<<endl);
|
||||
longname += "_" + paramSmallName(nodep->modp(),pinp->modVarp())+paramValueNumber(pinIrefp);
|
||||
|
@ -223,6 +223,7 @@ void process () {
|
||||
if (!v3Global.opt.xmlOnly()) {
|
||||
// Remove cell arrays (must be between V3Width and scoping)
|
||||
V3Inst::dearrayAll(v3Global.rootp());
|
||||
V3LinkDot::linkDotArrayed(v3Global.rootp());
|
||||
}
|
||||
|
||||
if (!v3Global.opt.xmlOnly()) {
|
||||
|
@ -3735,9 +3735,6 @@ AstVar* V3ParseGrammar::createVariable(FileLine* fileline, string name, AstRange
|
||||
return NULL;
|
||||
}
|
||||
AstVarType type = GRAMMARP->m_varIO;
|
||||
if (dtypep->castIfaceRefDType()) {
|
||||
if (arrayp) { fileline->v3error("Unsupported: Arrayed interfaces"); VL_DANGLING(arrayp); }
|
||||
}
|
||||
if (!dtypep) { // Created implicitly
|
||||
dtypep = new AstBasicDType(fileline, LOGIC_IMPLICIT);
|
||||
} else { // May make new variables with same type, so clone
|
||||
|
18
test_regress/t/t_interface_gen10.pl
Executable file
18
test_regress/t/t_interface_gen10.pl
Executable file
@ -0,0 +1,18 @@
|
||||
#!/usr/bin/perl
|
||||
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 2003-2009 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.
|
||||
|
||||
compile (
|
||||
);
|
||||
|
||||
execute (
|
||||
check_finished=>1,
|
||||
);
|
||||
|
||||
ok(1);
|
||||
1;
|
33
test_regress/t/t_interface_gen10.v
Normal file
33
test_regress/t/t_interface_gen10.v
Normal file
@ -0,0 +1,33 @@
|
||||
// DESCRIPTION: Verilator: Verilog Test module
|
||||
//
|
||||
// This file ONLY is placed into the Public Domain, for any use,
|
||||
// without warranty.
|
||||
|
||||
// bug998
|
||||
|
||||
interface intf
|
||||
#(parameter PARAM = 0)
|
||||
();
|
||||
logic val;
|
||||
function integer func (); return 5; endfunction
|
||||
endinterface
|
||||
|
||||
module t1(intf mod_intf);
|
||||
initial begin
|
||||
$display("%m %d", mod_intf.val);
|
||||
end
|
||||
endmodule
|
||||
|
||||
module t();
|
||||
generate
|
||||
begin : TestIf
|
||||
intf #(.PARAM(1)) my_intf [0:0] ();
|
||||
t1 t (.mod_intf(my_intf[0]));
|
||||
end
|
||||
endgenerate
|
||||
|
||||
initial begin
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
endmodule
|
18
test_regress/t/t_interface_gen11.pl
Executable file
18
test_regress/t/t_interface_gen11.pl
Executable file
@ -0,0 +1,18 @@
|
||||
#!/usr/bin/perl
|
||||
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 2003-2009 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.
|
||||
|
||||
compile (
|
||||
);
|
||||
|
||||
execute (
|
||||
check_finished=>1,
|
||||
);
|
||||
|
||||
ok(1);
|
||||
1;
|
39
test_regress/t/t_interface_gen11.v
Normal file
39
test_regress/t/t_interface_gen11.v
Normal file
@ -0,0 +1,39 @@
|
||||
// DESCRIPTION: Verilator: Verilog Test module
|
||||
//
|
||||
// This file ONLY is placed into the Public Domain, for any use,
|
||||
// without warranty.
|
||||
|
||||
// bug998
|
||||
|
||||
interface intf
|
||||
#(parameter PARAM = 0)
|
||||
();
|
||||
logic val;
|
||||
function integer func (); return 5; endfunction
|
||||
endinterface
|
||||
|
||||
module t1(intf mod_intf);
|
||||
initial begin
|
||||
$display("%m %d", mod_intf.val);
|
||||
end
|
||||
endmodule
|
||||
|
||||
module t2(intf mod_intfs [1:0]);
|
||||
generate
|
||||
begin
|
||||
t1 t(.mod_intf(mod_intfs[0]));
|
||||
end
|
||||
endgenerate
|
||||
endmodule
|
||||
|
||||
module t();
|
||||
|
||||
intf #(.PARAM(1)) my_intf [1:0] ();
|
||||
|
||||
t2 t2 (.mod_intfs(my_intf));
|
||||
|
||||
initial begin
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
endmodule
|
@ -9,23 +9,52 @@ interface intf
|
||||
#(parameter PARAM = 0)
|
||||
();
|
||||
logic val;
|
||||
function integer func (); return 5; endfunction
|
||||
endinterface
|
||||
|
||||
module t1(intf mod_intf);
|
||||
initial begin
|
||||
$display("%d", mod_intf.val);
|
||||
$display("%m %d", mod_intf.val);
|
||||
end
|
||||
endmodule
|
||||
|
||||
module t();
|
||||
generate
|
||||
begin : TestIf
|
||||
intf #(.PARAM(1)) my_intf;
|
||||
intf #(.PARAM(1)) my_intf ();
|
||||
assign my_intf.val = '0;
|
||||
t1 t (.mod_intf(my_intf));
|
||||
initial begin
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
// initial $display("%0d", my_intf.func());
|
||||
end
|
||||
endgenerate
|
||||
|
||||
generate
|
||||
begin
|
||||
intf #(.PARAM(1)) my_intf ();
|
||||
assign my_intf.val = '1;
|
||||
t1 t (.mod_intf(my_intf));
|
||||
// initial $display("%0d", my_intf.func());
|
||||
end
|
||||
endgenerate
|
||||
|
||||
localparam LP = 1;
|
||||
logic val;
|
||||
|
||||
generate begin
|
||||
if (LP) begin
|
||||
intf #(.PARAM(2)) my_intf ();
|
||||
assign my_intf.val = '1;
|
||||
assign val = my_intf.val;
|
||||
end else begin
|
||||
intf #(.PARAM(3)) my_intf ();
|
||||
assign my_intf.val = '1;
|
||||
assign val = my_intf.val;
|
||||
end
|
||||
end endgenerate
|
||||
|
||||
initial begin
|
||||
$display("%0d", val);
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
endmodule
|
||||
|
18
test_regress/t/t_interface_gen6.pl
Executable file
18
test_regress/t/t_interface_gen6.pl
Executable file
@ -0,0 +1,18 @@
|
||||
#!/usr/bin/perl
|
||||
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 2003-2009 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.
|
||||
|
||||
compile (
|
||||
);
|
||||
|
||||
execute (
|
||||
check_finished=>1,
|
||||
);
|
||||
|
||||
ok(1);
|
||||
1;
|
56
test_regress/t/t_interface_gen6.v
Normal file
56
test_regress/t/t_interface_gen6.v
Normal file
@ -0,0 +1,56 @@
|
||||
// DESCRIPTION: Verilator: Verilog Test module
|
||||
//
|
||||
// This file ONLY is placed into the Public Domain, for any use,
|
||||
// without warranty.
|
||||
|
||||
// bug1001
|
||||
|
||||
interface intf
|
||||
#(parameter PARAM = 0)
|
||||
();
|
||||
logic val;
|
||||
endinterface
|
||||
|
||||
module t();
|
||||
|
||||
generate
|
||||
if (1) begin
|
||||
intf #(.PARAM(2)) my_intf ();
|
||||
assign my_intf.val = '1;
|
||||
end else begin
|
||||
intf #(.PARAM(3)) my_intf ();
|
||||
assign my_intf.val = '0;
|
||||
end
|
||||
endgenerate
|
||||
|
||||
generate
|
||||
begin
|
||||
if (1) begin
|
||||
intf #(.PARAM(2)) my_intf ();
|
||||
assign my_intf.val = '1;
|
||||
end else begin
|
||||
intf #(.PARAM(3)) my_intf ();
|
||||
assign my_intf.val = '0;
|
||||
end
|
||||
end
|
||||
endgenerate
|
||||
|
||||
generate
|
||||
begin
|
||||
begin
|
||||
if (1) begin
|
||||
intf #(.PARAM(2)) my_intf ();
|
||||
assign my_intf.val = '1;
|
||||
end else begin
|
||||
intf #(.PARAM(3)) my_intf ();
|
||||
assign my_intf.val = '0;
|
||||
end
|
||||
end
|
||||
end
|
||||
endgenerate
|
||||
|
||||
initial begin
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
endmodule
|
18
test_regress/t/t_interface_gen7.pl
Executable file
18
test_regress/t/t_interface_gen7.pl
Executable file
@ -0,0 +1,18 @@
|
||||
#!/usr/bin/perl
|
||||
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 2003-2009 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.
|
||||
|
||||
compile (
|
||||
);
|
||||
|
||||
execute (
|
||||
check_finished=>1,
|
||||
);
|
||||
|
||||
ok(1);
|
||||
1;
|
67
test_regress/t/t_interface_gen7.v
Normal file
67
test_regress/t/t_interface_gen7.v
Normal file
@ -0,0 +1,67 @@
|
||||
// DESCRIPTION: Verilator: Verilog Test module
|
||||
//
|
||||
// This file ONLY is placed into the Public Domain, for any use,
|
||||
// without warranty.
|
||||
|
||||
// bug998
|
||||
|
||||
interface intf
|
||||
#(parameter PARAM = 0)
|
||||
();
|
||||
logic val;
|
||||
function integer func (); return 5; endfunction
|
||||
endinterface
|
||||
|
||||
module t1(intf mod_intf);
|
||||
initial begin
|
||||
$display("%m %d", mod_intf.val);
|
||||
end
|
||||
endmodule
|
||||
|
||||
module t();
|
||||
|
||||
intf #(.PARAM(1)) my_intf [1:0] ();
|
||||
|
||||
generate
|
||||
genvar the_genvar;
|
||||
begin
|
||||
for (the_genvar = 0; the_genvar < 2; the_genvar++) begin : TestIf
|
||||
begin
|
||||
assign my_intf[the_genvar].val = '1;
|
||||
t1 t (.mod_intf(my_intf[the_genvar]));
|
||||
end
|
||||
end
|
||||
end
|
||||
endgenerate
|
||||
|
||||
generate
|
||||
genvar the_second_genvar;
|
||||
begin
|
||||
intf #(.PARAM(1)) my_intf [1:0] ();
|
||||
for (the_second_genvar = 0; the_second_genvar < 2; the_second_genvar++) begin : TestIf
|
||||
begin
|
||||
assign my_intf[the_second_genvar].val = '1;
|
||||
t1 t (.mod_intf(my_intf[the_second_genvar]));
|
||||
end
|
||||
end
|
||||
end
|
||||
endgenerate
|
||||
|
||||
generate
|
||||
genvar the_third_genvar;
|
||||
begin
|
||||
for (the_third_genvar = 0; the_third_genvar < 2; the_third_genvar++) begin : TestIf
|
||||
begin
|
||||
intf #(.PARAM(1)) my_intf [1:0] ();
|
||||
assign my_intf[the_third_genvar].val = '1;
|
||||
t1 t (.mod_intf(my_intf[the_third_genvar]));
|
||||
end
|
||||
end
|
||||
end
|
||||
endgenerate
|
||||
|
||||
initial begin
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
endmodule
|
18
test_regress/t/t_interface_gen8.pl
Executable file
18
test_regress/t/t_interface_gen8.pl
Executable file
@ -0,0 +1,18 @@
|
||||
#!/usr/bin/perl
|
||||
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 2003-2009 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.
|
||||
|
||||
compile (
|
||||
);
|
||||
|
||||
execute (
|
||||
check_finished=>1,
|
||||
);
|
||||
|
||||
ok(1);
|
||||
1;
|
55
test_regress/t/t_interface_gen8.v
Normal file
55
test_regress/t/t_interface_gen8.v
Normal file
@ -0,0 +1,55 @@
|
||||
// DESCRIPTION: Verilator: Verilog Test module
|
||||
//
|
||||
// This file ONLY is placed into the Public Domain, for any use,
|
||||
// without warranty.
|
||||
|
||||
// bug998
|
||||
|
||||
interface intf
|
||||
#(parameter PARAM = 0)
|
||||
();
|
||||
logic val;
|
||||
function integer func (); return 5; endfunction
|
||||
endinterface
|
||||
|
||||
module t1(intf mod_intf);
|
||||
initial begin
|
||||
$display("%m %d", mod_intf.val);
|
||||
end
|
||||
endmodule
|
||||
|
||||
module t();
|
||||
|
||||
//intf #(.PARAM(1)) my_intf [1:0] ();
|
||||
intf #(.PARAM(1)) my_intf ();
|
||||
|
||||
generate
|
||||
genvar the_genvar;
|
||||
for (the_genvar = 0; the_genvar < 2; the_genvar++) begin : TestIf
|
||||
//assign my_intf[the_genvar].val = '1;
|
||||
//t1 t (.mod_intf(my_intf[the_genvar]));
|
||||
t1 t (.mod_intf(my_intf));
|
||||
end
|
||||
endgenerate
|
||||
|
||||
// t1 t (.mod_intf(my_intf[1]));
|
||||
|
||||
// generate
|
||||
// begin : TestIf
|
||||
// assign my_intf[1].val = '1;
|
||||
// t1 t (.mod_intf(my_intf[1]));
|
||||
// end
|
||||
// endgenerate
|
||||
|
||||
// generate
|
||||
// begin
|
||||
// assign my_intf[0].val = '1;
|
||||
// t1 t (.mod_intf(my_intf[0]));
|
||||
// end
|
||||
// endgenerate
|
||||
|
||||
initial begin
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
endmodule
|
18
test_regress/t/t_interface_gen9.pl
Executable file
18
test_regress/t/t_interface_gen9.pl
Executable file
@ -0,0 +1,18 @@
|
||||
#!/usr/bin/perl
|
||||
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 2003-2009 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.
|
||||
|
||||
compile (
|
||||
);
|
||||
|
||||
execute (
|
||||
check_finished=>1,
|
||||
);
|
||||
|
||||
ok(1);
|
||||
1;
|
32
test_regress/t/t_interface_gen9.v
Normal file
32
test_regress/t/t_interface_gen9.v
Normal file
@ -0,0 +1,32 @@
|
||||
// DESCRIPTION: Verilator: Verilog Test module
|
||||
//
|
||||
// This file ONLY is placed into the Public Domain, for any use,
|
||||
// without warranty.
|
||||
|
||||
// bug998
|
||||
|
||||
module t1(input logic foo);
|
||||
initial begin
|
||||
$display("%m %d", foo);
|
||||
end
|
||||
endmodule
|
||||
|
||||
module t();
|
||||
|
||||
logic [1:0] my_foo;
|
||||
|
||||
generate
|
||||
genvar the_genvar;
|
||||
for (the_genvar = 0; the_genvar < 2; the_genvar++) begin : TestIf
|
||||
//logic tmp_foo;
|
||||
//assign tmp_foo = my_foo[the_genvar];
|
||||
t1 t (.foo(my_foo[the_genvar]));
|
||||
//t1 t (.foo(tmp_foo));
|
||||
end
|
||||
endgenerate
|
||||
|
||||
initial begin
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
endmodule
|
18
test_regress/t/t_mod_interface_array.pl
Executable file
18
test_regress/t/t_mod_interface_array.pl
Executable file
@ -0,0 +1,18 @@
|
||||
#!/usr/bin/perl
|
||||
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 2003 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.
|
||||
|
||||
compile (
|
||||
);
|
||||
|
||||
execute (
|
||||
check_finished=>1,
|
||||
);
|
||||
|
||||
ok(1);
|
||||
1;
|
63
test_regress/t/t_mod_interface_array.v
Normal file
63
test_regress/t/t_mod_interface_array.v
Normal file
@ -0,0 +1,63 @@
|
||||
// DESCRIPTION: Verilator: Verilog Test module
|
||||
//
|
||||
// This file ONLY is placed into the Public Domain, for any use,
|
||||
// without warranty, 2015 by Johan Bjork.
|
||||
|
||||
parameter N = 4;
|
||||
|
||||
interface a_if #(parameter PARAM = 0) ();
|
||||
logic long_name;
|
||||
modport source (output long_name);
|
||||
modport sink (input long_name);
|
||||
endinterface
|
||||
|
||||
module intf_source
|
||||
(
|
||||
input logic [N-1:0] intf_input,
|
||||
a_if.source i_intf_source[N-1:0]
|
||||
);
|
||||
generate
|
||||
for (genvar i=0; i < N;i++) begin
|
||||
assign i_intf_source[i].long_name = intf_input[i];
|
||||
end
|
||||
endgenerate
|
||||
endmodule
|
||||
|
||||
module intf_sink
|
||||
(
|
||||
output [N-1:0] a_out,
|
||||
a_if.sink i_intf_sink[N-1:0]
|
||||
);
|
||||
generate
|
||||
for (genvar i=0; i < N;i++) begin
|
||||
assign a_out[i] = i_intf_sink[i].long_name;
|
||||
end
|
||||
endgenerate
|
||||
endmodule
|
||||
|
||||
module t
|
||||
(
|
||||
clk
|
||||
);
|
||||
input clk;
|
||||
logic [N-1:0] a_in;
|
||||
logic [N-1:0] a_out;
|
||||
logic [N-1:0] ack_out;
|
||||
a_if #(.PARAM(1)) tl_intf [N-1:0] ();
|
||||
intf_source source(a_in, tl_intf);
|
||||
intf_sink sink(a_out, tl_intf);
|
||||
|
||||
initial a_in = '0;
|
||||
always @(posedge clk) begin
|
||||
a_in <= a_in + { {N-1 {1'b0}}, 1'b1 };
|
||||
ack_out <= ack_out + { {N-1 {1'b0}}, 1'b1 };
|
||||
if (ack_out != a_out) begin
|
||||
$stop;
|
||||
end
|
||||
|
||||
if (& a_in) begin
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
end
|
||||
endmodule
|
18
test_regress/t/t_mod_interface_array1.pl
Executable file
18
test_regress/t/t_mod_interface_array1.pl
Executable file
@ -0,0 +1,18 @@
|
||||
#!/usr/bin/perl
|
||||
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 2003 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.
|
||||
|
||||
compile (
|
||||
);
|
||||
|
||||
execute (
|
||||
check_finished=>1,
|
||||
);
|
||||
|
||||
ok(1);
|
||||
1;
|
65
test_regress/t/t_mod_interface_array1.v
Normal file
65
test_regress/t/t_mod_interface_array1.v
Normal file
@ -0,0 +1,65 @@
|
||||
// DESCRIPTION: Verilator: Verilog Test module
|
||||
//
|
||||
// This file ONLY is placed into the Public Domain, for any use,
|
||||
// without warranty, 2015 by Johan Bjork.
|
||||
|
||||
parameter N = 4;
|
||||
|
||||
interface a_if #(parameter PARAM = 0) ();
|
||||
logic long_name;
|
||||
modport source (output long_name);
|
||||
modport sink (input long_name);
|
||||
endinterface
|
||||
|
||||
module intf_source
|
||||
(
|
||||
input logic [N-1:0] intf_input,
|
||||
a_if.source i_intf_source[N-1:0]
|
||||
);
|
||||
generate
|
||||
for (genvar i=0; i < N;i++) begin
|
||||
assign i_intf_source[i].long_name = intf_input[i];
|
||||
end
|
||||
endgenerate
|
||||
endmodule
|
||||
|
||||
module intf_sink
|
||||
(
|
||||
output [N-1:0] a_out,
|
||||
a_if.sink i_intf_sink[N-1:0]
|
||||
);
|
||||
generate
|
||||
for (genvar i=0; i < N;i++) begin
|
||||
assign a_out[i] = i_intf_sink[i].long_name;
|
||||
end
|
||||
endgenerate
|
||||
endmodule
|
||||
|
||||
module t
|
||||
(
|
||||
clk
|
||||
);
|
||||
input clk;
|
||||
logic [N-1:0] a_in;
|
||||
logic [N-1:0] a_out;
|
||||
logic [N-1:0] ack_out;
|
||||
// verilator lint_off LITENDIAN
|
||||
a_if #(.PARAM(1)) tl_intf [N] ();
|
||||
// verilator lint_on LITENDIAN
|
||||
intf_source source(a_in, tl_intf);
|
||||
intf_sink sink(a_out, tl_intf);
|
||||
|
||||
initial a_in = '0;
|
||||
always @(posedge clk) begin
|
||||
a_in <= a_in + { {N-1 {1'b0}}, 1'b1 };
|
||||
ack_out <= ack_out + { {N-1 {1'b0}}, 1'b1 };
|
||||
if (ack_out != a_out) begin
|
||||
$stop;
|
||||
end
|
||||
|
||||
if (& a_in) begin
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
end
|
||||
endmodule
|
18
test_regress/t/t_mod_interface_array2.pl
Executable file
18
test_regress/t/t_mod_interface_array2.pl
Executable file
@ -0,0 +1,18 @@
|
||||
#!/usr/bin/perl
|
||||
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 2003 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.
|
||||
|
||||
compile (
|
||||
);
|
||||
|
||||
execute (
|
||||
check_finished=>1,
|
||||
);
|
||||
|
||||
ok(1);
|
||||
1;
|
64
test_regress/t/t_mod_interface_array2.v
Normal file
64
test_regress/t/t_mod_interface_array2.v
Normal file
@ -0,0 +1,64 @@
|
||||
// DESCRIPTION: Verilator: Verilog Test module
|
||||
//
|
||||
// This file ONLY is placed into the Public Domain, for any use,
|
||||
// without warranty, 2015 by Johan Bjork.
|
||||
|
||||
parameter N = 4;
|
||||
// verilator lint_off LITENDIAN
|
||||
|
||||
interface a_if #(parameter PARAM = 0) ();
|
||||
logic long_name;
|
||||
modport source (output long_name);
|
||||
modport sink (input long_name);
|
||||
endinterface
|
||||
|
||||
module intf_source
|
||||
(
|
||||
input logic [0:N-1] intf_input,
|
||||
a_if.source i_intf_source[0:N-1]
|
||||
);
|
||||
generate
|
||||
for (genvar i=0; i < N;i++) begin
|
||||
assign i_intf_source[i].long_name = intf_input[i];
|
||||
end
|
||||
endgenerate
|
||||
endmodule
|
||||
|
||||
module intf_sink
|
||||
(
|
||||
output [0:N-1] a_out,
|
||||
a_if.sink i_intf_sink[0:N-1]
|
||||
);
|
||||
generate
|
||||
for (genvar i=0; i < N;i++) begin
|
||||
assign a_out[i] = i_intf_sink[i].long_name;
|
||||
end
|
||||
endgenerate
|
||||
endmodule
|
||||
|
||||
module t
|
||||
(
|
||||
clk
|
||||
);
|
||||
input clk;
|
||||
logic [0:N-1] a_in;
|
||||
logic [0:N-1] a_out;
|
||||
logic [0:N-1] ack_out;
|
||||
a_if #(.PARAM(1)) tl_intf [0:N-1] ();
|
||||
intf_source source(a_in, tl_intf);
|
||||
intf_sink sink(a_out, tl_intf);
|
||||
|
||||
initial a_in = '0;
|
||||
always @(posedge clk) begin
|
||||
a_in <= a_in + { {N-1 {1'b0}}, 1'b1 };
|
||||
ack_out <= ack_out + { {N-1 {1'b0}}, 1'b1 };
|
||||
if (ack_out != a_out) begin
|
||||
$stop;
|
||||
end
|
||||
|
||||
if (& a_in) begin
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
end
|
||||
endmodule
|
Loading…
Reference in New Issue
Block a user