Permalink
Browse files

Enum names in r-value expressions

When enum names are used as r-values in expressions, use their
values. Treat the enum names similar to (but not exactly as)
localparams so that they fit into the rest of the elaboration
flow naturally.
  • Loading branch information...
1 parent cced1e7 commit a14fa038b41cd56f40e33d7cfed975b55c82241a @steveicarus committed Oct 31, 2010
Showing with 304 additions and 44 deletions.
  1. +5 −0 PScope.h
  2. +7 −1 PWire.cc
  3. +4 −0 PWire.h
  4. +24 −0 design_dump.cc
  5. +8 −0 dup_expr.cc
  6. +27 −0 elab_scope.cc
  7. +5 −0 emit.cc
  8. +14 −0 net_expr.cc
  9. +38 −2 net_scope.cc
  10. +37 −0 netlist.h
  11. +2 −2 netmisc.h
  12. +100 −38 pform.cc
  13. +18 −0 pform_dump.cc
  14. +9 −0 pform_types.h
  15. +6 −1 set_width.cc
View
@@ -99,13 +99,18 @@ class LexicalScope {
list<PProcess*> behaviors;
list<AProcess*> analog_behaviors;
+ // Enumeration sets.
+ list<enum_set_t> enum_sets;
+
LexicalScope* parent_scope() const { return parent_; }
protected:
void dump_parameters_(ostream&out, unsigned indent) const;
void dump_localparams_(ostream&out, unsigned indent) const;
+ void dump_enumerations_(ostream&out, unsigned indent) const;
+
void dump_events_(ostream&out, unsigned indent) const;
void dump_wires_(ostream&out, unsigned indent) const;
View
@@ -30,7 +30,7 @@ PWire::PWire(perm_string n,
signed_(false), isint_(false),
port_msb_(0), port_lsb_(0), port_set_(false),
net_msb_(0), net_lsb_(0), net_set_(false), is_scalar_(false),
- error_cnt_(0), lidx_(0), ridx_(0), discipline_(0)
+ error_cnt_(0), lidx_(0), ridx_(0), enum_set_(0), discipline_(0)
{
if (t == NetNet::INTEGER) {
type_ = NetNet::REG;
@@ -206,6 +206,12 @@ void PWire::set_memory_idx(PExpr*ldx, PExpr*rdx)
}
}
+void PWire::set_enumeration(enum_set_t enum_set)
+{
+ assert(enum_set_ == 0);
+ enum_set_ = enum_set;
+}
+
void PWire::set_discipline(ivl_discipline_t d)
{
assert(discipline_ == 0);
View
@@ -79,6 +79,8 @@ class PWire : public LineInfo {
void set_memory_idx(PExpr*ldx, PExpr*rdx);
+ void set_enumeration(enum_set_t enum_set);
+
void set_discipline(ivl_discipline_t);
ivl_discipline_t get_discipline(void) const;
@@ -113,6 +115,8 @@ class PWire : public LineInfo {
PExpr*lidx_;
PExpr*ridx_;
+ enum_set_t enum_set_;
+
ivl_discipline_t discipline_;
private: // not implemented
View
@@ -1187,6 +1187,23 @@ void NetScope::dump(ostream&o) const
}
}
+ o << " enum sets {" << endl;
+
+ /* Dump the enumerations and enum names in this scope. */
+ for (list<enum_set_t>::const_iterator cur = enum_sets_.begin()
+ ; cur != enum_sets_.end() ; ++ cur) {
+ o << " " << *cur << endl;
+ }
+ o << " }" << endl;
+
+ o << " enum names {" << endl;
+ for (map<perm_string,NetEConstEnum*>::const_iterator cur = enum_names_.begin()
+ ; cur != enum_names_.end() ; ++ cur) {
+ o << " " << cur->first << " = " << cur->second->value()
+ << " from " << cur->second->enumeration() << endl;
+ }
+ o << " }" << endl;
+
/* Dump the events in this scope. */
for (NetEvent*cur = events_ ; cur ; cur = cur->snext_) {
o << " event " << cur->name() << "; nprobe="
@@ -1401,6 +1418,13 @@ void NetEConst::dump(ostream&o) const
o << value_;
}
+void NetEConstEnum::dump(ostream&o) const
+{
+ o << "<" << name_ << "=";
+ NetEConst::dump(o);
+ o << ", wid=" << expr_width() << ">";
+}
+
void NetEConstParam::dump(ostream&o) const
{
o << "<" << name_ << "=";
View
@@ -49,6 +49,14 @@ NetEConst* NetEConst::dup_expr() const
return tmp;
}
+NetEConstEnum* NetEConstEnum::dup_expr() const
+{
+ NetEConstEnum*tmp = new NetEConstEnum(scope_, name_, enum_set_, value());
+ assert(tmp);
+ tmp->set_line(*this);
+ return tmp;
+}
+
NetEConstParam* NetEConstParam::dup_expr() const
{
NetEConstParam*tmp = new NetEConstParam(scope_, name_, value());
View
@@ -206,6 +206,31 @@ static void elaborate_scope_localparams_(Design*des, NetScope*scope,
}
}
+static void elaborate_scope_enumeration(Design*des, NetScope*scope,
+ enum_set_t enum_set)
+{
+ scope->add_enumeration_set(enum_set);
+
+ for (map<perm_string,verinum>::const_iterator cur = enum_set->begin()
+ ; cur != enum_set->end() ; ++ cur) {
+
+ bool rc = scope->add_enumeration_name(enum_set, cur->first);
+ if (! rc) {
+ cerr << "<>:0: error: Duplicate enumeration name " << cur->first << endl;
+ des->errors += 1;
+ }
+ }
+}
+
+static void elaborate_scope_enumerations(Design*des, NetScope*scope,
+ const list<enum_set_t>&enum_sets)
+{
+ for (list<enum_set_t>::const_iterator cur = enum_sets.begin()
+ ; cur != enum_sets.end() ; ++ cur) {
+ elaborate_scope_enumeration(des, scope, *cur);
+ }
+}
+
static void replace_scope_parameters_(NetScope*scope, const LineInfo&loc,
const Module::replace_t&replacements)
{
@@ -434,6 +459,8 @@ bool Module::elaborate_scope(Design*des, NetScope*scope,
elaborate_scope_localparams_(des, scope, localparams);
+ elaborate_scope_enumerations(des, scope, enum_sets);
+
// Run through the defparams for this module, elaborate the
// expressions in this context and save the result is a table
// for later final override.
View
@@ -516,6 +516,11 @@ void NetEConst::expr_scan(struct expr_scan_t*tgt) const
tgt->expr_const(this);
}
+void NetEConstEnum::expr_scan(struct expr_scan_t*tgt) const
+{
+ tgt->expr_const(this);
+}
+
void NetEConstParam::expr_scan(struct expr_scan_t*tgt) const
{
tgt->expr_param(this);
View
@@ -432,6 +432,20 @@ unsigned NetEConcat::repeat() const
return repeat_value_;
}
+NetEConstEnum::NetEConstEnum(NetScope*s, perm_string n, enum_set_t eset, const verinum&v)
+: NetEConst(v), scope_(s), enum_set_(eset)
+{
+}
+
+NetEConstEnum::~NetEConstEnum()
+{
+}
+
+const enum_set_t NetEConstEnum::enumeration() const
+{
+ return enum_set_;
+}
+
NetECReal::NetECReal(const verireal&val)
: value_(val)
{
View
@@ -208,24 +208,41 @@ const NetExpr* NetScope::get_parameter(const char* key,
const NetExpr*&msb,
const NetExpr*&lsb) const
{
+ return get_parameter(perm_string::literal(key), msb, lsb);
+}
+
+const NetExpr* NetScope::get_parameter(perm_string key,
+ const NetExpr*&msb,
+ const NetExpr*&lsb) const
+{
map<perm_string,param_expr_t>::const_iterator idx;
- idx = parameters.find(perm_string::literal(key));
+ idx = parameters.find(key);
if (idx != parameters.end()) {
msb = (*idx).second.msb;
lsb = (*idx).second.lsb;
return (*idx).second.expr;
}
- idx = localparams.find(perm_string::literal(key));
+ idx = localparams.find(key);
if (idx != localparams.end()) {
msb = (*idx).second.msb;
lsb = (*idx).second.lsb;
return (*idx).second.expr;
}
+ map<perm_string,NetEConstEnum*>::const_iterator eidx;
+
+ eidx = enum_names_.find(key);
+ if (eidx != enum_names_.end()) {
+ msb = 0;
+ lsb = 0;
+ return eidx->second;
+ }
+
return 0;
}
+
map<perm_string,NetScope::param_expr_t>::iterator NetScope::find_parameter(perm_string key)
{
map<perm_string,param_expr_t>::iterator idx;
@@ -436,6 +453,25 @@ NetNet* NetScope::find_signal(perm_string key)
return 0;
}
+void NetScope::add_enumeration_set(enum_set_t enum_set)
+{
+ enum_sets_.push_back(enum_set);
+}
+
+bool NetScope::add_enumeration_name(enum_set_t enum_set, perm_string name)
+{
+ enum_set_m::const_iterator enum_val = enum_set->find(name);
+ assert(enum_val != enum_set->end());
+
+ NetEConstEnum*val = new NetEConstEnum(this, name, enum_set, enum_val->second);
+
+ pair<map<perm_string,NetEConstEnum*>::iterator, bool> cur;
+ cur = enum_names_.insert(make_pair(name,val));
+
+ // Return TRUE if the name is added (i.e. is NOT a duplicate.)
+ return cur.second;
+}
+
/*
* This method locates a child scope by name. The name is the simple
* name of the child, no hierarchy is searched.
View
@@ -64,6 +64,7 @@ class NetScope;
class NetEvProbe;
class NetExpr;
class NetEAccess;
+class NetEConstEnum;
class NetESignal;
class NetFuncDef;
class NetRamDq;
@@ -718,6 +719,9 @@ class NetScope : public Attrib {
const NetExpr*get_parameter(const char* name,
const NetExpr*&msb,
const NetExpr*&lsb) const;
+ const NetExpr*get_parameter(perm_string name,
+ const NetExpr*&msb,
+ const NetExpr*&lsb) const;
/* These are used by defparam elaboration to replace the
expression with a new expression, without affecting the
@@ -745,6 +749,9 @@ class NetScope : public Attrib {
void rem_signal(NetNet*);
NetNet* find_signal(perm_string name);
+ void add_enumeration_set(enum_set_t enum_set);
+ bool add_enumeration_name(enum_set_t enum_set, perm_string);
+
/* The parent and child() methods allow users of NetScope
objects to locate nearby scopes. */
NetScope* parent() { return up_; }
@@ -920,6 +927,13 @@ class NetScope : public Attrib {
NetFuncDef*func_;
};
+ // Enumerations. The enum_sets_ is a list of all the
+ // enumerations present in this scope. The enum_names_ is a
+ // map of all the enumeration names back to the sets that
+ // contain them.
+ std::list<enum_set_t> enum_sets_;
+ std::map<perm_string,NetEConstEnum*> enum_names_;
+
NetScope*up_;
map<hname_t,NetScope*> children_;
@@ -1707,6 +1721,29 @@ class NetEConst : public NetExpr {
verinum value_;
};
+class NetEConstEnum : public NetEConst {
+
+ public:
+ explicit NetEConstEnum(NetScope*scope, perm_string name,
+ enum_set_t enum_set, const verinum&val);
+ ~NetEConstEnum();
+
+ perm_string name() const;
+ const NetScope*scope() const;
+ const enum_set_t enumeration() const;
+
+ virtual bool set_width(unsigned w, bool last_chance =false);
+ virtual void expr_scan(struct expr_scan_t*) const;
+ virtual void dump(ostream&) const;
+
+ virtual NetEConstEnum* dup_expr() const;
+
+ private:
+ NetScope*scope_;
+ enum_set_t enum_set_;
+ perm_string name_;
+};
+
class NetEConstParam : public NetEConst {
public:
View
@@ -41,7 +41,7 @@ extern NetScope* symbol_search(const LineInfo*li,
NetScope*start,
pform_name_t path,
NetNet*&net, /* net/reg */
- const NetExpr*&par,/* parameter */
+ const NetExpr*&par,/* parameter/expr */
NetEvent*&eve, /* named event */
const NetExpr*&ex1, const NetExpr*&ex2);
@@ -50,7 +50,7 @@ inline NetScope* symbol_search(const LineInfo*li,
NetScope*start,
const pform_name_t&path,
NetNet*&net, /* net/reg */
- const NetExpr*&par,/* parameter */
+ const NetExpr*&par,/* parameter/expr */
NetEvent*&eve /* named event */)
{
const NetExpr*ex1, *ex2;
Oops, something went wrong.

0 comments on commit a14fa03

Please sign in to comment.