vlog95: Add support for emitting global tasks and functions

This commit is contained in:
Cary R 2014-10-13 09:50:42 -07:00
parent da4200c5bd
commit 3fd622e4eb
3 changed files with 46 additions and 4 deletions

View File

@ -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));

View File

@ -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));

View File

@ -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();