Support ports of array of reals, bug1154.

This commit is contained in:
Wilson Snyder 2017-04-28 06:10:14 -04:00
parent d693065afb
commit 96a5445d44
6 changed files with 85 additions and 4 deletions

View File

@ -5,6 +5,8 @@ The contributors that suggested a given feature are shown in []. Thanks!
* Verilator 3.903 devel
*** Support ports of array of reals, bug1154. [J Briquet]
**** Add warning on mis-sized literal, bug1156. [Todd Strader]

View File

@ -1675,6 +1675,7 @@ public:
virtual bool maybePointedTo() const { return true; }
virtual AstNodeDType* virtRefDTypep() const { return NULL; } // Iff has a non-null refDTypep(), as generic node function
virtual void virtRefDTypep(AstNodeDType* nodep) { } // Iff has refDTypep(), set as generic node function
virtual bool similarDType(AstNodeDType* samep) const = 0; // Assignable equivalence. Call skipRefp() on this and samep before calling
//
// Changing the width may confuse the data type resolution, so must clear TypeTable cache after use.
void widthForce(int width, int sized) { m_width=width; m_widthMin=sized; }
@ -1724,6 +1725,9 @@ public:
virtual int widthAlignBytes() const; // (Slow) recurses - Structure alignment 1,2,4 or 8 bytes (arrays affect this)
virtual int widthTotalBytes() const; // (Slow) recurses - Width in bytes rounding up 1,2,4,8,12,...
// op1 = members
virtual bool similarDType(AstNodeDType* samep) const {
return this==samep; // We don't compare members, require exact equivalence
}
AstMemberDType* membersp() const { return op1p()->castMemberDType(); } // op1 = AstMember list
void addMembersp(AstNode* nodep) { addNOp1p(nodep); }
bool packed() const { return m_packed; }
@ -1754,7 +1758,7 @@ public:
virtual void dump(ostream& str);
virtual void dumpSmall(ostream& str);
virtual const char* broken() const { BROKEN_RTN(!((m_refDTypep && !childDTypep() && m_refDTypep->brokeExists())
|| (!m_refDTypep && childDTypep()))); return NULL; }
|| (!m_refDTypep && childDTypep()))); return NULL; }
virtual void cloneRelink() { if (m_refDTypep && m_refDTypep->clonep()) {
m_refDTypep = m_refDTypep->clonep();
}}
@ -1763,6 +1767,14 @@ public:
return (msb()==sp->msb()
&& subDTypep()==sp->subDTypep()
&& rangenp()->sameTree(sp->rangenp())); } // HashedDT doesn't recurse, so need to check children
virtual bool similarDType(AstNodeDType* samep) const {
AstNodeArrayDType* sp = samep->castNodeArrayDType();
return (sp
&& type() == samep->type()
&& msb() == sp->msb()
&& rangenp()->sameTree(sp->rangenp())
&& subDTypep()->skipRefp()->similarDType(sp->subDTypep()->skipRefp()));
}
virtual V3Hash sameHash() const { return V3Hash(V3Hash(m_refDTypep),V3Hash(msb()),V3Hash(lsb())); }
AstNodeDType* getChildDTypep() const { return childDTypep(); }
AstNodeDType* childDTypep() const { return op1p()->castNodeDType(); } // op1 = Range of variable

View File

