vlog95: Add support for variable packed array accesses

This commit is contained in:
Cary R 2013-02-20 22:07:00 -08:00
parent 27b8738d06
commit 2e86c208d1
2 changed files with 62 additions and 20 deletions

View File

@ -331,6 +331,27 @@ static void emit_select_name(ivl_scope_t scope, ivl_expr_t expr, unsigned wid)
}
}
/*
* Emit a packed array access as a concatenation of bit selects.
*/
static void emit_expr_packed(ivl_scope_t scope, ivl_expr_t sig_expr,
ivl_expr_t sel_expr, unsigned wid)
{
unsigned idx;
assert(wid > 0);
fprintf(vlog_out, "{");
for (idx = wid - 1; idx > 0; idx -= 1) {
emit_select_name(scope, sig_expr, wid);
fprintf(vlog_out, "[");
emit_expr(scope, sel_expr, 0);
fprintf(vlog_out, " + %u], ", idx);
}
emit_select_name(scope, sig_expr, wid);
fprintf(vlog_out, "[");
emit_expr(scope, sel_expr, 0);
fprintf(vlog_out, "]}");
}
/*
* Emit an indexed part select as a concatenation of bit selects.
*/
@ -444,18 +465,19 @@ static void emit_expr_select(ivl_scope_t scope, ivl_expr_t expr, unsigned wid)
fprintf(vlog_out, "[");
emit_scaled_expr(scope, sel_expr, msb, lsb);
fprintf(vlog_out, "]");
} else if (ivl_expr_type(sel_expr) == IVL_EX_NUMBER) {
/* A constant part select. */
emit_select_name(scope, sig_expr, wid);
emit_scaled_range(scope, sel_expr, width, msb, lsb);
} else if (sel_type == IVL_SEL_OTHER) {
/* A packed array access. */
assert(lsb == 0);
assert(msb >= 0);
emit_expr_packed(scope, sig_expr, sel_expr, width);
} else {
if (ivl_expr_type(sel_expr) == IVL_EX_NUMBER) {
/* A constant part select. */
emit_select_name(scope, sig_expr, wid);
emit_scaled_range(scope, sel_expr, width,
msb, lsb);
} else {
/* An indexed part select. */
assert(sel_type != IVL_SEL_OTHER);
emit_expr_ips(scope, sig_expr, sel_expr,
sel_type, width, msb, lsb);
}
/* An indexed part select. */
emit_expr_ips(scope, sig_expr, sel_expr, sel_type,
width, msb, lsb);
}
}
} else {

View File

@ -105,6 +105,25 @@ static void emit_stmt_lval_name(ivl_scope_t scope, ivl_lval_t lval,
}
}
static void emit_stmt_lval_packed(ivl_scope_t scope, ivl_lval_t lval,
ivl_signal_t sig, ivl_expr_t sel_expr,
unsigned wid)
{
unsigned idx;
assert(wid > 0);
fprintf(vlog_out, "{");
for (idx = wid - 1; idx > 0; idx -= 1) {
emit_stmt_lval_name(scope, lval, sig);
fprintf(vlog_out, "[");
emit_expr(scope, sel_expr, 0);
fprintf(vlog_out, " + %u], ", idx);
}
emit_stmt_lval_name(scope, lval, sig);
fprintf(vlog_out, "[");
emit_expr(scope, sel_expr, 0);
fprintf(vlog_out, "]}");
}
static void emit_stmt_lval_ips(ivl_scope_t scope, ivl_lval_t lval,
ivl_signal_t sig, ivl_expr_t sel_expr,
ivl_select_type_t sel_type,
@ -245,17 +264,18 @@ static void emit_stmt_lval_piece(ivl_scope_t scope, ivl_lval_t lval)
fprintf(vlog_out, "[");
emit_scaled_expr(scope, sel_expr, msb, lsb);
fprintf(vlog_out, "]");
} else {
} else if (ivl_expr_type(sel_expr) == IVL_EX_NUMBER) {
/* A constant part select. */
if (ivl_expr_type(sel_expr) == IVL_EX_NUMBER) {
emit_stmt_lval_name(scope, lval, sig);
emit_scaled_range(scope, sel_expr, width, msb, lsb);
emit_stmt_lval_name(scope, lval, sig);
emit_scaled_range(scope, sel_expr, width, msb, lsb);
} else if (sel_type == IVL_SEL_OTHER) {
assert(lsb == 0);
assert(msb >= 0);
emit_stmt_lval_packed(scope, lval, sig, sel_expr, width);
} else {
/* An indexed part select. */
} else {
assert(sel_type != IVL_SEL_OTHER);
emit_stmt_lval_ips(scope, lval, sig, sel_expr, sel_type,
width, msb, lsb);
}
emit_stmt_lval_ips(scope, lval, sig, sel_expr, sel_type,
width, msb, lsb);
}
}