Unions through pform.

This commit is contained in:
Stephen Williams 2013-11-30 11:52:25 -08:00
parent 0b4056817a
commit 49756a8e7a
5 changed files with 41 additions and 38 deletions

View File

@ -873,28 +873,32 @@ static netclass_t* locate_class_type(Design*, NetScope*scope,
return use_class;
}
static netstruct_t* elaborate_struct_type(Design*des, NetScope*scope,
struct_type_t*struct_type)
netstruct_t* struct_type_t::elaborate_type(Design*des, NetScope*scope) const
{
netstruct_t*res = new netstruct_t;
res->packed(struct_type->packed_flag);
res->packed(packed_flag);
for (list<struct_member_t*>::iterator cur = struct_type->members->begin()
; cur != struct_type->members->end() ; ++ cur) {
if (union_flag)
res->union_flag(true);
for (list<struct_member_t*>::iterator cur = members->begin()
; cur != members->end() ; ++ cur) {
vector<netrange_t>packed_dimensions;
struct_member_t*curp = *cur;
if (curp->range.get() && ! curp->range->empty()) {
vector_type_t*vecp = dynamic_cast<vector_type_t*> (curp->type.get());
if (vecp && vecp->pdims.get() && ! vecp->pdims->empty()) {
bool bad_range;
bad_range = evaluate_ranges(des, scope, packed_dimensions, *curp->range);
bad_range = evaluate_ranges(des, scope, packed_dimensions, *vecp->pdims);
ivl_assert(*curp, !bad_range);
} else {
packed_dimensions.push_back(netrange_t(0,0));
}
netvector_t*mem_vec = new netvector_t(packed_dimensions, curp->type);
netvector_t*mem_vec = new netvector_t(packed_dimensions,
curp->type->figure_packed_base_type());
for (list<decl_assignment_t*>::iterator name = curp->names->begin()
; name != curp->names->end() ; ++ name) {
@ -914,7 +918,7 @@ static ivl_type_s*elaborate_type(Design*des, NetScope*scope,
data_type_t*pform_type)
{
if (struct_type_t*struct_type = dynamic_cast<struct_type_t*>(pform_type)) {
netstruct_t*use_type = elaborate_struct_type(des, scope, struct_type);
netstruct_t*use_type = struct_type->elaborate_type(des, scope);
return use_type;
}
@ -1245,7 +1249,7 @@ NetNet* PWire::elaborate_sig(Design*des, NetScope*scope) const
} else if (struct_type_t*struct_type = dynamic_cast<struct_type_t*>(set_data_type_)) {
// If this is a struct type, then build the net with the
// struct type.
netstruct_t*use_type = elaborate_struct_type(des, scope, struct_type);
netstruct_t*use_type = struct_type->elaborate_type(des, scope);
if (debug_elaborate) {
cerr << get_fileline() << ": debug: Create signal " << wtype;
if (use_type->packed())

36
parse.y
View File

@ -2259,6 +2259,7 @@ struct_data_type
{ struct_type_t*tmp = new struct_type_t;
FILE_NAME(tmp, @1);
tmp->packed_flag = $2;
tmp->union_flag = false;
tmp->members .reset($4);
$$ = tmp;
}
@ -2266,28 +2267,34 @@ struct_data_type
{ struct_type_t*tmp = new struct_type_t;
FILE_NAME(tmp, @1);
tmp->packed_flag = $2;
tmp->union_flag = true;
tmp->members .reset($4);
$$ = tmp;
yyerror(@4, "sorry: union data type not implemented.");
}
| K_struct K_packed_opt '{' error '}'
{ yyerror(@4, "error: Errors in struct member list.");
{ yyerror(@3, "error: Errors in struct member list.");
yyerrok;
struct_type_t*tmp = new struct_type_t;
FILE_NAME(tmp, @1);
tmp->packed_flag = $2;
tmp->union_flag = false;
$$ = tmp;
}
| K_union K_packed_opt '{' error '}'
{ yyerror(@4, "error: Errors in union member list.");
{ yyerror(@3, "error: Errors in union member list.");
yyerrok;
struct_type_t*tmp = new struct_type_t;
FILE_NAME(tmp, @1);
tmp->packed_flag = $2;
tmp->union_flag = true;
$$ = tmp;
}
;
/* This is an implementation of the rule snippet:
struct_union_member { struct_union_member }
that is used in the rule matching struct and union types
in IEEE 1800-2012 A.2.2.1. */
struct_union_member_list
: struct_union_member_list struct_union_member
{ list<struct_member_t*>*tmp = $1;
@ -2301,28 +2308,11 @@ struct_union_member_list
}
;
struct_union_member
: attribute_list_opt K_bit range_opt list_of_variable_decl_assignments ';'
struct_union_member /* IEEE 1800-2012 A.2.2.1 */
: attribute_list_opt data_type list_of_variable_decl_assignments ';'
{ struct_member_t*tmp = new struct_member_t;
FILE_NAME(tmp, @2);
tmp->type = IVL_VT_BOOL;
tmp->range .reset($3);
tmp->names .reset($4);
$$ = tmp;
}
| attribute_list_opt K_logic range_opt list_of_variable_decl_assignments ';'
{ struct_member_t*tmp = new struct_member_t;
FILE_NAME(tmp, @2);
tmp->type = IVL_VT_LOGIC;
tmp->range .reset($3);
tmp->names .reset($4);
$$ = tmp;
}
| attribute_list_opt atom2_type list_of_variable_decl_assignments ';'
{ struct_member_t*tmp = new struct_member_t;
FILE_NAME(tmp, @2);
tmp->type = IVL_VT_BOOL;
tmp->range .reset(make_range_from_width($2));
tmp->type .reset($2);
tmp->names .reset($3);
$$ = tmp;
}

View File

@ -217,7 +217,7 @@ void class_type_t::pform_dump_init(ostream&out, unsigned indent) const
void struct_member_t::pform_dump(ostream&out, unsigned indent) const
{
out << setw(indent) << "" << type;
out << setw(indent) << "" << (type.get()? typeid(*type).name() : "<nil type>");
for (list<decl_assignment_t*>::iterator cur = names->begin()
; cur != names->end() ; ++cur) {
decl_assignment_t*curp = *cur;

View File

@ -33,14 +33,21 @@ ivl_variable_type_t struct_type_t::figure_packed_base_type(void) const
struct_member_t*tmp = *cur;
if (tmp->type == IVL_VT_BOOL) {
ivl_variable_type_t tmp_type = IVL_VT_NO_TYPE;
if (tmp->type.get())
tmp_type = tmp->type->figure_packed_base_type();
if (tmp_type == IVL_VT_BOOL) {
continue;
}
if (tmp->type == IVL_VT_LOGIC) {
if (tmp_type == IVL_VT_LOGIC) {
base_type = IVL_VT_LOGIC;
continue;
}
// Oh no! Member is not a packable type!
return IVL_VT_NO_TYPE;
}
return base_type;

View File

@ -24,6 +24,7 @@
# include "LineInfo.h"
# include "verinum.h"
# include "named.h"
# include "netstruct.h"
# include "property_qual.h"
# include "ivl_target.h"
# include <iostream>
@ -115,8 +116,7 @@ struct enum_type_t : public data_type_t {
};
struct struct_member_t : public LineInfo {
ivl_variable_type_t type;
std::auto_ptr< list<pform_range_t> > range;
std::auto_ptr<data_type_t> type;
std::auto_ptr< list<decl_assignment_t*> > names;
void pform_dump(std::ostream&out, unsigned indent) const;
};
@ -124,8 +124,10 @@ 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;
bool packed_flag;
bool union_flag;
std::auto_ptr< list<struct_member_t*> > members;
};