Handle enumeration literals that are in $root.
This commit is contained in:
parent
b0491b9c54
commit
a3b29dd70b
|
|
@ -48,6 +48,7 @@
|
||||||
# include "netlist.h"
|
# include "netlist.h"
|
||||||
# include "netclass.h"
|
# include "netclass.h"
|
||||||
# include "netenum.h"
|
# include "netenum.h"
|
||||||
|
# include "parse_api.h"
|
||||||
# include "util.h"
|
# include "util.h"
|
||||||
# include <typeinfo>
|
# include <typeinfo>
|
||||||
# include <cassert>
|
# include <cassert>
|
||||||
|
|
@ -156,6 +157,10 @@ static void collect_scope_specparams_(Design*des, NetScope*scope,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Elaborate the enumeration into the given scope. If scope==0, then
|
||||||
|
* the enumeration goes into $root instead of a scope.
|
||||||
|
*/
|
||||||
static void elaborate_scope_enumeration(Design*des, NetScope*scope,
|
static void elaborate_scope_enumeration(Design*des, NetScope*scope,
|
||||||
enum_type_t*enum_type)
|
enum_type_t*enum_type)
|
||||||
{
|
{
|
||||||
|
|
@ -176,7 +181,10 @@ static void elaborate_scope_enumeration(Design*des, NetScope*scope,
|
||||||
msb, lsb, enum_type->names->size());
|
msb, lsb, enum_type->names->size());
|
||||||
|
|
||||||
use_enum->set_line(enum_type->li);
|
use_enum->set_line(enum_type->li);
|
||||||
|
if (scope)
|
||||||
scope->add_enumeration_set(use_enum);
|
scope->add_enumeration_set(use_enum);
|
||||||
|
else
|
||||||
|
des->add_enumeration_set(use_enum);
|
||||||
|
|
||||||
ivl_assert(*enum_type, enum_type->net_type == 0);
|
ivl_assert(*enum_type, enum_type->net_type == 0);
|
||||||
enum_type->net_type = use_enum;
|
enum_type->net_type = use_enum;
|
||||||
|
|
@ -270,7 +278,11 @@ static void elaborate_scope_enumeration(Design*des, NetScope*scope,
|
||||||
tmp_val.has_sign(enum_type->signed_flag);
|
tmp_val.has_sign(enum_type->signed_flag);
|
||||||
|
|
||||||
rc_flag = use_enum->insert_name(name_idx, cur->name, tmp_val);
|
rc_flag = use_enum->insert_name(name_idx, cur->name, tmp_val);
|
||||||
|
if (scope)
|
||||||
rc_flag &= scope->add_enumeration_name(use_enum, cur->name);
|
rc_flag &= scope->add_enumeration_name(use_enum, cur->name);
|
||||||
|
else
|
||||||
|
rc_flag &= des->add_enumeration_name(use_enum, cur->name);
|
||||||
|
|
||||||
if (! rc_flag) {
|
if (! rc_flag) {
|
||||||
cerr << use_enum->get_fileline()
|
cerr << use_enum->get_fileline()
|
||||||
<< ": error: Duplicate enumeration name "
|
<< ": error: Duplicate enumeration name "
|
||||||
|
|
@ -297,6 +309,15 @@ static void elaborate_scope_enumerations(Design*des, NetScope*scope,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void elaborate_rootscope_enumerations(Design*des)
|
||||||
|
{
|
||||||
|
for (set<enum_type_t*>::const_iterator cur = pform_enum_sets.begin()
|
||||||
|
; cur != pform_enum_sets.end() ; ++ cur) {
|
||||||
|
enum_type_t*curp = *cur;
|
||||||
|
elaborate_scope_enumeration(des, 0, curp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If the pclass includes an implicit and explicit constructor, then
|
* If the pclass includes an implicit and explicit constructor, then
|
||||||
* merge the implicit constructor into the explicit constructor as
|
* merge the implicit constructor into the explicit constructor as
|
||||||
|
|
|
||||||
|
|
@ -965,7 +965,10 @@ NetNet* PWire::elaborate_sig(Design*des, NetScope*scope) const
|
||||||
<< "'." << endl;
|
<< "'." << endl;
|
||||||
des->errors += 1;
|
des->errors += 1;
|
||||||
}
|
}
|
||||||
// A signal can not have the same name as a parameter.
|
// A signal can not have the same name as a parameter. Note
|
||||||
|
// that we treat enumeration literals similar to parameters,
|
||||||
|
// so if the name matches an enumeration literal, it will be
|
||||||
|
// caught here.
|
||||||
const NetExpr *ex_msb, *ex_lsb;
|
const NetExpr *ex_msb, *ex_lsb;
|
||||||
const NetExpr *parm = scope->get_parameter(des, name_, ex_msb, ex_lsb);
|
const NetExpr *parm = scope->get_parameter(des, name_, ex_msb, ex_lsb);
|
||||||
if (parm) {
|
if (parm) {
|
||||||
|
|
|
||||||
|
|
@ -5663,6 +5663,9 @@ Design* elaborate(list<perm_string>roots)
|
||||||
// module and elaborate what I find.
|
// module and elaborate what I find.
|
||||||
Design*des = new Design;
|
Design*des = new Design;
|
||||||
|
|
||||||
|
// Elaborate enum sets in $root scope.
|
||||||
|
elaborate_rootscope_enumerations(des);
|
||||||
|
|
||||||
// Elaborate the packages. Package elaboration is simpler
|
// Elaborate the packages. Package elaboration is simpler
|
||||||
// because there are fewer sub-scopes involved.
|
// because there are fewer sub-scopes involved.
|
||||||
i = 0;
|
i = 0;
|
||||||
|
|
|
||||||
|
|
@ -260,7 +260,7 @@ void NetEConcat::set(unsigned idx, NetExpr*e)
|
||||||
expr_width( expr_width() + repeat_ * e->expr_width() );
|
expr_width( expr_width() + repeat_ * e->expr_width() );
|
||||||
}
|
}
|
||||||
|
|
||||||
NetEConstEnum::NetEConstEnum(NetScope*s, perm_string n, const netenum_t*eset, const verinum&v)
|
NetEConstEnum::NetEConstEnum(Definitions*s, perm_string n, const netenum_t*eset, const verinum&v)
|
||||||
: NetEConst(v), scope_(s), enum_set_(eset), name_(n)
|
: NetEConst(v), scope_(s), enum_set_(eset), name_(n)
|
||||||
{
|
{
|
||||||
assert(has_width());
|
assert(has_width());
|
||||||
|
|
|
||||||
91
net_scope.cc
91
net_scope.cc
|
|
@ -30,6 +30,59 @@
|
||||||
|
|
||||||
class PExpr;
|
class PExpr;
|
||||||
|
|
||||||
|
Definitions::Definitions()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Definitions::~Definitions()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void Definitions::add_enumeration_set(netenum_t*enum_set)
|
||||||
|
{
|
||||||
|
enum_sets_.push_back(enum_set);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Definitions::add_enumeration_name(netenum_t*enum_set, perm_string name)
|
||||||
|
{
|
||||||
|
netenum_t::iterator enum_val = enum_set->find_name(name);
|
||||||
|
assert(enum_val != enum_set->end_name());
|
||||||
|
|
||||||
|
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 locates the enumeration TYPE for the given enumeration literal.
|
||||||
|
*/
|
||||||
|
const netenum_t*Definitions::enumeration_for_name(perm_string name)
|
||||||
|
{
|
||||||
|
NetEConstEnum*tmp = enum_names_[name];
|
||||||
|
assert(tmp != 0);
|
||||||
|
|
||||||
|
return tmp->enumeration();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This locates the VALUE for the given enumeration literal.
|
||||||
|
*/
|
||||||
|
const NetExpr* Definitions::enumeration_expr(perm_string key)
|
||||||
|
{
|
||||||
|
map<perm_string,NetEConstEnum*>::const_iterator eidx;
|
||||||
|
|
||||||
|
eidx = enum_names_.find(key);
|
||||||
|
if (eidx != enum_names_.end()) {
|
||||||
|
return eidx->second;
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The NetScope class keeps a scope tree organized. Each node of the
|
* The NetScope class keeps a scope tree organized. Each node of the
|
||||||
* scope tree points to its parent, its right sibling and its leftmost
|
* scope tree points to its parent, its right sibling and its leftmost
|
||||||
|
|
@ -265,14 +318,13 @@ const NetExpr* NetScope::get_parameter(Design*des,
|
||||||
return idx->second.val;
|
return idx->second.val;
|
||||||
}
|
}
|
||||||
|
|
||||||
map<perm_string,NetEConstEnum*>::const_iterator eidx;
|
|
||||||
|
|
||||||
eidx = enum_names_.find(key);
|
|
||||||
if (eidx != enum_names_.end()) {
|
|
||||||
msb = 0;
|
msb = 0;
|
||||||
lsb = 0;
|
lsb = 0;
|
||||||
return eidx->second;
|
const NetExpr*tmp = enumeration_expr(key);
|
||||||
}
|
if (tmp) return tmp;
|
||||||
|
|
||||||
|
tmp = des->enumeration_expr(key);
|
||||||
|
if (tmp) return tmp;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
@ -551,33 +603,6 @@ NetNet* NetScope::find_signal(perm_string key)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void NetScope::add_enumeration_set(netenum_t*enum_set)
|
|
||||||
{
|
|
||||||
enum_sets_.push_back(enum_set);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool NetScope::add_enumeration_name(netenum_t*enum_set, perm_string name)
|
|
||||||
{
|
|
||||||
netenum_t::iterator enum_val = enum_set->find_name(name);
|
|
||||||
assert(enum_val != enum_set->end_name());
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
const netenum_t*NetScope::enumeration_for_name(perm_string name)
|
|
||||||
{
|
|
||||||
NetEConstEnum*tmp = enum_names_[name];
|
|
||||||
assert(tmp != 0);
|
|
||||||
|
|
||||||
return tmp->enumeration();
|
|
||||||
}
|
|
||||||
|
|
||||||
void NetScope::add_class(netclass_t*net_class)
|
void NetScope::add_class(netclass_t*net_class)
|
||||||
{
|
{
|
||||||
classes_[net_class->get_name()] = net_class;
|
classes_[net_class->get_name()] = net_class;
|
||||||
|
|
|
||||||
53
netlist.h
53
netlist.h
|
|
@ -819,12 +819,44 @@ class NetBaseDef {
|
||||||
NetProc*proc_;
|
NetProc*proc_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Some definitions (and methods to manipulate them) are common to a
|
||||||
|
* couple of types. Keep them here.
|
||||||
|
*/
|
||||||
|
class Definitions {
|
||||||
|
|
||||||
|
public:
|
||||||
|
Definitions();
|
||||||
|
~Definitions();
|
||||||
|
|
||||||
|
void add_enumeration_set(netenum_t*enum_set);
|
||||||
|
bool add_enumeration_name(netenum_t*enum_set, perm_string enum_name);
|
||||||
|
|
||||||
|
// Look up the enumeration literal in this scope. if the name
|
||||||
|
// is present, then return the enumeration type that declares it.
|
||||||
|
const netenum_t* enumeration_for_name(perm_string name);
|
||||||
|
|
||||||
|
// Look up an enumeration literal in this scope. If the
|
||||||
|
// literal is present, return the expression that defines its
|
||||||
|
// value.
|
||||||
|
const NetExpr* enumeration_expr(perm_string key);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
// 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<netenum_t*> enum_sets_;
|
||||||
|
std::map<perm_string,NetEConstEnum*> enum_names_;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This object type is used to contain a logical scope within a
|
* This object type is used to contain a logical scope within a
|
||||||
* design. The scope doesn't represent any executable hardware, but is
|
* design. The scope doesn't represent any executable hardware, but is
|
||||||
* just a handle that netlist processors can use to grab at the design.
|
* just a handle that netlist processors can use to grab at the design.
|
||||||
*/
|
*/
|
||||||
class NetScope : public Attrib {
|
class NetScope : public Definitions, public Attrib {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
enum TYPE { MODULE, CLASS, TASK, FUNC, BEGIN_END, FORK_JOIN, GENBLOCK, PACKAGE };
|
enum TYPE { MODULE, CLASS, TASK, FUNC, BEGIN_END, FORK_JOIN, GENBLOCK, PACKAGE };
|
||||||
|
|
@ -897,11 +929,6 @@ class NetScope : public Attrib {
|
||||||
void rem_signal(NetNet*);
|
void rem_signal(NetNet*);
|
||||||
NetNet* find_signal(perm_string name);
|
NetNet* find_signal(perm_string name);
|
||||||
|
|
||||||
void add_enumeration_set(netenum_t*enum_set);
|
|
||||||
bool add_enumeration_name(netenum_t*enum_set, perm_string enum_name);
|
|
||||||
|
|
||||||
const netenum_t* enumeration_for_name(perm_string name);
|
|
||||||
|
|
||||||
void add_class(netclass_t*class_type);
|
void add_class(netclass_t*class_type);
|
||||||
netclass_t* find_class(perm_string name);
|
netclass_t* find_class(perm_string name);
|
||||||
|
|
||||||
|
|
@ -1153,13 +1180,6 @@ class NetScope : public Attrib {
|
||||||
const PFunction*func_pform_;
|
const PFunction*func_pform_;
|
||||||
unsigned elab_stage_;
|
unsigned elab_stage_;
|
||||||
|
|
||||||
// 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<netenum_t*> enum_sets_;
|
|
||||||
std::map<perm_string,NetEConstEnum*> enum_names_;
|
|
||||||
|
|
||||||
std::map<perm_string,netclass_t*> classes_;
|
std::map<perm_string,netclass_t*> classes_;
|
||||||
|
|
||||||
NetScope*up_;
|
NetScope*up_;
|
||||||
|
|
@ -1973,12 +1993,11 @@ class NetEConst : public NetExpr {
|
||||||
class NetEConstEnum : public NetEConst {
|
class NetEConstEnum : public NetEConst {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit NetEConstEnum(NetScope*scope, perm_string name,
|
explicit NetEConstEnum(Definitions*scope, perm_string name,
|
||||||
const netenum_t*enum_set, const verinum&val);
|
const netenum_t*enum_set, const verinum&val);
|
||||||
~NetEConstEnum();
|
~NetEConstEnum();
|
||||||
|
|
||||||
perm_string name() const;
|
perm_string name() const;
|
||||||
const NetScope*scope() const;
|
|
||||||
const netenum_t*enumeration() const;
|
const netenum_t*enumeration() const;
|
||||||
|
|
||||||
virtual void expr_scan(struct expr_scan_t*) const;
|
virtual void expr_scan(struct expr_scan_t*) const;
|
||||||
|
|
@ -1987,7 +2006,7 @@ class NetEConstEnum : public NetEConst {
|
||||||
virtual NetEConstEnum* dup_expr() const;
|
virtual NetEConstEnum* dup_expr() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
NetScope*scope_;
|
Definitions*scope_;
|
||||||
const netenum_t*enum_set_;
|
const netenum_t*enum_set_;
|
||||||
perm_string name_;
|
perm_string name_;
|
||||||
};
|
};
|
||||||
|
|
@ -4499,7 +4518,7 @@ struct elaborator_work_item_t {
|
||||||
* This class contains an entire design. It includes processes and a
|
* This class contains an entire design. It includes processes and a
|
||||||
* netlist, and can be passed around from function to function.
|
* netlist, and can be passed around from function to function.
|
||||||
*/
|
*/
|
||||||
class Design {
|
class Design : public Definitions {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Design();
|
Design();
|
||||||
|
|
|
||||||
|
|
@ -24,11 +24,14 @@
|
||||||
# include <string>
|
# include <string>
|
||||||
# include <ostream>
|
# include <ostream>
|
||||||
# include <map>
|
# include <map>
|
||||||
|
# include <set>
|
||||||
|
|
||||||
|
class Design;
|
||||||
class Module;
|
class Module;
|
||||||
class PPackage;
|
class PPackage;
|
||||||
class PUdp;
|
class PUdp;
|
||||||
class data_type_t;
|
class data_type_t;
|
||||||
|
class enum_type_t;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* These are maps of the modules and primitives parsed from the
|
* These are maps of the modules and primitives parsed from the
|
||||||
|
|
@ -38,10 +41,13 @@ class data_type_t;
|
||||||
extern std::map<perm_string,Module*> pform_modules;
|
extern std::map<perm_string,Module*> pform_modules;
|
||||||
extern std::map<perm_string,PUdp*> pform_primitives;
|
extern std::map<perm_string,PUdp*> pform_primitives;
|
||||||
extern std::map<perm_string,data_type_t*> pform_typedefs;
|
extern std::map<perm_string,data_type_t*> pform_typedefs;
|
||||||
|
extern std::set<enum_type_t*> pform_enum_sets;
|
||||||
|
|
||||||
extern std::map<perm_string,PPackage*> pform_packages;
|
extern std::map<perm_string,PPackage*> pform_packages;
|
||||||
extern void pform_dump(std::ostream&out, const PPackage*pac);
|
extern void pform_dump(std::ostream&out, const PPackage*pac);
|
||||||
|
|
||||||
|
extern void elaborate_rootscope_enumerations(Design*des);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This code actually invokes the parser to make modules. The first
|
* This code actually invokes the parser to make modules. The first
|
||||||
* parameter is the name of the file that is to be parsed. The
|
* parameter is the name of the file that is to be parsed. The
|
||||||
|
|
|
||||||
6
pform.cc
6
pform.cc
|
|
@ -55,6 +55,7 @@ map<perm_string,PUdp*> pform_primitives;
|
||||||
* typedefs in the $root scope go here.
|
* typedefs in the $root scope go here.
|
||||||
*/
|
*/
|
||||||
map<perm_string,data_type_t*>pform_typedefs;
|
map<perm_string,data_type_t*>pform_typedefs;
|
||||||
|
set<enum_type_t*>pform_enum_sets;
|
||||||
|
|
||||||
std::string vlltype::get_fileline() const
|
std::string vlltype::get_fileline() const
|
||||||
{
|
{
|
||||||
|
|
@ -487,7 +488,12 @@ static void pform_put_wire_in_scope(perm_string name, PWire*net)
|
||||||
|
|
||||||
static void pform_put_enum_type_in_scope(enum_type_t*enum_set)
|
static void pform_put_enum_type_in_scope(enum_type_t*enum_set)
|
||||||
{
|
{
|
||||||
|
if (lexical_scope) {
|
||||||
|
ivl_assert(*enum_set, lexical_scope);
|
||||||
lexical_scope->enum_sets.insert(enum_set);
|
lexical_scope->enum_sets.insert(enum_set);
|
||||||
|
} else {
|
||||||
|
pform_enum_sets.insert(enum_set);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
PWire*pform_get_make_wire_in_scope(perm_string name, NetNet::Type net_type, NetNet::PortType port_type, ivl_variable_type_t vt_type)
|
PWire*pform_get_make_wire_in_scope(perm_string name, NetNet::Type net_type, NetNet::PortType port_type, ivl_variable_type_t vt_type)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue