ivl: Functions may return dynamic arrays.

This commit is contained in:
Maciej Suminski 2014-12-18 17:38:34 +01:00
parent b6e16aea6b
commit 35401f0e2c
3 changed files with 24 additions and 4 deletions

View File

@ -917,8 +917,10 @@ class PECallFunction : public PExpr {
virtual bool has_aa_term(Design*des, NetScope*scope) const;
virtual NetExpr*elaborate_expr(Design*des, NetScope*scope,
unsigned expr_wid,
unsigned flags) const;
ivl_type_t type, unsigned flags) const;
virtual NetExpr*elaborate_expr(Design*des, NetScope*scope,
unsigned expr_wid, unsigned flags) const;
virtual unsigned test_width(Design*des, NetScope*scope,
width_mode_t&mode);

View File

@ -2181,6 +2181,14 @@ NetExpr* PECallFunction::elaborate_expr(Design*des, NetScope*scope,
return elaborate_base_(des, scope, dscope, expr_wid, flags);
}
NetExpr* PECallFunction::elaborate_expr(Design*des, NetScope*scope,
ivl_type_t type, unsigned flags) const
{
const netdarray_t*darray = dynamic_cast<const netdarray_t*>(type);
assert(darray);
return elaborate_expr(des, scope, darray->element_type()->packed_width(), flags);
}
NetExpr* PECallFunction::elaborate_base_(Design*des, NetScope*scope, NetScope*dscope,
unsigned expr_wid, unsigned flags) const
{
@ -2262,6 +2270,9 @@ NetExpr* PECallFunction::elaborate_base_(Design*des, NetScope*scope, NetScope*ds
NetEUFunc*func = new NetEUFunc(scope, dscope, eres, parms, need_const);
func->set_line(*this);
if(res->darray_type())
return func;
NetExpr*tmp = pad_to_width(func, expr_wid, *this);
tmp->cast_signed(signed_flag_);

View File

@ -2282,11 +2282,18 @@ NetAssign_* PAssign_::elaborate_lval(Design*des, NetScope*scope) const
PExpr::width_mode_t mode = PExpr::SIZED;
rval_->test_width(des, scope, mode);
// Create a L-value that matches the function return type.
NetNet*tmp;
netvector_t*tmp_vec = new netvector_t(rval_->expr_type(),
rval_->expr_width()-1, 0,
rval_->has_sign());
NetNet*tmp = new NetNet(scope, scope->local_symbol(),
NetNet::REG, tmp_vec);
if(rval_->expr_type() == IVL_VT_DARRAY) {
netdarray_t*darray = new netdarray_t(tmp_vec);
tmp = new NetNet(scope, scope->local_symbol(), NetNet::REG, darray);
} else {
tmp = new NetNet(scope, scope->local_symbol(), NetNet::REG, tmp_vec);
}
tmp->set_file(rval_->get_file());
tmp->set_lineno(rval_->get_lineno());
NetAssign_*lv = new NetAssign_(tmp);