Use data_type_t instead of raw type bits.

This commit is contained in:
Stephen Williams 2012-09-03 09:13:52 -07:00
parent 85e000ed0c
commit f24d6b055d
5 changed files with 158 additions and 142 deletions

88
parse.y
View File

@ -1842,11 +1842,11 @@ block_item_decl
recovering from an error. */
| data_type register_variable_list ';'
{ if ($1) pform_set_data_type(@1, $1, $2, attributes_in_context);
{ if ($1) pform_set_data_type(@1, $1, $2, NetNet::REG, attributes_in_context);
}
| K_reg data_type register_variable_list ';'
{ if ($2) pform_set_data_type(@2, $2, $3, attributes_in_context);
{ if ($2) pform_set_data_type(@2, $2, $3, NetNet::REG, attributes_in_context);
}
| K_event list_of_identifiers ';'
@ -3902,10 +3902,8 @@ module_item
delay3_opt
net_variable_list ';'
{ ivl_variable_type_t dtype = $3;
if (dtype == IVL_VT_NO_TYPE)
dtype = IVL_VT_LOGIC;
pform_makewire(@2, $5, $4, $7, $2, NetNet::NOT_A_PORT, dtype, $1);
{ vector_type_t*tmp = new vector_type_t($3, $4, $5);
pform_set_data_type(@2, tmp, $7, $2, $1);
if ($6 != 0) {
yyerror(@6, "sorry: net delays not supported.");
delete $6;
@ -3914,19 +3912,19 @@ module_item
}
| attribute_list_opt K_wreal delay3 net_variable_list ';'
{ pform_makewire(@2, 0, true, $4, NetNet::WIRE,
NetNet::NOT_A_PORT, IVL_VT_REAL, $1);
if ($3 != 0) {
yyerror(@3, "sorry: net delays not supported.");
delete $3;
}
delete $1;
{ real_type_t*tmpt = new real_type_t(real_type_t::REAL);
pform_set_data_type(@2, tmpt, $4, NetNet::WIRE, $1);
if ($3 != 0) {
yyerror(@3, "sorry: net delays not supported.");
delete $3;
}
delete $1;
}
| attribute_list_opt K_wreal net_variable_list ';'
{ pform_makewire(@2, 0, true, $3, NetNet::WIRE,
NetNet::NOT_A_PORT, IVL_VT_REAL, $1);
delete $1;
{ real_type_t*tmpt = new real_type_t(real_type_t::REAL);
pform_set_data_type(@2, tmpt, $3, NetNet::WIRE, $1);
delete $1;
}
/* Very similar to the rule above, but this takes a list of
@ -3940,8 +3938,8 @@ module_item
{ ivl_variable_type_t dtype = $3;
if (dtype == IVL_VT_NO_TYPE)
dtype = IVL_VT_LOGIC;
pform_makewire(@2, $5, $4, $6,
str_strength, $7, $2, dtype);
vector_type_t*data_type = new vector_type_t(dtype, $4, $5);
pform_makewire(@2, $6, str_strength, $7, $2, data_type);
if ($1) {
yyerror(@2, "sorry: Attributes not supported "
"on net declaration assignments.");
@ -3953,7 +3951,7 @@ module_item
| attribute_list_opt net_type struct_data_type net_variable_list ';'
{ pform_makewire(@2, $3, NetNet::NOT_A_PORT, $4, $1);
{ pform_set_data_type(@2, $3, $4, $2, $1);
delete $1;
}
@ -3968,29 +3966,31 @@ module_item
/* This form doesn't have the range, but does have strengths. This
gives strength to the assignment drivers. */
| attribute_list_opt net_type
primitive_type_opt unsigned_signed_opt
drive_strength net_decl_assigns ';'
| attribute_list_opt net_type
primitive_type_opt unsigned_signed_opt
drive_strength net_decl_assigns ';'
{ ivl_variable_type_t dtype = $3;
if (dtype == IVL_VT_NO_TYPE)
dtype = IVL_VT_LOGIC;
pform_makewire(@2, 0, $4, 0, $5, $6, $2, dtype);
if ($1) {
yyerror(@2, "sorry: Attributes not supported "
"on net declaration assignments.");
delete $1;
}
}
| attribute_list_opt K_wreal net_decl_assigns ';'
{ pform_makewire(@2, 0, true, 0, str_strength, $3,
NetNet::WIRE, IVL_VT_REAL);
if ($1) {
yyerror(@2, "sorry: Attributes not supported "
"on net declaration assignments.");
delete $1;
}
}
{ ivl_variable_type_t dtype = $3;
if (dtype == IVL_VT_NO_TYPE)
dtype = IVL_VT_LOGIC;
vector_type_t*data_type = new vector_type_t(dtype, $4, 0);
pform_makewire(@2, 0, $5, $6, $2, data_type);
if ($1) {
yyerror(@2, "sorry: Attributes not supported "
"on net declaration assignments.");
delete $1;
}
}
| attribute_list_opt K_wreal net_decl_assigns ';'
{ real_type_t*data_type = new real_type_t(real_type_t::REAL);
pform_makewire(@2, 0, str_strength, $3, NetNet::WIRE, data_type);
if ($1) {
yyerror(@2, "sorry: Attributes not supported "
"on net declaration assignments.");
delete $1;
}
}
| K_trireg charge_strength_opt range_opt delay3_opt list_of_identifiers ';'
{ yyerror(@1, "sorry: trireg nets not supported.");
@ -4890,10 +4890,10 @@ function_range_or_type_opt
so that bit ranges can be assigned. */
register_variable
: IDENTIFIER dimensions_opt
{ perm_string ident_name = lex_strings.make($1);
pform_makewire(@1, ident_name, NetNet::REG,
{ perm_string name = lex_strings.make($1);
pform_makewire(@1, name, NetNet::REG,
NetNet::NOT_A_PORT, IVL_VT_NO_TYPE, 0);
pform_set_reg_idx(ident_name, $2);
pform_set_reg_idx(name, $2);
$$ = $1;
}
| IDENTIFIER '=' expression

178
pform.cc
View File

@ -1563,6 +1563,7 @@ void pform_make_udp(perm_string name, bool synchronous_flag,
* and the name that I receive only has the tail component.
*/
static void pform_set_net_range(perm_string name,
NetNet::Type net_type,
const list<pform_range_t>*range,
bool signed_flag,
ivl_variable_type_t dt,
@ -1574,6 +1575,19 @@ static void pform_set_net_range(perm_string name,
VLerror("error: name is not a valid net.");
return;
}
// If this is not implicit ("implicit" meaning we don't
// know what the type is yet) then set the type now.
if (net_type != NetNet::IMPLICIT && net_type != NetNet::NONE) {
bool rc = cur->set_wire_type(net_type);
if (rc == false) {
ostringstream msg;
msg << name << " " << net_type
<< " definition conflicts with " << cur->get_wire_type()
<< " definition at " << cur->get_fileline()
<< ".";
VLerror(msg.str().c_str());
}
}
if (range == 0) {
/* This is the special case that we really mean a
@ -1595,12 +1609,13 @@ static void pform_set_net_range(list<perm_string>*names,
list<pform_range_t>*range,
bool signed_flag,
ivl_variable_type_t dt,
NetNet::Type net_type,
std::list<named_pexpr_t>*attr)
{
for (list<perm_string>::iterator cur = names->begin()
; cur != names->end() ; ++ cur ) {
perm_string txt = *cur;
pform_set_net_range(txt, range, signed_flag, dt, SR_NET, attr);
pform_set_net_range(txt, net_type, range, signed_flag, dt, SR_NET, attr);
}
delete names;
@ -2144,7 +2159,7 @@ void pform_makewire(const vlltype&li,
pform_makewire(li, txt, type, pt, dt, attr);
/* This has already been done for real variables. */
if (dt != IVL_VT_REAL) {
pform_set_net_range(txt, range, signed_flag, dt, rt, 0);
pform_set_net_range(txt, type, range, signed_flag, dt, rt, 0);
}
}
@ -2156,27 +2171,31 @@ void pform_makewire(const vlltype&li,
* This form makes nets with delays and continuous assignments.
*/
void pform_makewire(const vlltype&li,
list<pform_range_t>*range,
bool signed_flag,
list<PExpr*>*delay,
str_pair_t str,
net_decl_assign_t*decls,
NetNet::Type type,
ivl_variable_type_t dt)
data_type_t*data_type)
{
// The decls pointer is a circularly linked list.
net_decl_assign_t*first = decls->next;
decls->next = 0;
list<perm_string>*names = new list<perm_string>;
// Go through the circularly linked list non-destructively.
do {
pform_makewire(li, first->name, type, NetNet::NOT_A_PORT, IVL_VT_NO_TYPE, 0);
names->push_back(first->name);
first = first->next;
} while (first != decls->next);
pform_set_data_type(li, data_type, names, type, 0);
// This time, go through the list, deleting cells as I'm done.
first = decls->next;
decls->next = 0;
while (first) {
net_decl_assign_t*next = first->next;
pform_makewire(li, first->name, type, NetNet::NOT_A_PORT, dt, 0);
/* This has already been done for real variables. */
if (dt != IVL_VT_REAL) {
pform_set_net_range(first->name, range, signed_flag, dt,
SR_NET, 0);
}
PWire*cur = pform_get_wire_in_scope(first->name);
if (cur != 0) {
PEIdent*lval = new PEIdent(first->name);
@ -2705,7 +2724,7 @@ void pform_set_port_type(const struct vlltype&li,
; cur != names->end() ; ++ cur ) {
perm_string txt = *cur;
pform_set_port_type(txt, pt, li.text, li.first_line);
pform_set_net_range(txt, range, signed_flag, IVL_VT_NO_TYPE,
pform_set_net_range(txt, NetNet::NONE, range, signed_flag, IVL_VT_NO_TYPE,
SR_PORT, 0);
}
@ -2764,9 +2783,9 @@ void pform_set_reg_time(list<perm_string>*names, list<named_pexpr_t>*attr)
delete names;
}
static void pform_set_integer_2atom(uint64_t width, bool signed_flag, perm_string name, list<named_pexpr_t>*attr)
static void pform_set_integer_2atom(uint64_t width, bool signed_flag, perm_string name, NetNet::Type net_type, list<named_pexpr_t>*attr)
{
PWire*cur = pform_get_make_wire_in_scope(name, NetNet::REG, NetNet::NOT_A_PORT, IVL_VT_BOOL);
PWire*cur = pform_get_make_wire_in_scope(name, net_type, NetNet::NOT_A_PORT, IVL_VT_BOOL);
assert(cur);
cur->set_signed(signed_flag);
@ -2780,92 +2799,42 @@ static void pform_set_integer_2atom(uint64_t width, bool signed_flag, perm_strin
pform_bind_attributes(cur->attributes, attr, true);
}
static void pform_set_integer_2atom(uint64_t width, bool signed_flag, list<perm_string>*names, list<named_pexpr_t>*attr)
static void pform_set_integer_2atom(uint64_t width, bool signed_flag, list<perm_string>*names, NetNet::Type net_type, list<named_pexpr_t>*attr)
{
for (list<perm_string>::iterator cur = names->begin()
; cur != names->end() ; ++ cur ) {
perm_string txt = *cur;
pform_set_integer_2atom(width, signed_flag, txt, attr);
pform_set_integer_2atom(width, signed_flag, txt, net_type, attr);
}
delete names;
}
template <class T> static void pform_set2_data_type(const struct vlltype&li, T*data_type, perm_string name, list<named_pexpr_t>*attr)
template <class T> static void pform_set2_data_type(const struct vlltype&li, T*data_type, perm_string name, NetNet::Type net_type, list<named_pexpr_t>*attr)
{
ivl_variable_type_t base_type = data_type->figure_packed_base_type();
if (base_type == IVL_VT_NO_TYPE) {
VLerror(li, "Compound type is not PACKED in this context.");
}
PWire*net = pform_get_make_wire_in_scope(name, NetNet::REG, NetNet::NOT_A_PORT, base_type);
PWire*net = pform_get_make_wire_in_scope(name, net_type, NetNet::NOT_A_PORT, base_type);
net->set_packed_type(data_type);
pform_bind_attributes(net->attributes, attr, true);
}
template <class T> static void pform_set2_data_type(const struct vlltype&li, T*data_type, list<perm_string>*names, list<named_pexpr_t>*attr)
template <class T> static void pform_set2_data_type(const struct vlltype&li, T*data_type, list<perm_string>*names, NetNet::Type net_type, list<named_pexpr_t>*attr)
{
for (list<perm_string>::iterator cur = names->begin()
; cur != names->end() ; ++ cur) {
pform_set2_data_type(li, data_type, *cur, attr);
pform_set2_data_type(li, data_type, *cur, net_type, attr);
}
}
/*
* This function detects the derived class for the given type and
* dispatches the type to the proper subtype function.
*/
void pform_set_data_type(const struct vlltype&li, data_type_t*data_type, list<perm_string>*names, list<named_pexpr_t>*attr)
{
if (atom2_type_t*atom2_type = dynamic_cast<atom2_type_t*> (data_type)) {
pform_set_integer_2atom(atom2_type->type_code, atom2_type->signed_flag, names, attr);
return;
}
if (struct_type_t*struct_type = dynamic_cast<struct_type_t*> (data_type)) {
pform_set_struct_type(struct_type, names, attr);
return;
}
if (enum_type_t*enum_type = dynamic_cast<enum_type_t*> (data_type)) {
pform_set_enum(li, enum_type, names, attr);
return;
}
if (vector_type_t*vec_type = dynamic_cast<vector_type_t*> (data_type)) {
pform_set_net_range(names, vec_type->pdims.get(),
vec_type->signed_flag,
vec_type->base_type, attr);
return;
}
if (/*real_type_t*real_type =*/ dynamic_cast<real_type_t*> (data_type)) {
pform_set_net_range(names, 0, true, IVL_VT_REAL, attr);
return;
}
if (/*class_type_t*class_type =*/ dynamic_cast<class_type_t*> (data_type)) {
VLerror(li, "sorry: Class types not supported.");
return;
}
if (parray_type_t*array_type = dynamic_cast<parray_type_t*> (data_type)) {
pform_set2_data_type(li, array_type, names, attr);
return;
}
if (string_type_t*string_type = dynamic_cast<string_type_t*> (data_type)) {
pform_set_string_type(string_type, names, attr);
return;
}
assert(0);
}
static void pform_set_enum(const struct vlltype&li, enum_type_t*enum_type,
perm_string name, std::list<named_pexpr_t>*attr)
perm_string name, NetNet::Type net_type,
std::list<named_pexpr_t>*attr)
{
(void) li; // The line information is not currently needed.
PWire*cur = pform_get_make_wire_in_scope(name, NetNet::REG, NetNet::NOT_A_PORT, enum_type->base_type);
PWire*cur = pform_get_make_wire_in_scope(name, net_type, NetNet::NOT_A_PORT, enum_type->base_type);
assert(cur);
cur->set_signed(enum_type->signed_flag);
@ -2877,7 +2846,9 @@ static void pform_set_enum(const struct vlltype&li, enum_type_t*enum_type,
pform_bind_attributes(cur->attributes, attr, true);
}
void pform_set_enum(const struct vlltype&li, enum_type_t*enum_type, list<perm_string>*names, std::list<named_pexpr_t>*attr)
static void pform_set_enum(const struct vlltype&li, enum_type_t*enum_type,
list<perm_string>*names, NetNet::Type net_type,
std::list<named_pexpr_t>*attr)
{
// By definition, the base type can only be IVL_VT_LOGIC or
// IVL_VT_BOOL.
@ -2897,12 +2868,63 @@ void pform_set_enum(const struct vlltype&li, enum_type_t*enum_type, list<perm_st
for (list<perm_string>::iterator cur = names->begin()
; cur != names->end() ; ++ cur) {
perm_string txt = *cur;
pform_set_enum(li, enum_type, txt, attr);
pform_set_enum(li, enum_type, txt, net_type, attr);
}
delete names;
}
/*
* This function detects the derived class for the given type and
* dispatches the type to the proper subtype function.
*/
void pform_set_data_type(const struct vlltype&li, data_type_t*data_type, list<perm_string>*names, NetNet::Type net_type, list<named_pexpr_t>*attr)
{
if (atom2_type_t*atom2_type = dynamic_cast<atom2_type_t*> (data_type)) {
pform_set_integer_2atom(atom2_type->type_code, atom2_type->signed_flag, names, net_type, attr);
return;
}
if (struct_type_t*struct_type = dynamic_cast<struct_type_t*> (data_type)) {
pform_set_struct_type(struct_type, names, net_type, attr);
return;
}
if (enum_type_t*enum_type = dynamic_cast<enum_type_t*> (data_type)) {
pform_set_enum(li, enum_type, names, net_type, attr);
return;
}
if (vector_type_t*vec_type = dynamic_cast<vector_type_t*> (data_type)) {
pform_set_net_range(names, vec_type->pdims.get(),
vec_type->signed_flag,
vec_type->base_type, net_type, attr);
return;
}
if (/*real_type_t*real_type =*/ dynamic_cast<real_type_t*> (data_type)) {
pform_set_net_range(names, 0, true, IVL_VT_REAL, net_type, attr);
return;
}
if (/*class_type_t*class_type =*/ dynamic_cast<class_type_t*> (data_type)) {
VLerror(li, "sorry: Class types not supported.");
return;
}
if (parray_type_t*array_type = dynamic_cast<parray_type_t*> (data_type)) {
pform_set2_data_type(li, array_type, names, net_type, attr);
return;
}
if (string_type_t*string_type = dynamic_cast<string_type_t*> (data_type)) {
pform_set_string_type(string_type, names, net_type, attr);
return;
}
assert(0);
}
svector<PWire*>* pform_make_udp_input_ports(list<perm_string>*names)
{
svector<PWire*>*out = new svector<PWire*>(names->size());

14
pform.h
View File

@ -265,13 +265,11 @@ extern void pform_makewire(const struct vlltype&li,
/* This form handles assignment declarations. */
extern void pform_makewire(const struct vlltype&li,
list<pform_range_t>*range,
bool signed_flag,
list<PExpr*>*delay,
str_pair_t str,
net_decl_assign_t*assign_list,
NetNet::Type type,
ivl_variable_type_t);
data_type_t*data_type);
/* This form handles nets declared as structures. (See pform_struct_type.cc) */
extern void pform_makewire(const struct vlltype&li,
@ -297,15 +295,11 @@ extern void pform_set_reg_idx(perm_string name,
extern void pform_set_reg_integer(list<perm_string>*names, list<named_pexpr_t>*attr);
extern void pform_set_reg_time(list<perm_string>*names, list<named_pexpr_t>*attr);
//XXXXextern void pform_set_integer_2atom(uint64_t width, bool signed_flag, list<perm_string>*names);
extern void pform_set_data_type(const struct vlltype&li, data_type_t*, list<perm_string>*names, NetNet::Type net_type, list<named_pexpr_t>*attr);
extern void pform_set_data_type(const struct vlltype&li, data_type_t*, list<perm_string>*names, list<named_pexpr_t>*attr);
extern void pform_set_struct_type(struct_type_t*struct_type, std::list<perm_string>*names, NetNet::Type net_type, std::list<named_pexpr_t>*attr);
extern void pform_set_enum(const struct vlltype&li, enum_type_t*enum_type, list<perm_string>*names, std::list<named_pexpr_t>*attr);
extern void pform_set_struct_type(struct_type_t*struct_type, std::list<perm_string>*names, std::list<named_pexpr_t>*attr);
extern void pform_set_string_type(string_type_t*string_type, std::list<perm_string>*names, std::list<named_pexpr_t>*attr);
extern void pform_set_string_type(string_type_t*string_type, std::list<perm_string>*names, NetNet::Type net_type, std::list<named_pexpr_t>*attr);
/* pform_set_attrib and pform_set_type_attrib exist to support the
$attribute syntax, which can only set string values to

View File

@ -21,17 +21,17 @@
# include "parse_misc.h"
# include "ivl_assert.h"
static void pform_set_string_type(string_type_t*string_type, perm_string name, list<named_pexpr_t>*attr)
static void pform_set_string_type(string_type_t*string_type, perm_string name, NetNet::Type net_type, list<named_pexpr_t>*attr)
{
PWire*net = pform_get_make_wire_in_scope(name, NetNet::REG, NetNet::NOT_A_PORT, IVL_VT_STRING);
PWire*net = pform_get_make_wire_in_scope(name, net_type, NetNet::NOT_A_PORT, IVL_VT_STRING);
pform_bind_attributes(net->attributes, attr, true);
}
void pform_set_string_type(string_type_t*string_type, list<perm_string>*names, list<named_pexpr_t>*attr)
void pform_set_string_type(string_type_t*string_type, list<perm_string>*names, NetNet::Type net_type, list<named_pexpr_t>*attr)
{
for (list<perm_string>::iterator cur = names->begin()
; cur != names->end() ; ++ cur) {
pform_set_string_type(string_type, *cur, attr);
pform_set_string_type(string_type, *cur, net_type, attr);
}
}

View File

@ -51,19 +51,19 @@ ivl_variable_type_t struct_type_t::figure_packed_base_type(void) const
* out the base type of the packed variable. Elaboration, later on,
* well figure out the rest.
*/
static void pform_set_packed_struct(struct_type_t*struct_type, perm_string name, list<named_pexpr_t>*attr)
static void pform_set_packed_struct(struct_type_t*struct_type, perm_string name, NetNet::Type net_type, list<named_pexpr_t>*attr)
{
ivl_variable_type_t base_type = struct_type->figure_packed_base_type();
PWire*net = pform_get_make_wire_in_scope(name, NetNet::REG, NetNet::NOT_A_PORT, base_type);
PWire*net = pform_get_make_wire_in_scope(name, net_type, NetNet::NOT_A_PORT, base_type);
net->set_packed_type(struct_type);
pform_bind_attributes(net->attributes, attr, true);
}
static void pform_set_struct_type(struct_type_t*struct_type, perm_string name, list<named_pexpr_t>*attr)
static void pform_set_struct_type(struct_type_t*struct_type, perm_string name, NetNet::Type net_type, list<named_pexpr_t>*attr)
{
if (struct_type->packed_flag) {
pform_set_packed_struct(struct_type, name, attr);
pform_set_packed_struct(struct_type, name, net_type, attr);
return;
}
@ -71,11 +71,11 @@ static void pform_set_struct_type(struct_type_t*struct_type, perm_string name, l
ivl_assert(*struct_type, 0);
}
void pform_set_struct_type(struct_type_t*struct_type, list<perm_string>*names, list<named_pexpr_t>*attr)
void pform_set_struct_type(struct_type_t*struct_type, list<perm_string>*names, NetNet::Type net_type, list<named_pexpr_t>*attr)
{
for (list<perm_string>::iterator cur = names->begin()
; cur != names->end() ; ++ cur) {
pform_set_struct_type(struct_type, *cur, attr);
pform_set_struct_type(struct_type, *cur, net_type, attr);
}
}