Support "ref" and "const ref" pins and functions, bug1360.
This commit is contained in:
parent
d3e1dfd3f5
commit
ad2929dff0
2
Changes
2
Changes
|
|
@ -5,6 +5,8 @@ The contributors that suggested a given feature are shown in []. Thanks!
|
||||||
|
|
||||||
* Verilator 4.007 devel
|
* Verilator 4.007 devel
|
||||||
|
|
||||||
|
*** Support "ref" and "const ref" pins and functions, bug1360. [Jake Longo]
|
||||||
|
|
||||||
*** In --xml-only show the original unmodified names, msg2716. [Kanad Kanhere]
|
*** In --xml-only show the original unmodified names, msg2716. [Kanad Kanhere]
|
||||||
|
|
||||||
**** Fix --trace-lxt2 compile error on MinGW, msg2711. [HyungKi Jeong]
|
**** Fix --trace-lxt2 compile error on MinGW, msg2711. [HyungKi Jeong]
|
||||||
|
|
|
||||||
19
src/V3Ast.h
19
src/V3Ast.h
|
|
@ -470,7 +470,9 @@ public:
|
||||||
NONE,
|
NONE,
|
||||||
INPUT,
|
INPUT,
|
||||||
OUTPUT,
|
OUTPUT,
|
||||||
INOUT
|
INOUT,
|
||||||
|
REF,
|
||||||
|
CONSTREF
|
||||||
};
|
};
|
||||||
enum en m_e;
|
enum en m_e;
|
||||||
inline VDirection() : m_e(NONE) {}
|
inline VDirection() : m_e(NONE) {}
|
||||||
|
|
@ -480,23 +482,26 @@ public:
|
||||||
operator en() const { return m_e; }
|
operator en() const { return m_e; }
|
||||||
const char* ascii() const {
|
const char* ascii() const {
|
||||||
static const char* const names[] = {
|
static const char* const names[] = {
|
||||||
"NONE", "INPUT", "OUTPUT", "INOUT"};
|
"NONE", "INPUT", "OUTPUT", "INOUT", "REF", "CONSTREF"};
|
||||||
return names[m_e]; }
|
return names[m_e]; }
|
||||||
string verilogKwd() const {
|
string verilogKwd() const {
|
||||||
static const char* const names[] = {
|
static const char* const names[] = {
|
||||||
"", "input", "output", "inout"};
|
"", "input", "output", "inout", "ref", "const ref"};
|
||||||
return names[m_e]; }
|
return names[m_e]; }
|
||||||
string xmlKwd() const { // For historical reasons no "put" suffix
|
string xmlKwd() const { // For historical reasons no "put" suffix
|
||||||
static const char* const names[] = {
|
static const char* const names[] = {
|
||||||
"", "in", "out", "inout"};
|
"", "in", "out", "inout", "ref", "const ref"};
|
||||||
return names[m_e]; }
|
return names[m_e]; }
|
||||||
string prettyName() const { return verilogKwd(); }
|
string prettyName() const { return verilogKwd(); }
|
||||||
bool isAny() const { return m_e != NONE; }
|
bool isAny() const { return m_e != NONE; }
|
||||||
// Looks like inout - "ish" because not identical to being an INOUT
|
// Looks like inout - "ish" because not identical to being an INOUT
|
||||||
bool isInoutish() const { return m_e == INOUT; }
|
bool isInoutish() const { return m_e == INOUT; }
|
||||||
bool isNonOutput() const { return m_e == INPUT || m_e == INOUT; }
|
bool isNonOutput() const { return m_e == INPUT || m_e == INOUT
|
||||||
bool isReadOnly() const { return m_e == INPUT; }
|
|| m_e == REF || m_e == CONSTREF; }
|
||||||
bool isWritable() const { return m_e == OUTPUT || m_e == INOUT; }
|
bool isReadOnly() const { return m_e == INPUT || m_e == CONSTREF; }
|
||||||
|
bool isWritable() const { return m_e == OUTPUT || m_e == INOUT
|
||||||
|
|| m_e == REF; }
|
||||||
|
bool isRefOrConstRef() const { return m_e == REF || m_e == CONSTREF; }
|
||||||
};
|
};
|
||||||
inline bool operator== (VDirection lhs, VDirection rhs) { return (lhs.m_e == rhs.m_e); }
|
inline bool operator== (VDirection lhs, VDirection rhs) { return (lhs.m_e == rhs.m_e); }
|
||||||
inline bool operator== (VDirection lhs, VDirection::en rhs) { return (lhs.m_e == rhs); }
|
inline bool operator== (VDirection lhs, VDirection::en rhs) { return (lhs.m_e == rhs); }
|
||||||
|
|
|
||||||
|
|
@ -208,50 +208,68 @@ string AstVar::verilogKwd() const {
|
||||||
string AstVar::vlArgType(bool named, bool forReturn, bool forFunc) const {
|
string AstVar::vlArgType(bool named, bool forReturn, bool forFunc) const {
|
||||||
if (forReturn) named=false;
|
if (forReturn) named=false;
|
||||||
if (forReturn) v3fatalSrc("verilator internal data is never passed as return, but as first argument");
|
if (forReturn) v3fatalSrc("verilator internal data is never passed as return, but as first argument");
|
||||||
string arg;
|
string otype;
|
||||||
if (isWide() && isReadOnly()) arg += "const ";
|
|
||||||
AstBasicDType* bdtypep = basicp();
|
AstBasicDType* bdtypep = basicp();
|
||||||
bool strtype = bdtypep && bdtypep->keyword()==AstBasicDTypeKwd::STRING;
|
bool strtype = bdtypep && bdtypep->keyword()==AstBasicDTypeKwd::STRING;
|
||||||
if (bdtypep && bdtypep->keyword()==AstBasicDTypeKwd::CHARPTR) {
|
if (bdtypep && bdtypep->keyword()==AstBasicDTypeKwd::CHARPTR) {
|
||||||
arg += "const char*";
|
otype += "const char*";
|
||||||
} else if (bdtypep && bdtypep->keyword()==AstBasicDTypeKwd::SCOPEPTR) {
|
} else if (bdtypep && bdtypep->keyword()==AstBasicDTypeKwd::SCOPEPTR) {
|
||||||
arg += "const VerilatedScope*";
|
otype += "const VerilatedScope*";
|
||||||
} else if (bdtypep && bdtypep->keyword()==AstBasicDTypeKwd::DOUBLE) {
|
} else if (bdtypep && bdtypep->keyword()==AstBasicDTypeKwd::DOUBLE) {
|
||||||
arg += "double";
|
if (forFunc && isReadOnly()) otype += "const ";
|
||||||
|
otype += "double";
|
||||||
} else if (bdtypep && bdtypep->keyword()==AstBasicDTypeKwd::FLOAT) {
|
} else if (bdtypep && bdtypep->keyword()==AstBasicDTypeKwd::FLOAT) {
|
||||||
arg += "float";
|
if (forFunc && isReadOnly()) otype += "const ";
|
||||||
|
otype += "float";
|
||||||
} else if (strtype) {
|
} else if (strtype) {
|
||||||
if (isReadOnly()) arg += "const ";
|
if (forFunc && isReadOnly()) otype += "const ";
|
||||||
arg += "std::string";
|
otype += "std::string";
|
||||||
} else if (widthMin() <= 8) {
|
} else if (widthMin() <= 8) {
|
||||||
arg += "CData";
|
if (forFunc && isReadOnly()) otype += "const ";
|
||||||
|
otype += "CData";
|
||||||
} else if (widthMin() <= 16) {
|
} else if (widthMin() <= 16) {
|
||||||
arg += "SData";
|
if (forFunc && isReadOnly()) otype += "const ";
|
||||||
|
otype += "SData";
|
||||||
} else if (widthMin() <= VL_WORDSIZE) {
|
} else if (widthMin() <= VL_WORDSIZE) {
|
||||||
arg += "IData";
|
if (forFunc && isReadOnly()) otype += "const ";
|
||||||
|
otype += "IData";
|
||||||
} else if (isQuad()) {
|
} else if (isQuad()) {
|
||||||
arg += "QData";
|
if (forFunc && isReadOnly()) otype += "const ";
|
||||||
|
otype += "QData";
|
||||||
} else if (isWide()) {
|
} else if (isWide()) {
|
||||||
arg += "WData"; // []'s added later
|
if (forFunc && isReadOnly()) otype += "const ";
|
||||||
|
otype += "WData"; // []'s added later
|
||||||
}
|
}
|
||||||
if (isDpiOpenArray() || (isWide() && !strtype)) {
|
|
||||||
arg += " (& "+name()+")";
|
bool mayparen = false; // Need paren, to handle building "(& name)[2]"
|
||||||
|
string oname;
|
||||||
|
if (isDpiOpenArray()
|
||||||
|
|| (isWide() && !strtype)
|
||||||
|
|| (forFunc && (isWritable()
|
||||||
|
|| direction()==VDirection::REF
|
||||||
|
|| direction()==VDirection::CONSTREF
|
||||||
|
|| (strtype && isNonOutput())))) {
|
||||||
|
oname += "&";
|
||||||
|
mayparen = true;
|
||||||
|
}
|
||||||
|
if (named) oname += " "+name();
|
||||||
|
|
||||||
|
string oarray;
|
||||||
|
if (isDpiOpenArray() || direction().isRefOrConstRef()) {
|
||||||
for (AstNodeDType* dtp=dtypep(); dtp; ) {
|
for (AstNodeDType* dtp=dtypep(); dtp; ) {
|
||||||
dtp = dtp->skipRefp(); // Skip AstRefDType/AstTypedef, or return same node
|
dtp = dtp->skipRefp(); // Skip AstRefDType/AstTypedef, or return same node
|
||||||
if (AstUnpackArrayDType* adtypep = VN_CAST(dtp, UnpackArrayDType)) {
|
if (AstUnpackArrayDType* adtypep = VN_CAST(dtp, UnpackArrayDType)) {
|
||||||
arg += "["+cvtToStr(adtypep->declRange().elements())+"]";
|
if (mayparen) { oname = " ("+oname+")"; mayparen = false; }
|
||||||
|
oarray += "["+cvtToStr(adtypep->declRange().elements())+"]";
|
||||||
dtp = adtypep->subDTypep();
|
dtp = adtypep->subDTypep();
|
||||||
} else break;
|
} else break;
|
||||||
}
|
}
|
||||||
if (isWide() && !strtype) {
|
|
||||||
arg += "["+cvtToStr(widthWords())+"]";
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (forFunc && (isWritable()
|
|
||||||
|| (strtype && isNonOutput()))) arg += "&";
|
|
||||||
if (named) arg += " "+name();
|
|
||||||
}
|
}
|
||||||
return arg;
|
if (isWide() && !strtype) {
|
||||||
|
if (mayparen) { oname = " ("+oname+")"; mayparen = false; }
|
||||||
|
oarray += "["+cvtToStr(widthWords())+"]";
|
||||||
|
}
|
||||||
|
return otype+oname+oarray;
|
||||||
}
|
}
|
||||||
|
|
||||||
string AstVar::vlEnumType() const {
|
string AstVar::vlEnumType() const {
|
||||||
|
|
@ -342,7 +360,8 @@ string AstVar::cPubArgType(bool named, bool forReturn) const {
|
||||||
arg += " (& "+name();
|
arg += " (& "+name();
|
||||||
arg += ")["+cvtToStr(widthWords())+"]";
|
arg += ")["+cvtToStr(widthWords())+"]";
|
||||||
} else {
|
} else {
|
||||||
if (!forReturn && isWritable()) arg += "&";
|
if (!forReturn && (isWritable()
|
||||||
|
|| direction().isRefOrConstRef())) arg += "&";
|
||||||
if (named) arg += " "+name();
|
if (named) arg += " "+name();
|
||||||
}
|
}
|
||||||
return arg;
|
return arg;
|
||||||
|
|
|
||||||
|
|
@ -130,6 +130,10 @@ void V3LinkLevel::wrapTopCell(AstNetlist* rootp) {
|
||||||
oldvarp->primaryIO(false);
|
oldvarp->primaryIO(false);
|
||||||
varp->primaryIO(true);
|
varp->primaryIO(true);
|
||||||
}
|
}
|
||||||
|
if (varp->direction().isRefOrConstRef()) {
|
||||||
|
varp->v3error("Unsupported: ref/const ref as primary input/output: "
|
||||||
|
<<varp->prettyName());
|
||||||
|
}
|
||||||
if (varp->isIO() && v3Global.opt.systemC()) {
|
if (varp->isIO() && v3Global.opt.systemC()) {
|
||||||
varp->sc(true);
|
varp->sc(true);
|
||||||
// User can see trace one level down from the wrapper
|
// User can see trace one level down from the wrapper
|
||||||
|
|
|
||||||
|
|
@ -1287,7 +1287,10 @@ private:
|
||||||
if (!nodep->widthMin()) nodep->v3fatalSrc("LHS var should be size complete");
|
if (!nodep->widthMin()) nodep->v3fatalSrc("LHS var should be size complete");
|
||||||
}
|
}
|
||||||
//if (debug()>=9) nodep->dumpTree(cout," VRout ");
|
//if (debug()>=9) nodep->dumpTree(cout," VRout ");
|
||||||
if (nodep->lvalue() && nodep->varp()->isConst()
|
if (nodep->lvalue() && nodep->varp()->direction() == VDirection::CONSTREF) {
|
||||||
|
nodep->v3error("Assigning to const ref variable: "<<nodep->prettyName());
|
||||||
|
}
|
||||||
|
else if (nodep->lvalue() && nodep->varp()->isConst()
|
||||||
&& !m_paramsOnly
|
&& !m_paramsOnly
|
||||||
&& !m_initialp) { // Too loose, but need to allow our generated first assignment
|
&& !m_initialp) { // Too loose, but need to allow our generated first assignment
|
||||||
// // Move this to a property of the AstInitial block
|
// // Move this to a property of the AstInitial block
|
||||||
|
|
@ -2319,7 +2322,13 @@ private:
|
||||||
}
|
}
|
||||||
userIterateAndNext(nodep->exprp(), WidthVP(subDTypep,FINAL).p());
|
userIterateAndNext(nodep->exprp(), WidthVP(subDTypep,FINAL).p());
|
||||||
} else {
|
} else {
|
||||||
if (nodep->modVarp()->isTristate()) {
|
if (nodep->modVarp()->direction() == VDirection::REF) {
|
||||||
|
nodep->v3error("Ref connection '"<<nodep->modVarp()->prettyName()<<"'"
|
||||||
|
<<" requires matching types;"
|
||||||
|
<<" ref requires "<<pinDTypep->prettyTypeName()
|
||||||
|
<<" but connection is "
|
||||||
|
<<conDTypep->prettyTypeName()<<"."<<endl);
|
||||||
|
} else if (nodep->modVarp()->isTristate()) {
|
||||||
if (pinwidth != conwidth) {
|
if (pinwidth != conwidth) {
|
||||||
nodep->v3error("Unsupported: "<<ucfirst(nodep->prettyOperatorName())
|
nodep->v3error("Unsupported: "<<ucfirst(nodep->prettyOperatorName())
|
||||||
<<" to inout signal requires "<<pinwidth
|
<<" to inout signal requires "<<pinwidth
|
||||||
|
|
@ -2557,9 +2566,16 @@ private:
|
||||||
AstArg* argp = it->second;
|
AstArg* argp = it->second;
|
||||||
AstNode* pinp = argp->exprp();
|
AstNode* pinp = argp->exprp();
|
||||||
if (!pinp) continue; // Argument error we'll find later
|
if (!pinp) continue; // Argument error we'll find later
|
||||||
if (portp->isWritable()
|
if (portp->direction() == VDirection::REF
|
||||||
&& pinp->width() != portp->width()) {
|
&& !similarDTypeRecurse(portp->dtypep(), pinp->dtypep())) {
|
||||||
pinp->v3error("Unsupported: Function output argument '"<<portp->prettyName()<<"'"
|
pinp->v3error("Ref argument requires matching types;"
|
||||||
|
<<" port '"<<portp->prettyName()<<"'"
|
||||||
|
<<" requires "<<portp->prettyTypeName()
|
||||||
|
<<" but connection is "<<pinp->prettyTypeName()<<".");
|
||||||
|
} else if (portp->isWritable()
|
||||||
|
&& pinp->width() != portp->width()) {
|
||||||
|
pinp->v3error("Unsupported: Function output argument '"
|
||||||
|
<<portp->prettyName()<<"'"
|
||||||
<<" requires "<<portp->width()
|
<<" requires "<<portp->width()
|
||||||
<<" bits, but connection's "<<pinp->prettyTypeName()
|
<<" bits, but connection's "<<pinp->prettyTypeName()
|
||||||
<<" generates "<<pinp->width()<<" bits.");
|
<<" generates "<<pinp->width()<<" bits.");
|
||||||
|
|
|
||||||
|
|
@ -1301,8 +1301,8 @@ port_direction: // ==IEEE: port_direction + tf_port_direction
|
||||||
yINPUT { VARIO(INPUT); }
|
yINPUT { VARIO(INPUT); }
|
||||||
| yOUTPUT { VARIO(OUTPUT); }
|
| yOUTPUT { VARIO(OUTPUT); }
|
||||||
| yINOUT { VARIO(INOUT); }
|
| yINOUT { VARIO(INOUT); }
|
||||||
| yREF { $<fl>1->v3error("Unsupported: ref port"); VARIO(INOUT); }
|
| yREF { VARIO(REF); }
|
||||||
| yCONST__REF yREF { $<fl>1->v3error("Unsupported: const ref port"); VARIO(INOUT); }
|
| yCONST__REF yREF { VARIO(CONSTREF); }
|
||||||
;
|
;
|
||||||
|
|
||||||
port_directionReset: // IEEE: port_direction that starts a port_declaraiton
|
port_directionReset: // IEEE: port_direction that starts a port_declaraiton
|
||||||
|
|
@ -1310,8 +1310,8 @@ port_directionReset: // IEEE: port_direction that starts a port_declaraiton
|
||||||
yINPUT { VARRESET_NONLIST(UNKNOWN); VARIO(INPUT); }
|
yINPUT { VARRESET_NONLIST(UNKNOWN); VARIO(INPUT); }
|
||||||
| yOUTPUT { VARRESET_NONLIST(UNKNOWN); VARIO(OUTPUT); }
|
| yOUTPUT { VARRESET_NONLIST(UNKNOWN); VARIO(OUTPUT); }
|
||||||
| yINOUT { VARRESET_NONLIST(UNKNOWN); VARIO(INOUT); }
|
| yINOUT { VARRESET_NONLIST(UNKNOWN); VARIO(INOUT); }
|
||||||
| yREF { $<fl>1->v3error("Unsupported: ref port"); VARRESET_NONLIST(UNKNOWN); VARIO(INOUT); }
|
| yREF { VARRESET_NONLIST(UNKNOWN); VARIO(REF); }
|
||||||
| yCONST__REF yREF { $<fl>1->v3error("Unsupported: const ref port"); VARRESET_NONLIST(UNKNOWN); VARIO(INOUT); }
|
| yCONST__REF yREF { VARRESET_NONLIST(UNKNOWN); VARIO(CONSTREF); }
|
||||||
;
|
;
|
||||||
|
|
||||||
port_declaration<nodep>: // ==IEEE: port_declaration
|
port_declaration<nodep>: // ==IEEE: port_declaration
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,20 @@
|
||||||
|
#!/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.
|
||||||
|
|
||||||
|
scenarios(simulator => 1);
|
||||||
|
|
||||||
|
compile(
|
||||||
|
);
|
||||||
|
|
||||||
|
execute(
|
||||||
|
check_finished => 1,
|
||||||
|
);
|
||||||
|
|
||||||
|
ok(1);
|
||||||
|
1;
|
||||||
|
|
@ -0,0 +1,94 @@
|
||||||
|
// DESCRIPTION: Verilator: Verilog Test module
|
||||||
|
//
|
||||||
|
// This file ONLY is placed into the Public Domain, for any use,
|
||||||
|
// without warranty, 2018 by Wilson Snyder.
|
||||||
|
|
||||||
|
`define checkh(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got='h%x exp='h%x\n", `__FILE__,`__LINE__, (gotv), (expv));; end while(0);
|
||||||
|
|
||||||
|
module t(/*AUTOARG*/
|
||||||
|
// Inputs
|
||||||
|
clk
|
||||||
|
);
|
||||||
|
input clk;
|
||||||
|
|
||||||
|
int cyc;
|
||||||
|
|
||||||
|
int vr;
|
||||||
|
int va[2];
|
||||||
|
|
||||||
|
`ifdef T_NOINLINE
|
||||||
|
// verilator no_inline_module
|
||||||
|
`endif
|
||||||
|
|
||||||
|
//====
|
||||||
|
|
||||||
|
task fun(ref int r, const ref int c);
|
||||||
|
`ifdef T_NOINLINE
|
||||||
|
// verilator no_inline_task
|
||||||
|
`endif
|
||||||
|
`checkh(c, 32'h1234);
|
||||||
|
r = 32'h4567;
|
||||||
|
endtask
|
||||||
|
|
||||||
|
initial begin
|
||||||
|
int ci;
|
||||||
|
int ri;
|
||||||
|
ci = 32'h1234;
|
||||||
|
fun(ri, ci);
|
||||||
|
`checkh(ri, 32'h4567);
|
||||||
|
end
|
||||||
|
|
||||||
|
//====
|
||||||
|
|
||||||
|
task fun_array(ref int af[2], const ref int cf[2]);
|
||||||
|
`ifdef T_NOINLINE
|
||||||
|
// verilator no_inline_task
|
||||||
|
`endif
|
||||||
|
`checkh(cf[0], 32'h1234);
|
||||||
|
`checkh(cf[1], 32'h2345);
|
||||||
|
af[0] = 32'h5678;
|
||||||
|
af[1] = 32'h6789;
|
||||||
|
endtask
|
||||||
|
// Not checkint - element of unpacked array
|
||||||
|
|
||||||
|
initial begin
|
||||||
|
int ca[2];
|
||||||
|
int ra[2];
|
||||||
|
ca[0] = 32'h1234;
|
||||||
|
ca[1] = 32'h2345;
|
||||||
|
fun_array(ra, ca);
|
||||||
|
`checkh(ra[0], 32'h5678);
|
||||||
|
`checkh(ra[1], 32'h6789);
|
||||||
|
end
|
||||||
|
|
||||||
|
//====
|
||||||
|
|
||||||
|
sub sub(.clk, .vr, .va);
|
||||||
|
|
||||||
|
always @ (posedge clk) begin
|
||||||
|
cyc <= cyc + 1;
|
||||||
|
if (cyc == 0) begin
|
||||||
|
vr <= 32'h789;
|
||||||
|
va[0] <= 32'h89a;
|
||||||
|
va[1] <= 32'h9ab;
|
||||||
|
end
|
||||||
|
else if (cyc == 2) begin
|
||||||
|
`checkh(vr, 32'h987);
|
||||||
|
`checkh(va[0], 32'ha98);
|
||||||
|
`checkh(va[1], 32'ha9b);
|
||||||
|
$write("*-* All Finished *-*\n");
|
||||||
|
$finish;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
module sub(input clk, ref int vr, ref int va[2]);
|
||||||
|
|
||||||
|
always @(posedge clk) begin
|
||||||
|
vr <= 32'h987;
|
||||||
|
va[0] <= 32'ha98;
|
||||||
|
va[1] <= 32'ha9b;
|
||||||
|
end
|
||||||
|
|
||||||
|
endmodule
|
||||||
|
|
@ -0,0 +1,24 @@
|
||||||
|
#!/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.
|
||||||
|
|
||||||
|
scenarios(simulator => 1);
|
||||||
|
|
||||||
|
compile(
|
||||||
|
v_flags2 => ["--lint-only"],
|
||||||
|
make_top_shell => 0,
|
||||||
|
make_main => 0,
|
||||||
|
verilator_make_gcc => 0,
|
||||||
|
fails => 1,
|
||||||
|
expect =>
|
||||||
|
q{%Error: t/t_var_ref_bad1.v:\d+: Ref connection 'bad_sub_ref' requires matching types; ref requires BASICDTYPE 'real' but connection is BASICDTYPE 'bit'.
|
||||||
|
.*%Error: Exiting due to.*},
|
||||||
|
);
|
||||||
|
|
||||||
|
ok(1);
|
||||||
|
1;
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
// DESCRIPTION: Verilator: Verilog Test module
|
||||||
|
//
|
||||||
|
// This file ONLY is placed into the Public Domain, for any use,
|
||||||
|
// without warranty, 2018 by Wilson Snyder.
|
||||||
|
|
||||||
|
// Make sure type errors aren't suppressable
|
||||||
|
// verilator lint_off WIDTH
|
||||||
|
|
||||||
|
module t(/*AUTOARG*/);
|
||||||
|
|
||||||
|
bit bad_parent;
|
||||||
|
sub sub
|
||||||
|
(.bad_sub_ref(bad_parent)); // Type mismatch
|
||||||
|
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
module sub(ref real bad_sub_ref);
|
||||||
|
endmodule
|
||||||
|
|
@ -0,0 +1,25 @@
|
||||||
|
#!/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.
|
||||||
|
|
||||||
|
scenarios(simulator => 1);
|
||||||
|
|
||||||
|
compile(
|
||||||
|
v_flags2 => ["--lint-only"],
|
||||||
|
make_top_shell => 0,
|
||||||
|
make_main => 0,
|
||||||
|
verilator_make_gcc => 0,
|
||||||
|
fails => 1,
|
||||||
|
expect =>
|
||||||
|
q{%Error: t/t_var_ref_bad2.v:\d+: Assigning to const ref variable: bad_const_set
|
||||||
|
%Error: t/t_var_ref_bad2.v:\d+: Ref argument requires matching types; port 'int_ref' requires VAR 'int_ref' but connection is VARREF 'bad_non_int'.
|
||||||
|
.*%Error: Exiting due to.*},
|
||||||
|
);
|
||||||
|
|
||||||
|
ok(1);
|
||||||
|
1;
|
||||||
|
|
@ -0,0 +1,24 @@
|
||||||
|
// DESCRIPTION: Verilator: Verilog Test module
|
||||||
|
//
|
||||||
|
// This file ONLY is placed into the Public Domain, for any use,
|
||||||
|
// without warranty, 2018 by Wilson Snyder.
|
||||||
|
|
||||||
|
// Make sure type errors aren't suppressable
|
||||||
|
// verilator lint_off WIDTH
|
||||||
|
|
||||||
|
module t(/*AUTOARG*/);
|
||||||
|
|
||||||
|
task checkset(const ref int bad_const_set);
|
||||||
|
bad_const_set = 32'h4567; // Bad setting const
|
||||||
|
endtask
|
||||||
|
|
||||||
|
task checkset2(ref int int_ref);
|
||||||
|
endtask
|
||||||
|
|
||||||
|
initial begin
|
||||||
|
int i;
|
||||||
|
byte bad_non_int;
|
||||||
|
checkset(i);
|
||||||
|
checkset2(bad_non_int); // Type mismatch
|
||||||
|
end
|
||||||
|
endmodule
|
||||||
|
|
@ -0,0 +1,24 @@
|
||||||
|
#!/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.
|
||||||
|
|
||||||
|
scenarios(simulator => 1);
|
||||||
|
|
||||||
|
compile(
|
||||||
|
v_flags2 => ["--lint-only"],
|
||||||
|
make_top_shell => 0,
|
||||||
|
make_main => 0,
|
||||||
|
verilator_make_gcc => 0,
|
||||||
|
fails => 1,
|
||||||
|
expect =>
|
||||||
|
q{%Error: t/t_var_ref_bad3.v:\d+: Unsupported: ref/const ref as primary input/output: bad_primary_ref
|
||||||
|
.*%Error: Exiting due to.*},
|
||||||
|
);
|
||||||
|
|
||||||
|
ok(1);
|
||||||
|
1;
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
// DESCRIPTION: Verilator: Verilog Test module
|
||||||
|
//
|
||||||
|
// This file ONLY is placed into the Public Domain, for any use,
|
||||||
|
// without warranty, 2018 by Wilson Snyder.
|
||||||
|
|
||||||
|
// Make sure type errors aren't suppressable
|
||||||
|
// verilator lint_off WIDTH
|
||||||
|
|
||||||
|
module t(ref int bad_primary_ref
|
||||||
|
/*AUTOARG*/);
|
||||||
|
endmodule
|
||||||
|
|
@ -0,0 +1,23 @@
|
||||||
|
#!/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.
|
||||||
|
|
||||||
|
top_filename("t/t_var_ref.v");
|
||||||
|
|
||||||
|
scenarios(simulator => 1);
|
||||||
|
|
||||||
|
compile(
|
||||||
|
v_flags2 => ['+define+T_NOINLINE'],
|
||||||
|
);
|
||||||
|
|
||||||
|
execute(
|
||||||
|
check_finished => 1,
|
||||||
|
);
|
||||||
|
|
||||||
|
ok(1);
|
||||||
|
1;
|
||||||
Loading…
Reference in New Issue