Handle nets that are packed structures.

This commit is contained in:
Stephen Williams 2011-12-18 12:00:18 -08:00
parent 3a2866b57c
commit e9e2fb33e9
4 changed files with 99 additions and 28 deletions

13
parse.y
View File

@ -2775,6 +2775,19 @@ module_item
}
}
/* Allow struct nets. */
| attribute_list_opt net_type struct_data_type net_variable_list ';'
{ pform_makewire(@2, $3, NetNet::NOT_A_PORT, $4, $1);
delete $1;
}
| attribute_list_opt net_type struct_data_type error ';'
{ yyerror(@5, "error: Errors in net variable list.");
}
/* This form doesn't have the range, but does have strengths. This
gives strength to the assignment drivers. */

View File

@ -1898,6 +1898,36 @@ void pform_module_define_port(const struct vlltype&li,
* function is called for every declaration.
*/
static PWire* pform_get_or_make_wire(const vlltype&li, perm_string name,
NetNet::Type type, NetNet::PortType ptype,
ivl_variable_type_t dtype)
{
PWire*cur = pform_get_wire_in_scope(name);
if (cur) {
// If this is not implicit ("implicit" meaning we don't
// know what the type is yet) then set the type now.
if (type != NetNet::IMPLICIT) {
bool rc = cur->set_wire_type(type);
if (rc == false) {
ostringstream msg;
msg << name << " " << type
<< " definition conflicts with " << cur->get_wire_type()
<< " definition at " << cur->get_fileline()
<< ".";
VLerror(msg.str().c_str());
}
FILE_NAME(cur, li.text, li.first_line);
}
return cur;
}
cur = new PWire(name, type, ptype, dtype);
FILE_NAME(cur, li.text, li.first_line);
pform_put_wire_in_scope(name, cur);
return cur;
}
/*
* this is the basic form of pform_makewire. This takes a single simple
* name, port type, net type, data type, and attributes, and creates
@ -1909,22 +1939,7 @@ void pform_makewire(const vlltype&li, perm_string name,
ivl_variable_type_t dt,
list<named_pexpr_t>*attr)
{
PWire*cur = pform_get_wire_in_scope(name);
// If this is not implicit ("implicit" meaning we don't know
// what the type is yet) then set the type now.
if (cur && type != NetNet::IMPLICIT) {
bool rc = cur->set_wire_type(type);
if (rc == false) {
ostringstream msg;
msg << name << " " << type
<< " definition conflicts with " << cur->get_wire_type()
<< " definition at " << cur->get_fileline()
<< ".";
VLerror(msg.str().c_str());
}
}
PWire*cur = pform_get_or_make_wire(li, name, type, pt, dt);
bool new_wire_flag = false;
if (! cur) {
@ -1933,9 +1948,6 @@ void pform_makewire(const vlltype&li, perm_string name,
FILE_NAME(cur, li.text, li.first_line);
}
if (type != NetNet::IMPLICIT)
FILE_NAME(cur, li.text, li.first_line);
bool flag;
switch (dt) {
case IVL_VT_REAL:
@ -1960,9 +1972,6 @@ void pform_makewire(const vlltype&li, perm_string name,
cur->attributes[attr_cur->name] = attr_cur->parm;
}
}
if (new_wire_flag)
pform_put_wire_in_scope(name, cur);
}
/*

13
pform.h
View File

@ -245,6 +245,12 @@ extern void pform_makewire(const struct vlltype&li,
list<named_pexpr_t>*attr,
PWSRType rt = SR_NET);
extern void pform_makewire(const struct vlltype&li,
struct_type_t*struct_type,
list<perm_string>*names,
NetNet::PortType,
list<named_pexpr_t>*attr);
/* This form handles assignment declarations. */
extern void pform_makewire(const struct vlltype&li,
list<PExpr*>*range,
@ -255,6 +261,13 @@ extern void pform_makewire(const struct vlltype&li,
NetNet::Type type,
ivl_variable_type_t);
/* This form handles nets declared as structures. (See pform_struct_type.cc) */
extern void pform_makewire(const struct vlltype&li,
struct_type_t*struct_type,
NetNet::PortType,
list<perm_string>*names,
list<named_pexpr_t>*attr);
extern void pform_make_reginit(const struct vlltype&li,
perm_string name, PExpr*expr);

View File

@ -18,14 +18,10 @@
*/
# include "pform.h"
# include "parse_misc.h"
# include "ivl_assert.h"
/*
* When we parse a packed struct, we can early on (right here) figure
* 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)
static ivl_variable_type_t figure_struct_base_type(struct_type_t*struct_type)
{
ivl_variable_type_t base_type = IVL_VT_BOOL;
@ -44,6 +40,18 @@ static void pform_set_packed_struct(struct_type_t*struct_type, perm_string name)
}
}
return base_type;
}
/*
* When we parse a packed struct, we can early on (right here) figure
* 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)
{
ivl_variable_type_t base_type = figure_struct_base_type(struct_type);
PWire*net = pform_get_make_wire_in_scope(name, NetNet::REG, NetNet::NOT_A_PORT, base_type);
net->set_struct_type(struct_type);
}
@ -66,3 +74,31 @@ void pform_set_struct_type(struct_type_t*struct_type, list<perm_string>*names)
pform_set_struct_type(struct_type, *cur);
}
}
static void pform_makewire(const struct vlltype&li,
struct_type_t*struct_type,
NetNet::PortType ptype,
perm_string name,
list<named_pexpr_t>*attr)
{
ivl_variable_type_t base_type = figure_struct_base_type(struct_type);
PWire*cur = pform_get_make_wire_in_scope(name, NetNet::WIRE, ptype, base_type);
FILE_NAME(cur, li);
cur->set_struct_type(struct_type);
}
void pform_makewire(const struct vlltype&li,
struct_type_t*struct_type,
NetNet::PortType ptype,
list<perm_string>*names,
list<named_pexpr_t>*attr)
{
for (list<perm_string>::iterator cur = names->begin()
; cur != names->end() ; ++ cur ) {
perm_string txt = *cur;
pform_makewire(li, struct_type, ptype, txt, attr);
}
delete names;
}