Find assignments that could be initializers

This commit is contained in:
Nick Gasson 2008-06-13 13:59:48 +01:00
parent 70db096b6d
commit 0a8fd50c4a
3 changed files with 35 additions and 10 deletions

View File

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

View File

@ -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.

View File

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