For SystemVerilog, run variable initialization before main simulation starts.

This commit is contained in:
Martin Whitaker 2016-03-19 13:46:09 +00:00
parent 635adfc01e
commit 54feb89bf5
5 changed files with 33 additions and 6 deletions

View File

@ -5966,6 +5966,10 @@ bool LexicalScope::elaborate_var_inits_(Design*des, NetScope*scope) const
return false;
NetProcTop*top = new NetProcTop(scope, IVL_PR_INITIAL, proc);
if (gn_system_verilog()) {
top->attribute(perm_string::literal("_ivl_schedule_init"),
verinum(1));
}
des->add_process(top);
scope->set_var_init(proc);

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2001-2015 Stephen Williams (steve@icarus.com)
* Copyright (c) 2001-2016 Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@ -2306,6 +2306,7 @@ int draw_process(ivl_process_t net, void*x)
ivl_scope_t scope = ivl_process_scope(net);
ivl_statement_t stmt = ivl_process_stmt(net);
int init_flag = 0;
int push_flag = 0;
(void)x; /* Parameter is not used. */
@ -2314,6 +2315,12 @@ int draw_process(ivl_process_t net, void*x)
ivl_attribute_t attr = ivl_process_attr_val(net, idx);
if (strcmp(attr->key, "_ivl_schedule_init") == 0) {
init_flag = 1;
}
if (strcmp(attr->key, "_ivl_schedule_push") == 0) {
push_flag = 1;
@ -2357,7 +2364,9 @@ int draw_process(ivl_process_t net, void*x)
case IVL_PR_INITIAL:
case IVL_PR_ALWAYS:
if (push_flag) {
if (init_flag) {
fprintf(vvp_out, " .thread T_%u, $init;\n", thread_count);
} else if (push_flag) {
fprintf(vvp_out, " .thread T_%u, $push;\n", thread_count);
} else {
fprintf(vvp_out, " .thread T_%u;\n", thread_count);

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2001-2014 Stephen Williams (steve@icarus.com)
* Copyright (c) 2001-2016 Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@ -1915,7 +1915,9 @@ void compile_thread(char*start_sym, char*flag)
vthread_t thr = vthread_new(pc, vpip_peek_current_scope());
if (flag && (strcmp(flag,"$final") == 0))
if (flag && (strcmp(flag,"$init") == 0))
schedule_init_vthread(thr);
else if (flag && (strcmp(flag,"$final") == 0))
schedule_final_vthread(thr);
else
schedule_vthread(thr, 0, push_flag);

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2001-2015 Stephen Williams (steve@icarus.com)
* Copyright (c) 2001-2016 Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@ -764,6 +764,16 @@ void schedule_vthread(vthread_t thr, vvp_time64_t delay, bool push_flag)
}
}
void schedule_init_vthread(vthread_t thr)
{
struct vthread_event_s*cur = new vthread_event_s;
cur->thr = thr;
vthread_mark_scheduled(thr);
schedule_init_event(cur);
}
void schedule_final_vthread(vthread_t thr)
{
struct vthread_event_s*cur = new vthread_event_s;

View File

@ -1,7 +1,7 @@
#ifndef IVL_schedule_H
#define IVL_schedule_H
/*
* Copyright (c) 2001-2014 Stephen Williams (steve@icarus.com)
* Copyright (c) 2001-2016 Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@ -35,6 +35,8 @@
extern void schedule_vthread(vthread_t thr, vvp_time64_t delay,
bool push_flag =false);
extern void schedule_init_vthread(vthread_t thr);
extern void schedule_final_vthread(vthread_t thr);
/*