Internals: Create data types and attach to AstVars, in prep for typedefs.

Added AstNodeDType and AstBasicDType and associated enums.
This commit is contained in:
Wilson Snyder 2009-11-02 08:06:04 -05:00
parent 9a133ced2d
commit 4c26792c9b
25 changed files with 319 additions and 210 deletions

View File

@ -151,10 +151,13 @@ else
export OBJCACHE_JOBS := -j $(shell objcache --jobs "$(OBJCACHE_HOSTS)")
endif
default: all
all: all_nomsg msg_test
all_nomsg: verilator_exe $(VL_INST_MAN_FILES)
.PHONY:verilator_exe
.PHONY:verilator_bin
.PHONY:verilator_bin_dbg
verilator_exe verilator_bin verilator_bin_dbg:
@echo ------------------------------------------------------------
@echo "making verilator in src" ; \

View File

@ -198,6 +198,38 @@ public:
//######################################################################
class AstBasicDTypeKwd {
public:
enum en {
BYTE, SHORTINT, INT, LONGINT, INTEGER, TIME, BIT,
LOGIC, REG, SHORTREAL, REAL, REALTIME
};
enum en m_e;
const char* ascii() const {
static const char* names[] = {
"byte", "shortint", "int", "longint", "integer", "time", "bit",
"logic", "reg", "shortreal", "real", "realtime"
};
return names[m_e];
};
inline AstBasicDTypeKwd () {}
inline AstBasicDTypeKwd (en _e) : m_e(_e) {}
explicit inline AstBasicDTypeKwd (int _e) : m_e(static_cast<en>(_e)) {}
operator en () const { return 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::en lhs, AstBasicDTypeKwd rhs) { return (lhs == rhs.m_e); }
//######################################################################
enum AstSignedState {
// This can't be in the fancy class as the lexer union will get upset
signedst_NOP=0, signedst_SIGNED=1, signedst_UNSIGNED=2
};
//######################################################################
class AstVarType {
public:
enum en {
@ -205,7 +237,7 @@ public:
GPARAM,
LPARAM,
GENVAR,
INTEGER,
VAR, // Reg, integer, logic, etc
INPUT,
OUTPUT,
INOUT,
@ -213,7 +245,6 @@ public:
SUPPLY1,
WIRE,
IMPLICIT,
REG,
TRIWIRE,
PORT, // Temp type used in parser only
BLOCKTEMP,
@ -229,8 +260,8 @@ public:
const char* ascii() const {
static const char* names[] = {
"?","GPARAM","LPARAM","GENVAR",
"INTEGER","INPUT","OUTPUT","INOUT",
"SUPPLY0","SUPPLY1","WIRE","IMPLICIT","REG","TRIWIRE","PORT",
"VAR","INPUT","OUTPUT","INOUT",
"SUPPLY0","SUPPLY1","WIRE","IMPLICIT","TRIWIRE","PORT",
"BLOCKTEMP","MODULETEMP","STMTTEMP","XTEMP"};
return names[m_e]; }
};
@ -1121,10 +1152,19 @@ public:
return text()==samep->castNodeText()->text(); }
};
struct AstNodeDType : public AstNode {
// Data type
AstNodeDType(FileLine* fl) : AstNode(fl) {}
ASTNODE_BASE_FUNCS(NodeDType)
// Accessors
AstRange* rangep();
};
struct AstNodeSel : public AstNodeBiop {
// Single bit range extraction, perhaps with non-constant selection or array selection
AstNodeSel(FileLine* fl, AstNode* fromp, AstNode* bitp)
:AstNodeBiop(fl, fromp, bitp) {}
ASTNODE_BASE_FUNCS(NodeSel)
AstNode* fromp() const { return op1p()->castNode(); } // op1 = Extracting what (NULL=TBD during parsing)
AstNode* bitp() const { return op2p()->castNode(); } // op2 = Msb selection expression
int bitConst() const;

View File

@ -35,6 +35,11 @@
//======================================================================
// Special methods
AstRange* AstNodeDType::rangep() {
if (castBasicDType()) return castBasicDType()->rangep();
else return NULL;
}
// We need these here, because the classes they point to aren't defined when we declare the class
bool AstNodeVarRef::broken() const { return ((m_varScopep && !m_varScopep->brokeExists())
|| (m_varp && !m_varp->brokeExists())); }
@ -319,6 +324,10 @@ void AstAttrOf::dump(ostream& str) {
this->AstNode::dump(str);
str<<" ["<<attrType().ascii()<<"]";
}
void AstBasicDType::dump(ostream& str) {
this->AstNode::dump(str);
str<<" ["<<keyword().ascii()<<"]";
}
void AstCast::dump(ostream& str) {
this->AstNode::dump(str);
str<<" sz"<<size();

View File

@ -105,6 +105,47 @@ public:
virtual bool same(AstNode* samep) const { return true; }
};
struct AstBasicDType : public AstNodeDType {
// Builtin atomic/vectored data type
private:
AstBasicDTypeKwd m_keyword; // What keyword created it
public:
AstBasicDType(FileLine* fl, AstBasicDTypeKwd kwd, AstRange* rangep=NULL, AstSignedState signst=signedst_NOP)
: AstNodeDType(fl), m_keyword(kwd) {
init(signst, rangep);
}
private:
void init(AstSignedState signst, AstRange* rangep) {
if (rangep==NULL) { // Set based on keyword properties
if (m_keyword == AstBasicDTypeKwd::INTEGER) {
rangep = new AstRange(fileline(),31,0); signst = signedst_SIGNED;
}
}
setNOp1p(rangep); setSignedState(signst);
}
AstBasicDTypeKwd keyword() const { return m_keyword; }
public:
ASTNODE_NODE_FUNCS(BasicDType, BASICDTYPE)
virtual void dump(ostream& str);
virtual string name() const {
if (rangep()) return string(m_keyword.ascii())+"[]";
else return m_keyword.ascii();
}
AstRange* rangep() const { return op1p()->castRange(); } // op1 = Range of variable
void rangep(AstRange* nodep) { setNOp1p(nodep); }
void setSignedState(AstSignedState signst) {
if (signst!=signedst_NOP) isSigned(signst==signedst_SIGNED);
}
// METHODS
bool isInteger() const { return (keyword() == AstBasicDTypeKwd::INTEGER); }
int msb() const { if (!rangep()) return 0; return rangep()->msbConst(); }
int lsb() const { if (!rangep()) return 0; return rangep()->lsbConst(); }
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 msbMaxSelect() const { return (lsb()<0 ? msb()-lsb() : msb()); } // Maximum value a [] select may index
bool littleEndian() const { return (rangep() && rangep()->littleEndian()); }
};
struct AstArraySel : public AstNodeSel {
// Parents: math|stmt
// Children: varref|arraysel, math
@ -265,21 +306,30 @@ private:
m_trace=false;
}
public:
AstVar(FileLine* fl, AstVarType type, const string& name, AstRange* rangep, AstRange* arrayp=NULL)
AstVar(FileLine* fl, AstVarType type, const string& name, AstNodeDType* dtypep, AstRange* arrayp=NULL)
:AstNode(fl)
, m_name(name) {
init();
combineType(type); setNOp1p(rangep); addNOp2p(arrayp);
combineType(type); setOp1p(dtypep); addNOp2p(arrayp);
width(msb()-lsb()+1,0);
}
class LogicPacked {};
AstVar(FileLine* fl, AstVarType type, const string& name, LogicPacked, int wantwidth)
:AstNode(fl)
, m_name(name) {
init();
combineType(type);
setOp1p(new AstBasicDType(fl, AstBasicDTypeKwd::LOGIC,
((wantwidth > 1) ? new AstRange(fl, wantwidth-1, 0) : NULL)));
width(wantwidth,0);
}
AstVar(FileLine* fl, AstVarType type, const string& name, AstVar* examplep)
:AstNode(fl)
, m_name(name) {
init();
combineType(type);
if (examplep->rangep()) {
// Creating is faster than cloning; know have constant args
setOp1p(new AstRange(fl, examplep->msb(), examplep->lsb()));
if (examplep->dtypep()) {
setOp1p(examplep->dtypep()->cloneTree(true));
}
if (examplep->arraysp()) {
setOp2p(examplep->arraysp()->cloneTree(true));
@ -290,21 +340,23 @@ public:
virtual void dump(ostream& str);
virtual string name() const { return m_name; } // * = Var name
virtual bool maybePointedTo() const { return true; }
virtual bool broken() const { return !dtypep(); }
AstVarType varType() const { return m_varType; } // * = Type of variable
void varType2Out() { m_tristate=0; m_input=0; m_output=1; }
void varType2In() { m_tristate=0; m_input=1; m_output=0; }
string cType() const; // Return C type for declaration: bool, uint32_t, uint64_t, etc.
string scType() const; // Return SysC type: bool, uint32_t, uint64_t, sc_bv
void combineType(AstVarType type);
AstRange* rangep() const { return op1p()->castRange(); } // op1 = Range of variable
AstNodeDType* dtypep() const { return op1p()->castNodeDType(); } // op1 = Range of variable
AstRange* arraysp() const { return op2p()->castRange(); } // op2 = Array(s) of variable
void addArraysp(AstNode* nodep) { addNOp2p(nodep); }
AstRange* arrayp(int dim) const; // op2 = Range for specific dimension #
AstNode* initp() const { return op3p()->castNode(); } // op3 = Initial value that never changes (static const)
void initp(AstNode* nodep) { setOp3p(nodep); }
void addAttrsp(AstNode* nodep) { addNOp4p(nodep); }
AstNode* attrsp() const { return op4p()->castNode(); } // op4 = Attributes during early parse
bool hasSimpleInit() const { return (op3p() && !op3p()->castInitArray()); }
void rangep(AstRange* nodep) { setOp1p(nodep); }
void dtypep(AstRange* nodep) { setOp1p(nodep); }
void attrClockEn(bool flag) { m_attrClockEn = flag; }
void attrFileDescr(bool flag) { m_fileDescr = flag; }
void attrScClocked(bool flag) { m_scClocked = flag; }
@ -333,11 +385,11 @@ public:
bool isPrimaryIn() const { return isPrimaryIO() && isInput(); }
bool isIO() const { return (m_input||m_output); }
bool isSignal() const { return (varType()==AstVarType::WIRE || varType()==AstVarType::IMPLICIT
|| varType()==AstVarType::REG || varType()==AstVarType::INTEGER); }
|| varType()==AstVarType::VAR); }
bool isTemp() const { return (varType()==AstVarType::BLOCKTEMP || varType()==AstVarType::MODULETEMP
|| varType()==AstVarType::STMTTEMP || varType()==AstVarType::XTEMP); }
bool isToggleCoverable() const { return ((isIO() || isSignal())
&& varType()!=AstVarType::INTEGER
&& (isIO() || !isInteger())
// Wrapper would otherwise duplicate wrapped module's coverage
&& !isSc() && !isPrimaryIO()); }
bool isStatementTemp() const { return (varType()==AstVarType::STMTTEMP); }
@ -346,7 +398,7 @@ public:
bool isParam() const { return (varType()==AstVarType::LPARAM || varType()==AstVarType::GPARAM); }
bool isGParam() const { return (varType()==AstVarType::GPARAM); }
bool isGenVar() const { return (varType()==AstVarType::GENVAR); }
bool isInteger() const { return (varType() == AstVarType::INTEGER); }
bool isInteger() const { return dtypep()->castBasicDType() && dtypep()->castBasicDType()->isInteger(); }
bool isUsedClock() const { return m_usedClock; }
bool isUsedParam() const { return m_usedParam; }
bool isSc() const { return m_sc; }
@ -366,12 +418,12 @@ public:
bool attrIsolateAssign() const { return m_attrIsolateAssign; }
int widthAlignBytes() const; // Structure alignment 1,2,4 or 8 bytes (arrays affect this)
int widthTotalBytes() const; // Width in bytes rounding up 1,2,4,8,12,...
int msb() const { if (!rangep()) return 0; return rangep()->msbConst(); }
int lsb() const { if (!rangep()) return 0; return rangep()->lsbConst(); }
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 msbMaxSelect() const { return (lsb()<0 ? msb()-lsb() : msb()); } // Maximum value a [] select may index
bool littleEndian() const { return (rangep() && rangep()->littleEndian()); }
int msb() const { if (!dtypep()) return 0; return dtypep()->castBasicDType()->msb(); }
int lsb() const { if (!dtypep()) return 0; return dtypep()->castBasicDType()->lsb(); }
int msbEndianed() const { if (!dtypep()) return 0; return dtypep()->castBasicDType()->msbEndianed(); }
int lsbEndianed() const { if (!dtypep()) return 0; return dtypep()->castBasicDType()->lsbEndianed(); }
int msbMaxSelect() const { if (!dtypep()) return 0; return dtypep()->castBasicDType()->msbMaxSelect(); }
bool littleEndian() const { return (dtypep() && dtypep()->castBasicDType()->littleEndian()); }
int arrayDimensions() const;
uint32_t arrayElements() const; // 1, or total multiplication of all dimensions
virtual string verilogKwd() const;

View File

@ -157,8 +157,7 @@ private:
// Note var can be signed or unsigned based on original number.
AstNode* countp = nodep->countp()->unlinkFrBackWithNext();
string name = string("__Vrepeat")+cvtToStr(m_repeatNum++);
AstVar* varp = new AstVar(nodep->fileline(), AstVarType::BLOCKTEMP, name,
new AstRange(nodep->fileline(), countp->width()-1, 0));
AstVar* varp = new AstVar(nodep->fileline(), AstVarType::BLOCKTEMP, name, AstVar::LogicPacked(), countp->width());
m_modp->addStmtp(varp);
AstNode* initsp = new AstAssign(nodep->fileline(), new AstVarRef(nodep->fileline(), varp, true),
countp);

View File

@ -85,8 +85,7 @@ private:
AstVar* varp = vscp->varp();
if (varp->width()!=1) varp->v3error("Unsupported: Clock edge on non-single bit signal: "<<varp->prettyName());
string newvarname = ((string)"__Vclklast__"+vscp->scopep()->nameDotless()+"__"+varp->shortName());
AstVar* newvarp
= new AstVar (vscp->fileline(), AstVarType::MODULETEMP, newvarname, NULL, NULL); // No range; 1 bit.
AstVar* newvarp = new AstVar (vscp->fileline(), AstVarType::MODULETEMP, newvarname, AstVar::LogicPacked(), 1);
newvarp->width(1,1);
m_modp->addStmtp(newvarp);
AstVarScope* newvscp = new AstVarScope(vscp->fileline(), m_scopep, newvarp);
@ -105,7 +104,7 @@ private:
AstVarScope* getCreateLocalVar(FileLine* fl, const string& name, AstVar* examplep, int width) {
AstVar* newvarp;
if (width) {
newvarp = new AstVar (fl, AstVarType::BLOCKTEMP, name, new AstRange(fl, width-1, 0));
newvarp = new AstVar (fl, AstVarType::BLOCKTEMP, name, AstVar::LogicPacked(), width);
} else {
newvarp = new AstVar (fl, AstVarType::BLOCKTEMP, name, examplep); // No range; 1 bit.
}

View File

@ -309,10 +309,11 @@ private:
AstNode* basefromp = AstArraySel::baseFromp(nodep->fromp());
if (AstNodeVarRef* varrefp = basefromp->castNodeVarRef()) {
AstVar* varp = varrefp->varp();
if (!varp->dtypep()) varp->v3fatalSrc("Data type lost");
if (m_warn
&& nodep->lsbp()->castConst()
&& nodep->widthp()->castConst()
&& (!varp->rangep() || varp->msb())) { // else it's non-resolvable parameterized
&& (!varp->dtypep()->rangep() || varp->msb())) { // else it's non-resolvable parameterized
if (nodep->lsbp()->castConst()->num().isFourState()
|| nodep->widthp()->castConst()->num().isFourState()) {
nodep->v3error("Selection index is constantly unknown or tristated: "
@ -770,9 +771,9 @@ private:
string name1 = ((string)"__Vconcswap"+cvtToStr(m_modp->varNumGetInc()));
string name2 = ((string)"__Vconcswap"+cvtToStr(m_modp->varNumGetInc()));
AstVar* temp1p = new AstVar(sel1p->fileline(), AstVarType::BLOCKTEMP, name1,
new AstRange(sel1p->fileline(), msb1-lsb1, 0));
AstVar::LogicPacked(), msb1-lsb1+1);
AstVar* temp2p = new AstVar(sel2p->fileline(), AstVarType::BLOCKTEMP, name2,
new AstRange(sel2p->fileline(), msb2-lsb2, 0));
AstVar::LogicPacked(), msb2-lsb2+1);
m_modp->addStmtp(temp1p);
m_modp->addStmtp(temp2p);
AstNodeAssign* asn1ap=nodep->cloneType

View File

@ -176,7 +176,7 @@ private:
dimension+1, selects_docs, selects_code);
}
} else { // No more arraying - just each bit in the width
if (nodep->rangep()) {
if (nodep->msb() != nodep->lsb()) {
for (int bitindex_docs=nodep->lsb(); bitindex_docs<nodep->msb()+1; bitindex_docs++) {
toggleVarBottom(nodep, chgVarp,
dimension, selects_docs, selects_code,

View File

@ -128,19 +128,12 @@ private:
// Created module's AstVar earlier under some other scope
varp = iter->second;
} else {
AstRange* rangep = NULL;
if (width==0) {
rangep = new AstRange(oldvarscp->fileline(),
oldvarscp->varp()->msb(),
oldvarscp->varp()->lsb());
} else if (width==1) {
rangep = NULL;
varp = new AstVar (oldvarscp->fileline(), AstVarType::BLOCKTEMP, name, oldvarscp->varp());
varp->widthSignedFrom(oldvarscp);
} else {
rangep = new AstRange(oldvarscp->fileline(),
width-1, 0);
varp = new AstVar (oldvarscp->fileline(), AstVarType::BLOCKTEMP, name, AstVar::LogicPacked(), width);
}
varp = new AstVar (oldvarscp->fileline(), AstVarType::BLOCKTEMP, name, rangep);
if (width==0) varp->widthSignedFrom(oldvarscp);
addmodp->addStmtp(varp);
m_modVarMap.insert(make_pair(make_pair(addmodp, name), varp));
}

View File

@ -68,7 +68,7 @@ private:
// Width, not widthMin, as we may be in middle of BITSEL expression which
// though it's one bit wide, needs the mask in the upper bits.
// (Someday we'll have a valid bitmask instead of widths....)
new AstRange(nodep->fileline(), nodep->width()-1, 0));
AstVar::LogicPacked(), nodep->width());
if (!m_funcp) nodep->v3fatalSrc("Deep expression not under a function");
m_funcp->addInitsp(varp);
// Replace node tree with reference to var

View File

@ -421,11 +421,7 @@ class EmitVBaseVisitor : public EmitCBaseVisitor {
puts(nodep->verilogKwd());
puts(" ");
if (nodep->isSigned()) puts("signed ");
if (nodep->rangep()) {
puts("["+cvtToStr(nodep->msb())
+":"+cvtToStr(nodep->lsb())
+"] ");
}
nodep->dtypep()->iterateChildren(*this);
puts(nodep->name());
for (AstRange* arrayp=nodep->arraysp(); arrayp; arrayp = arrayp->nextp()->castRange()) {
puts(" ["+cvtToStr(arrayp->msbConst())

View File

@ -106,6 +106,16 @@ private:
UINFO(5," Inline CELL "<<nodep<<endl);
UINFO(5," To MOD "<<m_modp<<endl);
m_statCells++;
// Before cloning simplify pin assignments
// Better off before, as if module has multiple instantiations
// we'll save work, and we can't call pinReconnectSimple in
// this loop as it clone()s itself.
for (AstPin* pinp = nodep->pinsp(); pinp; pinp=pinp->nextp()->castPin()) {
V3Inst::pinReconnectSimple(pinp, nodep, m_modp);
}
// Clone original module
if (debug()>=9) { nodep->dumpTree(cout,"inlcell:"); }
//if (debug()>=9) { nodep->modp()->dumpTree(cout,"oldmod:"); }
AstModule* newmodp = nodep->modp()->cloneTree(false);
@ -119,8 +129,6 @@ private:
// Create assignments to the pins
for (AstPin* pinp = nodep->pinsp(); pinp; pinp=pinp->nextp()->castPin()) {
UINFO(6," Pin change from "<<pinp->modVarp()<<endl);
// First, simplify it
V3Inst::pinReconnectSimple(pinp, nodep, m_modp);
// Make new signal; even though we'll optimize the interconnect, we
// need an alias to trace correctly. If tracing is disabled, we'll
// delete it in later optimizations.

View File

@ -235,6 +235,7 @@ public:
void V3Inst::pinReconnectSimple(AstPin* pinp, AstCell* cellp, AstModule* modp) {
// If a pin connection is "simple" leave it as-is
// Else create a intermediate wire to perform the interconnect
// Note this module calles cloneTree() via new AstVar
AstVar* pinVarp = pinp->modVarp();
AstVarRef* connectRefp = pinp->exprp()->castVarRef();
if (connectRefp

View File

@ -157,7 +157,8 @@ private:
if (!forrefp->varp()) {
if (!noWarn) forrefp->v3warn(IMPLICIT,"Signal definition not found, creating implicitly: "<<forrefp->prettyName());
AstVar* newp = new AstVar (forrefp->fileline(), AstVarType::WIRE,
forrefp->name(), NULL, NULL); // width 1
forrefp->name(), AstVar::LogicPacked(), 1);
newp->trace(m_modp->modTrace());
m_modp->addStmtp(newp);
// Link it to signal list
@ -298,9 +299,12 @@ private:
// just attact normal signal attributes to it.
if (AstFunc* funcp = nodep->castFunc()) {
if (!funcp->fvarp()->castVar()) {
AstRange* rangep = funcp->fvarp()->castRange();
if (rangep) rangep->unlinkFrBack();
AstVar* newvarp = new AstVar(nodep->fileline(), AstVarType::OUTPUT, nodep->name(), rangep);
AstNodeDType* dtypep = funcp->fvarp()->castNodeDType();
// If unspecified, function returns one bit; however when we support NEW() it could
// also return the class reference.
if (dtypep) dtypep->unlinkFrBack();
else dtypep = new AstBasicDType(nodep->fileline(), AstBasicDTypeKwd::LOGIC, NULL);
AstVar* newvarp = new AstVar(nodep->fileline(), AstVarType::OUTPUT, nodep->name(), dtypep);
newvarp->isSigned(funcp->isSigned());
newvarp->funcReturn(true);
newvarp->trace(false); // Not user visible

View File

@ -124,7 +124,7 @@ private:
// Make a new temp wire
string newvarname = "__Vsenitemexpr"+cvtToStr(++m_senitemCvtNum);
AstVar* newvarp = new AstVar (sensp->fileline(), AstVarType::MODULETEMP, newvarname,
NULL,NULL);
AstVar::LogicPacked(), 1);
// We can't just add under the module, because we may be inside a generate, begin, etc.
// We know a SenItem should be under a SenTree/Always etc, we we'll just hunt upwards
AstNode* addwherep = nodep; // Add to this element's next

View File

@ -52,9 +52,11 @@ struct V3ParseBisonYYSType {
int cint;
double cdouble;
V3UniqState uniqstate;
AstSignedState signstate;
AstNode* nodep;
AstBasicDType* bdtypep;
AstBegin* beginp;
AstCase* casep;
AstCaseItem* caseitemp;
@ -62,6 +64,7 @@ struct V3ParseBisonYYSType {
AstFunc* funcp;
AstModule* modulep;
AstNodeSenItem* senitemp;
AstNodeDType* typep;
AstNodeVarRef* varnodep;
AstParseRef* parserefp;
AstPin* pinp;

View File

@ -103,7 +103,7 @@ private:
AstVar* getBlockTemp(AstNode* nodep) {
string newvarname = ((string)"__Vtemp"+cvtToStr(m_modp->varNumGetInc()));
AstVar* varp = new AstVar (nodep->fileline(), AstVarType::STMTTEMP, newvarname,
new AstRange(nodep->fileline(), nodep->widthMin()-1, 0));
AstVar::LogicPacked(), nodep->widthMin());
m_funcp->addInitsp(varp);
return varp;
}

View File

@ -139,9 +139,13 @@ private:
//=======
// These have proper signedness set when they were created.
virtual void visit(AstFunc* nodep, AstNUser*) { nodep->iterateChildren(*this); }
virtual void visit(AstVar* nodep, AstNUser*) { nodep->iterateChildren(*this); }
virtual void visit(AstNodeDType* nodep, AstNUser*) { nodep->iterateChildren(*this); }
// Inherit from others
virtual void visit(AstVar* nodep, AstNUser*) {
nodep->iterateChildren(*this);
nodep->signedFrom(nodep->dtypep());
}
virtual void visit(AstNodeVarRef* nodep, AstNUser*) {
nodep->varp()->iterate(*this);
nodep->signedFrom(nodep->varp());

View File

@ -182,7 +182,7 @@ private:
// Index into our table
AstVar* indexVarp = new AstVar (nodep->fileline(), AstVarType::BLOCKTEMP,
"__Vtableidx" + cvtToStr(m_modTables),
new AstRange (nodep->fileline(), m_inWidth-1, 0));
AstVar::LogicPacked(), m_inWidth);
m_modp->addStmtp(indexVarp);
AstVarScope* indexVscp = new AstVarScope (indexVarp->fileline(), m_scopep, indexVarp);
m_scopep->addVarp(indexVscp);
@ -190,8 +190,8 @@ private:
// Change it variable
AstVar* chgVarp = new AstVar (nodep->fileline(), AstVarType::MODULETEMP,
"__Vtablechg" + cvtToStr(m_modTables),
new AstRange (nodep->fileline(), m_outVarps.size()-1, 0),
new AstRange (nodep->fileline(), VL_MASK_I(m_inWidth), 0));
AstVar::LogicPacked(), m_outVarps.size());
chgVarp->addArraysp(new AstRange (nodep->fileline(), VL_MASK_I(m_inWidth), 0));
chgVarp->isConst(true);
chgVarp->initp(new AstInitArray (nodep->fileline(), NULL));
m_modp->addStmtp(chgVarp);
@ -232,8 +232,8 @@ private:
AstVar* tablevarp
= new AstVar (nodep->fileline(), AstVarType::MODULETEMP,
"__Vtable" + cvtToStr(m_modTables) +"_"+outvarp->name(),
new AstRange (nodep->fileline(), outvarp->widthMin()-1, 0),
new AstRange (nodep->fileline(), VL_MASK_I(m_inWidth), 0));
AstVar::LogicPacked(), outvarp->widthMin());
tablevarp->addArraysp(new AstRange (nodep->fileline(), VL_MASK_I(m_inWidth), 0));
tablevarp->isConst(true);
tablevarp->isStatic(true);
tablevarp->initp(new AstInitArray (nodep->fileline(), NULL));

View File

@ -311,10 +311,9 @@ private:
// Insert global variable
if (!activityNumber) activityNumber++; // For simplicity, always create it
activityNumber = VL_WORDS_I(activityNumber)*VL_WORDSIZE; // For tighter code; round to next 32 bit point.
int activityBits = VL_WORDS_I(activityNumber)*VL_WORDSIZE; // For tighter code; round to next 32 bit point.
AstVar* newvarp = new AstVar (m_chgFuncp->fileline(), AstVarType::MODULETEMP,
"__Vm_traceActivity",
new AstRange (m_chgFuncp->fileline(), activityNumber-1, 0));
"__Vm_traceActivity", AstVar::LogicPacked(), activityBits);
m_topModp->addStmtp(newvarp);
AstVarScope* newvscp = new AstVarScope(newvarp->fileline(), m_highScopep, newvarp);
m_highScopep->addVarp(newvscp);

View File

@ -207,7 +207,7 @@ private:
AstVar* enp = new AstVar (outrefp->varp()->fileline(),
AstVarType::MODULETEMP,
outrefp->name() + "__en" + suffix + cvtToStr(m_unique++),
(width>1) ? new AstRange(outp->fileline(), width-1, 0) : (AstRange *) NULL);
AstVar::LogicPacked(), width);
enp->varType2Out();
if (enp->width() != enrhsp->width()) {
@ -381,7 +381,7 @@ private:
AstVar* newlhsp = new AstVar(lhsp->fileline(),
AstVarType::MODULETEMP,
lhsp->name()+"__lhs"+cvtToStr(m_unique++),
(w>1) ? new AstRange(nodep->fileline(), w-1, 0) : (AstRange *) NULL);
AstVar::LogicPacked(), w);
nodep->addStmtp(newlhsp);
// now append this driver to the driver logic.
@ -396,7 +396,7 @@ private:
bitselp = new AstVar(lhsp->fileline(),
AstVarType::MODULETEMP,
lhsp->name()+"__sel"+cvtToStr(m_unique-1),
(ws>1) ? new AstRange(nodep->fileline(), ws-1, 0) : (AstRange*) NULL);
AstVar::LogicPacked(), ws);
//
nodep->addStmtp(bitselp);
nodep->addStmtp(new AstAssignW(lhsp->fileline(),

View File

@ -127,7 +127,7 @@ private:
else {
string name = ((string)"__Vlvbound"+cvtToStr(m_modp->varNumGetInc()));
AstVar* varp = new AstVar(fl, AstVarType::MODULETEMP, name,
new AstRange(fl, prep->width()-1, 0));
AstVar::LogicPacked(), prep->width());
m_modp->addStmtp(varp);
AstNode* abovep = prep->backp(); // Grab above point before loose it w/ next replace
@ -288,7 +288,7 @@ private:
+cvtToStr(m_modp->varNumGetInc()));
AstVar* newvarp
= new AstVar (nodep->fileline(), AstVarType::XTEMP, newvarname,
new AstRange(nodep->fileline(), nodep->width()-1, 0));
AstVar::LogicPacked(), nodep->width());
m_statUnkVars++;
AstNRelinker replaceHandle;
nodep->unlinkFrBack(&replaceHandle);

View File

@ -299,7 +299,7 @@ private:
int frommsb = nodep->fromp()->width() - 1;
int fromlsb = 0;
AstNodeVarRef* varrp = nodep->fromp()->castNodeVarRef();
if (varrp && varrp->varp()->rangep()) { // Selecting a bit from a multibit register
if (varrp && varrp->varp()->dtypep()->rangep()) { // Selecting a bit from a multibit register
frommsb = varrp->varp()->msbMaxSelect(); // Corrected for negative lsb
fromlsb = varrp->varp()->lsb();
}
@ -480,9 +480,9 @@ private:
// with non-constant range gets size 1, not size 0.
int width=1; int mwidth=1;
nodep->arraysp()->iterateAndNext(*this,WidthVP(ANYSIZE,0,BOTH).p());
if (nodep->rangep()) {
nodep->rangep()->iterateAndNext(*this,WidthVP(ANYSIZE,0,BOTH).p());
width = mwidth = nodep->rangep()->width();
if (nodep->dtypep()->rangep()) {
nodep->dtypep()->rangep()->iterateAndNext(*this,WidthVP(ANYSIZE,0,BOTH).p());
width = mwidth = nodep->dtypep()->rangep()->width();
}
else if (nodep->isInteger() || nodep->isGenVar()) {
width = 32;
@ -497,7 +497,7 @@ private:
// 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->rangep()) {
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()) {
@ -510,12 +510,13 @@ private:
}
//if (debug()) nodep->dumpTree(cout," final: ");
}
if (nodep->isParam() && !nodep->rangep()) {
if (nodep->isParam() && !nodep->dtypep()->rangep()) {
// Parameter sizes can come from the thing they get assigned from
// They then "stick" to that width.
if (!width) width=32; // Or, if nothing, they're 32 bits.
nodep->rangep(new AstRange(nodep->fileline(),width-1,0));
nodep->rangep()->width(width,width);
AstBasicDType* bdtypep = nodep->dtypep()->castBasicDType();
bdtypep->rangep(new AstRange(nodep->fileline(),width-1,0));
bdtypep->rangep()->width(width,width);
}
nodep->width(width,mwidth);
// See above note about initp()->...FINAL

View File

@ -86,7 +86,7 @@ private:
} else if (dimension > dimensions) { // Too many indexes provided
nodep->v3error("Illegal bit or array select; variable already selected, or bad dimension: "<<varp->prettyName());
} else if (dimension == dimensions) { // Right number, but...
if (!varp->rangep()) {
if (!varp->dtypep()->rangep()) {
nodep->v3error("Illegal bit select; variable does not have a bit range, or bad dimension: "<<varp->prettyName());
}
}
@ -133,12 +133,12 @@ private:
// Don't report WIDTH warnings etc here, as may be inside a generate branch that will be deleted
AstVar* varp = varFromBasefrom(basefromp);
// SUB #'s Not needed when LSB==0 and MSB>=0 (ie [0:-13] must still get added!)
if (!varp->rangep()) {
if (!varp->dtypep()->rangep()) {
// vector without range is ok, for example a INTEGER x; y = x[21:0];
return underp;
} else {
if (!varp->rangep()->msbp()->castConst()
|| !varp->rangep()->lsbp()->castConst())
if (!varp->dtypep()->rangep()->msbp()->castConst()
|| !varp->dtypep()->rangep()->lsbp()->castConst())
varp->v3fatalSrc("Non-constant variable range; errored earlier"); // in constifyParam(varp)
if (varp->littleEndian()) {
// reg [1:3] was swapped to [3:1] (lsbEndianedp==3) and needs a SUB(3,under)
@ -239,7 +239,7 @@ private:
vlsint32_t msb = msbp->castConst()->toSInt();
vlsint32_t lsb = lsbp->castConst()->toSInt();
selCheckDimension(nodep, basefromp, dimension, msb!=lsb);
if (varp->rangep() && varp->rangep()->littleEndian()) {
if (varp->dtypep()->rangep() && varp->dtypep()->rangep()->littleEndian()) {
// Below code assumes big bit endian; just works out if we swap
int x = msb; msb = lsb; lsb = x;
}
@ -277,7 +277,7 @@ private:
selCheckDimension(nodep, basefromp, dimension, width!=1);
AstSel* newp = NULL;
if (nodep->castSelPlus()) {
if (varp->rangep() && varp->rangep()->littleEndian()) {
if (varp->dtypep()->rangep() && varp->dtypep()->rangep()->littleEndian()) {
// SELPLUS(from,lsb,width) -> SEL(from, (vector_msb-width+1)-sel, width)
newp = new AstSel (nodep->fileline(),
fromp,
@ -291,7 +291,7 @@ private:
widthp);
}
} else if (nodep->castSelMinus()) {
if (varp->rangep() && varp->rangep()->littleEndian()) {
if (varp->dtypep()->rangep() && varp->dtypep()->rangep()->littleEndian()) {
// SELMINUS(from,msb,width) -> SEL(from, msb-[bit])
newp = new AstSel (nodep->fileline(),
fromp,

View File

@ -49,10 +49,9 @@ public:
bool m_impliedDecl; // Allow implied wire declarations
AstVarType m_varDecl; // Type for next signal declaration (reg/wire/etc)
AstVarType m_varIO; // Type for next signal declaration (input/output/etc)
bool m_varSigned; // Signed state for next signal declaration
AstVar* m_varAttrp; // Current variable for attribute adding
AstCase* m_caseAttrp; // Current case statement for attribute adding
AstRange* m_varRangep; // Pointer to range for next signal declaration
AstNodeDType* m_varDTypep; // Pointer to data type for next signal declaration
int m_pinNum; // Pin number currently parsing
string m_instModule; // Name of module referenced for instantiations
AstPin* m_instParamp; // Parameters for instantiations
@ -63,8 +62,7 @@ public:
m_impliedDecl = false;
m_varDecl = AstVarType::UNKNOWN;
m_varIO = AstVarType::UNKNOWN;
m_varSigned = false;
m_varRangep = NULL;
m_varDTypep = NULL;
m_pinNum = -1;
m_instModule;
m_instParamp = NULL;
@ -93,9 +91,9 @@ public:
new AstVarRef(fileline, varp->name(),true),
initp));
}
void setRange(AstRange* rangep) {
if (m_varRangep) { m_varRangep->deleteTree(); m_varRangep=NULL; } // It was cloned, so this is safe.
m_varRangep = rangep;
void setDType(AstNodeDType* dtypep) {
if (m_varDTypep) { m_varDTypep->deleteTree(); m_varDTypep=NULL; } // It was cloned, so this is safe.
m_varDTypep = dtypep;
}
string deQuote(FileLine* fileline, string text);
};
@ -104,6 +102,8 @@ public:
#define SYMP PARSEP->symp()
#define GRAMMARP V3ParseGrammar::singletonp()
const AstBasicDTypeKwd LOGIC = AstBasicDTypeKwd::LOGIC; // Shorthand "LOGIC"
//======================================================================
// Macro functions
@ -111,12 +111,10 @@ public:
#define VARRESET_LIST(decl) { GRAMMARP->m_pinNum=1; VARRESET(); VARDECL(decl); } // Start of pinlist
#define VARRESET_NONLIST(decl) { GRAMMARP->m_pinNum=0; VARRESET(); VARDECL(decl); } // Not in a pinlist
#define VARRESET() { VARDECL(UNKNOWN); VARIO(UNKNOWN); VARSIGNED(false); VARRANGE(NULL); }
#define VARRESET() { VARDECL(UNKNOWN); VARIO(UNKNOWN); VARDTYPE(NULL); }
#define VARDECL(type) { GRAMMARP->m_varDecl = AstVarType::type; }
#define VARIO(type) { GRAMMARP->m_varIO = AstVarType::type; }
#define VARSIGNED(value) { GRAMMARP->m_varSigned = value; }
#define VARRANGE(rangep) { GRAMMARP->setRange(rangep); }
#define VARTYPE(typep) { VARRANGE(typep); } // Temp until other data types supported
#define VARDTYPE(dtypep) { GRAMMARP->setDType(dtypep); }
#define VARDONEA(name,array,attrs) GRAMMARP->createVariable(CRELINE(),(name),(array),(attrs))
#define VARDONEP(portp,array,attrs) GRAMMARP->createVariable((portp)->fileline(),(portp)->name(),(array),(attrs))
@ -589,10 +587,10 @@ port<nodep>: // ==IEEE: port
// // IEEE: interface_port_header port_identifier { unpacked_dimension }
// // Expanded interface_port_header
// // We use instantCb here because the non-port form looks just like a module instantiation
//UNSUP portDirNetE id/*interface*/ idAny/*port*/ regArRangeE sigAttrListE { VARTYPE($2); VARDONEA($3, $4); PARSEP->instantCb(CRELINE(), $2, $3, $4); PINNUMINC(); }
//UNSUP portDirNetE yINTERFACE idAny/*port*/ regArRangeE sigAttrListE { VARTYPE($2); VARDONEA($3, $4); PINNUMINC(); }
//UNSUP portDirNetE id/*interface*/ '.' idAny/*modport*/ idAny/*port*/ regArRangeE sigAttrListE { VARTYPE($2); VARDONEA($5, $6); PARSEP->instantCb(CRELINE(), $2, $5, $6); PINNUMINC(); }
//UNSUP portDirNetE yINTERFACE '.' idAny/*modport*/ idAny/*port*/ regArRangeE sigAttrListE { VARTYPE($2); VARDONEA($5, $6); PINNUMINC(); }
//UNSUP portDirNetE id/*interface*/ idAny/*port*/ regArRangeE sigAttrListE { VARDTYPE($2); VARDONEA($3, $4); PARSEP->instantCb(CRELINE(), $2, $3, $4); PINNUMINC(); }
//UNSUP portDirNetE yINTERFACE idAny/*port*/ regArRangeE sigAttrListE { VARDTYPE($2); VARDONEA($3, $4); PINNUMINC(); }
//UNSUP portDirNetE id/*interface*/ '.' idAny/*modport*/ idAny/*port*/ regArRangeE sigAttrListE { VARDTYPE($2); VARDONEA($5, $6); PARSEP->instantCb(CRELINE(), $2, $5, $6); PINNUMINC(); }
//UNSUP portDirNetE yINTERFACE '.' idAny/*modport*/ idAny/*port*/ regArRangeE sigAttrListE { VARDTYPE($2); VARDONEA($5, $6); PINNUMINC(); }
//
// // IEEE: ansi_port_declaration, with [port_direction] removed
// // IEEE: [ net_port_header | interface_port_header ] port_identifier { unpacked_dimension }
@ -625,24 +623,24 @@ port<nodep>: // ==IEEE: port
//UNSUP portDirNetE signingE rangeList '.' portSig '(' portAssignExprE ')' sigAttrListE { UNSUP }
//UNSUP portDirNetE /*implicit*/ '.' portSig '(' portAssignExprE ')' sigAttrListE { UNSUP }
//
portDirNetE data_type portSig variable_dimensionListE sigAttrListE { $$=$3; VARTYPE($2); $$->addNextNull(VARDONEP($$,$4,$5)); }
//UNSUP portDirNetE yVAR data_type portSig variable_dimensionListE sigAttrListE { $$=$4; VARTYPE($3); $$->addNextNull(VARDONEP($$,$5,$6)); }
//UNSUP portDirNetE yVAR implicit_type portSig variable_dimensionListE sigAttrListE { $$=$4; VARTYPE($3); $$->addNextNull(VARDONEP($$,$5,$6)); }
| portDirNetE signingE rangeList portSig variable_dimensionListE sigAttrListE { $$=$4; VARTYPE($3); $$->addNextNull(VARDONEP($$,$5,$6)); }
| portDirNetE /*implicit*/ portSig variable_dimensionListE sigAttrListE { $$=$2; /*VARTYPE-same*/ $$->addNextNull(VARDONEP($$,$3,$4)); }
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 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 /*implicit*/ portSig variable_dimensionListE sigAttrListE { $$=$2; /*VARDTYPE-same*/ $$->addNextNull(VARDONEP($$,$3,$4)); }
//
| portDirNetE data_type portSig variable_dimensionListE sigAttrListE '=' constExpr { $$=$3; VARTYPE($2); $$->addNextNull(VARDONEP($$,$4,$5)); $$->addNextNull(GRAMMARP->newVarInit($6,$$,$7)); }
//UNSUP portDirNetE yVAR data_type portSig variable_dimensionListE sigAttrListE '=' constExpr { $$=$3; VARTYPE($3); $$->addNextNull(VARDONEP($$,$5,$6)); $$->addNextNull(GRAMMARP->newVarInit($7,$$,$8)); }
//UNSUP portDirNetE yVAR implicit_type portSig variable_dimensionListE sigAttrListE '=' constExpr { $$=$3; VARTYPE($3); $$->addNextNull(VARDONEP($$,$5,$6)); $$->addNextNull(GRAMMARP->newVarInit($7,$$,$8)); }
| portDirNetE /*implicit*/ portSig variable_dimensionListE sigAttrListE '=' constExpr { $$=$3; /*VARTYPE-same*/ $$->addNextNull(VARDONEP($$,$3,$4)); $$->addNextNull(GRAMMARP->newVarInit($5,$$,$6)); }
| portDirNetE data_type portSig variable_dimensionListE sigAttrListE '=' constExpr { $$=$3; VARDTYPE($2); $$->addNextNull(VARDONEP($$,$4,$5)); $$->addNextNull(GRAMMARP->newVarInit($6,$$,$7)); }
//UNSUP portDirNetE yVAR data_type portSig variable_dimensionListE sigAttrListE '=' constExpr { $$=$3; VARDTYPE($3); $$->addNextNull(VARDONEP($$,$5,$6)); $$->addNextNull(GRAMMARP->newVarInit($7,$$,$8)); }
//UNSUP portDirNetE yVAR implicit_type portSig variable_dimensionListE sigAttrListE '=' constExpr { $$=$3; VARDTYPE($3); $$->addNextNull(VARDONEP($$,$5,$6)); $$->addNextNull(GRAMMARP->newVarInit($7,$$,$8)); }
| portDirNetE /*implicit*/ portSig variable_dimensionListE sigAttrListE '=' constExpr { $$=$3; /*VARDTYPE-same*/ $$->addNextNull(VARDONEP($$,$3,$4)); $$->addNextNull(GRAMMARP->newVarInit($5,$$,$6)); }
;
portDirNetE: // IEEE: part of port, optional net type and/or direction
/* empty */ { }
// // Per spec, if direction given default the nettype.
// // The higher level rule may override this VARTYPE with one later in the parse.
| port_direction { VARDECL(PORT); VARTYPE(NULL/*default_nettype*/); }
| port_direction net_type { VARDECL(PORT); VARTYPE(NULL/*default_nettype*/); } // net_type calls VARNET
// // The higher level rule may override this VARDTYPE with one later in the parse.
| port_direction { VARDECL(PORT); VARDTYPE(NULL/*default_nettype*/); }
| port_direction net_type { VARDECL(PORT); VARDTYPE(NULL/*default_nettype*/); } // net_type calls VARNET
| net_type { } // net_type calls VARNET
;
@ -675,7 +673,9 @@ list_of_genvar_identifiers<nodep>: // IEEE: list_of_genvar_identifiers (for decl
;
genvar_identifierDecl<nodep>: // IEEE: genvar_identifier (for declaration)
id/*new-genvar_identifier*/ sigAttrListE { VARRESET_NONLIST(GENVAR); $$ = VARDONEA(*$1, NULL, $2); }
id/*new-genvar_identifier*/ sigAttrListE
{ VARRESET_NONLIST(GENVAR); VARDTYPE(new AstBasicDType($<fl>1,AstBasicDTypeKwd::INTEGER));
$$ = VARDONEA(*$1, NULL, $2); }
;
local_parameter_declaration<nodep>: // IEEE: local_parameter_declaration
@ -692,23 +692,23 @@ parameter_declaration<nodep>: // IEEE: parameter_declaration
;
local_parameter_declarationFront: // IEEE: local_parameter_declaration w/o assignment
varLParamReset implicit_type { /*VARRESET-in-varLParam*/ VARTYPE($2); }
//UNSUP varLParamReset data_type { /*VARRESET-in-varLParam*/ VARTYPE($2); }
//UNSUP varLParamReset yTYPE { /*VARRESET-in-varLParam*/ VARTYPE($2); }
varLParamReset implicit_type { /*VARRESET-in-varLParam*/ VARDTYPE($2); }
//UNSUP varLParamReset data_type { /*VARRESET-in-varLParam*/ VARDTYPE($2); }
//UNSUP varLParamReset yTYPE { /*VARRESET-in-varLParam*/ VARDTYPE($2); }
;
parameter_declarationFront: // IEEE: parameter_declaration w/o assignment
varGParamReset implicit_type { /*VARRESET-in-varGParam*/ VARTYPE($2); }
//UNSUP varGParamReset data_type { /*VARRESET-in-varGParam*/ VARTYPE($2); }
//UNSUP varGParamReset yTYPE { /*VARRESET-in-varGParam*/ VARTYPE($2); }
varGParamReset implicit_type { /*VARRESET-in-varGParam*/ VARDTYPE($2); }
//UNSUP varGParamReset data_type { /*VARRESET-in-varGParam*/ VARDTYPE($2); }
//UNSUP varGParamReset yTYPE { /*VARRESET-in-varGParam*/ VARDTYPE($2); }
;
parameter_port_declarationFront: // IEEE: parameter_port_declaration w/o assignment
// // IEEE: parameter_declaration (minus assignment)
parameter_declarationFront { }
//
//UNSUP data_type { VARTYPE($1); }
//UNSUP yTYPE { VARTYPE($1); }
//UNSUP data_type { VARDTYPE($1); }
//UNSUP yTYPE { VARDTYPE($1); }
;
net_declaration<nodep>: // IEEE: net_declaration - excluding implict
@ -716,7 +716,7 @@ net_declaration<nodep>: // IEEE: net_declaration - excluding implict
;
net_declarationFront: // IEEE: beginning of net_declaration
net_declRESET net_type strengthSpecE signingE delayrange { }
net_declRESET net_type strengthSpecE signingE delayrange { VARDTYPE($5); $5->setSignedState($4); }
;
net_declRESET:
@ -738,7 +738,7 @@ net_type: // ==IEEE: net_type
;
varRESET:
/* empty */ { VARRESET(); }
/* empty */ { VARRESET_NONLIST(VAR); }
;
varGParamReset:
@ -775,53 +775,57 @@ port_declaration<nodep>: // ==IEEE: port_declaration
// // IEEE: input_declaration
// // IEEE: output_declaration
// // IEEE: ref_declaration
port_directionReset port_declNetE data_type { VARTYPE($3); } list_of_variable_decl_assignments { $$ = $5; }
//UNSUP port_directionReset port_declNetE yVAR data_type { VARTYPE($4); } list_of_variable_decl_assignments { $$ = $6; }
//UNSUP port_directionReset port_declNetE yVAR implicit_type { VARTYPE($4); } list_of_variable_decl_assignments { $$ = $6; }
| port_directionReset port_declNetE signingE rangeList { VARTYPE($4); } list_of_variable_decl_assignments { $$ = $6; }
| port_directionReset port_declNetE signing { VARTYPE(NULL); } list_of_variable_decl_assignments { $$ = $5; }
| port_directionReset port_declNetE /*implicit*/ { VARTYPE(NULL);/*default_nettype*/} list_of_variable_decl_assignments { $$ = $4; }
port_directionReset port_declNetE data_type { VARDTYPE($3); }
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 implicit_type { VARDTYPE($4); } list_of_variable_decl_assignments { $$ = $6; }
| port_directionReset port_declNetE signingE rangeList { VARDTYPE(new AstBasicDType($4->fileline(), LOGIC, $4, $3)); }
list_of_variable_decl_assignments { $$ = $6; }
| port_directionReset port_declNetE signing { VARDTYPE(new AstBasicDType($<fl>3, LOGIC, NULL, $3)); }
list_of_variable_decl_assignments { $$ = $5; }
| port_directionReset port_declNetE /*implicit*/ { VARDTYPE(NULL);/*default_nettype*/}
list_of_variable_decl_assignments { $$ = $4; }
;
tf_port_declaration<nodep>: // ==IEEE: tf_port_declaration
// // Used inside function; followed by ';'
// // SIMILAR to port_declaration
//
port_directionReset data_type { VARTYPE($2); } list_of_tf_variable_identifiers ';' { $$ = $4; }
| port_directionReset implicit_type { VARTYPE($2); } list_of_tf_variable_identifiers ';' { $$ = $4; }
//UNSUP port_directionReset yVAR data_type { VARTYPE($3); } list_of_tf_variable_identifiers ';' { $$ = $5; }
//UNSUP port_directionReset yVAR implicit_type { VARTYPE($3); } list_of_tf_variable_identifiers ';' { $$ = $5; }
port_directionReset data_type { VARDTYPE($2); } list_of_tf_variable_identifiers ';' { $$ = $4; }
| port_directionReset implicit_type { VARDTYPE($2); } list_of_tf_variable_identifiers ';' { $$ = $4; }
//UNSUP port_directionReset yVAR data_type { VARDTYPE($3); } list_of_tf_variable_identifiers ';' { $$ = $5; }
//UNSUP port_directionReset yVAR implicit_type { VARDTYPE($3); } list_of_tf_variable_identifiers ';' { $$ = $5; }
;
integer_atom_type<rangep>: // ==IEEE: integer_atom_type
//UNSUP yBYTE { UNSUP }
//UNSUP ySHORTINT { UNSUP }
//UNSUP yINT { UNSUP }
//UNSUP yLONGINT { UNSUP }
yINTEGER { VARDECL(INTEGER); $$ = new AstRange($1,31,0); $$->isSigned(true); }
//UNSUP yTIME { UNSUP }
integer_atom_type<bdtypep>: // ==IEEE: integer_atom_type
//UNSUP yBYTE { $$ = new AstBasicDType($1,AstBasicDTypeKwd::BYTE); }
//UNSUP ySHORTINT { $$ = new AstBasicDType($1,AstBasicDTypeKwd::SHORTINT); }
//UNSUP yINT { $$ = new AstBasicDType($1,AstBasicDTypeKwd::INT); }
//UNSUP yLONGINT { $$ = new AstBasicDType($1,AstBasicDTypeKwd::LONGINT); }
yINTEGER { $$ = new AstBasicDType($1,AstBasicDTypeKwd::INTEGER); }
//UNSUP yTIME { $$ = new AstBasicDType($1,AstBasicDTypeKwd::TIME); }
;
integer_vector_type: // ==IEEE: integer_atom_type
yBIT { VARDECL(REG); }
| yLOGIC { VARDECL(REG); }
| yREG { VARDECL(REG); }
integer_vector_type<bdtypep>: // ==IEEE: integer_atom_type
yBIT { $$ = new AstBasicDType($1,AstBasicDTypeKwd::BIT); }
| yLOGIC { $$ = new AstBasicDType($1,AstBasicDTypeKwd::LOGIC); }
| yREG { $$ = new AstBasicDType($1,AstBasicDTypeKwd::REG); }
;
signingE: // IEEE: signing - plus empty
/*empty*/ { }
| signing { }
signingE<signstate>: // IEEE: signing - plus empty
/*empty*/ { $$ = signedst_NOP; }
| signing { $$ = $1; }
;
signing: // ==IEEE: signing
ySIGNED { VARSIGNED(true); }
| yUNSIGNED { VARSIGNED(false); }
signing<signstate>: // ==IEEE: signing
ySIGNED { $<fl>$ = $<fl>1; $$ = signedst_SIGNED; }
| yUNSIGNED { $<fl>$ = $<fl>1; $$ = signedst_UNSIGNED; }
;
//************************************************
// Data Types
data_type<rangep>: // ==IEEE: data_type
data_type<typep>: // ==IEEE: data_type
// // This expansion also replicated elsewhere, IE data_type__AndID
data_typeNoRef { $$ = $1; }
// // IEEE: [ class_scope | package_scope ] type_identifier { packed_dimension }
@ -833,10 +837,14 @@ data_type<rangep>: // ==IEEE: data_type
//UNSUP ps_covergroup_identifier { $$ = $1; }
;
data_typeNoRef<rangep>: // ==IEEE: data_type, excluding class_type etc references
integer_vector_type signingE rangeListE { $$ = $3; }
| integer_atom_type signingE { $$ = $1; }
data_typeBasic<bdtypep>: // IEEE: part of data_type
integer_vector_type signingE rangeListE { $$ = $1; $$->setSignedState($2); $$->rangep($3); }
| integer_atom_type signingE { $$ = $1; $$->setSignedState($2); }
//UNSUP non_integer_type { UNSUP }
;
data_typeNoRef<typep>: // ==IEEE: data_type, excluding class_type etc references
data_typeBasic { $$ = $1; }
//UNSUP ySTRUCT packedSigningE '{' struct_union_memberList '}' packed_dimensionE { UNSUP }
//UNSUP yUNION taggedE packedSigningE '{' struct_union_memberList '}' packed_dimensionE { UNSUP }
//UNSUP enumDecl { UNSUP }
@ -939,22 +947,22 @@ data_declarationVar<nodep>: // IEEE: part of data_declaration
data_declarationVarFront: // IEEE: part of data_declaration
// // implicit_type expanded into /*empty*/ or "signingE rangeList"
//UNSUP constE yVAR lifetimeE data_type { /*VARRESET-in-ddVar*/ VARDECL("var"); VARTYPE(SPACED($1,$4)); }
//UNSUP constE yVAR lifetimeE { /*VARRESET-in-ddVar*/ VARDECL("var"); VARTYPE($1); }
//UNSUP constE yVAR lifetimeE signingE rangeList { /*VARRESET-in-ddVar*/ VARDECL("var"); VARTYPE(SPACED($1,SPACED($4,$5))); }
//UNSUP constE yVAR lifetimeE data_type { /*VARRESET-in-ddVar*/ VARDECL("var"); VARDTYPE(SPACED($1,$4)); }
//UNSUP constE yVAR lifetimeE { /*VARRESET-in-ddVar*/ VARDECL("var"); VARDTYPE($1); }
//UNSUP constE yVAR lifetimeE signingE rangeList { /*VARRESET-in-ddVar*/ VARDECL("var"); VARDTYPE(SPACED($1,SPACED($4,$5))); }
//
// // Expanded: "constE lifetimeE data_type"
/**/ data_type { /*VARRESET-in-ddVar*/ VARTYPE($1); }
| /**/ lifetime data_type { /*VARRESET-in-ddVar*/ VARTYPE($2); }
//UNSUP yCONST__ETC lifetimeE data_type { /*VARRESET-in-ddVar*/ VARTYPE($3); }
/**/ data_type { /*VARRESET-in-ddVar*/ VARDTYPE($1); }
| /**/ lifetime data_type { /*VARRESET-in-ddVar*/ VARDTYPE($2); }
//UNSUP yCONST__ETC lifetimeE data_type { /*VARRESET-in-ddVar*/ VARDTYPE($3); }
// // = class_new is in variable_decl_assignment
;
implicit_type<rangep>: // IEEE: part of *data_type_or_implicit
implicit_type<typep>: // IEEE: part of *data_type_or_implicit
// // Also expanded in data_declaration
/* empty */ { $$ = NULL; }
| signingE rangeList { $$ = $2; } // signing sets VARSIGNED, so not passed up
| signing { $$ = NULL; } // signing sets VARSIGNED, so not passed up
| signingE rangeList { $$ = new AstBasicDType($2->fileline(), LOGIC, $2, $1); }
| signing { $$ = new AstBasicDType($<fl>1, LOGIC, NULL, $1); }
;
//************************************************
@ -1232,9 +1240,9 @@ rangeList<rangep>: // IEEE: {packed_dimension}
| rangeList anyrange { $$ = $1; $1->addNext($2); }
;
regrangeE<rangep>:
/* empty */ { $$ = NULL; VARRANGE($$); }
| anyrange { $$ = $1; VARRANGE($$); }
regrangeE<bdtypep>:
/* empty */ { $$ = new AstBasicDType(CRELINE(), LOGIC, NULL); }
| anyrange { $$ = new AstBasicDType(CRELINE(), LOGIC, $1); }
;
// IEEE: select
@ -1244,7 +1252,7 @@ anyrange<rangep>:
'[' constExpr ':' constExpr ']' { $$ = new AstRange($1,$2,$4); }
;
delayrange<rangep>:
delayrange<bdtypep>:
regrangeE delayE { $$ = $1; }
| ySCALARED regrangeE delayE { $$ = $2; }
| yVECTORED regrangeE delayE { $$ = $2; }
@ -1791,12 +1799,12 @@ tfBodyE<nodep>: // IEEE: part of function_body_declaration/task_body_declarati
| stmtList { $$ = $1; }
;
funcTypeE<rangep>:
funcTypeE<typep>:
/* empty */ { $$ = NULL; }
| yINTEGER { $$ = new AstRange($1,31,0); $$->isSigned(true); }
| ySIGNED { $$ = new AstRange($1,0,0); $$->isSigned(true); }
| ySIGNED '[' constExpr ':' constExpr ']' { $$ = new AstRange($1,$3,$5); $$->isSigned(true); }
| '[' constExpr ':' constExpr ']' { $$ = new AstRange($1,$2,$4); }
| 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>:
@ -1833,18 +1841,18 @@ tf_port_item<nodep>: // ==IEEE: tf_port_item
;
tf_port_itemFront: // IEEE: part of tf_port_item, which has the data type
data_type { VARTYPE($1); }
| signingE rangeList { VARTYPE($2); }
| signing { VARTYPE(NULL); }
//UNSUP yVAR data_type { VARTYPE($2); }
//UNSUP yVAR implicit_type { VARTYPE($2); }
data_type { VARDTYPE($1); }
| signingE rangeList { VARDTYPE(new AstBasicDType($2->fileline(), LOGIC, $2, $1)); }
| signing { VARDTYPE(new AstBasicDType($<fl>1, LOGIC, NULL, $1)); }
//UNSUP yVAR data_type { VARDTYPE($2); }
//UNSUP yVAR implicit_type { VARDTYPE($2); }
//
| tf_port_itemDir /*implicit*/ { VARTYPE(NULL); /*default_nettype-see spec*/ }
| tf_port_itemDir data_type { VARTYPE($2); }
| tf_port_itemDir signingE rangeList { VARTYPE($3); }
| tf_port_itemDir signing { VARTYPE(NULL); }
//UNSUP tf_port_itemDir yVAR data_type { VARTYPE($3); }
//UNSUP tf_port_itemDir yVAR implicit_type { VARTYPE($3); }
| tf_port_itemDir /*implicit*/ { VARDTYPE(NULL); /*default_nettype-see spec*/ }
| tf_port_itemDir data_type { VARDTYPE($2); }
| tf_port_itemDir signingE rangeList { VARDTYPE(new AstBasicDType($3->fileline(), LOGIC, $3, $2)); }
| tf_port_itemDir signing { VARDTYPE(new AstBasicDType($<fl>2, LOGIC, NULL, $2)); }
//UNSUP tf_port_itemDir yVAR data_type { VARDTYPE($3); }
//UNSUP tf_port_itemDir yVAR implicit_type { VARDTYPE($3); }
;
tf_port_itemDir: // IEEE: part of tf_port_item, direction
@ -2555,7 +2563,7 @@ const char* V3ParseImp::tokenName(int token) {
void V3ParseImp::parserClear() {
// Clear up any dynamic memory V3Parser required
GRAMMARP->setRange(NULL);
VARDTYPE(NULL);
}
AstNode* V3ParseGrammar::createSupplyExpr(FileLine* fileline, string name, int value) {
@ -2570,43 +2578,33 @@ AstNode* V3ParseGrammar::createSupplyExpr(FileLine* fileline, string name, int v
}
AstVar* V3ParseGrammar::createVariable(FileLine* fileline, string name, AstRange* arrayp, AstNode* attrsp) {
AstVarType type = GRAMMARP->m_varIO;
AstRange* rangep = GRAMMARP->m_varRangep;
AstRange* cleanup_rangep = NULL;
//UINFO(0,"CREVAR "<<fileline->ascii()<<" decl="<<GRAMMARP->m_varDecl.ascii()<<" io="<<GRAMMARP->m_varIO.ascii()<<endl);
if (type == AstVarType::UNKNOWN || type == AstVarType::PORT) type = GRAMMARP->m_varDecl;
if (type == AstVarType::PORT) {
// Just wanted port decl; we've already made it.
if (rangep) fileline->v3error("Unsupported: Ranges ignored in port-lists");
AstNodeDType* dtypep = GRAMMARP->m_varDTypep;
UINFO(5," creVar "<<name<<" decl="<<GRAMMARP->m_varDecl<<" io="<<GRAMMARP->m_varIO<<" dt="<<(dtypep?"set":"")<<endl);
if (GRAMMARP->m_varIO == AstVarType::UNKNOWN
&& GRAMMARP->m_varDecl == AstVarType::PORT) {
// Just a port list with variable name (not v2k format); AstPort already created
if (dtypep) fileline->v3error("Unsupported: Ranges ignored in port-lists");
return NULL;
}
if (type == AstVarType::UNKNOWN) fileline->v3fatalSrc("Unknown signal type declared");
// Linting, because we allow parsing of a superset of the language
if (type == AstVarType::INTEGER || GRAMMARP->m_varDecl == AstVarType::INTEGER
|| type == AstVarType::GENVAR) {
if (rangep) {
if (rangep->msbConst()==31 && rangep->lsbConst()==0) {
// For backward compatibility with functions some INTEGERS are internally made as [31:0]
rangep->deleteTree(); rangep=NULL; GRAMMARP->m_varRangep=NULL;
} else {
fileline->v3error("Integers may not be ranged: "<<name);
}
}
cleanup_rangep = new AstRange(fileline, 31, 0); // Integer == REG[31:0]
rangep = cleanup_rangep;
AstVarType type = GRAMMARP->m_varIO;
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);
} else { // May make new variables with same type, so clone
dtypep = dtypep->cloneTree(false);
}
//UINFO(0,"CREVAR "<<fileline->ascii()<<" decl="<<GRAMMARP->m_varDecl.ascii()<<" io="<<GRAMMARP->m_varIO.ascii()<<endl);
if (type == AstVarType::UNKNOWN
|| (type == AstVarType::PORT && GRAMMARP->m_varDecl != AstVarType::UNKNOWN))
type = GRAMMARP->m_varDecl;
if (type == AstVarType::UNKNOWN) fileline->v3fatalSrc("Unknown signal type declared");
if (type == AstVarType::GENVAR) {
if (arrayp) fileline->v3error("Genvars may not be arrayed: "<<name);
}
AstVar* nodep = new AstVar(fileline, type, name,
rangep->cloneTree(false),
dtypep,
arrayp);
nodep->addAttrsp(attrsp);
nodep->isSigned(GRAMMARP->m_varSigned);
if (type == AstVarType::INTEGER || GRAMMARP->m_varDecl == AstVarType::INTEGER
|| type == AstVarType::GENVAR) {
nodep->isSigned(true);
}
if (GRAMMARP->m_varDecl != AstVarType::UNKNOWN) nodep->combineType(GRAMMARP->m_varDecl);
if (GRAMMARP->m_varIO != AstVarType::UNKNOWN) nodep->combineType(GRAMMARP->m_varIO);
@ -2625,7 +2623,6 @@ AstVar* V3ParseGrammar::createVariable(FileLine* fileline, string name, AstRange
// Remember the last variable created, so we can attach attributes to it in later parsing
GRAMMARP->m_varAttrp = nodep;
if (cleanup_rangep) { cleanup_rangep->deleteTree(); cleanup_rangep=NULL; }
return nodep;
}