@ -180,6 +180,10 @@ public:
virtual AstNodeDType* skipRefp() const { return subDTypep()->skipRefp(); }
virtual AstNodeDType* skipRefToConstp() const { return subDTypep()->skipRefToConstp(); }
virtual AstNodeDType* skipRefToEnump() const { return subDTypep()->skipRefToEnump(); }
virtual bool similarDType(AstNodeDType* samep) const {
AstParamTypeDType* sp = samep->castParamTypeDType();
return (sp && this->subDTypep()->skipRefp()->similarDType(sp->subDTypep()->skipRefp()));
}
virtual int widthAlignBytes() const { return dtypep()->widthAlignBytes(); }
virtual int widthTotalBytes() const { return dtypep()->widthTotalBytes(); }
// METHODS
@ -250,7 +254,9 @@ public:
m_uniqueNum = uniqueNumInc();
}
ASTNODE_NODE_FUNCS(DefImplicitDType)
virtual bool same(AstNode* samep) const { return m_uniqueNum==samep->castDefImplicitDType()->m_uniqueNum; }
virtual bool same(AstNode* samep) const { return m_uniqueNum==samep->castDefImplicitDType()->m_uniqueNum; }
virtual bool similarDType(AstNodeDType* samep) const {
return type()==samep->type() && same(samep); }
virtual V3Hash sameHash() const { return V3Hash(m_uniqueNum); }
AstNodeDType* getChildDTypep() const { return childDTypep(); }
AstNodeDType* childDTypep() const { return op1p()->castNodeDType(); } // op1 = Range of variable
@ -392,6 +398,8 @@ public:
virtual V3Hash sameHash() const { return V3Hash(V3Hash(m.m_keyword), V3Hash(m.m_nrange.hi())); }
virtual bool same(AstNode* samep) const { // width/widthMin/numeric compared elsewhere
return samep->castBasicDType()->m == m; }
virtual bool similarDType(AstNodeDType* samep) const {
return type()==samep->type() && same(samep); }
virtual string name() const { return m.m_keyword.ascii(); }
virtual const char* broken() const { BROKEN_RTN(dtypep()!=this); return NULL; }
AstRange* rangep() const { return op1p()->castRange(); } // op1 = Range of variable
@ -456,6 +464,8 @@ public:
}}
virtual bool same(AstNode* samep) const {
return (m_refDTypep==samep->castConstDType()->m_refDTypep); }
virtual bool similarDType(AstNodeDType* samep) const {
return skipRefp()->similarDType(samep->skipRefp()); }
virtual V3Hash sameHash() const { return V3Hash(m_refDTypep); } // node's type() included elsewhere
AstNodeDType* getChildDTypep() const { return childDTypep(); }
AstNodeDType* childDTypep() const { return op1p()->castNodeDType(); } // op1 = Range of variable
@ -499,6 +509,7 @@ public:
virtual AstNodeDType* skipRefp() const { return (AstNodeDType*)this; }
virtual AstNodeDType* skipRefToConstp() const { return (AstNodeDType*)this; }
virtual AstNodeDType* skipRefToEnump() const { return (AstNodeDType*)this; }
virtual bool similarDType(AstNodeDType* samep) const { return this==samep; }
virtual int widthAlignBytes() const { return 1; }
virtual int widthTotalBytes() const { return 1; }
string cellName() const { return m_cellName; }
@ -540,6 +551,8 @@ public:
return (m_refDTypep==samep->castRefDType()->m_refDTypep
&& m_name==samep->castRefDType()->m_name
&& m_packagep==samep->castRefDType()->m_packagep); }
virtual bool similarDType(AstNodeDType* samep) const {
return skipRefp()->similarDType(samep->skipRefp()); }
virtual V3Hash sameHash() const { return V3Hash(V3Hash(m_refDTypep),V3Hash(m_packagep)); }
virtual void dump(ostream& str=cout);
virtual string name() const { return m_name; }
@ -623,6 +636,7 @@ public:
void refDTypep(AstNodeDType* nodep) { m_refDTypep = nodep; }
virtual AstNodeDType* virtRefDTypep() const { return m_refDTypep; }
virtual void virtRefDTypep(AstNodeDType* nodep) { refDTypep(nodep); }
virtual bool similarDType(AstNodeDType* samep) const { return this==samep; }
//
virtual AstBasicDType* basicp() const { return subDTypep()->basicp(); } // (Slow) recurse down to find basic data type (Note don't need virtual - AstVar isn't a NodeDType)
AstNodeDType* dtypeSkipRefp() const { return subDTypep()->skipRefp(); } // op1 = Range of variable (Note don't need virtual - AstVar isn't a NodeDType)
@ -704,6 +718,7 @@ public:
m_refDTypep = m_refDTypep->clonep();
}}
virtual bool same(AstNode* samep) const { return m_uniqueNum==samep->castEnumDType()->m_uniqueNum; }
virtual bool similarDType(AstNodeDType* samep) const { return this==samep; }
virtual V3Hash sameHash() const { return V3Hash(m_uniqueNum); }
AstNodeDType* getChildDTypep() const { return childDTypep(); }
AstNodeDType* childDTypep() const { return op1p()->castNodeDType(); } // op1 = Data type
@ -733,6 +748,7 @@ public:
ASTNODE_NODE_FUNCS(ParseTypeDType)
AstNodeDType* dtypep() const { return NULL; }
// METHODS
virtual bool similarDType(AstNodeDType* samep) const { return this==samep; }
virtual AstBasicDType* basicp() const { return NULL; }
virtual AstNodeDType* skipRefp() const { return NULL; }
virtual AstNodeDType* skipRefToConstp() const { return (AstNodeDType*)this; }

