Add support for non-constant default subroutine arguments.

Input ports only at the moment. Output "sorry" message for other
port types.
This commit is contained in:
Martin Whitaker 2015-06-20 21:39:45 +01:00
parent b23faff27c
commit 0e66e9781a
3 changed files with 19 additions and 11 deletions

View File

@ -715,16 +715,23 @@ void PTaskFunc::elaborate_sig_ports_(Design*des, NetScope*scope,
continue;
}
// If the port has a default expression that can be used
// as a value when the caller doesn't bind, then
// elaborate that expression here. This expression
// should evaluate down do a constant.
// If the port has a default expression, elaborate
// that expression here.
if (ports_->at(idx).defe != 0) {
tmp_def = elab_and_eval(des, scope, ports_->at(idx).defe, -1, true);
if (tmp_def==0) {
cerr << get_fileline() << ": error: Unable to evaluate "
<< *ports_->at(idx).defe
<< " as a port default (constant) expression." << endl;
if (tmp->port_type() == NetNet::PINPUT) {
tmp_def = elab_and_eval(des, scope, ports_->at(idx).defe,
-1, scope->need_const_func());
if (tmp_def == 0) {
cerr << get_fileline()
<< ": error: Unable to evaluate "
<< *ports_->at(idx).defe
<< " as a port default expression." << endl;
des->errors += 1;
}
} else {
cerr << get_fileline() << ": sorry: Default arguments "
"for subroutine output or inout ports are not "
"yet supported." << endl;
des->errors += 1;
}
}

View File

@ -3740,9 +3740,9 @@ NetProc* PCallTask::elaborate_build_call_(Design*des, NetScope*scope,
} else if (def->port_defe(idx)) {
if (! gn_system_verilog()) {
cerr << get_fileline() << ": internal error: "
cerr << get_fileline() << ": error: "
<< "Found (and using) default task expression "
<< " requires SystemVerilog." << endl;
"requires SystemVerilog." << endl;
des->errors += 1;
}
rv = def->port_defe(idx);

View File

@ -847,6 +847,7 @@ NetFuncDef* Design::find_function(NetScope*scope, const pform_name_t&name)
// the function's signals have been elaborated. If this is
// the case, elaborate them now.
if (func->elab_stage() < 2) {
func->need_const_func(true);
const PFunction*pfunc = func->func_pform();
assert(pfunc);
pfunc->elaborate_sig(this, func);