Handle enumerations as packed struct/union members.
There were also some subtleties related to using enumerations from typedefs and using them in multiple places. Fix various bugs related to those issues.
This commit is contained in:
parent
7669a42cfb
commit
819770a6c4
3
PScope.h
3
PScope.h
|
|
@ -24,6 +24,7 @@
|
|||
# include "pform_types.h"
|
||||
# include "ivl_target.h"
|
||||
# include <map>
|
||||
# include <set>
|
||||
# include <vector>
|
||||
|
||||
class PEvent;
|
||||
|
|
@ -112,7 +113,7 @@ class LexicalScope {
|
|||
list<AProcess*> analog_behaviors;
|
||||
|
||||
// Enumeration sets.
|
||||
list<enum_type_t*> enum_sets;
|
||||
std::set<enum_type_t*> enum_sets;
|
||||
|
||||
LexicalScope* parent_scope() const { return parent_; }
|
||||
|
||||
|
|
|
|||
|
|
@ -178,6 +178,9 @@ static void elaborate_scope_enumeration(Design*des, NetScope*scope,
|
|||
use_enum->set_line(enum_type->li);
|
||||
scope->add_enumeration_set(use_enum);
|
||||
|
||||
ivl_assert(*enum_type, enum_type->net_type == 0);
|
||||
enum_type->net_type = use_enum;
|
||||
|
||||
verinum cur_value (0);
|
||||
verinum one_value (1);
|
||||
size_t name_idx = 0;
|
||||
|
|
@ -285,11 +288,12 @@ static void elaborate_scope_enumeration(Design*des, NetScope*scope,
|
|||
}
|
||||
|
||||
static void elaborate_scope_enumerations(Design*des, NetScope*scope,
|
||||
const list<enum_type_t*>&enum_types)
|
||||
const set<enum_type_t*>&enum_types)
|
||||
{
|
||||
for (list<enum_type_t*>::const_iterator cur = enum_types.begin()
|
||||
for (set<enum_type_t*>::const_iterator cur = enum_types.begin()
|
||||
; cur != enum_types.end() ; ++ cur) {
|
||||
elaborate_scope_enumeration(des, scope, *cur);
|
||||
enum_type_t*curp = *cur;
|
||||
elaborate_scope_enumeration(des, scope, curp);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@
|
|||
# include "netlist.h"
|
||||
# include "netclass.h"
|
||||
# include "netdarray.h"
|
||||
# include "netenum.h"
|
||||
# include "netscalar.h"
|
||||
# include "netstruct.h"
|
||||
# include "netvector.h"
|
||||
|
|
@ -79,6 +80,12 @@ ivl_type_s* class_type_t::elaborate_type(Design*, NetScope*scope) const
|
|||
return scope->find_class(name);
|
||||
}
|
||||
|
||||
ivl_type_s* enum_type_t::elaborate_type(Design*des, NetScope*scope) const
|
||||
{
|
||||
ivl_assert(*this, net_type);
|
||||
return net_type;
|
||||
}
|
||||
|
||||
ivl_type_s* vector_type_t::elaborate_type(Design*des, NetScope*scope) const
|
||||
{
|
||||
vector<netrange_t> packed;
|
||||
|
|
@ -146,6 +153,8 @@ netstruct_t* struct_type_t::elaborate_type(Design*des, NetScope*scope) const
|
|||
// Elaborate the type of the member.
|
||||
struct_member_t*curp = *cur;
|
||||
ivl_type_t mem_vec = curp->type->elaborate_type(des, scope);
|
||||
if (mem_vec == 0)
|
||||
continue;
|
||||
|
||||
// There may be several names that are the same type:
|
||||
// <data_type> name1, name2, ...;
|
||||
|
|
|
|||
|
|
@ -39,6 +39,14 @@ bool netenum_t::get_signed() const
|
|||
return signed_flag_;
|
||||
}
|
||||
|
||||
/*
|
||||
* Enumerations are by definition always packed.
|
||||
*/
|
||||
bool netenum_t::packed() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
long netenum_t::packed_width() const
|
||||
{
|
||||
if (msb_ >= lsb_)
|
||||
|
|
|
|||
|
|
@ -36,8 +36,9 @@ class netenum_t : public LineInfo, public ivl_type_s {
|
|||
long msb, long lsb, size_t name_count);
|
||||
~netenum_t();
|
||||
|
||||
ivl_variable_type_t base_type() const;
|
||||
long packed_width() const;
|
||||
virtual ivl_variable_type_t base_type() const;
|
||||
virtual bool packed() const;
|
||||
virtual long packed_width() const;
|
||||
std::vector<netrange_t> slice_dimensions() const;
|
||||
bool get_signed() const;
|
||||
|
||||
|
|
|
|||
|
|
@ -52,6 +52,8 @@ void netstruct_t::packed(bool flag)
|
|||
|
||||
void netstruct_t::append_member(Design*des, const netstruct_t::member_t&val)
|
||||
{
|
||||
ivl_assert(*this, val.net_type);
|
||||
|
||||
members_.push_back(val);
|
||||
if (packed_) {
|
||||
if (! members_.back().net_type->packed()) {
|
||||
|
|
|
|||
6
pform.cc
6
pform.cc
|
|
@ -484,7 +484,7 @@ 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)
|
||||
{
|
||||
lexical_scope->enum_sets.push_back(enum_set);
|
||||
lexical_scope->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)
|
||||
|
|
@ -508,6 +508,10 @@ void pform_set_typedef(perm_string name, data_type_t*data_type)
|
|||
data_type_t*&ref = lexical_scope->typedefs[name];
|
||||
ivl_assert(*data_type, ref == 0);
|
||||
ref = data_type;
|
||||
|
||||
if (enum_type_t*enum_type = dynamic_cast<enum_type_t*>(data_type)) {
|
||||
pform_put_enum_type_in_scope(enum_type);
|
||||
}
|
||||
}
|
||||
|
||||
data_type_t* pform_test_type_identifier(const char*txt)
|
||||
|
|
|
|||
|
|
@ -1328,7 +1328,7 @@ void LexicalScope::dump_localparams_(ostream&out, unsigned indent) const
|
|||
|
||||
void LexicalScope::dump_enumerations_(ostream&out, unsigned indent) const
|
||||
{
|
||||
for (list<enum_type_t*>::const_iterator cur = enum_sets.begin()
|
||||
for (set<enum_type_t*>::const_iterator cur = enum_sets.begin()
|
||||
; cur != enum_sets.end() ; ++ cur) {
|
||||
out << setw(indent) << "" << "enum {" << endl;
|
||||
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@ class PExpr;
|
|||
class PWire;
|
||||
class Statement;
|
||||
class ivl_type_s;
|
||||
class netenum_t;
|
||||
typedef named<verinum> named_number_t;
|
||||
typedef named<PExpr*> named_pexpr_t;
|
||||
typedef std::pair<PExpr*,PExpr*> pform_range_t;
|
||||
|
|
@ -104,15 +105,24 @@ struct void_type_t : public data_type_t {
|
|||
/*
|
||||
* The enum_type_t holds the parsed declaration to represent an
|
||||
* enumeration. Since this is in the pform, it represents the type
|
||||
* before elaboration to the range, for example, man not be complete
|
||||
* before elaboration so the range, for example, may not be complete
|
||||
* until it is elaborated in a scope.
|
||||
*/
|
||||
struct enum_type_t : public data_type_t {
|
||||
inline enum_type_t(void) : net_type(0) { }
|
||||
// Return the elaborated version of the type.
|
||||
virtual ivl_type_s*elaborate_type(Design*des, NetScope*scope) const;
|
||||
|
||||
ivl_variable_type_t base_type;
|
||||
bool signed_flag;
|
||||
std::auto_ptr< list<pform_range_t> > range;
|
||||
std::auto_ptr< list<named_pexpr_t> > names;
|
||||
LineInfo li;
|
||||
// This is the elaborated type. The enumeration type is
|
||||
// elaborated early so that names can be placed in the scope,
|
||||
// but that means the result needs to be saved for the actual
|
||||
// elaborate_type method to use.
|
||||
netenum_t*net_type;
|
||||
};
|
||||
|
||||
struct struct_member_t : public LineInfo {
|
||||
|
|
@ -124,7 +134,7 @@ struct struct_member_t : public LineInfo {
|
|||
struct struct_type_t : public data_type_t {
|
||||
virtual ivl_variable_type_t figure_packed_base_type(void)const;
|
||||
virtual void pform_dump(std::ostream&out, unsigned indent) const;
|
||||
netstruct_t* elaborate_type(Design*des, NetScope*scope) const;
|
||||
virtual netstruct_t* elaborate_type(Design*des, NetScope*scope) const;
|
||||
|
||||
bool packed_flag;
|
||||
bool union_flag;
|
||||
|
|
|
|||
Loading…
Reference in New Issue