Skip to content

Commit

Permalink
Convert group_array_ref to use group_calc_offset
Browse files Browse the repository at this point in the history
  • Loading branch information
nickg committed Sep 28, 2014
1 parent 1813e7f commit 93c622a
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 75 deletions.
114 changes: 49 additions & 65 deletions src/group.c
Original file line number Diff line number Diff line change
Expand Up @@ -208,70 +208,6 @@ static int64_t rebase_index(type_t array_type, int dim, int64_t value)
return (r.kind == RANGE_TO) ? value - left : left - value;
}

static void group_array_ref(tree_t target, group_nets_ctx_t *ctx)
{
tree_t value = tree_value(target);

switch (tree_kind(value)) {
case T_REF:
{
type_t type = tree_type(value);
if (type_is_unconstrained(type))
return;

const int width = type_width(type);
const int stride = type_width(type_elem(type));

if (tree_params(target) == 1) {
tree_t index = tree_value(tree_param(target, 0));

if (tree_kind(index) == T_LITERAL) {
const int64_t offset =
stride * rebase_index(type, 0, assume_int(index));
group_ref(value, ctx, offset, stride);
}
else {
for (int i = 0; i < width; i += stride)
group_ref(value, ctx, i, stride);
}
}
else {
// Ungroup multi-dimensional arrays
// TODO: this is inefficient
for (int i = 0; i < width; i += stride)
group_ref(value, ctx, i, stride);
}
}
break;

case T_ARRAY_REF:
case T_ARRAY_SLICE:
{
// We could handle this better but for now just map each
// net to a single group
while (tree_kind(value) != T_REF)
value = tree_value(value);

tree_t decl = tree_ref(value);
if (tree_kind(decl) != T_SIGNAL_DECL)
return;

const int nnets = tree_nets(decl);
for (int i = 0; i < nnets; i++)
group_add(ctx, tree_net(decl, i), 1);
}
break;

case T_AGGREGATE:
// This can appear due to assignments to open ports with a
// default value
break;

default:
assert(false);
}
}

static bool group_calc_offset(tree_t t, int *offset, tree_t *ref)
{
switch (tree_kind(t)) {
Expand Down Expand Up @@ -302,17 +238,65 @@ static bool group_calc_offset(tree_t t, int *offset, tree_t *ref)
return true;
}

case T_AGGREGATE:
// This can appear due to assignments to open ports with a
// default value
*offset = 0;
*ref = NULL;
return false;

default:
fatal_at(tree_loc(t), "tree kind %s not yet supported for offset "
"calculation", tree_kind_str(tree_kind(t)));
}
}

static void group_array_ref(tree_t target, group_nets_ctx_t *ctx)
{
tree_t value = tree_value(target);

type_t type = tree_type(value);
if (type_is_unconstrained(type))
return; // Only in procedure

const int width = type_width(type);
const int stride = type_width(type_elem(type));

tree_t ref = NULL;
int offset;
if (group_calc_offset(value, &offset, &ref)) {
if (tree_params(target) == 1) {
tree_t index = tree_value(tree_param(target, 0));

if (tree_kind(index) == T_LITERAL) {
const int64_t indexi =
stride * rebase_index(type, 0, assume_int(index));
group_ref(ref, ctx, offset + indexi, stride);
}
else {
for (int i = 0; i < width; i += stride)
group_ref(ref, ctx, offset + i, stride);
}
}
else {
// Ungroup multi-dimensional arrays
// TODO: this is inefficient
for (int i = 0; i < width; i += stride)
group_ref(ref, ctx, offset + i, stride);
}
}
else if (ref != NULL)
ungroup_ref(ref, ctx);
}

static void group_array_slice(tree_t target, group_nets_ctx_t *ctx)
{
tree_t value = tree_value(target);
type_t type = tree_type(value);

if (type_is_unconstrained(type))
return; // Only in procedure

range_t slice = tree_range(target);

const bool folded =
Expand All @@ -331,7 +315,7 @@ static void group_array_slice(tree_t target, group_nets_ctx_t *ctx)

group_ref(ref, ctx, offset + (low0 * stride), length * stride);
}
else
else if (ref != NULL)
ungroup_ref(ref, ctx);
}

Expand Down
5 changes: 4 additions & 1 deletion test/group/arrayref1.vhd
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ architecture test of arrayref is
signal y : bit_vector(1 downto 0); -- 3..4
signal i : integer; -- 5..5
signal p : bv2d(0 to 1); -- 6..9
signal q : bv2d(0 to 1); -- 10..13
signal q : bv2d(0 to 2); -- 10..15
signal r : bv2d(0 to 2); -- 16..21
begin

x(0) <= '1';
Expand All @@ -21,4 +22,6 @@ begin

q(i) <= "10";

r(2)(i) <= '1';

end architecture;
21 changes: 12 additions & 9 deletions test/test_group.c
Original file line number Diff line number Diff line change
Expand Up @@ -93,10 +93,7 @@ static void group_expect(group_nets_ctx_t *ctx, const group_expect_t *expect,
for (group_t *it = ctx->groups; it != NULL; it = it->next)
ngroups++;

if (ngroups != n_expect) {
group_dump(ctx);
fail("expected %d groups but have %d", n_expect, ngroups);
}
const int n_expect_orig = n_expect;

for (; n_expect-- > 0; expect++) {
const int length = expect->last - expect->first + 1;
Expand All @@ -112,6 +109,11 @@ static void group_expect(group_nets_ctx_t *ctx, const group_expect_t *expect,
fail("missing expected group %d..%d", expect->first, expect->last);
}
}

if (ngroups != n_expect_orig) {
group_dump(ctx);
fail("expected %d groups but have %d", n_expect_orig, ngroups);
}
}

START_TEST(test_group_one)
Expand Down Expand Up @@ -291,11 +293,12 @@ START_TEST(test_arrayref1)
fail_unless(group_sanity_check(&ctx, nnets - 1));

const group_expect_t expect[] = {
{ 1, 1 }, { 0, 0 }, { 2, 2 }, // X
{ 3, 3 }, { 4, 4 }, // Y
{ 5, 5 }, // I
{ 6, 6 }, { 7, 7 }, { 8, 8 }, { 9, 9 }, // P (sub-optimal!)
{ 10, 11 }, { 12, 13 } // Q
{ 1, 1 }, { 0, 0 }, { 2, 2 }, // X
{ 3, 3 }, { 4, 4 }, // Y
{ 5, 5 }, // I
{ 6, 6 }, { 7, 7 }, { 8, 9 }, // P
{ 10, 11 }, { 12, 13 }, { 14, 15 }, // Q
{ 16, 19 }, { 21, 21 }, { 20, 20 } // R
};

group_expect(&ctx, expect, ARRAY_LEN(expect));
Expand Down

0 comments on commit 93c622a

Please sign in to comment.