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)") export OBJCACHE_JOBS := -j $(shell objcache --jobs "$(OBJCACHE_HOSTS)")
endif endif
default: all
all: all_nomsg msg_test all: all_nomsg msg_test
all_nomsg: verilator_exe $(VL_INST_MAN_FILES) all_nomsg: verilator_exe $(VL_INST_MAN_FILES)
.PHONY:verilator_exe .PHONY:verilator_exe
.PHONY:verilator_bin
.PHONY:verilator_bin_dbg
verilator_exe verilator_bin verilator_bin_dbg: verilator_exe verilator_bin verilator_bin_dbg:
@echo ------------------------------------------------------------ @echo ------------------------------------------------------------
@echo "making verilator in src" ; \ @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 { class AstVarType {
public: public:
enum en { enum en {
@ -205,7 +237,7 @@ public:
GPARAM, GPARAM,
LPARAM, LPARAM,
GENVAR, GENVAR,
INTEGER, VAR, // Reg, integer, logic, etc
INPUT, INPUT,
OUTPUT, OUTPUT,
INOUT, INOUT,
@ -213,7 +245,6 @@ public:
SUPPLY1, SUPPLY1,
WIRE, WIRE,
IMPLICIT, IMPLICIT,
REG,
TRIWIRE, TRIWIRE,
PORT, // Temp type used in parser only PORT, // Temp type used in parser only
BLOCKTEMP, BLOCKTEMP,
@ -229,8 +260,8 @@ public:
const char* ascii() const { const char* ascii() const {
static const char* names[] = { static const char* names[] = {
"?","GPARAM","LPARAM","GENVAR", "?","GPARAM","LPARAM","GENVAR",
"INTEGER","INPUT","OUTPUT","INOUT", "VAR","INPUT","OUTPUT","INOUT",
"SUPPLY0","SUPPLY1","WIRE","IMPLICIT","REG","TRIWIRE","PORT", "SUPPLY0","SUPPLY1","WIRE","IMPLICIT","TRIWIRE","PORT",
"BLOCKTEMP","MODULETEMP","STMTTEMP","XTEMP"}; "BLOCKTEMP","MODULETEMP","STMTTEMP","XTEMP"};
return names[m_e]; } return names[m_e]; }
}; };
@ -1121,10 +1152,19 @@ public:
return text()==samep->castNodeText()->text(); } 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 { struct AstNodeSel : public AstNodeBiop {
// Single bit range extraction, perhaps with non-constant selection or array selection // Single bit range extraction, perhaps with non-constant selection or array selection
AstNodeSel(FileLine* fl, AstNode* fromp, AstNode* bitp) AstNodeSel(FileLine* fl, AstNode* fromp, AstNode* bitp)
:AstNodeBiop(fl, fromp, bitp) {} :AstNodeBiop(fl, fromp, bitp) {}
ASTNODE_BASE_FUNCS(NodeSel)
AstNode* fromp() const { return op1p()->castNode(); } // op1 = Extracting what (NULL=TBD during parsing) AstNode* fromp() const { return op1p()->castNode(); } // op1 = Extracting what (NULL=TBD during parsing)
AstNode* bitp() const { return op2p()->castNode(); } // op2 = Msb selection expression AstNode* bitp() const { return op2p()->castNode(); } // op2 = Msb selection expression
int bitConst() const; int bitConst() const;

View File

@ -35,6 +35,11 @@
//====================================================================== //======================================================================
// Special methods // 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 // 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()) bool AstNodeVarRef::broken() const { return ((m_varScopep && !m_varScopep->brokeExists())
|| (m_varp && !m_varp->brokeExists())); } || (m_varp && !m_varp->brokeExists())); }
@ -319,6 +324,10 @@ void AstAttrOf::dump(ostream& str) {
this->AstNode::dump(str); this->AstNode::dump(str);
str<<" ["<<attrType().ascii()<<"]"; str<<" ["<<attrType().ascii()<<"]";
} }
void AstBasicDType::dump(ostream& str) {
this->AstNode::dump(str);
str<<" ["<<keyword().ascii()<<"]";
}
void AstCast::dump(ostream& str) { void AstCast::dump(ostream& str) {
this->AstNode::dump(str); this->AstNode::dump(str);
str<<" sz"<<size(); str<<" sz"<<size();

View File

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

View File

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

View File

@ -85,8 +85,7 @@ private:
AstVar* varp = vscp->varp(); AstVar* varp = vscp->varp();
if (varp->width()!=1) varp->v3error("Unsupported: Clock edge on non-single bit signal: "<<varp->prettyName()); 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()); string newvarname = ((string)"__Vclklast__"+vscp->scopep()->nameDotless()+"__"+varp->shortName());
AstVar* newvarp AstVar* newvarp = new AstVar (vscp->fileline(), AstVarType::MODULETEMP, newvarname, AstVar::LogicPacked(), 1);
= new AstVar (vscp->fileline(), AstVarType::MODULETEMP, newvarname, NULL, NULL); // No range; 1 bit.
newvarp->width(1,1); newvarp->width(1,1);
m_modp->addStmtp(newvarp); m_modp->addStmtp(newvarp);
AstVarScope* newvscp = new AstVarScope(vscp->fileline(), m_scopep, 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) { AstVarScope* getCreateLocalVar(FileLine* fl, const string& name, AstVar* examplep, int width) {
AstVar* newvarp; AstVar* newvarp;
if (width) { 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 { } else {
newvarp = new AstVar (fl, AstVarType::BLOCKTEMP, name, examplep); // No range; 1 bit. 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()); AstNode* basefromp = AstArraySel::baseFromp(nodep->fromp());
if (AstNodeVarRef* varrefp = basefromp->castNodeVarRef()) { if (AstNodeVarRef* varrefp = basefromp->castNodeVarRef()) {
AstVar* varp = varrefp->varp(); AstVar* varp = varrefp->varp();
if (!varp->dtypep()) varp->v3fatalSrc("Data type lost");
if (m_warn if (m_warn
&& nodep->lsbp()->castConst() && nodep->lsbp()->castConst()
&& nodep->widthp()->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() if (nodep->lsbp()->castConst()->num().isFourState()
|| nodep->widthp()->castConst()->num().isFourState()) { || nodep->widthp()->castConst()->num().isFourState()) {
nodep->v3error("Selection index is constantly unknown or tristated: " nodep->v3error("Selection index is constantly unknown or tristated: "
@ -770,9 +771,9 @@ private:
string name1 = ((string)"__Vconcswap"+cvtToStr(m_modp->varNumGetInc())); string name1 = ((string)"__Vconcswap"+cvtToStr(m_modp->varNumGetInc()));
string name2 = ((string)"__Vconcswap"+cvtToStr(m_modp->varNumGetInc())); string name2 = ((string)"__Vconcswap"+cvtToStr(m_modp->varNumGetInc()));
AstVar* temp1p = new AstVar(sel1p->fileline(), AstVarType::BLOCKTEMP, name1, 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, 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(temp1p);
m_modp->addStmtp(temp2p); m_modp->addStmtp(temp2p);
AstNodeAssign* asn1ap=nodep->cloneType AstNodeAssign* asn1ap=nodep->cloneType

View File

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

View File

@ -128,19 +128,12 @@ private:
// Created module's AstVar earlier under some other scope // Created module's AstVar earlier under some other scope
varp = iter->second; varp = iter->second;
} else { } else {
AstRange* rangep = NULL;
if (width==0) { if (width==0) {
rangep = new AstRange(oldvarscp->fileline(), varp = new AstVar (oldvarscp->fileline(), AstVarType::BLOCKTEMP, name, oldvarscp->varp());
oldvarscp->varp()->msb(), varp->widthSignedFrom(oldvarscp);
oldvarscp->varp()->lsb());
} else if (width==1) {
rangep = NULL;
} else { } else {
rangep = new AstRange(oldvarscp->fileline(), varp = new AstVar (oldvarscp->fileline(), AstVarType::BLOCKTEMP, name, AstVar::LogicPacked(), width);
width-1, 0);
} }
varp = new AstVar (oldvarscp->fileline(), AstVarType::BLOCKTEMP, name, rangep);
if (width==0) varp->widthSignedFrom(oldvarscp);
addmodp->addStmtp(varp); addmodp->addStmtp(varp);
m_modVarMap.insert(make_pair(make_pair(addmodp, name), 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 // 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. // though it's one bit wide, needs the mask in the upper bits.
// (Someday we'll have a valid bitmask instead of widths....) // (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"); if (!m_funcp) nodep->v3fatalSrc("Deep expression not under a function");
m_funcp->addInitsp(varp); m_funcp->addInitsp(varp);
// Replace node tree with reference to var // Replace node tree with reference to var

View File

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

View File

@ -106,6 +106,16 @@ private:
UINFO(5," Inline CELL "<<nodep<<endl); UINFO(5," Inline CELL "<<nodep<<endl);
UINFO(5," To MOD "<<m_modp<<endl); UINFO(5," To MOD "<<m_modp<<endl);
m_statCells++; 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->dumpTree(cout,"inlcell:"); }
//if (debug()>=9) { nodep->modp()->dumpTree(cout,"oldmod:"); } //if (debug()>=9) { nodep->modp()->dumpTree(cout,"oldmod:"); }
AstModule* newmodp = nodep->modp()->cloneTree(false); AstModule* newmodp = nodep->modp()->cloneTree(false);
@ -119,8 +129,6 @@ private:
// Create assignments to the pins // Create assignments to the pins
for (AstPin* pinp = nodep->pinsp(); pinp; pinp=pinp->nextp()->castPin()) { for (AstPin* pinp = nodep->pinsp(); pinp; pinp=pinp->nextp()->castPin()) {
UINFO(6," Pin change from "<<pinp->modVarp()<<endl); 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 // Make new signal; even though we'll optimize the interconnect, we
// need an alias to trace correctly. If tracing is disabled, we'll // need an alias to trace correctly. If tracing is disabled, we'll
// delete it in later optimizations. // delete it in later optimizations.

View File

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

View File

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

View File

@ -124,7 +124,7 @@ private:
// Make a new temp wire // Make a new temp wire
string newvarname = "__Vsenitemexpr"+cvtToStr(++m_senitemCvtNum); string newvarname = "__Vsenitemexpr"+cvtToStr(++m_senitemCvtNum);
AstVar* newvarp = new AstVar (sensp->fileline(), AstVarType::MODULETEMP, newvarname, 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 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 // 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 AstNode* addwherep = nodep; // Add to this element's next

View File

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

View File

@ -103,7 +103,7 @@ private:
AstVar* getBlockTemp(AstNode* nodep) { AstVar* getBlockTemp(AstNode* nodep) {
string newvarname = ((string)"__Vtemp"+cvtToStr(m_modp->varNumGetInc())); string newvarname = ((string)"__Vtemp"+cvtToStr(m_modp->varNumGetInc()));
AstVar* varp = new AstVar (nodep->fileline(), AstVarType::STMTTEMP, newvarname, 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); m_funcp->addInitsp(varp);
return varp; return varp;
} }

View File

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

View File

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

View File

@ -311,10 +311,9 @@ private:
// Insert global variable // Insert global variable
if (!activityNumber) activityNumber++; // For simplicity, always create it 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, AstVar* newvarp = new AstVar (m_chgFuncp->fileline(), AstVarType::MODULETEMP,
"__Vm_traceActivity", "__Vm_traceActivity", AstVar::LogicPacked(), activityBits);
new AstRange (m_chgFuncp->fileline(), activityNumber-1, 0));
m_topModp->addStmtp(newvarp); m_topModp->addStmtp(newvarp);
AstVarScope* newvscp = new AstVarScope(newvarp->fileline(), m_highScopep, newvarp); AstVarScope* newvscp = new AstVarScope(newvarp->fileline(), m_highScopep, newvarp);
m_highScopep->addVarp(newvscp); m_highScopep->addVarp(newvscp);

View File

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

View File

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

View File

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

View File

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

View File

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