Fix interface inside generate, bug1001, bug1003.

Signed-off-by: Wilson Snyder <wsnyder@wsnyder.org>
This commit is contained in:
Todd Strader 2015-12-05 19:39:40 -05:00 committed by Wilson Snyder
parent f0af8726e3
commit 5e54d3e41a
27 changed files with 832 additions and 31 deletions

View File

@ -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]

View File

@ -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);
}

View File

@ -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

View File

@ -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);
}

View File

@ -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);

View File

@ -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);

View File

@ -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()) {

View File

@ -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

View 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;

View 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

View 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;

View 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

View File

@ -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

View 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;

View 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

View 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;

View 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

View 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;

View 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

View 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;

View 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

View 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;

View 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

View 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;

View 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

View 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;

View 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