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:
parent
b5e12077b2
commit
d343db34fd
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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_; }
|
||||
|
|
|
|||
Loading…
Reference in New Issue