Generate a vhdl_var_ref for every assignment lval
This completes the refactoring of make_assignment necessary to implement multiple lvals.
This commit is contained in:
parent
fad8abee34
commit
c706c94e38
112
tgt-vhdl/stmt.cc
112
tgt-vhdl/stmt.cc
|
|
@ -92,8 +92,7 @@ static int draw_block(vhdl_procedural *proc, stmt_container *container,
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* A no-op statement. This corresponds to a `null' statement in
|
* A no-op statement. This corresponds to a `null' statement in VHDL.
|
||||||
* VHDL.
|
|
||||||
*/
|
*/
|
||||||
static int draw_noop(vhdl_procedural *proc, stmt_container *container,
|
static int draw_noop(vhdl_procedural *proc, stmt_container *container,
|
||||||
ivl_statement_t stmt)
|
ivl_statement_t stmt)
|
||||||
|
|
@ -102,40 +101,6 @@ static int draw_noop(vhdl_procedural *proc, stmt_container *container,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static vhdl_expr *make_assign_rhs(ivl_signal_t sig, vhdl_scope *scope,
|
|
||||||
ivl_expr_t e, vhdl_expr *base,
|
|
||||||
int lval_width)
|
|
||||||
{
|
|
||||||
string signame(get_renamed_signal(sig));
|
|
||||||
|
|
||||||
vhdl_decl *decl = scope->get_decl(signame);
|
|
||||||
assert(decl);
|
|
||||||
|
|
||||||
vhdl_expr *rhs = translate_expr(e);
|
|
||||||
if (rhs == NULL)
|
|
||||||
return rhs;
|
|
||||||
|
|
||||||
if (base == NULL)
|
|
||||||
return rhs->cast(decl->get_type());
|
|
||||||
else if (decl->get_type()->get_name() == VHDL_TYPE_ARRAY)
|
|
||||||
return rhs->cast(decl->get_type()->get_base());
|
|
||||||
else {
|
|
||||||
// Doesn't make sense to part select on something that's
|
|
||||||
// not a vector
|
|
||||||
vhdl_type_name_t tname = decl->get_type()->get_name();
|
|
||||||
assert(tname == VHDL_TYPE_SIGNED || tname == VHDL_TYPE_UNSIGNED);
|
|
||||||
|
|
||||||
if (lval_width == 1) {
|
|
||||||
vhdl_type t(VHDL_TYPE_STD_LOGIC);
|
|
||||||
return rhs->cast(&t);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
vhdl_type t(tname, lval_width - 1);
|
|
||||||
return rhs->cast(&t);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static vhdl_var_ref *make_assign_lhs(ivl_signal_t sig, vhdl_scope *scope,
|
static vhdl_var_ref *make_assign_lhs(ivl_signal_t sig, vhdl_scope *scope,
|
||||||
vhdl_expr *base, int lval_width)
|
vhdl_expr *base, int lval_width)
|
||||||
{
|
{
|
||||||
|
|
@ -154,28 +119,18 @@ static vhdl_var_ref *make_assign_lhs(ivl_signal_t sig, vhdl_scope *scope,
|
||||||
return lval_ref;
|
return lval_ref;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
static bool assignment_lvals(ivl_statement_t stmt, vhdl_procedural *proc,
|
||||||
* Generate an assignment of type T for the Verilog statement stmt.
|
list<vhdl_var_ref*> &lvals)
|
||||||
*/
|
|
||||||
template <class T>
|
|
||||||
void make_assignment(vhdl_procedural *proc, stmt_container *container,
|
|
||||||
ivl_statement_t stmt, bool blocking, vhdl_expr *after)
|
|
||||||
{
|
{
|
||||||
int nlvals = ivl_stmt_lvals(stmt);
|
int nlvals = ivl_stmt_lvals(stmt);
|
||||||
if (nlvals != 1) {
|
|
||||||
error("Can only have 1 lval at the moment (found %d)", nlvals);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
vhdl_expr *rhs = translate_expr(ivl_stmt_rval(stmt));
|
|
||||||
// make_assign_rhs(sig, proc->get_scope(), rval, base, lval_width);
|
|
||||||
if (NULL == rhs)
|
|
||||||
return;
|
|
||||||
|
|
||||||
for (int i = 0; i < nlvals; i++) {
|
for (int i = 0; i < nlvals; i++) {
|
||||||
ivl_lval_t lval = ivl_stmt_lval(stmt, 0);
|
ivl_lval_t lval = ivl_stmt_lval(stmt, i);
|
||||||
ivl_signal_t sig;
|
|
||||||
if ((sig = ivl_lval_sig(lval))) {
|
ivl_signal_t sig = ivl_lval_sig(lval);
|
||||||
|
if (!sig) {
|
||||||
|
error("Only signals as lvals supported at the moment");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
vhdl_expr *base = NULL;
|
vhdl_expr *base = NULL;
|
||||||
ivl_expr_t e_off = ivl_lval_part_off(lval);
|
ivl_expr_t e_off = ivl_lval_part_off(lval);
|
||||||
|
|
@ -183,7 +138,7 @@ void make_assignment(vhdl_procedural *proc, stmt_container *container,
|
||||||
e_off = ivl_lval_idx(lval);
|
e_off = ivl_lval_idx(lval);
|
||||||
if (e_off) {
|
if (e_off) {
|
||||||
if ((base = translate_expr(e_off)) == NULL)
|
if ((base = translate_expr(e_off)) == NULL)
|
||||||
return;
|
return false;
|
||||||
|
|
||||||
vhdl_type integer(VHDL_TYPE_INTEGER);
|
vhdl_type integer(VHDL_TYPE_INTEGER);
|
||||||
base = base->cast(&integer);
|
base = base->cast(&integer);
|
||||||
|
|
@ -192,7 +147,31 @@ void make_assignment(vhdl_procedural *proc, stmt_container *container,
|
||||||
unsigned lval_width = ivl_lval_width(lval);
|
unsigned lval_width = ivl_lval_width(lval);
|
||||||
|
|
||||||
string signame(get_renamed_signal(sig));
|
string signame(get_renamed_signal(sig));
|
||||||
vhdl_decl *decl = proc->get_scope()->get_decl(signame);
|
|
||||||
|
lvals.push_back(make_assign_lhs(sig, proc->get_scope(), base, lval_width));
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Generate an assignment of type T for the Verilog statement stmt.
|
||||||
|
*/
|
||||||
|
template <class T>
|
||||||
|
void make_assignment(vhdl_procedural *proc, stmt_container *container,
|
||||||
|
ivl_statement_t stmt, bool blocking, vhdl_expr *after)
|
||||||
|
{
|
||||||
|
list<vhdl_var_ref*> lvals;
|
||||||
|
if (!assignment_lvals(stmt, proc, lvals))
|
||||||
|
return;
|
||||||
|
|
||||||
|
vhdl_expr *rhs;
|
||||||
|
if ((rhs = translate_expr(ivl_stmt_rval(stmt))) == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (lvals.size() == 1) {
|
||||||
|
vhdl_var_ref *lhs = lvals.front();
|
||||||
|
rhs = rhs->cast(lhs->get_type());
|
||||||
|
|
||||||
// Where possible, move constant assignments into the
|
// Where possible, move constant assignments into the
|
||||||
// declaration as initializers. This optimisation is only
|
// declaration as initializers. This optimisation is only
|
||||||
|
|
@ -208,12 +187,13 @@ void make_assignment(vhdl_procedural *proc, stmt_container *container,
|
||||||
// `always' process may then use the uninitialized signal value.
|
// `always' process may then use the uninitialized signal value.
|
||||||
// The second test ensures that we only try to initialise
|
// The second test ensures that we only try to initialise
|
||||||
// internal signals not ports
|
// internal signals not ports
|
||||||
|
ivl_lval_t lval = ivl_stmt_lval(stmt, 0);
|
||||||
|
vhdl_decl *decl = proc->get_scope()->get_decl(lhs->get_name());
|
||||||
if (proc->get_scope()->initializing()
|
if (proc->get_scope()->initializing()
|
||||||
&& ivl_signal_port(sig) == IVL_SIP_NONE
|
&& ivl_signal_port(ivl_lval_sig(lval)) == IVL_SIP_NONE
|
||||||
&& !decl->has_initial()
|
&& !decl->has_initial()
|
||||||
&& rhs->constant()
|
&& rhs->constant()
|
||||||
&& decl->get_type()->get_name() != VHDL_TYPE_ARRAY
|
&& decl->get_type()->get_name() != VHDL_TYPE_ARRAY) {
|
||||||
&& nlvals == 1) {
|
|
||||||
|
|
||||||
// If this assignment is not in the top-level container
|
// If this assignment is not in the top-level container
|
||||||
// it will not be made on all paths through the code
|
// it will not be made on all paths through the code
|
||||||
|
|
@ -222,14 +202,12 @@ void make_assignment(vhdl_procedural *proc, stmt_container *container,
|
||||||
decl->set_initial(NULL); // Default initial value
|
decl->set_initial(NULL); // Default initial value
|
||||||
else {
|
else {
|
||||||
decl->set_initial(rhs);
|
decl->set_initial(rhs);
|
||||||
|
delete lhs;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
vhdl_var_ref *lval_ref =
|
T *a = new T(lhs, rhs);
|
||||||
make_assign_lhs(sig, proc->get_scope(), base, lval_width);
|
|
||||||
|
|
||||||
T *a = new T(lval_ref, rhs);
|
|
||||||
container->add_stmt(a);
|
container->add_stmt(a);
|
||||||
|
|
||||||
ivl_expr_t i_delay;
|
ivl_expr_t i_delay;
|
||||||
|
|
@ -238,13 +216,9 @@ void make_assignment(vhdl_procedural *proc, stmt_container *container,
|
||||||
|
|
||||||
if (after != NULL)
|
if (after != NULL)
|
||||||
a->set_after(after);
|
a->set_after(after);
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
error("Only signals as lvals supported at the moment");
|
assert(false);
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue