Skip to content
Permalink
Browse files

Cleaner elaboration of void functions.

This fixed githun issue # 281.
  • Loading branch information
steveicarus committed Nov 7, 2019
1 parent a621fa4 commit 7feb26ff6b0e9c392107304195ddd94f2c7be075
Showing with 30 additions and 3 deletions.
  1. +2 −0 Statement.h
  2. +1 −1 elab_lval.cc
  3. +18 −0 elaborate.cc
  4. +7 −0 netlist.h
  5. +2 −2 t-dll.cc
@@ -232,6 +232,8 @@ class PCallTask : public Statement {
NetProc*elaborate_method_(Design*des, NetScope*scope,
bool add_this_flag = false) const;
NetProc*elaborate_function_(Design*des, NetScope*scope) const;
NetProc*elaborate_void_function_(Design*des, NetScope*scope,
NetFuncDef*def) const;

NetProc*elaborate_build_call_(Design*des, NetScope*scope,
NetScope*task, NetExpr*use_this) const;
@@ -204,7 +204,7 @@ NetAssign_* PEIdent::elaborate_lval(Design*des,
print a useful error message. */
if (reg == 0) {
if (use_scope->type()==NetScope::FUNC
&& use_scope->func_def()->return_sig()==0
&& use_scope->func_def()->is_void()
&& use_scope->basename()==peek_tail_name(path_)) {
cerr << get_fileline() << ": error: "
<< "Cannot assign to " << path_
@@ -3672,6 +3672,9 @@ NetProc* PCallTask::elaborate_function_(Design*des, NetScope*scope) const
// call with a missing return assignment.
if (! func) return 0;

if (gn_system_verilog() && func->is_void())
return elaborate_void_function_(des, scope, func);

// Generate a function call version of this task call.
PExpr*rval = new PECallFunction(package_, path_, parms_);
rval->set_file(get_file());
@@ -3686,6 +3689,21 @@ NetProc* PCallTask::elaborate_function_(Design*des, NetScope*scope) const
return tmp->elaborate(des, scope);
}

NetProc* PCallTask::elaborate_void_function_(Design*des, NetScope*scope,
NetFuncDef*def) const
{
NetScope*dscope = def->scope();

if (debug_elaborate) {
cerr << get_fileline() << ": PCallTask::elaborate_void_function_: "
<< "function void " << scope_path(dscope)
<< endl;
}

ivl_assert(*this, dscope->elab_stage() >= 3);
return elaborate_build_call_(des, scope, dscope, 0);
}

NetProc* PCallTask::elaborate_build_call_(Design*des, NetScope*scope,
NetScope*task, NetExpr*use_this) const
{
@@ -3650,6 +3650,13 @@ class NetFuncDef : public NetBaseDef {
const std::vector<NetExpr*>&pd);
~NetFuncDef();

// Return true if the function returns "void". We still treat
// it as a function since we need to check that the contents
// meet the requirements of a function, but we need to know
// that it is void because it can be evaluated differently.
inline bool is_void() const { return result_sig_ == 0; }

// Non-void functions have a return value as a signal.
const NetNet*return_sig() const;

// When we want to evaluate the function during compile time,
@@ -596,14 +596,14 @@ static void fill_in_scope_function(ivl_scope_t scope, const NetScope*net)
const NetFuncDef*def = net->func_def();
assert(def);

const NetNet*return_sig = def->return_sig();
if (return_sig == 0) {
if (def->is_void()) {
// Special case: If there is no return signal, this is
// apparently a VOID function.
scope->func_type = IVL_VT_VOID;
scope->func_signed = 0;
scope->func_width = 0;
} else {
const NetNet*return_sig = def->return_sig();
scope->func_type = return_sig->data_type();
scope->func_signed = return_sig->get_signed();
scope->func_width = return_sig->vector_width();

0 comments on commit 7feb26f

Please sign in to comment.
You can’t perform that action at this time.