From 72fc3d712deafcdb6f67fabf4bae4d9b6aebc386 Mon Sep 17 00:00:00 2001 From: Martin Whitaker Date: Sat, 19 Mar 2016 13:46:09 +0000 Subject: [PATCH] For SystemVerilog, run variable initialization before main simulation starts. (cherry picked from commit 54feb89bf540fb75abc31ede03cc9be444015e94) --- elaborate.cc | 4 ++++ tgt-vvp/vvp_process.c | 13 +++++++++++-- vvp/compile.cc | 6 ++++-- vvp/schedule.cc | 12 +++++++++++- vvp/schedule.h | 4 +++- 5 files changed, 33 insertions(+), 6 deletions(-) diff --git a/elaborate.cc b/elaborate.cc index d22d35735..77692372a 100644 --- a/elaborate.cc +++ b/elaborate.cc @@ -5989,6 +5989,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); diff --git a/tgt-vvp/vvp_process.c b/tgt-vvp/vvp_process.c index 571c8b100..98ca72cff 100644 --- a/tgt-vvp/vvp_process.c +++ b/tgt-vvp/vvp_process.c @@ -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 @@ -2298,6 +2298,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. */ @@ -2306,6 +2307,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; @@ -2349,7 +2356,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); diff --git a/vvp/compile.cc b/vvp/compile.cc index 3bf1d7474..ef1e49bf9 100644 --- a/vvp/compile.cc +++ b/vvp/compile.cc @@ -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 @@ -1935,7 +1935,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); diff --git a/vvp/schedule.cc b/vvp/schedule.cc index 9ed169fab..79c68b024 100644 --- a/vvp/schedule.cc +++ b/vvp/schedule.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001-2013 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 @@ -760,6 +760,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; diff --git a/vvp/schedule.h b/vvp/schedule.h index 49db903e9..4dace3d04 100644 --- a/vvp/schedule.h +++ b/vvp/schedule.h @@ -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); /*