From 5d9a196819633ed495ccd646c307900b16a379b5 Mon Sep 17 00:00:00 2001 From: Martin Whitaker Date: Sat, 12 Mar 2016 23:06:54 +0000 Subject: [PATCH] tgt-vlog95: Handle variable initialisation in named blocks. --- tgt-vlog95/scope.c | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/tgt-vlog95/scope.c b/tgt-vlog95/scope.c index 1f939d8d2..c4b8278d9 100644 --- a/tgt-vlog95/scope.c +++ b/tgt-vlog95/scope.c @@ -710,13 +710,16 @@ static void emit_named_block_scope(ivl_scope_t scope) * variables. In reality SystemVerilog requires this to be before the * initial/always blocks are processed, but that's not how it is currently * implemented in Icarus! + * + * In Verilog-2001 a named block can also have a process to initialize + * variables. This is handled the same way. */ -static int find_tf_process(ivl_process_t proc, ivl_scope_t scope) +static int find_tfb_process(ivl_process_t proc, ivl_scope_t scope) { if (scope == ivl_process_scope(proc)) { ivl_scope_t mod_scope = scope; - /* A task or function can only have initial processes that - * are used to set local variables. */ + /* A task or function or named block can only have initial + * processes that are used to set local variables. */ assert(ivl_process_type(proc) == IVL_PR_INITIAL); /* Find the module scope for this task/function. */ while (ivl_scope_type(mod_scope) != IVL_SCT_MODULE) { @@ -731,15 +734,16 @@ static int find_tf_process(ivl_process_t proc, ivl_scope_t scope) } /* - * Emit any initial blocks for the tasks or functions in a module. + * Emit any initial blocks for the tasks/functions/named blocks in a module. */ -static int emit_tf_process(ivl_scope_t scope, ivl_scope_t parent) +static int emit_tfb_process(ivl_scope_t scope, ivl_scope_t parent) { ivl_scope_type_t sc_type = ivl_scope_type(scope); (void)parent; /* Parameter is not used. */ - if ((sc_type == IVL_SCT_FUNCTION) || (sc_type == IVL_SCT_TASK)) { + if ((sc_type == IVL_SCT_FUNCTION) || (sc_type == IVL_SCT_TASK) || + (sc_type == IVL_SCT_BEGIN) || (sc_type == IVL_SCT_FORK)) { /* Output the initial/always blocks for this module. */ - ivl_design_process(design, (ivl_process_f)find_tf_process, scope); + ivl_design_process(design, (ivl_process_f)find_tfb_process, scope); } return 0; } @@ -1172,9 +1176,10 @@ int emit_scope(ivl_scope_t scope, ivl_scope_t parent) emit_tran(scope, ivl_scope_switch(scope, idx)); } - /* Output any initial blocks for tasks or functions defined - * in this module. Used to initialize local variables. */ - ivl_scope_children(scope, (ivl_scope_f*) emit_tf_process, scope); + /* Output any initial blocks for tasks or functions or named + * blocks defined in this module. Used to initialize local + * variables. */ + ivl_scope_children(scope, (ivl_scope_f*) emit_tfb_process, scope); /* Output the initial/always blocks for this module. */ ivl_design_process(design, (ivl_process_f)find_process, scope);