vlog95: Add support for variable packed array accesses
This commit is contained in:
parent
27b8738d06
commit
2e86c208d1
|
|
@ -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.
|
* 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, "[");
|
fprintf(vlog_out, "[");
|
||||||
emit_scaled_expr(scope, sel_expr, msb, lsb);
|
emit_scaled_expr(scope, sel_expr, msb, lsb);
|
||||||
fprintf(vlog_out, "]");
|
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 {
|
} else {
|
||||||
if (ivl_expr_type(sel_expr) == IVL_EX_NUMBER) {
|
/* An indexed part select. */
|
||||||
/* A constant part select. */
|
emit_expr_ips(scope, sig_expr, sel_expr, sel_type,
|
||||||
emit_select_name(scope, sig_expr, wid);
|
width, msb, lsb);
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
|
|
@ -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,
|
static void emit_stmt_lval_ips(ivl_scope_t scope, ivl_lval_t lval,
|
||||||
ivl_signal_t sig, ivl_expr_t sel_expr,
|
ivl_signal_t sig, ivl_expr_t sel_expr,
|
||||||
ivl_select_type_t sel_type,
|
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, "[");
|
fprintf(vlog_out, "[");
|
||||||
emit_scaled_expr(scope, sel_expr, msb, lsb);
|
emit_scaled_expr(scope, sel_expr, msb, lsb);
|
||||||
fprintf(vlog_out, "]");
|
fprintf(vlog_out, "]");
|
||||||
} else {
|
} else if (ivl_expr_type(sel_expr) == IVL_EX_NUMBER) {
|
||||||
/* A constant part select. */
|
/* A constant part select. */
|
||||||
if (ivl_expr_type(sel_expr) == IVL_EX_NUMBER) {
|
emit_stmt_lval_name(scope, lval, sig);
|
||||||
emit_stmt_lval_name(scope, lval, sig);
|
emit_scaled_range(scope, sel_expr, width, msb, lsb);
|
||||||
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. */
|
/* An indexed part select. */
|
||||||
} else {
|
emit_stmt_lval_ips(scope, lval, sig, sel_expr, sel_type,
|
||||||
assert(sel_type != IVL_SEL_OTHER);
|
width, msb, lsb);
|
||||||
emit_stmt_lval_ips(scope, lval, sig, sel_expr, sel_type,
|
|
||||||
width, msb, lsb);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue