forked from github/verilator
Internals: Create data types and attach to AstVars, in prep for typedefs.
Added AstNodeDType and AstBasicDType and associated enums.
This commit is contained in:
parent
9a133ced2d
commit
4c26792c9b
@ -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" ; \
|
||||
|
48
src/V3Ast.h
48
src/V3Ast.h
@ -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;
|
||||
|
@ -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();
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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.
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
|
@ -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));
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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())
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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());
|
||||
|
@ -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));
|
||||
|
@ -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);
|
||||
|
@ -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(),
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
|
253
src/verilog.y
253
src/verilog.y
@ -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;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user