Support byte, shortint, int, longint in variables, parameters and functions.
Internals: function/var sizing and signing now comes via dtypep() Internals: cleanup code that widths parameters (again)
This commit is contained in:
parent
4c26792c9b
commit
6bc81d3d26
5
Changes
5
Changes
|
|
@ -3,6 +3,11 @@ Revision history for Verilator
|
||||||
The contributors that suggested a given feature are shown in []. [by ...]
|
The contributors that suggested a given feature are shown in []. [by ...]
|
||||||
indicates the contributor was also the author of the fix; Thanks!
|
indicates the contributor was also the author of the fix; Thanks!
|
||||||
|
|
||||||
|
* Verilator 3.7**
|
||||||
|
|
||||||
|
*** Support byte, shortint, int, longint in variables, parameters and
|
||||||
|
functions.
|
||||||
|
|
||||||
* Verilator 3.720 2009/10/26
|
* Verilator 3.720 2009/10/26
|
||||||
|
|
||||||
** Support little endian bit vectors ("reg [0:2] x;").
|
** Support little endian bit vectors ("reg [0:2] x;").
|
||||||
|
|
|
||||||
|
|
@ -1700,13 +1700,13 @@ This section describes specific limitations for each language keyword.
|
||||||
|
|
||||||
Fully supported.
|
Fully supported.
|
||||||
|
|
||||||
=item always, always_comb, always_ff, always_latch, and, assign, begin,
|
=item int, shortint, longint, always, always_comb, always_ff, always_latch,
|
||||||
buf, case, casex, casez, default, defparam, do-while, else, end, endcase,
|
and, assign, begin, buf, byte, case, casex, casez, default, defparam,
|
||||||
endfunction, endgenerate, endmodule, endspecify, endtask, final, for,
|
do-while, else, end, endcase, endfunction, endgenerate, endmodule,
|
||||||
function, generate, genvar, if, initial, inout, input, integer, localparam,
|
endspecify, endtask, final, for, function, generate, genvar, if, initial,
|
||||||
macromodule, module, nand, negedge, nor, not, or, output, parameter,
|
inout, input, integer, logic, localparam, macromodule, module, nand,
|
||||||
posedge, reg, scalared, signed, supply0, supply1, task, tri, vectored,
|
negedge, nor, not, or, output, parameter, posedge, reg, scalared, signed,
|
||||||
while, wire, xnor, xor
|
supply0, supply1, task, tri, vectored, while, wire, xnor, xor
|
||||||
|
|
||||||
Generally supported.
|
Generally supported.
|
||||||
|
|
||||||
|
|
|
||||||
42
src/V3Ast.h
42
src/V3Ast.h
|
|
@ -202,13 +202,16 @@ class AstBasicDTypeKwd {
|
||||||
public:
|
public:
|
||||||
enum en {
|
enum en {
|
||||||
BYTE, SHORTINT, INT, LONGINT, INTEGER, TIME, BIT,
|
BYTE, SHORTINT, INT, LONGINT, INTEGER, TIME, BIT,
|
||||||
LOGIC, REG, SHORTREAL, REAL, REALTIME
|
LOGIC, SHORTREAL, REAL, REALTIME,
|
||||||
|
// Internal types
|
||||||
|
LOGIC_IMPLICIT
|
||||||
};
|
};
|
||||||
enum en m_e;
|
enum en m_e;
|
||||||
const char* ascii() const {
|
const char* ascii() const {
|
||||||
static const char* names[] = {
|
static const char* names[] = {
|
||||||
"byte", "shortint", "int", "longint", "integer", "time", "bit",
|
"byte", "shortint", "int", "longint", "integer", "time", "bit",
|
||||||
"logic", "reg", "shortreal", "real", "realtime"
|
"logic", "shortreal", "real", "realtime",
|
||||||
|
"LOGIC_IMPLICIT"
|
||||||
};
|
};
|
||||||
return names[m_e];
|
return names[m_e];
|
||||||
};
|
};
|
||||||
|
|
@ -216,6 +219,30 @@ public:
|
||||||
inline AstBasicDTypeKwd (en _e) : m_e(_e) {}
|
inline AstBasicDTypeKwd (en _e) : m_e(_e) {}
|
||||||
explicit inline AstBasicDTypeKwd (int _e) : m_e(static_cast<en>(_e)) {}
|
explicit inline AstBasicDTypeKwd (int _e) : m_e(static_cast<en>(_e)) {}
|
||||||
operator en () const { return m_e; }
|
operator en () const { return m_e; }
|
||||||
|
int width() const {
|
||||||
|
switch (m_e) {
|
||||||
|
case BYTE: return 8;
|
||||||
|
case SHORTINT: return 16;
|
||||||
|
case INT: return 32;
|
||||||
|
case LONGINT: return 64;
|
||||||
|
case INTEGER: return 32;
|
||||||
|
case LOGIC: return 1;
|
||||||
|
case BIT: return 1;
|
||||||
|
default: return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
int isSigned() const {
|
||||||
|
return m_e==BYTE || m_e==SHORTINT || m_e==INT || m_e==LONGINT || m_e==INTEGER;
|
||||||
|
}
|
||||||
|
int isFourstate() const {
|
||||||
|
return m_e==INTEGER || m_e==LOGIC || m_e==LOGIC_IMPLICIT;
|
||||||
|
}
|
||||||
|
int isSloppy() const { // Don't be as anal about width warnings
|
||||||
|
return !(m_e==LOGIC || m_e==BIT);
|
||||||
|
}
|
||||||
|
int isBitLogic() const { // Don't be as anal about width warnings
|
||||||
|
return (m_e==LOGIC || m_e==BIT);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
inline bool operator== (AstBasicDTypeKwd lhs, AstBasicDTypeKwd rhs) { return (lhs.m_e == rhs.m_e); }
|
inline bool operator== (AstBasicDTypeKwd lhs, AstBasicDTypeKwd rhs) { return (lhs.m_e == rhs.m_e); }
|
||||||
inline bool operator== (AstBasicDTypeKwd lhs, AstBasicDTypeKwd::en rhs) { return (lhs.m_e == rhs); }
|
inline bool operator== (AstBasicDTypeKwd lhs, AstBasicDTypeKwd::en rhs) { return (lhs.m_e == rhs); }
|
||||||
|
|
@ -244,7 +271,7 @@ public:
|
||||||
SUPPLY0,
|
SUPPLY0,
|
||||||
SUPPLY1,
|
SUPPLY1,
|
||||||
WIRE,
|
WIRE,
|
||||||
IMPLICIT,
|
IMPLICITWIRE,
|
||||||
TRIWIRE,
|
TRIWIRE,
|
||||||
PORT, // Temp type used in parser only
|
PORT, // Temp type used in parser only
|
||||||
BLOCKTEMP,
|
BLOCKTEMP,
|
||||||
|
|
@ -261,7 +288,7 @@ public:
|
||||||
static const char* names[] = {
|
static const char* names[] = {
|
||||||
"?","GPARAM","LPARAM","GENVAR",
|
"?","GPARAM","LPARAM","GENVAR",
|
||||||
"VAR","INPUT","OUTPUT","INOUT",
|
"VAR","INPUT","OUTPUT","INOUT",
|
||||||
"SUPPLY0","SUPPLY1","WIRE","IMPLICIT","TRIWIRE","PORT",
|
"SUPPLY0","SUPPLY1","WIRE","IMPLICITWIRE","TRIWIRE","PORT",
|
||||||
"BLOCKTEMP","MODULETEMP","STMTTEMP","XTEMP"};
|
"BLOCKTEMP","MODULETEMP","STMTTEMP","XTEMP"};
|
||||||
return names[m_e]; }
|
return names[m_e]; }
|
||||||
};
|
};
|
||||||
|
|
@ -1176,12 +1203,13 @@ struct AstNodeSel : public AstNodeBiop {
|
||||||
struct AstNodeFTask : public AstNode {
|
struct AstNodeFTask : public AstNode {
|
||||||
private:
|
private:
|
||||||
string m_name; // Name of task
|
string m_name; // Name of task
|
||||||
bool m_taskPublic; // Public task
|
bool m_taskPublic:1; // Public task
|
||||||
|
bool m_didSigning:1; // V3Signed completed; can skip iteration
|
||||||
public:
|
public:
|
||||||
// Node that simply puts name into the output stream
|
// Node that simply puts name into the output stream
|
||||||
AstNodeFTask(FileLine* fileline, const string& name, AstNode* stmtsp)
|
AstNodeFTask(FileLine* fileline, const string& name, AstNode* stmtsp)
|
||||||
: AstNode(fileline)
|
: AstNode(fileline)
|
||||||
, m_name(name), m_taskPublic(false) {
|
, m_name(name), m_taskPublic(false), m_didSigning(false) {
|
||||||
addNOp3p(stmtsp);
|
addNOp3p(stmtsp);
|
||||||
}
|
}
|
||||||
ASTNODE_BASE_FUNCS(NodeFTask)
|
ASTNODE_BASE_FUNCS(NodeFTask)
|
||||||
|
|
@ -1195,6 +1223,8 @@ public:
|
||||||
void addStmtsp(AstNode* nodep) { addNOp3p(nodep); }
|
void addStmtsp(AstNode* nodep) { addNOp3p(nodep); }
|
||||||
void taskPublic(bool flag) { m_taskPublic=flag; }
|
void taskPublic(bool flag) { m_taskPublic=flag; }
|
||||||
bool taskPublic() const { return m_taskPublic; }
|
bool taskPublic() const { return m_taskPublic; }
|
||||||
|
void didSigning(bool flag) { m_didSigning=flag; }
|
||||||
|
bool didSigning() const { return m_didSigning; }
|
||||||
};
|
};
|
||||||
|
|
||||||
struct AstNodeFTaskRef : public AstNode {
|
struct AstNodeFTaskRef : public AstNode {
|
||||||
|
|
|
||||||
|
|
@ -98,14 +98,12 @@ string AstVar::verilogKwd() const {
|
||||||
return "input";
|
return "input";
|
||||||
} else if (isOutput()) {
|
} else if (isOutput()) {
|
||||||
return "output";
|
return "output";
|
||||||
} else if (isInteger()) {
|
|
||||||
return "integer";
|
|
||||||
} else if (isTristate()) {
|
} else if (isTristate()) {
|
||||||
return "tri";
|
return "tri";
|
||||||
} else if (varType()==AstVarType::WIRE) {
|
} else if (varType()==AstVarType::WIRE) {
|
||||||
return "wire";
|
return "wire";
|
||||||
} else {
|
} else {
|
||||||
return "reg";
|
return dtypep()->name();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -327,6 +325,7 @@ void AstAttrOf::dump(ostream& str) {
|
||||||
void AstBasicDType::dump(ostream& str) {
|
void AstBasicDType::dump(ostream& str) {
|
||||||
this->AstNode::dump(str);
|
this->AstNode::dump(str);
|
||||||
str<<" ["<<keyword().ascii()<<"]";
|
str<<" ["<<keyword().ascii()<<"]";
|
||||||
|
if (implicit()) str<<" [IMPLICIT]";
|
||||||
}
|
}
|
||||||
void AstCast::dump(ostream& str) {
|
void AstCast::dump(ostream& str) {
|
||||||
this->AstNode::dump(str);
|
this->AstNode::dump(str);
|
||||||
|
|
|
||||||
|
|
@ -109,6 +109,7 @@ struct AstBasicDType : public AstNodeDType {
|
||||||
// Builtin atomic/vectored data type
|
// Builtin atomic/vectored data type
|
||||||
private:
|
private:
|
||||||
AstBasicDTypeKwd m_keyword; // What keyword created it
|
AstBasicDTypeKwd m_keyword; // What keyword created it
|
||||||
|
bool m_implicit; // Implicitly declared
|
||||||
public:
|
public:
|
||||||
AstBasicDType(FileLine* fl, AstBasicDTypeKwd kwd, AstRange* rangep=NULL, AstSignedState signst=signedst_NOP)
|
AstBasicDType(FileLine* fl, AstBasicDTypeKwd kwd, AstRange* rangep=NULL, AstSignedState signst=signedst_NOP)
|
||||||
: AstNodeDType(fl), m_keyword(kwd) {
|
: AstNodeDType(fl), m_keyword(kwd) {
|
||||||
|
|
@ -116,14 +117,24 @@ public:
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
void init(AstSignedState signst, AstRange* rangep) {
|
void init(AstSignedState signst, AstRange* rangep) {
|
||||||
if (rangep==NULL) { // Set based on keyword properties
|
// Implicitness: // "parameter X" is implicit and sized from initial value, "parameter reg x" not
|
||||||
if (m_keyword == AstBasicDTypeKwd::INTEGER) {
|
m_implicit = false;
|
||||||
rangep = new AstRange(fileline(),31,0); signst = signedst_SIGNED;
|
if (keyword()==AstBasicDTypeKwd::LOGIC_IMPLICIT) {
|
||||||
}
|
if (!rangep) m_implicit = true;
|
||||||
|
m_keyword = AstBasicDTypeKwd::LOGIC;
|
||||||
}
|
}
|
||||||
setNOp1p(rangep); setSignedState(signst);
|
if (signst == signedst_NOP && keyword().isSigned()) signst = signedst_SIGNED;
|
||||||
|
setSignedState(signst);
|
||||||
|
if (!rangep) { // Set based on keyword properties
|
||||||
|
// V3Width will pull from this width
|
||||||
|
if (keyword().width() > 1) rangep = new AstRange(fileline(), keyword().width()-1, 0);
|
||||||
|
width(keyword().width(), keyword().width());
|
||||||
|
} else {
|
||||||
|
widthFrom(rangep); // Maybe unknown if parameters underneath it
|
||||||
|
}
|
||||||
|
setNOp1p(rangep);
|
||||||
}
|
}
|
||||||
AstBasicDTypeKwd keyword() const { return m_keyword; }
|
AstBasicDTypeKwd keyword() const { return m_keyword; } // private - use isSomething accessors instead
|
||||||
public:
|
public:
|
||||||
ASTNODE_NODE_FUNCS(BasicDType, BASICDTYPE)
|
ASTNODE_NODE_FUNCS(BasicDType, BASICDTYPE)
|
||||||
virtual void dump(ostream& str);
|
virtual void dump(ostream& str);
|
||||||
|
|
@ -137,13 +148,15 @@ public:
|
||||||
if (signst!=signedst_NOP) isSigned(signst==signedst_SIGNED);
|
if (signst!=signedst_NOP) isSigned(signst==signedst_SIGNED);
|
||||||
}
|
}
|
||||||
// METHODS
|
// METHODS
|
||||||
bool isInteger() const { return (keyword() == AstBasicDTypeKwd::INTEGER); }
|
bool isBitLogic() const { return keyword().isBitLogic(); }
|
||||||
|
bool isSloppy() const { return keyword().isSloppy(); }
|
||||||
int msb() const { if (!rangep()) return 0; return rangep()->msbConst(); }
|
int msb() const { if (!rangep()) return 0; return rangep()->msbConst(); }
|
||||||
int lsb() const { if (!rangep()) return 0; return rangep()->lsbConst(); }
|
int lsb() const { if (!rangep()) return 0; return rangep()->lsbConst(); }
|
||||||
int msbEndianed() const { if (!rangep()) return 0; return littleEndian()?rangep()->lsbConst():rangep()->msbConst(); }
|
int msbEndianed() const { if (!rangep()) return 0; return littleEndian()?rangep()->lsbConst():rangep()->msbConst(); }
|
||||||
int lsbEndianed() const { if (!rangep()) return 0; return littleEndian()?rangep()->msbConst():rangep()->lsbConst(); }
|
int lsbEndianed() const { if (!rangep()) return 0; return littleEndian()?rangep()->msbConst():rangep()->lsbConst(); }
|
||||||
int msbMaxSelect() const { return (lsb()<0 ? msb()-lsb() : msb()); } // Maximum value a [] select may index
|
int msbMaxSelect() const { return (lsb()<0 ? msb()-lsb() : msb()); } // Maximum value a [] select may index
|
||||||
bool littleEndian() const { return (rangep() && rangep()->littleEndian()); }
|
bool littleEndian() const { return (rangep() && rangep()->littleEndian()); }
|
||||||
|
bool implicit() const { return m_implicit; }
|
||||||
};
|
};
|
||||||
|
|
||||||
struct AstArraySel : public AstNodeSel {
|
struct AstArraySel : public AstNodeSel {
|
||||||
|
|
@ -384,12 +397,12 @@ public:
|
||||||
bool isPrimaryIO() const { return m_primaryIO; }
|
bool isPrimaryIO() const { return m_primaryIO; }
|
||||||
bool isPrimaryIn() const { return isPrimaryIO() && isInput(); }
|
bool isPrimaryIn() const { return isPrimaryIO() && isInput(); }
|
||||||
bool isIO() const { return (m_input||m_output); }
|
bool isIO() const { return (m_input||m_output); }
|
||||||
bool isSignal() const { return (varType()==AstVarType::WIRE || varType()==AstVarType::IMPLICIT
|
bool isSignal() const { return (varType()==AstVarType::WIRE || varType()==AstVarType::IMPLICITWIRE
|
||||||
|| varType()==AstVarType::VAR); }
|
|| varType()==AstVarType::VAR); }
|
||||||
bool isTemp() const { return (varType()==AstVarType::BLOCKTEMP || varType()==AstVarType::MODULETEMP
|
bool isTemp() const { return (varType()==AstVarType::BLOCKTEMP || varType()==AstVarType::MODULETEMP
|
||||||
|| varType()==AstVarType::STMTTEMP || varType()==AstVarType::XTEMP); }
|
|| varType()==AstVarType::STMTTEMP || varType()==AstVarType::XTEMP); }
|
||||||
bool isToggleCoverable() const { return ((isIO() || isSignal())
|
bool isToggleCoverable() const { return ((isIO() || isSignal())
|
||||||
&& (isIO() || !isInteger())
|
&& (isIO() || isBitLogic())
|
||||||
// Wrapper would otherwise duplicate wrapped module's coverage
|
// Wrapper would otherwise duplicate wrapped module's coverage
|
||||||
&& !isSc() && !isPrimaryIO()); }
|
&& !isSc() && !isPrimaryIO()); }
|
||||||
bool isStatementTemp() const { return (varType()==AstVarType::STMTTEMP); }
|
bool isStatementTemp() const { return (varType()==AstVarType::STMTTEMP); }
|
||||||
|
|
@ -398,7 +411,7 @@ public:
|
||||||
bool isParam() const { return (varType()==AstVarType::LPARAM || varType()==AstVarType::GPARAM); }
|
bool isParam() const { return (varType()==AstVarType::LPARAM || varType()==AstVarType::GPARAM); }
|
||||||
bool isGParam() const { return (varType()==AstVarType::GPARAM); }
|
bool isGParam() const { return (varType()==AstVarType::GPARAM); }
|
||||||
bool isGenVar() const { return (varType()==AstVarType::GENVAR); }
|
bool isGenVar() const { return (varType()==AstVarType::GENVAR); }
|
||||||
bool isInteger() const { return dtypep()->castBasicDType() && dtypep()->castBasicDType()->isInteger(); }
|
bool isBitLogic() const { return dtypep()->castBasicDType() && dtypep()->castBasicDType()->isBitLogic(); }
|
||||||
bool isUsedClock() const { return m_usedClock; }
|
bool isUsedClock() const { return m_usedClock; }
|
||||||
bool isUsedParam() const { return m_usedParam; }
|
bool isUsedParam() const { return m_usedParam; }
|
||||||
bool isSc() const { return m_sc; }
|
bool isSc() const { return m_sc; }
|
||||||
|
|
|
||||||
|
|
@ -138,7 +138,6 @@ private:
|
||||||
|
|
||||||
//=======
|
//=======
|
||||||
// These have proper signedness set when they were created.
|
// These have proper signedness set when they were created.
|
||||||
virtual void visit(AstFunc* nodep, AstNUser*) { nodep->iterateChildren(*this); }
|
|
||||||
virtual void visit(AstNodeDType* nodep, AstNUser*) { nodep->iterateChildren(*this); }
|
virtual void visit(AstNodeDType* nodep, AstNUser*) { nodep->iterateChildren(*this); }
|
||||||
|
|
||||||
// Inherit from others
|
// Inherit from others
|
||||||
|
|
@ -150,20 +149,28 @@ private:
|
||||||
nodep->varp()->iterate(*this);
|
nodep->varp()->iterate(*this);
|
||||||
nodep->signedFrom(nodep->varp());
|
nodep->signedFrom(nodep->varp());
|
||||||
}
|
}
|
||||||
virtual void visit(AstFuncRef* nodep, AstNUser* vup) {
|
|
||||||
visit(nodep->castNodeFTaskRef(), vup); // Deal with as if was task
|
|
||||||
nodep->signedFrom(nodep->taskp());
|
|
||||||
}
|
|
||||||
virtual void visit(AstConst* nodep, AstNUser*) {
|
virtual void visit(AstConst* nodep, AstNUser*) {
|
||||||
// The node got setup with the signed state of the node.
|
// The node got setup with the signed state of the node.
|
||||||
// However a later operation may have changed the node->signed w/o changing
|
// However a later operation may have changed the node->signed w/o changing
|
||||||
// the number's sign. So we don't: nodep->isSigned(nodep->num().isSigned());
|
// the number's sign. So we don't: nodep->isSigned(nodep->num().isSigned());
|
||||||
}
|
}
|
||||||
virtual void visit(AstNodeFTaskRef* nodep, AstNUser*) {
|
virtual void visit(AstFunc* nodep, AstNUser*) {
|
||||||
// Fortunately, the input variables to the task keep whatever sign they are given
|
// Avoid recursion; can't use user() as they're all full, and anyhow this is often called
|
||||||
// And we already did the function's output signedness above in visit(AstFuncRef,
|
if (nodep->didSigning()) return;
|
||||||
// so, it's just
|
nodep->didSigning(true);
|
||||||
nodep->iterateChildren(*this);
|
nodep->iterateChildren(*this);
|
||||||
|
nodep->signedFrom(nodep->fvarp()); // Which will get it from fvarp()->dtypep()
|
||||||
|
}
|
||||||
|
virtual void visit(AstTask* nodep, AstNUser*) {
|
||||||
|
// Avoid recursion; can't use user() as they're all full, and anyhow this is often called
|
||||||
|
if (nodep->didSigning()) return;
|
||||||
|
nodep->didSigning(true);
|
||||||
|
nodep->iterateChildren(*this);
|
||||||
|
}
|
||||||
|
virtual void visit(AstNodeFTaskRef* nodep, AstNUser*) {
|
||||||
|
nodep->iterateChildren(*this);
|
||||||
|
if (nodep->taskp()) nodep->taskp()->iterate(*this);
|
||||||
|
nodep->signedFrom(nodep->taskp());
|
||||||
}
|
}
|
||||||
virtual void visit(AstNodeIf* nodep, AstNUser*) {
|
virtual void visit(AstNodeIf* nodep, AstNUser*) {
|
||||||
if (!nodep->castGenIf()) { // for m_paramsOnly
|
if (!nodep->castGenIf()) { // for m_paramsOnly
|
||||||
|
|
|
||||||
|
|
@ -473,6 +473,14 @@ private:
|
||||||
virtual void visit(AstScopeName* nodep, AstNUser* vup) {
|
virtual void visit(AstScopeName* nodep, AstNUser* vup) {
|
||||||
// Only used in Displays which don't care....
|
// Only used in Displays which don't care....
|
||||||
}
|
}
|
||||||
|
virtual void visit(AstBasicDType* nodep, AstNUser* vup) {
|
||||||
|
if (nodep->rangep()) {
|
||||||
|
nodep->rangep()->iterateAndNext(*this,WidthVP(ANYSIZE,0,BOTH).p());
|
||||||
|
nodep->widthFrom(nodep->rangep());
|
||||||
|
}
|
||||||
|
// else width in node is correct; it was set based on keyword().width()
|
||||||
|
// at construction time
|
||||||
|
}
|
||||||
virtual void visit(AstVar* nodep, AstNUser* vup) {
|
virtual void visit(AstVar* nodep, AstNUser* vup) {
|
||||||
//if (debug()) nodep->dumpTree(cout," InitPre: ");
|
//if (debug()) nodep->dumpTree(cout," InitPre: ");
|
||||||
// Must have deterministic constant width
|
// Must have deterministic constant width
|
||||||
|
|
@ -480,27 +488,18 @@ private:
|
||||||
// with non-constant range gets size 1, not size 0.
|
// with non-constant range gets size 1, not size 0.
|
||||||
int width=1; int mwidth=1;
|
int width=1; int mwidth=1;
|
||||||
nodep->arraysp()->iterateAndNext(*this,WidthVP(ANYSIZE,0,BOTH).p());
|
nodep->arraysp()->iterateAndNext(*this,WidthVP(ANYSIZE,0,BOTH).p());
|
||||||
if (nodep->dtypep()->rangep()) {
|
|
||||||
nodep->dtypep()->rangep()->iterateAndNext(*this,WidthVP(ANYSIZE,0,BOTH).p());
|
// Parameters if implicit untyped inherit from what they are assigned to
|
||||||
width = mwidth = nodep->dtypep()->rangep()->width();
|
AstBasicDType* bdtypep = nodep->dtypep()->castBasicDType();
|
||||||
}
|
if (nodep->isParam() && bdtypep && bdtypep->implicit()) {
|
||||||
else if (nodep->isInteger() || nodep->isGenVar()) {
|
width = mwidth = 0;
|
||||||
width = 32;
|
if (nodep->initp()) {
|
||||||
mwidth = 1; // Consider it unsized, as we want x[int] to work, and also want {int} to fail.
|
nodep->initp()->iterateAndNext(*this,WidthVP(width,0,PRELIM).p());
|
||||||
}
|
// Although nodep will get a different width for parameters just below,
|
||||||
else if (nodep->isParam()) { // unranged
|
// we want the init numbers to retain their width/minwidth until parameters are replaced.
|
||||||
width = mwidth = 0; // But see below later.
|
// This prevents width warnings at the location the parameter is substituted in
|
||||||
}
|
nodep->initp()->iterateAndNext(*this,WidthVP(width,0,FINAL).p());
|
||||||
if (nodep->initp()) {
|
if (nodep->initp()->widthSized()) {
|
||||||
nodep->initp()->iterateAndNext(*this,WidthVP(width,0,PRELIM).p());
|
|
||||||
// Although nodep will get a different width for parameters just below,
|
|
||||||
// we want the init numbers to retain their width/minwidth until parameters are replaced.
|
|
||||||
nodep->initp()->iterateAndNext(*this,WidthVP(width,0,FINAL).p());
|
|
||||||
if (nodep->isParam()) {
|
|
||||||
if (nodep->dtypep()->rangep()) {
|
|
||||||
// Parameters need to preserve widthMin from the value, not get a constant size
|
|
||||||
mwidth = nodep->initp()->widthMin();
|
|
||||||
} else if (nodep->initp()->widthSized()) {
|
|
||||||
width = mwidth = nodep->initp()->width();
|
width = mwidth = nodep->initp()->width();
|
||||||
} else {
|
} else {
|
||||||
if (nodep->initp()->width()>32) nodep->initp()->v3warn(WIDTH,"Assigning >32 bit to unranged parameter (defaults to 32 bits)\n");
|
if (nodep->initp()->width()>32) nodep->initp()->v3warn(WIDTH,"Assigning >32 bit to unranged parameter (defaults to 32 bits)\n");
|
||||||
|
|
@ -508,34 +507,43 @@ private:
|
||||||
mwidth = nodep->initp()->widthMin();
|
mwidth = nodep->initp()->widthMin();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//if (debug()) nodep->dumpTree(cout," final: ");
|
|
||||||
}
|
|
||||||
if (nodep->isParam() && !nodep->dtypep()->rangep()) {
|
|
||||||
// Parameter sizes can come from the thing they get assigned from
|
// Parameter sizes can come from the thing they get assigned from
|
||||||
// They then "stick" to that width.
|
// They then "stick" to that width.
|
||||||
if (!width) width=32; // Or, if nothing, they're 32 bits.
|
if (!width) width=32; // Or, if nothing, they're 32 bits.
|
||||||
AstBasicDType* bdtypep = nodep->dtypep()->castBasicDType();
|
if (bdtypep->rangep()) bdtypep->rangep()->unlinkFrBackWithNext()->deleteTree();
|
||||||
bdtypep->rangep(new AstRange(nodep->fileline(),width-1,0));
|
bdtypep->rangep(new AstRange(nodep->fileline(),width-1,0));
|
||||||
bdtypep->rangep()->width(width,width);
|
nodep->dtypep()->iterateAndNext(*this,WidthVP(ANYSIZE,0,BOTH).p());
|
||||||
|
}
|
||||||
|
else { // non param or sized param
|
||||||
|
nodep->dtypep()->iterateAndNext(*this,WidthVP(ANYSIZE,0,BOTH).p());
|
||||||
|
width = nodep->dtypep()->width(); mwidth = nodep->dtypep()->widthMin();
|
||||||
|
if (nodep->initp()) {
|
||||||
|
nodep->initp()->iterateAndNext(*this,WidthVP(width,0,BOTH).p());
|
||||||
|
//if (debug()) nodep->dumpTree(cout," final: ");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
nodep->width(width,mwidth);
|
nodep->width(width,mwidth);
|
||||||
// See above note about initp()->...FINAL
|
// See above note about initp()->...FINAL
|
||||||
if (nodep->initp()) widthCheck(nodep,"Initial value",nodep->initp(),width,mwidth);
|
if (nodep->initp()) widthCheck(nodep,"Initial value",nodep->initp(),width,mwidth);
|
||||||
UINFO(4,"varWidthed "<<nodep<<endl);
|
UINFO(4,"varWidthed "<<nodep<<endl);
|
||||||
//if (debug()) nodep->dumpTree(cout," InitPos: ");
|
//if (debug()) nodep->dumpTree(cout," InitOut: ");
|
||||||
}
|
}
|
||||||
virtual void visit(AstNodeVarRef* nodep, AstNUser* vup) {
|
virtual void visit(AstNodeVarRef* nodep, AstNUser* vup) {
|
||||||
if (nodep->varp()->width()==0) {
|
if (nodep->varp()->width()==0) {
|
||||||
// Var hasn't been widthed, so make it so.
|
// Var hasn't been widthed, so make it so.
|
||||||
nodep->varp()->iterate(*this);
|
nodep->varp()->iterate(*this);
|
||||||
}
|
}
|
||||||
if ((nodep->varp()->isInteger() || nodep->varp()->isGenVar())
|
//if (debug()>=9) { nodep->dumpTree(cout," VRin "); nodep->varp()->dumpTree(cout," forvar "); }
|
||||||
|
// Note genvar's are also entered as integers
|
||||||
|
AstBasicDType* bdtypep = nodep->varp()->dtypep()->castBasicDType();
|
||||||
|
if (bdtypep && bdtypep->isSloppy()
|
||||||
&& nodep->backp()->castNodeAssign()) { // On LHS
|
&& nodep->backp()->castNodeAssign()) { // On LHS
|
||||||
// Consider Integers on LHS to sized (else would be unsized.)
|
// Consider Integers on LHS to sized (else would be unsized.)
|
||||||
nodep->width(32,32);
|
nodep->width(bdtypep->width(),bdtypep->width());
|
||||||
} else {
|
} else {
|
||||||
nodep->width(nodep->varp()->width(), nodep->varp()->widthMin());
|
nodep->widthFrom(nodep->varp());
|
||||||
}
|
}
|
||||||
|
//if (debug()>=9) nodep->dumpTree(cout," VRout ");
|
||||||
}
|
}
|
||||||
virtual void visit(AstPslClocked* nodep, AstNUser*) {
|
virtual void visit(AstPslClocked* nodep, AstNUser*) {
|
||||||
nodep->propp()->iterateAndNext(*this,WidthVP(1,1,BOTH).p());
|
nodep->propp()->iterateAndNext(*this,WidthVP(1,1,BOTH).p());
|
||||||
|
|
@ -625,14 +633,14 @@ private:
|
||||||
}
|
}
|
||||||
nodep->condp()->iterateAndNext(*this,WidthVP(1,1,BOTH).p());
|
nodep->condp()->iterateAndNext(*this,WidthVP(1,1,BOTH).p());
|
||||||
widthCheckReduce(nodep,"If",nodep->condp(),1,1); // it's like an if() condition.
|
widthCheckReduce(nodep,"If",nodep->condp(),1,1); // it's like an if() condition.
|
||||||
//if (debug()) nodep->dumpTree(cout," IfPos: ");
|
//if (debug()) nodep->dumpTree(cout," IfOut: ");
|
||||||
}
|
}
|
||||||
virtual void visit(AstNodeAssign* nodep, AstNUser*) {
|
virtual void visit(AstNodeAssign* nodep, AstNUser*) {
|
||||||
// TOP LEVEL NODE
|
// TOP LEVEL NODE
|
||||||
//if (debug()) nodep->dumpTree(cout," AssignPre: ");
|
//if (debug()) nodep->dumpTree(cout," AssignPre: ");
|
||||||
nodep->lhsp()->iterateAndNext(*this,WidthVP(ANYSIZE,0,BOTH).p());
|
nodep->lhsp()->iterateAndNext(*this,WidthVP(ANYSIZE,0,BOTH).p());
|
||||||
nodep->rhsp()->iterateAndNext(*this,WidthVP(ANYSIZE,0,PRELIM).p());
|
nodep->rhsp()->iterateAndNext(*this,WidthVP(ANYSIZE,0,PRELIM).p());
|
||||||
if(!nodep->lhsp()->widthSized()) nodep->v3fatalSrc("How can LHS be unsized?");
|
if (!nodep->lhsp()->widthSized()) nodep->v3fatalSrc("How can LHS be unsized?");
|
||||||
int awidth = nodep->lhsp()->width();
|
int awidth = nodep->lhsp()->width();
|
||||||
if (awidth==0) {
|
if (awidth==0) {
|
||||||
awidth = nodep->rhsp()->width(); // Parameters can propagate by unsized assignment
|
awidth = nodep->rhsp()->width(); // Parameters can propagate by unsized assignment
|
||||||
|
|
@ -643,7 +651,7 @@ private:
|
||||||
// than using "width" and have the optimizer truncate the result, we do
|
// than using "width" and have the optimizer truncate the result, we do
|
||||||
// it using the normal width reduction checks.
|
// it using the normal width reduction checks.
|
||||||
widthCheck(nodep,"Assign RHS",nodep->rhsp(),awidth,awidth);
|
widthCheck(nodep,"Assign RHS",nodep->rhsp(),awidth,awidth);
|
||||||
//if (debug()) nodep->dumpTree(cout," AssignPos: ");
|
//if (debug()) nodep->dumpTree(cout," AssignOut: ");
|
||||||
}
|
}
|
||||||
virtual void visit(AstNodePli* nodep, AstNUser*) {
|
virtual void visit(AstNodePli* nodep, AstNUser*) {
|
||||||
// Excludes NodeDisplay, see below
|
// Excludes NodeDisplay, see below
|
||||||
|
|
@ -797,7 +805,7 @@ private:
|
||||||
widthCheckPin(nodep, nodep->exprp(), pinwidth, inputPin);
|
widthCheckPin(nodep, nodep->exprp(), pinwidth, inputPin);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//if (debug()) nodep->dumpTree(cout,"- PinPos: ");
|
//if (debug()) nodep->dumpTree(cout,"- PinOut: ");
|
||||||
}
|
}
|
||||||
virtual void visit(AstCell* nodep, AstNUser*) {
|
virtual void visit(AstCell* nodep, AstNUser*) {
|
||||||
if (!m_paramsOnly) {
|
if (!m_paramsOnly) {
|
||||||
|
|
@ -822,6 +830,7 @@ private:
|
||||||
virtual void visit(AstFuncRef* nodep, AstNUser* vup) {
|
virtual void visit(AstFuncRef* nodep, AstNUser* vup) {
|
||||||
visit(nodep->castNodeFTaskRef(), vup);
|
visit(nodep->castNodeFTaskRef(), vup);
|
||||||
nodep->widthSignedFrom(nodep->taskp());
|
nodep->widthSignedFrom(nodep->taskp());
|
||||||
|
//if (debug()) nodep->dumpTree(cout," FuncOut: ");
|
||||||
}
|
}
|
||||||
virtual void visit(AstNodeFTaskRef* nodep, AstNUser* vup) {
|
virtual void visit(AstNodeFTaskRef* nodep, AstNUser* vup) {
|
||||||
// Function hasn't been widthed, so make it so.
|
// Function hasn't been widthed, so make it so.
|
||||||
|
|
|
||||||
|
|
@ -196,6 +196,7 @@ escid \\[^ \t\f\r\n]+
|
||||||
"buf" { FL; return yBUF; }
|
"buf" { FL; return yBUF; }
|
||||||
"bufif0" { FL; return yBUFIF0; }
|
"bufif0" { FL; return yBUFIF0; }
|
||||||
"bufif1" { FL; return yBUFIF1; }
|
"bufif1" { FL; return yBUFIF1; }
|
||||||
|
"byte" { FL; return yBYTE; }
|
||||||
"case" { FL; return yCASE; }
|
"case" { FL; return yCASE; }
|
||||||
"casex" { FL; return yCASEX; }
|
"casex" { FL; return yCASEX; }
|
||||||
"casez" { FL; return yCASEZ; }
|
"casez" { FL; return yCASEZ; }
|
||||||
|
|
@ -217,7 +218,9 @@ escid \\[^ \t\f\r\n]+
|
||||||
"initial" { FL; return yINITIAL; }
|
"initial" { FL; return yINITIAL; }
|
||||||
"inout" { FL; return yINOUT; }
|
"inout" { FL; return yINOUT; }
|
||||||
"input" { FL; return yINPUT; }
|
"input" { FL; return yINPUT; }
|
||||||
|
"int" { FL; return yINT; }
|
||||||
"integer" { FL; return yINTEGER; }
|
"integer" { FL; return yINTEGER; }
|
||||||
|
"longint" { FL; return yLONGINT; }
|
||||||
"macromodule" { FL; return yMODULE; }
|
"macromodule" { FL; return yMODULE; }
|
||||||
"module" { FL; return yMODULE; }
|
"module" { FL; return yMODULE; }
|
||||||
"nand" { FL; return yNAND; }
|
"nand" { FL; return yNAND; }
|
||||||
|
|
@ -235,6 +238,7 @@ escid \\[^ \t\f\r\n]+
|
||||||
"reg" { FL; return yREG; }
|
"reg" { FL; return yREG; }
|
||||||
"repeat" { FL; return yREPEAT; }
|
"repeat" { FL; return yREPEAT; }
|
||||||
"scalared" { FL; return ySCALARED; }
|
"scalared" { FL; return ySCALARED; }
|
||||||
|
"shortint" { FL; return ySHORTINT; }
|
||||||
"specify" { FL; return ySPECIFY; }
|
"specify" { FL; return ySPECIFY; }
|
||||||
"specparam" { FL; return ySPECPARAM; }
|
"specparam" { FL; return ySPECPARAM; }
|
||||||
"supply0" { FL; return ySUPPLY0; }
|
"supply0" { FL; return ySUPPLY0; }
|
||||||
|
|
@ -382,7 +386,6 @@ escid \\[^ \t\f\r\n]+
|
||||||
"bins" { yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext); }
|
"bins" { yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext); }
|
||||||
"binsof" { yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext); }
|
"binsof" { yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext); }
|
||||||
"break" { yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext); }
|
"break" { yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext); }
|
||||||
"byte" { yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext); }
|
|
||||||
"chandle" { yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext); }
|
"chandle" { yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext); }
|
||||||
"class" { yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext); }
|
"class" { yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext); }
|
||||||
"constraint" { yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext); }
|
"constraint" { yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext); }
|
||||||
|
|
@ -410,13 +413,11 @@ escid \\[^ \t\f\r\n]+
|
||||||
"illegal_bins" { yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext); }
|
"illegal_bins" { yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext); }
|
||||||
"import" { yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext); }
|
"import" { yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext); }
|
||||||
"inside" { yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext); }
|
"inside" { yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext); }
|
||||||
"int" { yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext); }
|
|
||||||
"interface" { yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext); }
|
"interface" { yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext); }
|
||||||
"intersect" { yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext); }
|
"intersect" { yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext); }
|
||||||
"join_any" { yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext); }
|
"join_any" { yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext); }
|
||||||
"join_none" { yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext); }
|
"join_none" { yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext); }
|
||||||
"local" { yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext); }
|
"local" { yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext); }
|
||||||
"longint" { yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext); }
|
|
||||||
"matches" { yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext); }
|
"matches" { yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext); }
|
||||||
"modport" { yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext); }
|
"modport" { yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext); }
|
||||||
"new" { yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext); }
|
"new" { yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext); }
|
||||||
|
|
@ -433,7 +434,6 @@ escid \\[^ \t\f\r\n]+
|
||||||
"randsequence" { yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext); }
|
"randsequence" { yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext); }
|
||||||
"ref" { yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext); }
|
"ref" { yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext); }
|
||||||
"return" { yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext); }
|
"return" { yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext); }
|
||||||
"shortint" { yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext); }
|
|
||||||
"shortreal" { yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext); }
|
"shortreal" { yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext); }
|
||||||
"solve" { yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext); }
|
"solve" { yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext); }
|
||||||
"string" { yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext); }
|
"string" { yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext); }
|
||||||
|
|
|
||||||
|
|
@ -103,6 +103,7 @@ public:
|
||||||
#define GRAMMARP V3ParseGrammar::singletonp()
|
#define GRAMMARP V3ParseGrammar::singletonp()
|
||||||
|
|
||||||
const AstBasicDTypeKwd LOGIC = AstBasicDTypeKwd::LOGIC; // Shorthand "LOGIC"
|
const AstBasicDTypeKwd LOGIC = AstBasicDTypeKwd::LOGIC; // Shorthand "LOGIC"
|
||||||
|
const AstBasicDTypeKwd LOGIC_IMPLICIT = AstBasicDTypeKwd::LOGIC_IMPLICIT;
|
||||||
|
|
||||||
//======================================================================
|
//======================================================================
|
||||||
// Macro functions
|
// Macro functions
|
||||||
|
|
@ -208,6 +209,7 @@ class AstSenTree;
|
||||||
%token<fl> yBUF "buf"
|
%token<fl> yBUF "buf"
|
||||||
%token<fl> yBUFIF0 "bufif0"
|
%token<fl> yBUFIF0 "bufif0"
|
||||||
%token<fl> yBUFIF1 "bufif1"
|
%token<fl> yBUFIF1 "bufif1"
|
||||||
|
%token<fl> yBYTE "byte"
|
||||||
%token<fl> yCASE "case"
|
%token<fl> yCASE "case"
|
||||||
%token<fl> yCASEX "casex"
|
%token<fl> yCASEX "casex"
|
||||||
%token<fl> yCASEZ "casez"
|
%token<fl> yCASEZ "casez"
|
||||||
|
|
@ -235,12 +237,14 @@ class AstSenTree;
|
||||||
%token<fl> yGENVAR "genvar"
|
%token<fl> yGENVAR "genvar"
|
||||||
%token<fl> yIF "if"
|
%token<fl> yIF "if"
|
||||||
%token<fl> yIFF "iff"
|
%token<fl> yIFF "iff"
|
||||||
%token<fl> yLOGIC "logic"
|
|
||||||
%token<fl> yINITIAL "initial"
|
%token<fl> yINITIAL "initial"
|
||||||
%token<fl> yINOUT "inout"
|
%token<fl> yINOUT "inout"
|
||||||
%token<fl> yINPUT "input"
|
%token<fl> yINPUT "input"
|
||||||
|
%token<fl> yINT "int"
|
||||||
%token<fl> yINTEGER "integer"
|
%token<fl> yINTEGER "integer"
|
||||||
%token<fl> yLOCALPARAM "localparam"
|
%token<fl> yLOCALPARAM "localparam"
|
||||||
|
%token<fl> yLOGIC "logic"
|
||||||
|
%token<fl> yLONGINT "longint"
|
||||||
%token<fl> yMODULE "module"
|
%token<fl> yMODULE "module"
|
||||||
%token<fl> yNAND "nand"
|
%token<fl> yNAND "nand"
|
||||||
%token<fl> yNEGEDGE "negedge"
|
%token<fl> yNEGEDGE "negedge"
|
||||||
|
|
@ -259,6 +263,7 @@ class AstSenTree;
|
||||||
%token<fl> yREG "reg"
|
%token<fl> yREG "reg"
|
||||||
%token<fl> yREPEAT "repeat"
|
%token<fl> yREPEAT "repeat"
|
||||||
%token<fl> ySCALARED "scalared"
|
%token<fl> ySCALARED "scalared"
|
||||||
|
%token<fl> ySHORTINT "shortint"
|
||||||
%token<fl> ySIGNED "signed"
|
%token<fl> ySIGNED "signed"
|
||||||
%token<fl> ySPECIFY "specify"
|
%token<fl> ySPECIFY "specify"
|
||||||
%token<fl> ySPECPARAM "specparam"
|
%token<fl> ySPECPARAM "specparam"
|
||||||
|
|
@ -626,7 +631,7 @@ port<nodep>: // ==IEEE: port
|
||||||
portDirNetE data_type portSig variable_dimensionListE sigAttrListE { $$=$3; VARDTYPE($2); $$->addNextNull(VARDONEP($$,$4,$5)); }
|
portDirNetE data_type portSig variable_dimensionListE sigAttrListE { $$=$3; VARDTYPE($2); $$->addNextNull(VARDONEP($$,$4,$5)); }
|
||||||
//UNSUP portDirNetE yVAR data_type portSig variable_dimensionListE sigAttrListE { $$=$4; VARDTYPE($3); $$->addNextNull(VARDONEP($$,$5,$6)); }
|
//UNSUP portDirNetE yVAR data_type portSig variable_dimensionListE sigAttrListE { $$=$4; VARDTYPE($3); $$->addNextNull(VARDONEP($$,$5,$6)); }
|
||||||
//UNSUP portDirNetE yVAR implicit_type portSig variable_dimensionListE sigAttrListE { $$=$4; VARDTYPE($3); $$->addNextNull(VARDONEP($$,$5,$6)); }
|
//UNSUP portDirNetE yVAR implicit_type portSig variable_dimensionListE sigAttrListE { $$=$4; VARDTYPE($3); $$->addNextNull(VARDONEP($$,$5,$6)); }
|
||||||
| portDirNetE signingE rangeList portSig variable_dimensionListE sigAttrListE { $$=$4; VARDTYPE(new AstBasicDType($3->fileline(), LOGIC, $3, $2)); $$->addNextNull(VARDONEP($$,$5,$6)); }
|
| portDirNetE signingE rangeList portSig variable_dimensionListE sigAttrListE { $$=$4; VARDTYPE(new AstBasicDType($3->fileline(), LOGIC_IMPLICIT, $3, $2)); $$->addNextNull(VARDONEP($$,$5,$6)); }
|
||||||
| portDirNetE /*implicit*/ portSig variable_dimensionListE sigAttrListE { $$=$2; /*VARDTYPE-same*/ $$->addNextNull(VARDONEP($$,$3,$4)); }
|
| portDirNetE /*implicit*/ portSig variable_dimensionListE sigAttrListE { $$=$2; /*VARDTYPE-same*/ $$->addNextNull(VARDONEP($$,$3,$4)); }
|
||||||
//
|
//
|
||||||
| portDirNetE data_type portSig variable_dimensionListE sigAttrListE '=' constExpr { $$=$3; VARDTYPE($2); $$->addNextNull(VARDONEP($$,$4,$5)); $$->addNextNull(GRAMMARP->newVarInit($6,$$,$7)); }
|
| portDirNetE data_type portSig variable_dimensionListE sigAttrListE '=' constExpr { $$=$3; VARDTYPE($2); $$->addNextNull(VARDONEP($$,$4,$5)); $$->addNextNull(GRAMMARP->newVarInit($6,$$,$7)); }
|
||||||
|
|
@ -693,13 +698,13 @@ parameter_declaration<nodep>: // IEEE: parameter_declaration
|
||||||
|
|
||||||
local_parameter_declarationFront: // IEEE: local_parameter_declaration w/o assignment
|
local_parameter_declarationFront: // IEEE: local_parameter_declaration w/o assignment
|
||||||
varLParamReset implicit_type { /*VARRESET-in-varLParam*/ VARDTYPE($2); }
|
varLParamReset implicit_type { /*VARRESET-in-varLParam*/ VARDTYPE($2); }
|
||||||
//UNSUP varLParamReset data_type { /*VARRESET-in-varLParam*/ VARDTYPE($2); }
|
| varLParamReset data_type { /*VARRESET-in-varLParam*/ VARDTYPE($2); }
|
||||||
//UNSUP varLParamReset yTYPE { /*VARRESET-in-varLParam*/ VARDTYPE($2); }
|
//UNSUP varLParamReset yTYPE { /*VARRESET-in-varLParam*/ VARDTYPE($2); }
|
||||||
;
|
;
|
||||||
|
|
||||||
parameter_declarationFront: // IEEE: parameter_declaration w/o assignment
|
parameter_declarationFront: // IEEE: parameter_declaration w/o assignment
|
||||||
varGParamReset implicit_type { /*VARRESET-in-varGParam*/ VARDTYPE($2); }
|
varGParamReset implicit_type { /*VARRESET-in-varGParam*/ VARDTYPE($2); }
|
||||||
//UNSUP varGParamReset data_type { /*VARRESET-in-varGParam*/ VARDTYPE($2); }
|
| varGParamReset data_type { /*VARRESET-in-varGParam*/ VARDTYPE($2); }
|
||||||
//UNSUP varGParamReset yTYPE { /*VARRESET-in-varGParam*/ VARDTYPE($2); }
|
//UNSUP varGParamReset yTYPE { /*VARRESET-in-varGParam*/ VARDTYPE($2); }
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
@ -779,9 +784,9 @@ port_declaration<nodep>: // ==IEEE: port_declaration
|
||||||
list_of_variable_decl_assignments { $$ = $5; }
|
list_of_variable_decl_assignments { $$ = $5; }
|
||||||
//UNSUP port_directionReset port_declNetE yVAR data_type { VARDTYPE($4); } list_of_variable_decl_assignments { $$ = $6; }
|
//UNSUP port_directionReset port_declNetE yVAR data_type { VARDTYPE($4); } list_of_variable_decl_assignments { $$ = $6; }
|
||||||
//UNSUP port_directionReset port_declNetE yVAR implicit_type { VARDTYPE($4); } list_of_variable_decl_assignments { $$ = $6; }
|
//UNSUP port_directionReset port_declNetE yVAR implicit_type { VARDTYPE($4); } list_of_variable_decl_assignments { $$ = $6; }
|
||||||
| port_directionReset port_declNetE signingE rangeList { VARDTYPE(new AstBasicDType($4->fileline(), LOGIC, $4, $3)); }
|
| port_directionReset port_declNetE signingE rangeList { VARDTYPE(new AstBasicDType($4->fileline(), LOGIC_IMPLICIT, $4, $3)); }
|
||||||
list_of_variable_decl_assignments { $$ = $6; }
|
list_of_variable_decl_assignments { $$ = $6; }
|
||||||
| port_directionReset port_declNetE signing { VARDTYPE(new AstBasicDType($<fl>3, LOGIC, NULL, $3)); }
|
| port_directionReset port_declNetE signing { VARDTYPE(new AstBasicDType($<fl>3, LOGIC_IMPLICIT, NULL, $3)); }
|
||||||
list_of_variable_decl_assignments { $$ = $5; }
|
list_of_variable_decl_assignments { $$ = $5; }
|
||||||
| port_directionReset port_declNetE /*implicit*/ { VARDTYPE(NULL);/*default_nettype*/}
|
| port_directionReset port_declNetE /*implicit*/ { VARDTYPE(NULL);/*default_nettype*/}
|
||||||
list_of_variable_decl_assignments { $$ = $4; }
|
list_of_variable_decl_assignments { $$ = $4; }
|
||||||
|
|
@ -798,18 +803,18 @@ tf_port_declaration<nodep>: // ==IEEE: tf_port_declaration
|
||||||
;
|
;
|
||||||
|
|
||||||
integer_atom_type<bdtypep>: // ==IEEE: integer_atom_type
|
integer_atom_type<bdtypep>: // ==IEEE: integer_atom_type
|
||||||
//UNSUP yBYTE { $$ = new AstBasicDType($1,AstBasicDTypeKwd::BYTE); }
|
yBYTE { $$ = new AstBasicDType($1,AstBasicDTypeKwd::BYTE); }
|
||||||
//UNSUP ySHORTINT { $$ = new AstBasicDType($1,AstBasicDTypeKwd::SHORTINT); }
|
| ySHORTINT { $$ = new AstBasicDType($1,AstBasicDTypeKwd::SHORTINT); }
|
||||||
//UNSUP yINT { $$ = new AstBasicDType($1,AstBasicDTypeKwd::INT); }
|
| yINT { $$ = new AstBasicDType($1,AstBasicDTypeKwd::INT); }
|
||||||
//UNSUP yLONGINT { $$ = new AstBasicDType($1,AstBasicDTypeKwd::LONGINT); }
|
| yLONGINT { $$ = new AstBasicDType($1,AstBasicDTypeKwd::LONGINT); }
|
||||||
yINTEGER { $$ = new AstBasicDType($1,AstBasicDTypeKwd::INTEGER); }
|
| yINTEGER { $$ = new AstBasicDType($1,AstBasicDTypeKwd::INTEGER); }
|
||||||
//UNSUP yTIME { $$ = new AstBasicDType($1,AstBasicDTypeKwd::TIME); }
|
//UNSUP yTIME { $$ = new AstBasicDType($1,AstBasicDTypeKwd::TIME); }
|
||||||
;
|
;
|
||||||
|
|
||||||
integer_vector_type<bdtypep>: // ==IEEE: integer_atom_type
|
integer_vector_type<bdtypep>: // ==IEEE: integer_atom_type
|
||||||
yBIT { $$ = new AstBasicDType($1,AstBasicDTypeKwd::BIT); }
|
yBIT { $$ = new AstBasicDType($1,AstBasicDTypeKwd::BIT); }
|
||||||
| yLOGIC { $$ = new AstBasicDType($1,AstBasicDTypeKwd::LOGIC); }
|
| yLOGIC { $$ = new AstBasicDType($1,AstBasicDTypeKwd::LOGIC); }
|
||||||
| yREG { $$ = new AstBasicDType($1,AstBasicDTypeKwd::REG); }
|
| yREG { $$ = new AstBasicDType($1,AstBasicDTypeKwd::LOGIC); } // logic==reg
|
||||||
;
|
;
|
||||||
|
|
||||||
signingE<signstate>: // IEEE: signing - plus empty
|
signingE<signstate>: // IEEE: signing - plus empty
|
||||||
|
|
@ -961,8 +966,8 @@ data_declarationVarFront: // IEEE: part of data_declaration
|
||||||
implicit_type<typep>: // IEEE: part of *data_type_or_implicit
|
implicit_type<typep>: // IEEE: part of *data_type_or_implicit
|
||||||
// // Also expanded in data_declaration
|
// // Also expanded in data_declaration
|
||||||
/* empty */ { $$ = NULL; }
|
/* empty */ { $$ = NULL; }
|
||||||
| signingE rangeList { $$ = new AstBasicDType($2->fileline(), LOGIC, $2, $1); }
|
| signingE rangeList { $$ = new AstBasicDType($2->fileline(), LOGIC_IMPLICIT, $2, $1); }
|
||||||
| signing { $$ = new AstBasicDType($<fl>1, LOGIC, NULL, $1); }
|
| signing { $$ = new AstBasicDType($<fl>1, LOGIC_IMPLICIT, NULL, $1); }
|
||||||
;
|
;
|
||||||
|
|
||||||
//************************************************
|
//************************************************
|
||||||
|
|
@ -1240,9 +1245,9 @@ rangeList<rangep>: // IEEE: {packed_dimension}
|
||||||
| rangeList anyrange { $$ = $1; $1->addNext($2); }
|
| rangeList anyrange { $$ = $1; $1->addNext($2); }
|
||||||
;
|
;
|
||||||
|
|
||||||
regrangeE<bdtypep>:
|
wirerangeE<bdtypep>:
|
||||||
/* empty */ { $$ = new AstBasicDType(CRELINE(), LOGIC, NULL); }
|
/* empty */ { $$ = new AstBasicDType(CRELINE(), LOGIC, NULL); } // not implicit
|
||||||
| anyrange { $$ = new AstBasicDType(CRELINE(), LOGIC, $1); }
|
| anyrange { $$ = new AstBasicDType(CRELINE(), LOGIC, $1); } // not implicit
|
||||||
;
|
;
|
||||||
|
|
||||||
// IEEE: select
|
// IEEE: select
|
||||||
|
|
@ -1253,9 +1258,9 @@ anyrange<rangep>:
|
||||||
;
|
;
|
||||||
|
|
||||||
delayrange<bdtypep>:
|
delayrange<bdtypep>:
|
||||||
regrangeE delayE { $$ = $1; }
|
wirerangeE delayE { $$ = $1; }
|
||||||
| ySCALARED regrangeE delayE { $$ = $2; }
|
| ySCALARED wirerangeE delayE { $$ = $2; }
|
||||||
| yVECTORED regrangeE delayE { $$ = $2; }
|
| yVECTORED wirerangeE delayE { $$ = $2; }
|
||||||
//UNSUP: ySCALARED/yVECTORED ignored
|
//UNSUP: ySCALARED/yVECTORED ignored
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
@ -1744,15 +1749,17 @@ task_declaration<taskp>: // ==IEEE: task_declaration
|
||||||
;
|
;
|
||||||
|
|
||||||
function_declaration<funcp>: // IEEE: function_declaration + function_body_declaration
|
function_declaration<funcp>: // IEEE: function_declaration + function_body_declaration
|
||||||
yFUNCTION lifetimeE funcTypeE funcId tfGuts yENDFUNCTION endLabelE
|
yFUNCTION lifetimeE funcId funcIsolateE tfGuts yENDFUNCTION endLabelE
|
||||||
{ $$ = $4; $$->addFvarp($3); $$->addStmtsp($5); if ($3) $$->isSigned($3->isSigned());
|
{ $$ = $3; $$->attrIsolateAssign($4); $$->addStmtsp($5);
|
||||||
SYMP->popScope($$); }
|
|
||||||
| yFUNCTION lifetimeE funcTypeE funcId yVL_ISOLATE_ASSIGNMENTS tfGuts yENDFUNCTION endLabelE
|
|
||||||
{ $$ = $4; $$->addFvarp($3); $$->addStmtsp($6); $$->attrIsolateAssign(true); if ($3) $$->isSigned($3->isSigned());
|
|
||||||
SYMP->popScope($$); }
|
SYMP->popScope($$); }
|
||||||
//UNSUP: Generic function return types
|
//UNSUP: Generic function return types
|
||||||
;
|
;
|
||||||
|
|
||||||
|
funcIsolateE<cint>:
|
||||||
|
/* empty */ { $$ = 0; }
|
||||||
|
| yVL_ISOLATE_ASSIGNMENTS { $$ = 1; }
|
||||||
|
;
|
||||||
|
|
||||||
lifetimeE: // IEEE: [lifetime]
|
lifetimeE: // IEEE: [lifetime]
|
||||||
/* empty */ { }
|
/* empty */ { }
|
||||||
| lifetime { }
|
| lifetime { }
|
||||||
|
|
@ -1773,11 +1780,23 @@ taskId<taskp>:
|
||||||
funcId<funcp>: // IEEE: function_data_type_or_implicit + part of function_body_declaration
|
funcId<funcp>: // IEEE: function_data_type_or_implicit + part of function_body_declaration
|
||||||
// // IEEE: function_data_type_or_implicit must be expanded here to prevent conflict
|
// // IEEE: function_data_type_or_implicit must be expanded here to prevent conflict
|
||||||
// // function_data_type expanded here to prevent conflicts with implicit_type:empty vs data_type:ID
|
// // function_data_type expanded here to prevent conflicts with implicit_type:empty vs data_type:ID
|
||||||
tfIdScoped
|
/**/ tfIdScoped
|
||||||
{ $$ = new AstFunc ($<fl>1,*$<strp>1,NULL,NULL);
|
{ $$ = new AstFunc ($<fl>1,*$<strp>1,NULL,NULL);
|
||||||
|
$$->addFvarp(new AstBasicDType($$->fileline(), LOGIC_IMPLICIT, NULL));
|
||||||
|
SYMP->pushNewUnder($$, NULL); }
|
||||||
|
| signingE rangeList tfIdScoped
|
||||||
|
{ $$ = new AstFunc ($<fl>3,*$<strp>3,NULL,NULL);
|
||||||
|
$$->addFvarp(new AstBasicDType($$->fileline(), LOGIC_IMPLICIT, $2, $1));
|
||||||
|
SYMP->pushNewUnder($$, NULL); }
|
||||||
|
| signing tfIdScoped
|
||||||
|
{ $$ = new AstFunc ($<fl>2,*$<strp>2,NULL,NULL);
|
||||||
|
$$->addFvarp(new AstBasicDType($$->fileline(), LOGIC_IMPLICIT, NULL, $1));
|
||||||
|
SYMP->pushNewUnder($$, NULL); }
|
||||||
|
//UNSUP yVOID tfIdScoped { UNSUP }
|
||||||
|
| data_type tfIdScoped
|
||||||
|
{ $$ = new AstFunc ($<fl>2,*$<strp>2,NULL,NULL);
|
||||||
|
$$->addFvarp($1);
|
||||||
SYMP->pushNewUnder($$, NULL); }
|
SYMP->pushNewUnder($$, NULL); }
|
||||||
//UNSUP id/*interface_identifier*/ '.' id { UNSUP }
|
|
||||||
//UNSUP class_scope_id { UNSUP }
|
|
||||||
;
|
;
|
||||||
|
|
||||||
tfIdScoped<strp>: // IEEE: part of function_body_declaration/task_body_declaration
|
tfIdScoped<strp>: // IEEE: part of function_body_declaration/task_body_declaration
|
||||||
|
|
@ -1799,14 +1818,6 @@ tfBodyE<nodep>: // IEEE: part of function_body_declaration/task_body_declarati
|
||||||
| stmtList { $$ = $1; }
|
| stmtList { $$ = $1; }
|
||||||
;
|
;
|
||||||
|
|
||||||
funcTypeE<typep>:
|
|
||||||
/* empty */ { $$ = NULL; }
|
|
||||||
| yINTEGER { $$ = new AstBasicDType($1,AstBasicDTypeKwd::INTEGER); }
|
|
||||||
| ySIGNED { $$ = new AstBasicDType($1,LOGIC, NULL); $$->isSigned(true); }
|
|
||||||
| ySIGNED '[' constExpr ':' constExpr ']' { $$ = new AstBasicDType($1,LOGIC, new AstRange($1,$3,$5)); $$->isSigned(true); }
|
|
||||||
| '[' constExpr ':' constExpr ']' { $$ = new AstBasicDType($1,LOGIC, new AstRange($1,$2,$4)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
tf_item_declarationList<nodep>:
|
tf_item_declarationList<nodep>:
|
||||||
tf_item_declaration { $$ = $1; }
|
tf_item_declaration { $$ = $1; }
|
||||||
| tf_item_declarationList tf_item_declaration { $$ = $1->addNextNull($2); }
|
| tf_item_declarationList tf_item_declaration { $$ = $1->addNextNull($2); }
|
||||||
|
|
@ -1842,15 +1853,15 @@ tf_port_item<nodep>: // ==IEEE: tf_port_item
|
||||||
|
|
||||||
tf_port_itemFront: // IEEE: part of tf_port_item, which has the data type
|
tf_port_itemFront: // IEEE: part of tf_port_item, which has the data type
|
||||||
data_type { VARDTYPE($1); }
|
data_type { VARDTYPE($1); }
|
||||||
| signingE rangeList { VARDTYPE(new AstBasicDType($2->fileline(), LOGIC, $2, $1)); }
|
| signingE rangeList { VARDTYPE(new AstBasicDType($2->fileline(), LOGIC_IMPLICIT, $2, $1)); }
|
||||||
| signing { VARDTYPE(new AstBasicDType($<fl>1, LOGIC, NULL, $1)); }
|
| signing { VARDTYPE(new AstBasicDType($<fl>1, LOGIC_IMPLICIT, NULL, $1)); }
|
||||||
//UNSUP yVAR data_type { VARDTYPE($2); }
|
//UNSUP yVAR data_type { VARDTYPE($2); }
|
||||||
//UNSUP yVAR implicit_type { VARDTYPE($2); }
|
//UNSUP yVAR implicit_type { VARDTYPE($2); }
|
||||||
//
|
//
|
||||||
| tf_port_itemDir /*implicit*/ { VARDTYPE(NULL); /*default_nettype-see spec*/ }
|
| tf_port_itemDir /*implicit*/ { VARDTYPE(NULL); /*default_nettype-see spec*/ }
|
||||||
| tf_port_itemDir data_type { VARDTYPE($2); }
|
| tf_port_itemDir data_type { VARDTYPE($2); }
|
||||||
| tf_port_itemDir signingE rangeList { VARDTYPE(new AstBasicDType($3->fileline(), LOGIC, $3, $2)); }
|
| tf_port_itemDir signingE rangeList { VARDTYPE(new AstBasicDType($3->fileline(), LOGIC_IMPLICIT, $3, $2)); }
|
||||||
| tf_port_itemDir signing { VARDTYPE(new AstBasicDType($<fl>2, LOGIC, NULL, $2)); }
|
| tf_port_itemDir signing { VARDTYPE(new AstBasicDType($<fl>2, LOGIC_IMPLICIT, NULL, $2)); }
|
||||||
//UNSUP tf_port_itemDir yVAR data_type { VARDTYPE($3); }
|
//UNSUP tf_port_itemDir yVAR data_type { VARDTYPE($3); }
|
||||||
//UNSUP tf_port_itemDir yVAR implicit_type { VARDTYPE($3); }
|
//UNSUP tf_port_itemDir yVAR implicit_type { VARDTYPE($3); }
|
||||||
;
|
;
|
||||||
|
|
@ -2588,8 +2599,7 @@ AstVar* V3ParseGrammar::createVariable(FileLine* fileline, string name, AstRange
|
||||||
}
|
}
|
||||||
AstVarType type = GRAMMARP->m_varIO;
|
AstVarType type = GRAMMARP->m_varIO;
|
||||||
if (!dtypep) { // Created implicitly
|
if (!dtypep) { // Created implicitly
|
||||||
// We also make them for standalone ports, which is a bit silly, but we'll clean up later
|
dtypep = new AstBasicDType(fileline, LOGIC_IMPLICIT);
|
||||||
dtypep = new AstBasicDType(fileline, LOGIC);
|
|
||||||
} else { // May make new variables with same type, so clone
|
} else { // May make new variables with same type, so clone
|
||||||
dtypep = dtypep->cloneTree(false);
|
dtypep = dtypep->cloneTree(false);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,83 +0,0 @@
|
||||||
// DESCRIPTION: Verilator: Verilog Test module
|
|
||||||
//
|
|
||||||
// This file ONLY is placed into the Public Domain, for any use,
|
|
||||||
// without warranty, 2009 by Wilson Snyder.
|
|
||||||
|
|
||||||
module t (/*AUTOARG*/
|
|
||||||
// Inputs
|
|
||||||
clk
|
|
||||||
);
|
|
||||||
input clk;
|
|
||||||
|
|
||||||
|
|
||||||
integer cyc=0;
|
|
||||||
// Test that we can actually use the logic keyword without an error popping up
|
|
||||||
//reg [63:0] crc;
|
|
||||||
logic [63:0] crc;
|
|
||||||
reg [63:0] sum;
|
|
||||||
|
|
||||||
|
|
||||||
// Take CRC data and apply to testblock inputs
|
|
||||||
wire [31:0] in = crc[31:0];
|
|
||||||
|
|
||||||
/*AUTOWIRE*/
|
|
||||||
// Beginning of automatic wires (for undeclared instantiated-module outputs)
|
|
||||||
wire [31:0] out; // From test of Test.v
|
|
||||||
// End of automatics
|
|
||||||
|
|
||||||
Test test (/*AUTOINST*/
|
|
||||||
// Outputs
|
|
||||||
.out (out[31:0]),
|
|
||||||
// Inputs
|
|
||||||
.clk (clk),
|
|
||||||
.in (in[31:0]));
|
|
||||||
|
|
||||||
// Aggregate outputs into a single result vector
|
|
||||||
wire [63:0] result = {32'h0, out};
|
|
||||||
|
|
||||||
// Test loop
|
|
||||||
always @ (posedge clk) begin
|
|
||||||
`ifdef TEST_VERBOSE
|
|
||||||
$write("[%0t] cyc==%0d crc=%x result=%x\n",$time, cyc, crc, result);
|
|
||||||
`endif
|
|
||||||
cyc <= cyc + 1;
|
|
||||||
crc <= {crc[62:0], crc[63]^crc[2]^crc[0]};
|
|
||||||
sum <= result ^ {sum[62:0],sum[63]^sum[2]^sum[0]};
|
|
||||||
if (cyc==0) begin
|
|
||||||
// Setup
|
|
||||||
crc <= 64'h5aef0c8d_d70a4497;
|
|
||||||
sum <= 64'h0;
|
|
||||||
end
|
|
||||||
else if (cyc<10) begin
|
|
||||||
sum <= 64'h0;
|
|
||||||
end
|
|
||||||
else if (cyc<90) begin
|
|
||||||
end
|
|
||||||
else if (cyc==99) begin
|
|
||||||
$write("[%0t] cyc==%0d crc=%x sum=%x\n",$time, cyc, crc, sum);
|
|
||||||
if (crc !== 64'hc77bb9b3784ea091) $stop;
|
|
||||||
// What checksum will we end up with (above print should match)
|
|
||||||
`define EXPECTED_SUM 64'h4afe43fb79d7b71e
|
|
||||||
if (sum !== `EXPECTED_SUM) $stop;
|
|
||||||
$write("*-* All Finished *-*\n");
|
|
||||||
$finish;
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
endmodule
|
|
||||||
|
|
||||||
module Test (/*AUTOARG*/
|
|
||||||
// Outputs
|
|
||||||
out,
|
|
||||||
// Inputs
|
|
||||||
clk, in
|
|
||||||
);
|
|
||||||
|
|
||||||
input clk;
|
|
||||||
input [31:0] in;
|
|
||||||
output reg [31:0] out;
|
|
||||||
|
|
||||||
always @(posedge clk) begin
|
|
||||||
out <= in;
|
|
||||||
end
|
|
||||||
endmodule
|
|
||||||
|
|
@ -0,0 +1,133 @@
|
||||||
|
// DESCRIPTION: Verilator: Verilog Test module
|
||||||
|
//
|
||||||
|
// This file ONLY is placed into the Public Domain, for any use,
|
||||||
|
// without warranty, 2009 by Wilson Snyder.
|
||||||
|
|
||||||
|
module t (/*AUTOARG*/);
|
||||||
|
|
||||||
|
// IEEE: integer_atom_type
|
||||||
|
byte d_byte;
|
||||||
|
shortint d_shortint;
|
||||||
|
int d_int;
|
||||||
|
longint d_longint;
|
||||||
|
integer d_integer;
|
||||||
|
//UNSUP time d_time;
|
||||||
|
|
||||||
|
// IEEE: integer_atom_type
|
||||||
|
bit d_bit;
|
||||||
|
logic d_logic;
|
||||||
|
reg d_reg;
|
||||||
|
|
||||||
|
bit [1:0] d_bit2;
|
||||||
|
logic [1:0] d_logic2;
|
||||||
|
reg [1:0] d_reg2;
|
||||||
|
|
||||||
|
// IEEE: non_integer_type
|
||||||
|
//UNSUP shortreal d_shortreal;
|
||||||
|
//UNSUP real d_real;
|
||||||
|
//UNSUP realtime d_realtime;
|
||||||
|
|
||||||
|
// verilator lint_off WIDTH
|
||||||
|
localparam p_implicit = {96{1'b1}};
|
||||||
|
localparam [89:0] p_explicit = {96{1'b1}};
|
||||||
|
localparam byte p_byte = {96{1'b1}};
|
||||||
|
localparam shortint p_shortint = {96{1'b1}};
|
||||||
|
localparam int p_int = {96{1'b1}};
|
||||||
|
localparam longint p_longint = {96{1'b1}};
|
||||||
|
localparam integer p_integer = {96{1'b1}};
|
||||||
|
localparam reg p_reg = {96{1'b1}};
|
||||||
|
localparam bit p_bit = {96{1'b1}};
|
||||||
|
localparam logic p_logic = {96{1'b1}};
|
||||||
|
localparam reg [1:0] p_reg2 = {96{1'b1}};
|
||||||
|
localparam bit [1:0] p_bit2 = {96{1'b1}};
|
||||||
|
localparam logic [1:0] p_logic2= {96{1'b1}};
|
||||||
|
// verilator lint_on WIDTH
|
||||||
|
|
||||||
|
// verilator lint_off WIDTH
|
||||||
|
function f_implicit; f_implicit = {96{1'b1}}; endfunction
|
||||||
|
function [89:0] f_explicit; f_explicit = {96{1'b1}}; endfunction
|
||||||
|
function byte f_byte; f_byte = {96{1'b1}}; endfunction
|
||||||
|
function shortint f_shortint; f_shortint = {96{1'b1}}; endfunction
|
||||||
|
function int f_int; f_int = {96{1'b1}}; endfunction
|
||||||
|
function longint f_longint; f_longint = {96{1'b1}}; endfunction
|
||||||
|
function integer f_integer; f_integer = {96{1'b1}}; endfunction
|
||||||
|
function reg f_reg; f_reg = {96{1'b1}}; endfunction
|
||||||
|
function bit f_bit; f_bit = {96{1'b1}}; endfunction
|
||||||
|
function logic f_logic; f_logic = {96{1'b1}}; endfunction
|
||||||
|
function reg [1:0] f_reg2; f_reg2 = {96{1'b1}}; endfunction
|
||||||
|
function bit [1:0] f_bit2; f_bit2 = {96{1'b1}}; endfunction
|
||||||
|
function logic [1:0] f_logic2; f_logic2 = {96{1'b1}}; endfunction
|
||||||
|
// verilator lint_on WIDTH
|
||||||
|
|
||||||
|
`define CHECK_ALL(name,bits,issigned,twostate) \
|
||||||
|
name = {96{1'b1}}; \
|
||||||
|
if (name !== {(bits){1'b1}}) begin $display("%%Error: Bad size for %s",`"name`"); $stop; end \
|
||||||
|
if (issigned ? (name > 0) : (name < 0)) begin $display("%%Error: Bad signed for %s",`"name`"); $stop; end \
|
||||||
|
name = {96{1'bx}}; \
|
||||||
|
|
||||||
|
//Everything is twostate in Verilator
|
||||||
|
// if (name !== {(bits){twostate ? 1'b0 : 1'bx}}) begin $display("%%Error: Bad twostate for %s",`"name`"); $stop; end \
|
||||||
|
|
||||||
|
initial begin
|
||||||
|
// verilator lint_off WIDTH
|
||||||
|
// verilator lint_off UNSIGNED
|
||||||
|
// name b sign twost
|
||||||
|
`CHECK_ALL(d_byte ,8 ,1'b1,1'b1);
|
||||||
|
`CHECK_ALL(d_shortint ,16,1'b1,1'b1);
|
||||||
|
`CHECK_ALL(d_int ,32,1'b1,1'b1);
|
||||||
|
`CHECK_ALL(d_longint ,64,1'b1,1'b1);
|
||||||
|
`CHECK_ALL(d_integer ,32,1'b1,1'b0);
|
||||||
|
`CHECK_ALL(d_bit ,1 ,1'b0,1'b1);
|
||||||
|
`CHECK_ALL(d_logic ,1 ,1'b0,1'b0);
|
||||||
|
`CHECK_ALL(d_reg ,1 ,1'b0,1'b0);
|
||||||
|
`CHECK_ALL(d_bit2 ,2 ,1'b0,1'b1);
|
||||||
|
`CHECK_ALL(d_logic2 ,2 ,1'b0,1'b0);
|
||||||
|
`CHECK_ALL(d_reg2 ,2 ,1'b0,1'b0);
|
||||||
|
// verilator lint_on WIDTH
|
||||||
|
// verilator lint_on UNSIGNED
|
||||||
|
|
||||||
|
`define CHECK_P(name,bits) \
|
||||||
|
if (name !== {(bits){1'b1}}) begin $display("%%Error: Bad size for %s",`"name`"); $stop; end \
|
||||||
|
|
||||||
|
`CHECK_P(p_implicit ,96);
|
||||||
|
`CHECK_P(p_explicit ,90);
|
||||||
|
`CHECK_P(p_byte ,8 );
|
||||||
|
`CHECK_P(p_shortint ,16);
|
||||||
|
`CHECK_P(p_int ,32);
|
||||||
|
`CHECK_P(p_longint ,64);
|
||||||
|
`CHECK_P(p_integer ,32);
|
||||||
|
`CHECK_P(p_bit ,1 );
|
||||||
|
`CHECK_P(p_logic ,1 );
|
||||||
|
`CHECK_P(p_reg ,1 );
|
||||||
|
`CHECK_P(p_bit2 ,2 );
|
||||||
|
`CHECK_P(p_logic2 ,2 );
|
||||||
|
`CHECK_P(p_reg2 ,2 );
|
||||||
|
|
||||||
|
`define CHECK_F(name,bits) \
|
||||||
|
if (name() !== {(bits){1'b1}}) begin $display("%%Error: Bad size for %s",`"name`"); $stop; end \
|
||||||
|
|
||||||
|
`CHECK_F(f_implicit ,1 ); // Note 1 bit, not 96
|
||||||
|
`CHECK_F(f_explicit ,90);
|
||||||
|
`CHECK_F(f_byte ,8 );
|
||||||
|
`CHECK_F(f_shortint ,16);
|
||||||
|
`CHECK_F(f_int ,32);
|
||||||
|
`CHECK_F(f_longint ,64);
|
||||||
|
`CHECK_F(f_integer ,32);
|
||||||
|
`CHECK_F(f_bit ,1 );
|
||||||
|
`CHECK_F(f_logic ,1 );
|
||||||
|
`CHECK_F(f_reg ,1 );
|
||||||
|
`CHECK_F(f_bit2 ,2 );
|
||||||
|
`CHECK_F(f_logic2 ,2 );
|
||||||
|
`CHECK_F(f_reg2 ,2 );
|
||||||
|
|
||||||
|
// For unpacked types we don't want width warnings for unsized numbers that fit
|
||||||
|
d_byte = 2;
|
||||||
|
d_shortint= 2;
|
||||||
|
d_int = 2;
|
||||||
|
d_longint = 2;
|
||||||
|
d_integer = 2;
|
||||||
|
|
||||||
|
$write("*-* All Finished *-*\n");
|
||||||
|
$finish;
|
||||||
|
end
|
||||||
|
endmodule
|
||||||
Loading…
Reference in New Issue