Clean up PWire handling of wire data type. / Reword packed type handling

This commit is contained in:
Stephen Williams 2012-08-02 20:14:55 -07:00
parent f5aafc32f9
commit 3d9ed1f0f8
12 changed files with 110 additions and 102 deletions

View File

@ -29,7 +29,7 @@ PWire::PWire(perm_string n,
: name_(n), type_(t), port_type_(pt), data_type_(dt),
signed_(false), isint_(false),
port_set_(false), net_set_(false), is_scalar_(false),
error_cnt_(0), enum_type_(0), struct_type_(0),
error_cnt_(0), set_data_type_(0),
discipline_(0)
{
if (t == NetNet::INTEGER) {
@ -253,18 +253,10 @@ void PWire::set_unpacked_idx(const list<pform_range_t>&ranges)
}
}
void PWire::set_enumeration(enum_type_t*enum_type)
void PWire::set_packed_type(data_type_t*type)
{
assert(enum_type_ == 0);
assert(struct_type_ == 0);
enum_type_ = enum_type;
}
void PWire::set_struct_type(struct_type_t*type)
{
assert(enum_type_ == 0);
assert(struct_type_ == 0);
struct_type_ = type;
assert(set_data_type_ == 0);
set_data_type_ = type;
}
void PWire::set_discipline(ivl_discipline_t d)

View File

@ -81,8 +81,7 @@ class PWire : public LineInfo {
void set_unpacked_idx(const std::list<pform_range_t>&ranges);
void set_enumeration(enum_type_t*enum_type);
void set_struct_type(struct_type_t*type);
void set_packed_type(data_type_t*type);
void set_discipline(ivl_discipline_t);
ivl_discipline_t get_discipline(void) const;
@ -119,8 +118,7 @@ class PWire : public LineInfo {
// me the size and address ranges of the memory.
std::list<pform_range_t>unpacked_;
enum_type_t*enum_type_;
struct_type_t*struct_type_;
data_type_t*set_data_type_;
ivl_discipline_t discipline_;

View File

@ -892,6 +892,20 @@ static netstruct_t* elaborate_struct_type(Design*des, NetScope*scope,
return res;
}
static netdarray_t* elaborate_parray_type(Design*des, NetScope*scope,
parray_type_t*data_type)
{
list<netrange_t>packed_dimensions;
bool bad_range = evaluate_ranges(des, scope, packed_dimensions, * data_type->packed_dims);
ivl_assert(*data_type, bad_range);
netdarray_t*res = new netdarray_t(packed_dimensions, IVL_VT_NO_TYPE, 0);
//res->set_line(*data_type);
return res;
}
bool test_ranges_eeq(const list<netrange_t>&lef, const list<netrange_t>&rig)
{
if (lef.size() != rig.size())
@ -1158,8 +1172,8 @@ NetNet* PWire::elaborate_sig(Design*des, NetScope*scope) const
// If this is a struct type, then build the net with the
// struct type.
if (struct_type_) {
netstruct_t*use_type = elaborate_struct_type(des, scope, struct_type_);
if (struct_type_t*struct_type = dynamic_cast<struct_type_t*>(set_data_type_)) {
netstruct_t*use_type = elaborate_struct_type(des, scope, struct_type);
if (debug_elaborate) {
cerr << get_fileline() << ": debug: Create signal " << wtype;
if (use_type->packed())
@ -1172,10 +1186,8 @@ NetNet* PWire::elaborate_sig(Design*des, NetScope*scope) const
sig = new NetNet(scope, name_, wtype, use_type);
} else if (enum_type_) {
ivl_assert(*this, struct_type_ == 0);
ivl_assert(*this, ! enum_type_->names->empty());
list<named_pexpr_t>::const_iterator sample_name = enum_type_->names->begin();
} else if (enum_type_t*enum_type = dynamic_cast<enum_type_t*>(set_data_type_)) {
list<named_pexpr_t>::const_iterator sample_name = enum_type->names->begin();
netenum_t*use_enum = scope->enumeration_for_name(sample_name->name);
if (debug_elaborate) {
@ -1186,9 +1198,8 @@ NetNet* PWire::elaborate_sig(Design*des, NetScope*scope) const
sig = new NetNet(scope, name_, wtype, packed_dimensions, unpacked_dimensions, use_enum);
} else if (netarray) {
ivl_assert(*this, struct_type_==0);
ivl_assert(*this, enum_type_==0);
if (debug_elaborate) {
cerr << get_fileline() << ": debug: Create signal " << wtype
@ -1200,6 +1211,15 @@ NetNet* PWire::elaborate_sig(Design*des, NetScope*scope) const
ivl_assert(*this, unpacked_dimensions.empty());
sig = new NetNet(scope, name_, wtype, netarray);
} else if (parray_type_t*parray_type = dynamic_cast<parray_type_t*>(set_data_type_)) {
netdarray_t*use_type = elaborate_parray_type(des, scope, parray_type);
sig = new NetNet(scope, name_, wtype, use_type);
#if 0
cerr << get_fileline() << ": sorry: Packed arrays not supported here." << endl;
des->errors += 1;
#endif
} else {
if (debug_elaborate) {
cerr << get_fileline() << ": debug: Create signal " << wtype;

View File

@ -1,48 +0,0 @@
#ifndef __netarray_H
#define __netarray_H
/*
* Copyright (c) 2012 Stephen Williams (steve@icarus.com)
* Copyright CERN 2012 / Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
* General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
# include "LineInfo.h"
# include <vector>
class netarray_t : public LineInfo {
public:
explicit netarray_t(const std::list<netrange_t>&packed);
~netarray_t();
unsigned packed_width() const;
private:
std::list<netrange_t> packed_dims_;
};
inline netarray_t::netarray_t(const std::list<netrange_t>&packed)
: packed_dims_(packed)
{
}
netarray_t::~netarray_t()
{
}
#endif

View File

@ -611,7 +611,7 @@ NetNet::NetNet(NetScope*s, perm_string n, Type t,
s->add_signal(this);
}
static unsigned calculate_count(netstruct_t*type)
template <class T> static unsigned calculate_count(T*type)
{
long wid = type->packed_width();
if (wid >= 0)

View File

@ -894,7 +894,7 @@ data_type /* IEEE1800-2005: A.2.2.1 */
$$ = tmp;
}
| TYPE_IDENTIFIER range_opt
{ if ($2) $$ = new array_type_t($1, $2);
{ if ($2) $$ = new parray_type_t($1, $2);
else $$ = $1;
}
| K_string

View File

@ -1591,11 +1591,11 @@ static void pform_set_net_range(perm_string name,
pform_bind_attributes(cur->attributes, attr, true);
}
void pform_set_net_range(list<perm_string>*names,
list<pform_range_t>*range,
bool signed_flag,
ivl_variable_type_t dt,
std::list<named_pexpr_t>*attr)
static void pform_set_net_range(list<perm_string>*names,
list<pform_range_t>*range,
bool signed_flag,
ivl_variable_type_t dt,
std::list<named_pexpr_t>*attr)
{
for (list<perm_string>::iterator cur = names->begin()
; cur != names->end() ; ++ cur ) {
@ -1997,7 +1997,7 @@ void pform_module_define_port(const struct vlltype&li,
}
} else if ((struct_type = dynamic_cast<struct_type_t*>(vtype))) {
data_type = figure_struct_base_type(struct_type);
data_type = struct_type->figure_packed_base_type();
signed_flag = false;
range = 0;
@ -2017,7 +2017,7 @@ void pform_module_define_port(const struct vlltype&li,
cur->set_signed(signed_flag);
if (struct_type) {
cur->set_struct_type(struct_type);
cur->set_packed_type(struct_type);
} else if (range == 0) {
cur->set_range_scalar((type == NetNet::IMPLICIT) ? SR_PORT : SR_BOTH);
@ -2790,6 +2790,26 @@ static void pform_set_integer_2atom(uint64_t width, bool signed_flag, list<perm_
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)
{
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);
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)
{
for (list<perm_string>::iterator cur = names->begin()
; cur != names->end() ; ++ cur) {
pform_set2_data_type(li, data_type, *cur, attr);
}
}
/*
* This function detects the derived class for the given type and
* dispatches the type to the proper subtype function.
@ -2828,8 +2848,8 @@ void pform_set_data_type(const struct vlltype&li, data_type_t*data_type, list<pe
return;
}
if (/*array_type_t*array_type = */ dynamic_cast<array_type_t*> (data_type)) {
VLerror(li, "sorry: General array types not supported.");
if (parray_type_t*array_type = dynamic_cast<parray_type_t*> (data_type)) {
pform_set2_data_type(li, array_type, names, attr);
return;
}
@ -2853,7 +2873,7 @@ static void pform_set_enum(const struct vlltype&li, enum_type_t*enum_type,
assert(enum_type->range.get() != 0);
assert(enum_type->range->size() == 1);
cur->set_range(*enum_type->range, SR_NET);
cur->set_enumeration(enum_type);
cur->set_packed_type(enum_type);
pform_bind_attributes(cur->attributes, attr, true);
}

View File

@ -292,11 +292,6 @@ extern void pform_set_port_type(const struct vlltype&li,
bool signed_flag,
NetNet::PortType);
extern void pform_set_net_range(list<perm_string>*names,
list<pform_range_t>*,
bool signed_flag,
ivl_variable_type_t,
std::list<named_pexpr_t>*attr);
extern void pform_set_reg_idx(perm_string name,
std::list<pform_range_t>*indices);
extern void pform_set_reg_integer(list<perm_string>*names, list<named_pexpr_t>*attr);

View File

@ -391,6 +391,10 @@ void PWire::dump(ostream&out, unsigned ind) const
}
out << ";" << endl;
if (set_data_type_) {
set_data_type_->pform_dump(out, 8);
}
dump_attributes_map(out, attributes, 8);
}

View File

@ -21,12 +21,15 @@
# include "parse_misc.h"
# include "ivl_assert.h"
ivl_variable_type_t figure_struct_base_type(struct_type_t*struct_type)
ivl_variable_type_t struct_type_t::figure_packed_base_type(void) const
{
if (! packed_flag)
return IVL_VT_NO_TYPE;
ivl_variable_type_t base_type = IVL_VT_BOOL;
for (list<struct_member_t*>::iterator cur = struct_type->members->begin()
; cur != struct_type->members->end() ; ++ cur) {
for (list<struct_member_t*>::iterator cur = members->begin()
; cur != members->end() ; ++ cur) {
struct_member_t*tmp = *cur;
@ -50,10 +53,10 @@ ivl_variable_type_t figure_struct_base_type(struct_type_t*struct_type)
*/
static void pform_set_packed_struct(struct_type_t*struct_type, perm_string name, list<named_pexpr_t>*attr)
{
ivl_variable_type_t base_type = figure_struct_base_type(struct_type);
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);
net->set_struct_type(struct_type);
net->set_packed_type(struct_type);
pform_bind_attributes(net->attributes, attr, true);
}
@ -82,11 +85,11 @@ static void pform_makewire(const struct vlltype&li,
perm_string name,
list<named_pexpr_t>*)
{
ivl_variable_type_t base_type = figure_struct_base_type(struct_type);
ivl_variable_type_t base_type = struct_type->figure_packed_base_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);
cur->set_packed_type(struct_type);
}
void pform_makewire(const struct vlltype&li,

View File

@ -27,3 +27,18 @@ data_type_t::~data_type_t()
string_type_t::~string_type_t()
{
}
ivl_variable_type_t data_type_t::figure_packed_base_type(void) const
{
return IVL_VT_NO_TYPE;
}
ivl_variable_type_t parray_type_t::figure_packed_base_type(void) const
{
return base_type->figure_packed_base_type();
}
ivl_variable_type_t vector_type_t::figure_packed_base_type(void) const
{
return base_type;
}

View File

@ -69,9 +69,12 @@ struct decl_assignment_t {
* "data_type" rule in the parse rule. We make the type virtual so
* that dynamic types will work.
*/
struct data_type_t : public LineInfo {
class data_type_t : public LineInfo {
public:
virtual ~data_type_t() = 0;
// This method is used to figure out the base type of a packed
// compound object. Return IVL_VT_NO_TYPE if the type is not packed.
virtual ivl_variable_type_t figure_packed_base_type(void)const;
// This method is used by the pform dumper to diagnostic dump.
virtual void pform_dump(std::ostream&out, unsigned indent) const;
};
@ -97,10 +100,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;
bool packed_flag;
std::auto_ptr< list<struct_member_t*> > members;
};
extern ivl_variable_type_t figure_struct_base_type(struct_type_t*struct_type);
struct atom2_type_t : public data_type_t {
inline explicit atom2_type_t(int tc, bool flag)
@ -132,6 +135,8 @@ struct vector_type_t : public data_type_t {
inline explicit vector_type_t(ivl_variable_type_t bt, bool sf,
std::list<pform_range_t>*pd)
: base_type(bt), signed_flag(sf), reg_flag(false), implicit_flag(false), pdims(pd) { }
virtual ivl_variable_type_t figure_packed_base_type(void)const;
ivl_variable_type_t base_type;
bool signed_flag;
bool reg_flag; // True if "reg" was used
@ -141,11 +146,15 @@ struct vector_type_t : public data_type_t {
/*
* The array_type_t is a generalization of the vector_type_t in that
* the base type is another general data type.
* the base type is another general data type. Ultimately, the subtype
* must also be packed (as this is a packed array) but that may be
* worked out during elaboration.
*/
struct array_type_t : public data_type_t {
inline explicit array_type_t(data_type_t*btype, std::list<pform_range_t>*pd)
struct parray_type_t : public data_type_t {
inline explicit parray_type_t(data_type_t*btype, std::list<pform_range_t>*pd)
: base_type(btype), packed_dims(pd) { }
virtual ivl_variable_type_t figure_packed_base_type(void)const;
data_type_t*base_type;
std::auto_ptr< list<pform_range_t> > packed_dims;
};