diff --git a/tgt-vlog95/misc.c b/tgt-vlog95/misc.c index 7b2f96119..8787c0302 100644 --- a/tgt-vlog95/misc.c +++ b/tgt-vlog95/misc.c @@ -816,8 +816,12 @@ void emit_scope_module_path(ivl_scope_t scope, ivl_scope_t call_scope) * references for variables, etc. */ void emit_scope_call_path(ivl_scope_t scope, ivl_scope_t call_scope) { - ivl_scope_t mod_scope = get_module_scope(scope); - ivl_scope_t call_mod_scope = get_module_scope(call_scope); + ivl_scope_t mod_scope, call_mod_scope; + + if (scope == call_scope) return; + + mod_scope = get_module_scope(scope); + call_mod_scope = get_module_scope(call_scope); if (mod_scope != call_mod_scope) { emit_scope_piece(mod_scope, call_mod_scope); @@ -864,8 +868,17 @@ static void emit_scope_path_piece(ivl_scope_t scope, ivl_scope_t call_scope) */ void emit_scope_path(ivl_scope_t scope, ivl_scope_t call_scope) { - ivl_scope_t mod_scope = get_module_scope(scope); - ivl_scope_t call_mod_scope = get_module_scope(call_scope); + ivl_scope_t mod_scope, call_mod_scope; + + /* Check to see if this is a root scope task or function. */ + if (ivl_scope_parent(call_scope) == 0) { + fprintf(vlog_out, "ivl_root_scope."); + mod_scope = 0; + call_mod_scope = 0; + } else { + mod_scope = get_module_scope(scope); + call_mod_scope = get_module_scope(call_scope); + } if (mod_scope == call_mod_scope) { emit_id(ivl_scope_basename(call_scope)); diff --git a/tgt-vlog95/scope.c b/tgt-vlog95/scope.c index e6dd88efa..e5043fa77 100644 --- a/tgt-vlog95/scope.c +++ b/tgt-vlog95/scope.c @@ -1055,6 +1055,8 @@ int emit_scope(ivl_scope_t scope, ivl_scope_t parent) emit_module_ports(scope); break; case IVL_SCT_FUNCTION: + /* Root scope functions have already been emitted. */ + if (! parent) return 0; assert(indent != 0); fprintf(vlog_out, "\n%*cfunction", indent, ' '); if (ivl_scope_ports(scope) < 1) { @@ -1077,6 +1079,8 @@ int emit_scope(ivl_scope_t scope, ivl_scope_t parent) } break; case IVL_SCT_TASK: + /* Root scope tasks have already been emitted. */ + if (! parent) return 0; assert(indent != 0); fprintf(vlog_out, "\n%*ctask ", indent, ' '); emit_id(ivl_scope_tname(scope)); diff --git a/tgt-vlog95/vlog95.c b/tgt-vlog95/vlog95.c index dcd893570..1765b9468 100644 --- a/tgt-vlog95/vlog95.c +++ b/tgt-vlog95/vlog95.c @@ -60,6 +60,7 @@ int target_design(ivl_design_t des) { ivl_scope_t *roots; unsigned nroots, idx; + unsigned has_root_scope = 0; const char*path = ivl_design_flag(des, "-o"); /* Set the indent spacing with the -pspacing flag passed to iverilog * (e.g. -pspacing=4). The default is 2 spaces. */ @@ -184,6 +185,30 @@ int target_design(ivl_design_t des) /* Get all the root modules and then convert each one. */ ivl_design_roots(des, &roots, &nroots); + /* Emit any root scope tasks or functions first. */ + for (idx = 0; idx < nroots; idx += 1) { + switch(ivl_scope_type(roots[idx])) { + case IVL_SCT_FUNCTION: + case IVL_SCT_TASK: + if (! has_root_scope) { + fprintf(vlog_out, "module ivl_root_scope;\n"); + indent += indent_incr; + has_root_scope = 1; + } + /* Say this task/function has a parent so the + * definition is emitted correctly. */ + emit_scope(roots[idx], roots[idx]); + break; + default: + break; + } + } + if (has_root_scope) { + indent -= indent_incr; + assert(indent == 0); + fprintf(vlog_out, "endmodule /* ivl_root_scope */\n"); + } + /* Emit the rest of the scope objets. */ for (idx = 0; idx < nroots; idx += 1) emit_scope(roots[idx], 0); free_emitted_scope_list();