From 899a70908ec52f638fa3b61baea46a89152e395a Mon Sep 17 00:00:00 2001 From: Nick Gasson Date: Tue, 24 Jun 2008 20:13:18 +0100 Subject: [PATCH] Fix small bug with initialisation and ammend comments --- tgt-vhdl/process.cc | 5 +---- tgt-vhdl/stmt.cc | 32 +++++++++++++++++++------------- tgt-vhdl/vhdl_syntax.hh | 1 + 3 files changed, 21 insertions(+), 17 deletions(-) diff --git a/tgt-vhdl/process.cc b/tgt-vhdl/process.cc index 5833cb5b3..73cc51e92 100644 --- a/tgt-vhdl/process.cc +++ b/tgt-vhdl/process.cc @@ -47,10 +47,7 @@ * that have been generated. Any subsequent blocking assignments * are made to the same variable. At either the end of the * process or a `wait' statement, the temporaries are assigned - * back to the signals, and the temporaries are forgotten. This - * has exactly the same (external) behaviour as the Verilog - * blocking assignment, since no external process will be able - * to observe that the assignment wasn't made immediately. + * back to the signals, and the temporaries are forgotten. * * For example: * diff --git a/tgt-vhdl/stmt.cc b/tgt-vhdl/stmt.cc index 791ce7545..59166026d 100644 --- a/tgt-vhdl/stmt.cc +++ b/tgt-vhdl/stmt.cc @@ -129,20 +129,23 @@ static int draw_nbassign(vhdl_procedural *proc, stmt_container *container, return 1; vhdl_expr *rhs = rhs_raw->cast(decl->get_type()); - // TODO: CORRECT THIS!!! - // If this is an `inital' process and we haven't yet - // generated a `wait' statement then this assignment - // needs to be moved to the declaration. Otherwise the - // Verilog behaviour won't be preserved: VHDL does not - // distinguish `initial' and `always' processes so an - // `always' process might be activatated before an - // `initial' process at time 0. The `always' process may - // then use the uninitialized signal value. + // Where possible, move constant assignments into the + // declaration as initializers. This optimisation is only + // performed on assignments of constant values to prevent + // ordering problems. + + // This also has another application: If this is an `inital' + // process and we haven't yet generated a `wait' statement then + // moving the assignment to the initialization preserves the + // expected Verilog behaviour: VHDL does not distinguish + // `initial' and `always' processes so an `always' process might + // be activatated before an `initial' process at time 0. The + // `always' process may then use the uninitialized signal value. // The second test ensures that we only try to initialise // internal signals not ports if (proc->get_scope()->initializing() && ivl_signal_port(sig) == IVL_SIP_NONE - && rhs->constant()) { + && !decl->has_initial() && rhs->constant()) { decl->set_initial(rhs); } @@ -186,12 +189,15 @@ static int draw_assign(vhdl_procedural *proc, stmt_container *container, return 1; vhdl_expr *rhs = rhs_raw->cast(decl->get_type()); + bool isvar = strip_var(signame) != signame; + // As with non-blocking assignment, push constant assignments - // into the initialisation if we can + // into the initialisation if we can (but only if this is + // the first time we assign to this variable). if (proc->get_scope()->initializing() && ivl_signal_port(sig) == IVL_SIP_NONE - && rhs->constant() - && !proc->get_scope()->have_declared(signame)) { + && rhs->constant() && !decl->has_initial() + && !isvar) { decl->set_initial(rhs); diff --git a/tgt-vhdl/vhdl_syntax.hh b/tgt-vhdl/vhdl_syntax.hh index b328dca60..b4b40d21b 100644 --- a/tgt-vhdl/vhdl_syntax.hh +++ b/tgt-vhdl/vhdl_syntax.hh @@ -416,6 +416,7 @@ public: const std::string &get_name() const { return name_; } const vhdl_type *get_type() const { return type_; } void set_initial(vhdl_expr *initial); + bool has_initial() const { return initial_ != NULL; } protected: std::string name_; vhdl_type *type_;