Generate rising/falling edge detectors
This commit is contained in:
parent
19e60b698f
commit
7eb41304e6
|
|
@ -238,8 +238,6 @@ static int draw_delay(vhdl_process *proc, stmt_container *container,
|
|||
/*
|
||||
* A wait statement waits for a level change on a @(..) list of
|
||||
* signals.
|
||||
* TODO: This won't yet handle the posedge to rising_edge, etc.
|
||||
* mapping.
|
||||
*/
|
||||
static int draw_wait(vhdl_process *proc, stmt_container *container,
|
||||
ivl_statement_t stmt)
|
||||
|
|
@ -248,10 +246,9 @@ static int draw_wait(vhdl_process *proc, stmt_container *container,
|
|||
for (int i = 0; i < nevents; i++) {
|
||||
ivl_event_t event = ivl_stmt_events(stmt, i);
|
||||
|
||||
if (ivl_event_nneg(event) != 0)
|
||||
error("Negative edge events not supported yet");
|
||||
if (ivl_event_npos(event) != 0)
|
||||
error("Positive edge events not supported yet");
|
||||
// A list of the non-edge triggered signals to they can
|
||||
// be added to the edge-detecting `if' statement later
|
||||
string_list_t non_edges;
|
||||
|
||||
int nany = ivl_event_nany(event);
|
||||
for (int i = 0; i < nany; i++) {
|
||||
|
|
@ -268,14 +265,77 @@ static int draw_wait(vhdl_process *proc, stmt_container *container,
|
|||
// Only add this signal to the sensitivity if it's part
|
||||
// of the containing architecture (i.e. it has already
|
||||
// been declared)
|
||||
if (proc->get_parent()->have_declared(signame))
|
||||
if (proc->get_parent()->have_declared(signame)) {
|
||||
proc->add_sensitivity(signame);
|
||||
non_edges.push_back(signame);
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Ignore all other types of nexus pointer
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int nneg = ivl_event_nneg(event);
|
||||
int npos = ivl_event_npos(event);
|
||||
if (nneg + npos > 0) {
|
||||
vhdl_binop_expr *test =
|
||||
new vhdl_binop_expr(VHDL_BINOP_OR, vhdl_type::boolean());
|
||||
|
||||
// Generate falling_edge(..) calls for each negedge event
|
||||
for (int i = 0; i < nneg; i++) {
|
||||
ivl_nexus_t nexus = ivl_event_neg(event, i);
|
||||
|
||||
int nptrs = ivl_nexus_ptrs(nexus);
|
||||
for (int j = 0; j < nptrs; j++) {
|
||||
ivl_nexus_ptr_t nexus_ptr = ivl_nexus_ptr(nexus, j);
|
||||
|
||||
ivl_signal_t sig;
|
||||
if ((sig = ivl_nexus_ptr_sig(nexus_ptr))) {
|
||||
vhdl_fcall *detect
|
||||
= new vhdl_fcall("falling_edge", vhdl_type::boolean());
|
||||
detect->add_expr
|
||||
(new vhdl_var_ref(ivl_signal_basename(sig),
|
||||
vhdl_type::std_logic()));
|
||||
test->add_expr(detect);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Generate rising_edge(..) calls for each posedge event
|
||||
for (int i = 0; i < npos; i++) {
|
||||
ivl_nexus_t nexus = ivl_event_pos(event, i);
|
||||
|
||||
int nptrs = ivl_nexus_ptrs(nexus);
|
||||
for (int j = 0; j < nptrs; j++) {
|
||||
ivl_nexus_ptr_t nexus_ptr = ivl_nexus_ptr(nexus, j);
|
||||
|
||||
ivl_signal_t sig;
|
||||
if ((sig = ivl_nexus_ptr_sig(nexus_ptr))) {
|
||||
vhdl_fcall *detect
|
||||
= new vhdl_fcall("rising_edge", vhdl_type::boolean());
|
||||
detect->add_expr
|
||||
(new vhdl_var_ref(ivl_signal_basename(sig),
|
||||
vhdl_type::std_logic()));
|
||||
test->add_expr(detect);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Add Name'Event terms for each non-edge-triggered signal
|
||||
string_list_t::iterator it;
|
||||
for (it = non_edges.begin(); it != non_edges.end(); ++it) {
|
||||
test->add_expr
|
||||
(new vhdl_var_ref((*it + "'Event").c_str(),
|
||||
vhdl_type::boolean()));
|
||||
}
|
||||
|
||||
container->add_stmt(new vhdl_if_stmt(test));
|
||||
}
|
||||
else {
|
||||
// Don't bother generating an edge detector if there
|
||||
// are no edge-triggered events
|
||||
}
|
||||
}
|
||||
|
||||
ivl_statement_t sub_stmt = ivl_stmt_sub_stmt(stmt);
|
||||
|
|
|
|||
|
|
@ -163,7 +163,6 @@ private:
|
|||
vhdl_expr_list exprs_;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* A concurrent statement appears in architecture bodies but not
|
||||
* processes.
|
||||
|
|
|
|||
|
|
@ -38,6 +38,11 @@ vhdl_type *vhdl_type::line()
|
|||
return new vhdl_type(VHDL_TYPE_LINE);
|
||||
}
|
||||
|
||||
vhdl_type *vhdl_type::boolean()
|
||||
{
|
||||
return new vhdl_type(VHDL_TYPE_BOOLEAN);
|
||||
}
|
||||
|
||||
vhdl_type *vhdl_type::integer()
|
||||
{
|
||||
return new vhdl_type(VHDL_TYPE_INTEGER);
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ enum vhdl_type_name_t {
|
|||
VHDL_TYPE_LINE,
|
||||
VHDL_TYPE_FILE,
|
||||
VHDL_TYPE_INTEGER,
|
||||
VHDL_TYPE_BOOLEAN,
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
@ -54,6 +55,7 @@ public:
|
|||
static vhdl_type *line();
|
||||
static vhdl_type *std_logic_vector(int msb, int lsb);
|
||||
static vhdl_type *integer();
|
||||
static vhdl_type *boolean();
|
||||
protected:
|
||||
vhdl_type_name_t name_;
|
||||
int msb_, lsb_;
|
||||
|
|
|
|||
Loading…
Reference in New Issue