Remove some redundant code from draw_synthesisable_wait
The default draw_wait now produces code for FFs with sync waits that should synthesise OK.
This commit is contained in:
parent
6047eab005
commit
02b58f6ae8
|
|
@ -529,30 +529,12 @@ static void get_nexuses_from_expr(ivl_expr_t expr, set<ivl_nexus_t> &out)
|
||||||
* ...
|
* ...
|
||||||
* end if;
|
* end if;
|
||||||
* end process;
|
* end process;
|
||||||
*
|
|
||||||
* ----
|
|
||||||
*
|
|
||||||
* always @(posedge A)
|
|
||||||
* if (...)
|
|
||||||
* ...
|
|
||||||
* else
|
|
||||||
* ...
|
|
||||||
*
|
|
||||||
* This is assumed to be a template for a FF with synchronous reset,
|
|
||||||
* if A does not appear in the `if' test expression. This should produce
|
|
||||||
* the following VHDL:
|
|
||||||
*
|
|
||||||
* process (A) is
|
|
||||||
* begin
|
|
||||||
* if rising_edge(A) then
|
|
||||||
* ...
|
|
||||||
* end if;
|
|
||||||
* end process;
|
|
||||||
*/
|
*/
|
||||||
static bool draw_synthesisable_wait(vhdl_process *proc, stmt_container *container,
|
static bool draw_synthesisable_wait(vhdl_process *proc, stmt_container *container,
|
||||||
ivl_statement_t stmt)
|
ivl_statement_t stmt)
|
||||||
{
|
{
|
||||||
enum ff_type_t { SYNC_RESET, ASYNC_RESET };
|
// At the moment this only detects FFs with an asynchronous reset
|
||||||
|
// All other code will fall back on the default draw_wait
|
||||||
|
|
||||||
// Store a set of the edge triggered signals
|
// Store a set of the edge triggered signals
|
||||||
// The second item is true if this is positive-edge
|
// The second item is true if this is positive-edge
|
||||||
|
|
@ -575,15 +557,9 @@ static bool draw_synthesisable_wait(vhdl_process *proc, stmt_container *containe
|
||||||
edge_triggered.insert(ivl_event_neg(event, j));
|
edge_triggered.insert(ivl_event_neg(event, j));
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we're sensitive to a single signal edge that should be a clock
|
// If we're edge-sensitive to less than two signals this doesn't
|
||||||
// (but we try to make sure), if there are two signals one might be
|
// match the expected template, so use the default draw_wait
|
||||||
// an asynchronous reset
|
if (edge_triggered.size() < 2)
|
||||||
ff_type_t ff_type;
|
|
||||||
if (edge_triggered.size() == 2)
|
|
||||||
ff_type = ASYNC_RESET;
|
|
||||||
else if (edge_triggered.size() == 1)
|
|
||||||
ff_type = SYNC_RESET;
|
|
||||||
else
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Now check to see if the immediately embedded statement is an `if'
|
// Now check to see if the immediately embedded statement is an `if'
|
||||||
|
|
@ -591,6 +567,11 @@ static bool draw_synthesisable_wait(vhdl_process *proc, stmt_container *containe
|
||||||
if (ivl_statement_type(sub_stmt) != IVL_ST_CONDIT)
|
if (ivl_statement_type(sub_stmt) != IVL_ST_CONDIT)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
// The if should have two branches: one is the reset branch and
|
||||||
|
// one is the clocked branch
|
||||||
|
if (ivl_stmt_cond_false(sub_stmt) == NULL)
|
||||||
|
return false;
|
||||||
|
|
||||||
// Check the first branch of the if statement
|
// Check the first branch of the if statement
|
||||||
// If it matches exactly one of the edge-triggered signals then assume
|
// If it matches exactly one of the edge-triggered signals then assume
|
||||||
// this is the (dominant) reset branch
|
// this is the (dominant) reset branch
|
||||||
|
|
@ -638,21 +619,20 @@ static bool draw_synthesisable_wait(vhdl_process *proc, stmt_container *containe
|
||||||
|
|
||||||
// Draw the clocked branch
|
// Draw the clocked branch
|
||||||
// For an asynchronous reset we just want this around the else branch,
|
// For an asynchronous reset we just want this around the else branch,
|
||||||
// for a synchronous reset we want this to contain both branches
|
stmt_container *else_container = body->add_elsif(edge);
|
||||||
stmt_container *else_container = NULL;
|
|
||||||
if (ff_type == SYNC_RESET) {
|
|
||||||
vhdl_if_stmt *clocked = new vhdl_if_stmt(edge);
|
|
||||||
clocked->get_then_container()->add_stmt(body);
|
|
||||||
container->add_stmt(clocked);
|
|
||||||
else_container = body->get_else_container();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
else_container = body->add_elsif(edge);
|
|
||||||
container->add_stmt(body);
|
|
||||||
}
|
|
||||||
|
|
||||||
draw_stmt(proc, else_container, ivl_stmt_cond_false(sub_stmt));
|
draw_stmt(proc, else_container, ivl_stmt_cond_false(sub_stmt));
|
||||||
|
|
||||||
|
if (proc->contains_wait_stmt()) {
|
||||||
|
// Expanding the body produced a `wait' statement which can't
|
||||||
|
// be included in a sensitised process so undo all this work
|
||||||
|
// and fall back on the default draw_wait
|
||||||
|
delete body;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
container->add_stmt(body);
|
||||||
|
|
||||||
// Add all the edge triggered signals to the sensitivity list
|
// Add all the edge triggered signals to the sensitivity list
|
||||||
for (set<ivl_nexus_t>::const_iterator it = edge_triggered.begin();
|
for (set<ivl_nexus_t>::const_iterator it = edge_triggered.begin();
|
||||||
it != edge_triggered.end(); ++it) {
|
it != edge_triggered.end(); ++it) {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue