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)
This commit is contained in:
Nick Gasson 2008-07-16 12:00:11 +01:00
parent b5e12077b2
commit d343db34fd
4 changed files with 27 additions and 11 deletions

View File

@ -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);

View File

@ -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);

View File

@ -36,6 +36,13 @@ vhdl_scope::~vhdl_scope()
delete_children<vhdl_decl>(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);
@ -319,9 +326,11 @@ const vhdl_type *vhdl_decl::get_type() const
void vhdl_decl::set_initial(vhdl_expr *initial)
{
if (initial_ != NULL)
delete initial_;
if (!has_initial_) {
assert(initial_ == NULL);
initial_ = initial;
has_initial_ = true;
}
}
void vhdl_port_decl::emit(std::ostream &of, int level) const

View File

@ -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<vhdl_decl*> 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_; }