Skip to content

Commit 0b40568

Browse files
committed
Generalize struct member type
1 parent aced587 commit 0b40568

File tree

11 files changed

+70
-28
lines changed

11 files changed

+70
-28
lines changed

elab_expr.cc

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1793,7 +1793,9 @@ static NetExpr* check_for_struct_members(const LineInfo*li,
17931793
comp.name, off);
17941794
if (mem == 0) return 0;
17951795

1796-
unsigned use_width = mem->width();
1796+
ivl_assert(*li, mem->net_type && mem->net_type->packed());
1797+
1798+
unsigned use_width = mem->net_type->packed_width();
17971799

17981800
if (debug_elaborate) {
17991801
cerr << li->get_fileline() << ": debug: check_for_struct_members: "
@@ -1805,6 +1807,11 @@ static NetExpr* check_for_struct_members(const LineInfo*li,
18051807
// The struct member may be a packed array. Process index
18061808
// expression that address the member element.
18071809
if ( ! comp.index.empty() ) {
1810+
const netvector_t*mem_vec = dynamic_cast<const netvector_t*> (mem->net_type);
1811+
ivl_assert(*li, mem_vec);
1812+
1813+
const vector<netrange_t>&packed_dims = mem_vec->packed_dims();
1814+
18081815
// Evaluate all but the last index expression, into prefix_indices.
18091816
list<long>prefix_indices;
18101817
bool rc = evaluate_index_prefix(des, scope, prefix_indices, comp.index);
@@ -1814,7 +1821,7 @@ static NetExpr* check_for_struct_members(const LineInfo*li,
18141821
// elements are in fact like bit selects. The tail may
18151822
// be part selects only if we are taking the part-select
18161823
// of the word of an array.
1817-
ivl_assert(*li, comp.index.size() >= mem->packed_dims.size() || comp.index.back().sel == index_component_t::SEL_BIT);
1824+
ivl_assert(*li, comp.index.size() >= packed_dims.size() || comp.index.back().sel == index_component_t::SEL_BIT);
18181825

18191826
// Evaluate the part/bit select expressions. This may be
18201827
// a bit select or a part select. In any case, assume
@@ -1829,7 +1836,7 @@ static NetExpr* check_for_struct_members(const LineInfo*li,
18291836
// offset and width of the addressed slice of the member.
18301837
long loff;
18311838
unsigned long lwid;
1832-
prefix_to_slice(mem->packed_dims, prefix_indices, poff, loff, lwid);
1839+
prefix_to_slice(packed_dims, prefix_indices, poff, loff, lwid);
18331840

18341841
if (debug_elaborate) {
18351842
cerr << li->get_fileline() << ": debug: check_for_struct_members: "
@@ -1838,7 +1845,7 @@ static NetExpr* check_for_struct_members(const LineInfo*li,
18381845
}
18391846

18401847
off += loff;
1841-
if (comp.index.size() >= mem->packed_dims.size())
1848+
if (comp.index.size() >= packed_dims.size())
18421849
use_width = pwid;
18431850
else
18441851
use_width = lwid;
@@ -2920,7 +2927,7 @@ unsigned PEIdent::test_width(Design*des, NetScope*scope, width_mode_t&mode)
29202927
method_name, unused);
29212928
if (mem) {
29222929
expr_type_ = mem->data_type();
2923-
expr_width_ = mem->width();
2930+
expr_width_ = mem->net_type->packed_width();
29242931
min_width_ = expr_width_;
29252932
signed_flag_ = mem->get_signed();
29262933
return expr_width_;

elab_lval.cc

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
# include "netstruct.h"
2828
# include "netclass.h"
2929
# include "netdarray.h"
30+
# include "netvector.h"
3031
# include "compiler.h"
3132
# include <cstdlib>
3233
# include <iostream>
@@ -1014,9 +1015,13 @@ bool PEIdent::elaborate_lval_net_packed_member_(Design*des, NetScope*scope,
10141015
return false;
10151016
}
10161017

1017-
unsigned long use_width = member->width();
1018+
unsigned long use_width = member->net_type->packed_width();
10181019

1019-
if (name_tail.index.size() > member->packed_dims.size()) {
1020+
const netvector_t*mem_vec = dynamic_cast<const netvector_t*>(member->net_type);
1021+
ivl_assert(*this, mem_vec);
1022+
const vector<netrange_t>&mem_packed_dims = mem_vec->packed_dims();
1023+
1024+
if (name_tail.index.size() > mem_packed_dims.size()) {
10201025
cerr << get_fileline() << ": error: Too many index expressions for member." << endl;
10211026
des->errors += 1;
10221027
return false;
@@ -1052,7 +1057,7 @@ bool PEIdent::elaborate_lval_net_packed_member_(Design*des, NetScope*scope,
10521057
// offset and width of the addressed slice of the member.
10531058
long loff;
10541059
unsigned long lwid;
1055-
prefix_to_slice(member->packed_dims, prefix_indices, tmp, loff, lwid);
1060+
prefix_to_slice(mem_packed_dims, prefix_indices, tmp, loff, lwid);
10561061

10571062
off += loff;
10581063
use_width = lwid;

elab_net.cc

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -524,15 +524,15 @@ NetNet* PEIdent::elaborate_lnet_common_(Design*des, NetScope*scope,
524524
if (debug_elaborate) {
525525
cerr << get_fileline() << ": PEIdent::elaborate_lnet_common_: "
526526
<< "Member " << method_name
527-
<< " has packed dimensions " << member->packed_dims << "." << endl;
527+
<< " has type " << *member->net_type << "." << endl;
528528
cerr << get_fileline() << ": : "
529529
<< "Tail name has " << path_tail.index.size() << " indices." << endl;
530530
}
531531

532532
// Rewrite a member select of a packed structure as a
533533
// part select of the base variable.
534534
lidx = member_off;
535-
midx = lidx + member->width() - 1;
535+
midx = lidx + member->net_type->packed_width() - 1;
536536

537537
// The dimensions of the tail of the prefix must match
538538
// the dimensions of the signal at this point. (The sig
@@ -563,7 +563,7 @@ NetNet* PEIdent::elaborate_lnet_common_(Design*des, NetScope*scope,
563563
long tmp;
564564
if (packed_base && eval_as_long(tmp, packed_base)) {
565565
lidx = tmp;
566-
midx = lidx + member->width() - 1;
566+
midx = lidx + member->net_type->packed_width() - 1;
567567
delete packed_base;
568568
packed_base = 0;
569569
}
@@ -574,7 +574,7 @@ NetNet* PEIdent::elaborate_lnet_common_(Design*des, NetScope*scope,
574574
// Now the lidx/midx values get us to the member. Next
575575
// up, deal with bit/part selects from the member
576576
// itself.
577-
ivl_assert(*this, member->packed_dims.size() <= 1);
577+
//XXXXivl_assert(*this, member->packed_dims.size() <= 1);
578578
ivl_assert(*this, path_tail.index.size() <= 1);
579579
if (! path_tail.index.empty()) {
580580
long tmp_off;

elab_sig.cc

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -894,14 +894,15 @@ static netstruct_t* elaborate_struct_type(Design*des, NetScope*scope,
894894
packed_dimensions.push_back(netrange_t(0,0));
895895
}
896896

897+
netvector_t*mem_vec = new netvector_t(packed_dimensions, curp->type);
898+
897899
for (list<decl_assignment_t*>::iterator name = curp->names->begin()
898900
; name != curp->names->end() ; ++ name) {
899901
decl_assignment_t*namep = *name;
900902

901903
netstruct_t::member_t memb;
902904
memb.name = namep->name;
903-
memb.type = curp->type;
904-
memb.packed_dims = packed_dimensions;
905+
memb.net_type = mem_vec;
905906
res->append_member(memb);
906907
}
907908
}

netparray.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,9 +47,9 @@ class netparray_t : public netarray_t {
4747

4848
};
4949

50-
inline netparray_t::netparray_t(const std::vector<netrange_t>&packed,
50+
inline netparray_t::netparray_t(const std::vector<netrange_t>&pd,
5151
ivl_type_t etype)
52-
: netarray_t(etype), packed_dims_(packed)
52+
: netarray_t(etype), packed_dims_(pd)
5353
{
5454
}
5555

netstruct.cc

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,19 +18,25 @@
1818
*/
1919

2020
# include "netstruct.h"
21+
# include "netvector.h"
2122
# include <iostream>
2223

2324
using namespace std;
2425

2526
netstruct_t::netstruct_t()
26-
: packed_(false)
27+
: union_(false), packed_(false)
2728
{
2829
}
2930

3031
netstruct_t::~netstruct_t()
3132
{
3233
}
3334

35+
void netstruct_t::union_flag(bool flag)
36+
{
37+
union_ = flag;
38+
}
39+
3440
void netstruct_t::packed(bool flag)
3541
{
3642
packed_ = flag;
@@ -49,7 +55,7 @@ const netstruct_t::member_t* netstruct_t::packed_member(perm_string name, unsign
4955
off = count_off;
5056
return &members_[idx-1];
5157
}
52-
count_off += members_[idx-1].width();
58+
count_off += members_[idx-1].net_type->packed_width();
5359
}
5460

5561
return 0;
@@ -62,7 +68,7 @@ long netstruct_t::packed_width(void) const
6268

6369
long res = 0;
6470
for (size_t idx = 0 ; idx < members_.size() ; idx += 1)
65-
res += members_[idx].width();
71+
res += members_[idx].net_type->packed_width();
6672

6773
return res;
6874
}

netstruct.h

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,9 @@ class netstruct_t : public LineInfo, public ivl_type_s {
2929
public:
3030
struct member_t {
3131
perm_string name;
32-
ivl_variable_type_t type;
33-
std::vector<netrange_t> packed_dims;
34-
long width() const;
35-
ivl_variable_type_t data_type() const { return type; };
32+
ivl_type_t net_type;
33+
inline ivl_variable_type_t data_type() const
34+
{ return net_type->base_type(); };
3635
// We need to keep the individual element sign information.
3736
bool get_signed() const { return false; };
3837
};
@@ -41,6 +40,12 @@ class netstruct_t : public LineInfo, public ivl_type_s {
4140
netstruct_t();
4241
~netstruct_t();
4342

43+
// If this is a union (instead of struct) then this flag is
44+
// set. We handle union and struct together because they are
45+
// so similar.
46+
void union_flag(bool);
47+
bool union_flag(void) const;
48+
4449
void packed(bool flag);
4550
bool packed(void) const;
4651

@@ -61,13 +66,12 @@ class netstruct_t : public LineInfo, public ivl_type_s {
6166
ivl_variable_type_t base_type() const;
6267

6368
private:
69+
bool union_;
6470
bool packed_;
6571
std::vector<member_t>members_;
6672
};
6773

74+
inline bool netstruct_t::union_flag(void) const { return union_; }
6875
inline bool netstruct_t::packed(void) const { return packed_; }
6976

70-
inline long netstruct_t::member_t::width() const
71-
{ return netrange_width(packed_dims); }
72-
7377
#endif

nettypes.cc

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,15 @@ ivl_type_s::~ivl_type_s()
2626
{
2727
}
2828

29+
/*
30+
* The derived class may override this to provide a more accurate
31+
* response.
32+
*/
33+
bool ivl_type_s::packed(void) const
34+
{
35+
return false;
36+
}
37+
2938
long ivl_type_s::packed_width(void) const
3039
{
3140
return 1;

nettypes.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ class netrange_t;
3535
class ivl_type_s {
3636
public:
3737
virtual ~ivl_type_s() =0;
38+
virtual bool packed(void) const;
3839
virtual long packed_width(void) const;
3940
virtual std::vector<netrange_t> slice_dimensions() const;
4041

netvector.cc

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,14 @@ ivl_variable_type_t netvector_t::base_type() const
5454
return type_;
5555
}
5656

57+
/*
58+
* vectors are by definition packed.
59+
*/
60+
bool netvector_t::packed(void) const
61+
{
62+
return true;
63+
}
64+
5765
long netvector_t::packed_width() const
5866
{
5967
return netrange_width(packed_dims_);

netvector.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ class netvector_t : public ivl_type_s {
6060
ivl_variable_type_t base_type() const;
6161
const std::vector<netrange_t>&packed_dims() const;
6262

63+
bool packed(void) const;
6364
long packed_width() const;
6465
std::vector<netrange_t> slice_dimensions() const;
6566

@@ -89,9 +90,9 @@ class netvector_t : public ivl_type_s {
8990
bool is_scalar_ : 1;
9091
};
9192

92-
inline netvector_t::netvector_t(const std::vector<netrange_t>&packed,
93+
inline netvector_t::netvector_t(const std::vector<netrange_t>&pd,
9394
ivl_variable_type_t type)
94-
: packed_dims_(packed), type_(type), signed_(false), isint_(false),
95+
: packed_dims_(pd), type_(type), signed_(false), isint_(false),
9596
is_scalar_(false)
9697
{
9798
}

0 commit comments

Comments
 (0)