Generalize struct member type
This commit is contained in:
parent
aced587461
commit
0b4056817a
17
elab_expr.cc
17
elab_expr.cc
|
|
@ -1793,7 +1793,9 @@ static NetExpr* check_for_struct_members(const LineInfo*li,
|
|||
comp.name, off);
|
||||
if (mem == 0) return 0;
|
||||
|
||||
unsigned use_width = mem->width();
|
||||
ivl_assert(*li, mem->net_type && mem->net_type->packed());
|
||||
|
||||
unsigned use_width = mem->net_type->packed_width();
|
||||
|
||||
if (debug_elaborate) {
|
||||
cerr << li->get_fileline() << ": debug: check_for_struct_members: "
|
||||
|
|
@ -1805,6 +1807,11 @@ static NetExpr* check_for_struct_members(const LineInfo*li,
|
|||
// The struct member may be a packed array. Process index
|
||||
// expression that address the member element.
|
||||
if ( ! comp.index.empty() ) {
|
||||
const netvector_t*mem_vec = dynamic_cast<const netvector_t*> (mem->net_type);
|
||||
ivl_assert(*li, mem_vec);
|
||||
|
||||
const vector<netrange_t>&packed_dims = mem_vec->packed_dims();
|
||||
|
||||
// Evaluate all but the last index expression, into prefix_indices.
|
||||
list<long>prefix_indices;
|
||||
bool rc = evaluate_index_prefix(des, scope, prefix_indices, comp.index);
|
||||
|
|
@ -1814,7 +1821,7 @@ static NetExpr* check_for_struct_members(const LineInfo*li,
|
|||
// elements are in fact like bit selects. The tail may
|
||||
// be part selects only if we are taking the part-select
|
||||
// of the word of an array.
|
||||
ivl_assert(*li, comp.index.size() >= mem->packed_dims.size() || comp.index.back().sel == index_component_t::SEL_BIT);
|
||||
ivl_assert(*li, comp.index.size() >= packed_dims.size() || comp.index.back().sel == index_component_t::SEL_BIT);
|
||||
|
||||
// Evaluate the part/bit select expressions. This may be
|
||||
// a bit select or a part select. In any case, assume
|
||||
|
|
@ -1829,7 +1836,7 @@ static NetExpr* check_for_struct_members(const LineInfo*li,
|
|||
// offset and width of the addressed slice of the member.
|
||||
long loff;
|
||||
unsigned long lwid;
|
||||
prefix_to_slice(mem->packed_dims, prefix_indices, poff, loff, lwid);
|
||||
prefix_to_slice(packed_dims, prefix_indices, poff, loff, lwid);
|
||||
|
||||
if (debug_elaborate) {
|
||||
cerr << li->get_fileline() << ": debug: check_for_struct_members: "
|
||||
|
|
@ -1838,7 +1845,7 @@ static NetExpr* check_for_struct_members(const LineInfo*li,
|
|||
}
|
||||
|
||||
off += loff;
|
||||
if (comp.index.size() >= mem->packed_dims.size())
|
||||
if (comp.index.size() >= packed_dims.size())
|
||||
use_width = pwid;
|
||||
else
|
||||
use_width = lwid;
|
||||
|
|
@ -2920,7 +2927,7 @@ unsigned PEIdent::test_width(Design*des, NetScope*scope, width_mode_t&mode)
|
|||
method_name, unused);
|
||||
if (mem) {
|
||||
expr_type_ = mem->data_type();
|
||||
expr_width_ = mem->width();
|
||||
expr_width_ = mem->net_type->packed_width();
|
||||
min_width_ = expr_width_;
|
||||
signed_flag_ = mem->get_signed();
|
||||
return expr_width_;
|
||||
|
|
|
|||
11
elab_lval.cc
11
elab_lval.cc
|
|
@ -27,6 +27,7 @@
|
|||
# include "netstruct.h"
|
||||
# include "netclass.h"
|
||||
# include "netdarray.h"
|
||||
# include "netvector.h"
|
||||
# include "compiler.h"
|
||||
# include <cstdlib>
|
||||
# include <iostream>
|
||||
|
|
@ -1014,9 +1015,13 @@ bool PEIdent::elaborate_lval_net_packed_member_(Design*des, NetScope*scope,
|
|||
return false;
|
||||
}
|
||||
|
||||
unsigned long use_width = member->width();
|
||||
unsigned long use_width = member->net_type->packed_width();
|
||||
|
||||
if (name_tail.index.size() > member->packed_dims.size()) {
|
||||
const netvector_t*mem_vec = dynamic_cast<const netvector_t*>(member->net_type);
|
||||
ivl_assert(*this, mem_vec);
|
||||
const vector<netrange_t>&mem_packed_dims = mem_vec->packed_dims();
|
||||
|
||||
if (name_tail.index.size() > mem_packed_dims.size()) {
|
||||
cerr << get_fileline() << ": error: Too many index expressions for member." << endl;
|
||||
des->errors += 1;
|
||||
return false;
|
||||
|
|
@ -1052,7 +1057,7 @@ bool PEIdent::elaborate_lval_net_packed_member_(Design*des, NetScope*scope,
|
|||
// offset and width of the addressed slice of the member.
|
||||
long loff;
|
||||
unsigned long lwid;
|
||||
prefix_to_slice(member->packed_dims, prefix_indices, tmp, loff, lwid);
|
||||
prefix_to_slice(mem_packed_dims, prefix_indices, tmp, loff, lwid);
|
||||
|
||||
off += loff;
|
||||
use_width = lwid;
|
||||
|
|
|
|||
|
|
@ -524,7 +524,7 @@ NetNet* PEIdent::elaborate_lnet_common_(Design*des, NetScope*scope,
|
|||
if (debug_elaborate) {
|
||||
cerr << get_fileline() << ": PEIdent::elaborate_lnet_common_: "
|
||||
<< "Member " << method_name
|
||||
<< " has packed dimensions " << member->packed_dims << "." << endl;
|
||||
<< " has type " << *member->net_type << "." << endl;
|
||||
cerr << get_fileline() << ": : "
|
||||
<< "Tail name has " << path_tail.index.size() << " indices." << endl;
|
||||
}
|
||||
|
|
@ -532,7 +532,7 @@ NetNet* PEIdent::elaborate_lnet_common_(Design*des, NetScope*scope,
|
|||
// Rewrite a member select of a packed structure as a
|
||||
// part select of the base variable.
|
||||
lidx = member_off;
|
||||
midx = lidx + member->width() - 1;
|
||||
midx = lidx + member->net_type->packed_width() - 1;
|
||||
|
||||
// The dimensions of the tail of the prefix must match
|
||||
// the dimensions of the signal at this point. (The sig
|
||||
|
|
@ -563,7 +563,7 @@ NetNet* PEIdent::elaborate_lnet_common_(Design*des, NetScope*scope,
|
|||
long tmp;
|
||||
if (packed_base && eval_as_long(tmp, packed_base)) {
|
||||
lidx = tmp;
|
||||
midx = lidx + member->width() - 1;
|
||||
midx = lidx + member->net_type->packed_width() - 1;
|
||||
delete packed_base;
|
||||
packed_base = 0;
|
||||
}
|
||||
|
|
@ -574,7 +574,7 @@ NetNet* PEIdent::elaborate_lnet_common_(Design*des, NetScope*scope,
|
|||
// Now the lidx/midx values get us to the member. Next
|
||||
// up, deal with bit/part selects from the member
|
||||
// itself.
|
||||
ivl_assert(*this, member->packed_dims.size() <= 1);
|
||||
//XXXXivl_assert(*this, member->packed_dims.size() <= 1);
|
||||
ivl_assert(*this, path_tail.index.size() <= 1);
|
||||
if (! path_tail.index.empty()) {
|
||||
long tmp_off;
|
||||
|
|
|
|||
|
|
@ -894,14 +894,15 @@ static netstruct_t* elaborate_struct_type(Design*des, NetScope*scope,
|
|||
packed_dimensions.push_back(netrange_t(0,0));
|
||||
}
|
||||
|
||||
netvector_t*mem_vec = new netvector_t(packed_dimensions, curp->type);
|
||||
|
||||
for (list<decl_assignment_t*>::iterator name = curp->names->begin()
|
||||
; name != curp->names->end() ; ++ name) {
|
||||
decl_assignment_t*namep = *name;
|
||||
|
||||
netstruct_t::member_t memb;
|
||||
memb.name = namep->name;
|
||||
memb.type = curp->type;
|
||||
memb.packed_dims = packed_dimensions;
|
||||
memb.net_type = mem_vec;
|
||||
res->append_member(memb);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -47,9 +47,9 @@ class netparray_t : public netarray_t {
|
|||
|
||||
};
|
||||
|
||||
inline netparray_t::netparray_t(const std::vector<netrange_t>&packed,
|
||||
inline netparray_t::netparray_t(const std::vector<netrange_t>&pd,
|
||||
ivl_type_t etype)
|
||||
: netarray_t(etype), packed_dims_(packed)
|
||||
: netarray_t(etype), packed_dims_(pd)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
|||
12
netstruct.cc
12
netstruct.cc
|
|
@ -18,12 +18,13 @@
|
|||
*/
|
||||
|
||||
# include "netstruct.h"
|
||||
# include "netvector.h"
|
||||
# include <iostream>
|
||||
|
||||
using namespace std;
|
||||
|
||||
netstruct_t::netstruct_t()
|
||||
: packed_(false)
|
||||
: union_(false), packed_(false)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
@ -31,6 +32,11 @@ netstruct_t::~netstruct_t()
|
|||
{
|
||||
}
|
||||
|
||||
void netstruct_t::union_flag(bool flag)
|
||||
{
|
||||
union_ = flag;
|
||||
}
|
||||
|
||||
void netstruct_t::packed(bool flag)
|
||||
{
|
||||
packed_ = flag;
|
||||
|
|
@ -49,7 +55,7 @@ const netstruct_t::member_t* netstruct_t::packed_member(perm_string name, unsign
|
|||
off = count_off;
|
||||
return &members_[idx-1];
|
||||
}
|
||||
count_off += members_[idx-1].width();
|
||||
count_off += members_[idx-1].net_type->packed_width();
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
@ -62,7 +68,7 @@ long netstruct_t::packed_width(void) const
|
|||
|
||||
long res = 0;
|
||||
for (size_t idx = 0 ; idx < members_.size() ; idx += 1)
|
||||
res += members_[idx].width();
|
||||
res += members_[idx].net_type->packed_width();
|
||||
|
||||
return res;
|
||||
}
|
||||
|
|
|
|||
18
netstruct.h
18
netstruct.h
|
|
@ -29,10 +29,9 @@ class netstruct_t : public LineInfo, public ivl_type_s {
|
|||
public:
|
||||
struct member_t {
|
||||
perm_string name;
|
||||
ivl_variable_type_t type;
|
||||
std::vector<netrange_t> packed_dims;
|
||||
long width() const;
|
||||
ivl_variable_type_t data_type() const { return type; };
|
||||
ivl_type_t net_type;
|
||||
inline ivl_variable_type_t data_type() const
|
||||
{ return net_type->base_type(); };
|
||||
// We need to keep the individual element sign information.
|
||||
bool get_signed() const { return false; };
|
||||
};
|
||||
|
|
@ -41,6 +40,12 @@ class netstruct_t : public LineInfo, public ivl_type_s {
|
|||
netstruct_t();
|
||||
~netstruct_t();
|
||||
|
||||
// If this is a union (instead of struct) then this flag is
|
||||
// set. We handle union and struct together because they are
|
||||
// so similar.
|
||||
void union_flag(bool);
|
||||
bool union_flag(void) const;
|
||||
|
||||
void packed(bool flag);
|
||||
bool packed(void) const;
|
||||
|
||||
|
|
@ -61,13 +66,12 @@ class netstruct_t : public LineInfo, public ivl_type_s {
|
|||
ivl_variable_type_t base_type() const;
|
||||
|
||||
private:
|
||||
bool union_;
|
||||
bool packed_;
|
||||
std::vector<member_t>members_;
|
||||
};
|
||||
|
||||
inline bool netstruct_t::union_flag(void) const { return union_; }
|
||||
inline bool netstruct_t::packed(void) const { return packed_; }
|
||||
|
||||
inline long netstruct_t::member_t::width() const
|
||||
{ return netrange_width(packed_dims); }
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -26,6 +26,15 @@ ivl_type_s::~ivl_type_s()
|
|||
{
|
||||
}
|
||||
|
||||
/*
|
||||
* The derived class may override this to provide a more accurate
|
||||
* response.
|
||||
*/
|
||||
bool ivl_type_s::packed(void) const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
long ivl_type_s::packed_width(void) const
|
||||
{
|
||||
return 1;
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@ class netrange_t;
|
|||
class ivl_type_s {
|
||||
public:
|
||||
virtual ~ivl_type_s() =0;
|
||||
virtual bool packed(void) const;
|
||||
virtual long packed_width(void) const;
|
||||
virtual std::vector<netrange_t> slice_dimensions() const;
|
||||
|
||||
|
|
|
|||
|
|
@ -54,6 +54,14 @@ ivl_variable_type_t netvector_t::base_type() const
|
|||
return type_;
|
||||
}
|
||||
|
||||
/*
|
||||
* vectors are by definition packed.
|
||||
*/
|
||||
bool netvector_t::packed(void) const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
long netvector_t::packed_width() const
|
||||
{
|
||||
return netrange_width(packed_dims_);
|
||||
|
|
|
|||
|
|
@ -60,6 +60,7 @@ class netvector_t : public ivl_type_s {
|
|||
ivl_variable_type_t base_type() const;
|
||||
const std::vector<netrange_t>&packed_dims() const;
|
||||
|
||||
bool packed(void) const;
|
||||
long packed_width() const;
|
||||
std::vector<netrange_t> slice_dimensions() const;
|
||||
|
||||
|
|
@ -89,9 +90,9 @@ class netvector_t : public ivl_type_s {
|
|||
bool is_scalar_ : 1;
|
||||
};
|
||||
|
||||
inline netvector_t::netvector_t(const std::vector<netrange_t>&packed,
|
||||
inline netvector_t::netvector_t(const std::vector<netrange_t>&pd,
|
||||
ivl_variable_type_t type)
|
||||
: packed_dims_(packed), type_(type), signed_(false), isint_(false),
|
||||
: packed_dims_(pd), type_(type), signed_(false), isint_(false),
|
||||
is_scalar_(false)
|
||||
{
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue