From 0a8fd50c4af30c449ac25937e75f6bd416b45a2f Mon Sep 17 00:00:00 2001 From: Nick Gasson Date: Fri, 13 Jun 2008 13:59:48 +0100 Subject: [PATCH] Find assignments that could be initializers --- tgt-vhdl/process.cc | 7 ++++++- tgt-vhdl/stmt.cc | 32 +++++++++++++++++++++++--------- tgt-vhdl/vhdl_syntax.hh | 6 ++++++ 3 files changed, 35 insertions(+), 10 deletions(-) diff --git a/tgt-vhdl/process.cc b/tgt-vhdl/process.cc index b43e0ee64..ac11cefa5 100644 --- a/tgt-vhdl/process.cc +++ b/tgt-vhdl/process.cc @@ -36,7 +36,12 @@ static int generate_vhdl_process(vhdl_entity *ent, ivl_process_t proc) // parent link won't be valid (and draw_stmt needs this // to add information to the architecture) vhdl_process *vhdl_proc = new vhdl_process(); - ent->get_arch()->add_stmt(vhdl_proc); + ent->get_arch()->add_stmt(vhdl_proc); + + // If this is an initial process, push signal initialisation + // into the declarations + if (ivl_process_type(proc) == IVL_PR_INITIAL) + vhdl_proc->set_initial(true); ivl_statement_t stmt = ivl_process_stmt(proc); int rc = draw_stmt(vhdl_proc, vhdl_proc->get_container(), stmt); diff --git a/tgt-vhdl/stmt.cc b/tgt-vhdl/stmt.cc index 4013dafac..1e80d11b4 100644 --- a/tgt-vhdl/stmt.cc +++ b/tgt-vhdl/stmt.cc @@ -192,13 +192,25 @@ static int draw_nbassign(vhdl_process *proc, stmt_container *container, return 1; vhdl_expr *rhs = rhs_raw->cast(decl->get_type()); - // The type here can be null as it is never actually needed - vhdl_var_ref *lval_ref = new vhdl_var_ref(signame, NULL); - - vhdl_nbassign_stmt *nbassign = new vhdl_nbassign_stmt(lval_ref, rhs); - if (after != NULL) - nbassign->set_after(after); - container->add_stmt(nbassign); + // If this is an `inital' process and we haven't yet + // generated a `wait' statement then initializing the + // signal here is equivalent to initializing to in the + // declaration + // The second test ensures that we only try to initialise + // internal signals not ports + if (proc->is_initial() + && !proc->get_parent()->get_parent()->get_decl(signame)) { + std::cout << "Pushing " << signame << " init up" << std::endl; + } + else { + // The type here can be null as it is never actually needed + vhdl_var_ref *lval_ref = new vhdl_var_ref(signame, NULL); + + vhdl_nbassign_stmt *nbassign = new vhdl_nbassign_stmt(lval_ref, rhs); + if (after != NULL) + nbassign->set_after(after); + container->add_stmt(nbassign); + } } else { error("Only signals as lvals supported at the moment"); @@ -244,9 +256,12 @@ static int draw_delay(vhdl_process *proc, stmt_container *container, // is caught here instead if (ivl_statement_type(sub_stmt) != IVL_ST_NOOP) draw_stmt(proc, container, sub_stmt); - } + // Any further assignments occur after simulation time 0 + // so they cannot be used to initialize signal declarations + proc->set_initial(false); + return 0; } @@ -278,7 +293,6 @@ static void edge_detector(ivl_nexus_t nexus, vhdl_process *proc, } } - /* * A wait statement waits for a level change on a @(..) list of * signals. diff --git a/tgt-vhdl/vhdl_syntax.hh b/tgt-vhdl/vhdl_syntax.hh index 441c6c1bb..27607d076 100644 --- a/tgt-vhdl/vhdl_syntax.hh +++ b/tgt-vhdl/vhdl_syntax.hh @@ -420,6 +420,9 @@ private: /* * Container for sequential statements. + * Verilog `initial' processes are used for variable + * initialisation whereas VHDL initialises variables in + * their declaration. */ class vhdl_process : public vhdl_conc_stmt { public: @@ -431,11 +434,14 @@ public: void add_decl(vhdl_decl *decl); void add_sensitivity(const char *name); bool have_declared_var(const std::string &name) const; + void set_initial(bool i) { initial_ = i; } + bool is_initial() const { return initial_; } private: stmt_container stmts_; decl_list_t decls_; std::string name_; string_list_t sens_; + bool initial_; };