tgt-vlog95: Handle variable initialisation in named blocks.

This commit is contained in:
Martin Whitaker 2016-03-12 23:06:54 +00:00
parent dc189fec8c
commit 5d9a196819
1 changed files with 15 additions and 10 deletions

View File

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