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