View File

@ -1861,7 +1861,7 @@ private:
}
//
if (!ok) {
//Cells/interfaces can't be implicit
// Cells/interfaces can't be implicit
bool isCell = foundp ? foundp->nodep()->castCell() != NULL : false;
bool checkImplicit = (!m_ds.m_dotp && m_ds.m_dotText=="" && !isCell);
bool err = !(checkImplicit && m_statep->implicitOk(m_modp, nodep->name()));

View File

@ -2136,7 +2136,8 @@ private:
AstNodeDType* subDTypep = pinDTypep;
int pinwidth = pinDTypep->width();
int conwidth = conDTypep->width();
if (conDTypep == pinDTypep) { // If match, we're golden
if (conDTypep == pinDTypep // If match, we're golden
|| similarDTypeRecurse(conDTypep, pinDTypep)) {
userIterateAndNext(nodep->exprp(), WidthVP(subDTypep,FINAL).p());
}
else if (m_cellRangep) {
@ -2909,6 +2910,9 @@ private:
return false; // No change
}
bool similarDTypeRecurse(AstNodeDType* node1p, AstNodeDType* node2p) {
return node1p->skipRefp()->similarDType(node2p->skipRefp());
}
void iterateCheckFileDesc (AstNode* nodep, AstNode* underp, Stage stage) {
if (stage != BOTH) nodep->v3fatalSrc("Bad call");
// underp may change as a result of replacement

View File

@ -30,6 +30,26 @@ module t (/*autoarg*/
// Outputs
.out (out));
// wreal bus declaration
wreal vin_upper_bus[1:0];
// wreal nets declaration
wreal vout_split_0;
wreal vout_split_1;
wreal_bus wreal_bus( .vin_bus(vin_upper_bus[1:0]),
.vout_split_0(vout_split_0),
.vout_split_1(vout_split_1));
// implicit declaration of wreal
`ifdef VERILATOR
wreal wreal_implicit_net; // implicit declaration of wreal not supported yet
`endif
// verilator lint_off IMPLICIT
first_level first_level(.in(cyc[0]), .out(wreal_implicit_net));
// verilator lint_on IMPLICIT
parameter real lsb = 1;
// verilator lint_off WIDTH
assign aout = $itor(in) * lsb;
@ -87,3 +107,30 @@ module within_range
wreal in_int = vpass - gnd;
wire out = (V_MIN <= in_int && in_int <= V_MAX);
endmodule
module wreal_bus
(input wreal vin_bus [1:0],
output wreal vout_split_0,
output wreal vout_split_1);
assign vout_split_0 = vin_bus[0];
assign vout_split_1 = vin_bus[1];
endmodule
module first_level
(input in,
`ifdef VERILATOR
output wreal out
`else
output out // Implicity becomes real
`endif
);
second_level second_level(.in(in), .out(out));
endmodule
module second_level
(input in,
output out);
wreal out;
assign out = in ? 1.23456: 7.8910;
endmodule