From d343db34fd792f0a2d1bf611d92b42c1c41913f0 Mon Sep 17 00:00:00 2001 From: Nick Gasson Date: Wed, 16 Jul 2008 12:00:11 +0100 Subject: [PATCH] Fix initialisation order Initial processes set a magic flag in the code generator which allows it to push constant assignments into the VHDL signal initialisation and omit the assignment. However, it should only do this if the signal has not already been read (otherwise the previous read would not get the undefined value as expected) --- tgt-vhdl/expr.cc | 7 ++++++- tgt-vhdl/process.cc | 4 ++-- tgt-vhdl/vhdl_syntax.cc | 19 ++++++++++++++----- tgt-vhdl/vhdl_syntax.hh | 8 +++++--- 4 files changed, 27 insertions(+), 11 deletions(-) diff --git a/tgt-vhdl/expr.cc b/tgt-vhdl/expr.cc index dc69cd687..b5a76ca37 100644 --- a/tgt-vhdl/expr.cc +++ b/tgt-vhdl/expr.cc @@ -58,9 +58,14 @@ static vhdl_var_ref *translate_signal(ivl_expr_t e) const char *renamed = get_renamed_signal(sig).c_str(); - const vhdl_decl *decl = scope->get_decl(renamed); + vhdl_decl *decl = scope->get_decl(renamed); assert(decl); + // Can't generate a constant initialiser for this signal + // later as it has already been read + if (scope->initializing()) + decl->set_initial(NULL); + vhdl_type *type = new vhdl_type(*decl->get_type()); return new vhdl_var_ref(renamed, type); diff --git a/tgt-vhdl/process.cc b/tgt-vhdl/process.cc index 57326a11e..7333dff2b 100644 --- a/tgt-vhdl/process.cc +++ b/tgt-vhdl/process.cc @@ -40,8 +40,8 @@ static int generate_vhdl_process(vhdl_entity *ent, ivl_process_t proc) // If this is an initial process, push signal initialisation // into the declarations - if (ivl_process_type(proc) == IVL_PR_INITIAL) - vhdl_proc->get_scope()->set_initializing(true); + vhdl_proc->get_scope()->set_initializing + (ivl_process_type(proc) == IVL_PR_INITIAL); ivl_statement_t stmt = ivl_process_stmt(proc); int rc = draw_stmt(vhdl_proc, vhdl_proc->get_container(), stmt); diff --git a/tgt-vhdl/vhdl_syntax.cc b/tgt-vhdl/vhdl_syntax.cc index c0b1e3060..af65ee0a1 100644 --- a/tgt-vhdl/vhdl_syntax.cc +++ b/tgt-vhdl/vhdl_syntax.cc @@ -28,7 +28,7 @@ vhdl_scope::vhdl_scope() : parent_(NULL), init_(false), sig_assign_(true) { - + } vhdl_scope::~vhdl_scope() @@ -36,6 +36,13 @@ vhdl_scope::~vhdl_scope() delete_children(decls_); } +void vhdl_scope::set_initializing(bool i) +{ + init_ = i; + if (parent_) + parent_->set_initializing(i); +} + void vhdl_scope::add_decl(vhdl_decl *decl) { decls_.push_back(decl); @@ -318,10 +325,12 @@ const vhdl_type *vhdl_decl::get_type() const } void vhdl_decl::set_initial(vhdl_expr *initial) -{ - if (initial_ != NULL) - delete initial_; - initial_ = initial; +{ + if (!has_initial_) { + assert(initial_ == NULL); + initial_ = initial; + has_initial_ = true; + } } void vhdl_port_decl::emit(std::ostream &of, int level) const diff --git a/tgt-vhdl/vhdl_syntax.hh b/tgt-vhdl/vhdl_syntax.hh index d76370b37..5fa684e21 100644 --- a/tgt-vhdl/vhdl_syntax.hh +++ b/tgt-vhdl/vhdl_syntax.hh @@ -425,18 +425,20 @@ class vhdl_decl : public vhdl_element { public: vhdl_decl(const char *name, vhdl_type *type = NULL, vhdl_expr *initial = NULL) - : name_(name), type_(type), initial_(initial) {} + : name_(name), type_(type), initial_(initial), + has_initial_(initial != NULL) {} virtual ~vhdl_decl(); const std::string &get_name() const { return name_; } const vhdl_type *get_type() const; void set_type(vhdl_type *t) { type_ = t; } void set_initial(vhdl_expr *initial); - bool has_initial() const { return initial_ != NULL; } + bool has_initial() const { return has_initial_; } protected: std::string name_; vhdl_type *type_; vhdl_expr *initial_; + bool has_initial_; }; typedef std::list decl_list_t; @@ -566,7 +568,7 @@ public: void set_parent(vhdl_scope *p) { parent_ = p; } bool initializing() const { return init_; } - void set_initializing(bool i) { init_ = i; } + void set_initializing(bool i); void set_allow_signal_assignment(bool b) { sig_assign_ = b; } bool allow_signal_assignment() const { return sig_assign_; }