Remove some uneccessary zero-time waits from VHDL outputs
This patch optimises away straight line sequences like: wait for 0 ns; wait for X ns; to: wait for X ns; This tidies up the output a bit. It also has the effect of removing all code from initial processes where the assignments have been extracted as VHDL signal intialisers. (c.f. pr2391337)
This commit is contained in:
parent
712e08ebe8
commit
651d208451
|
|
@ -56,10 +56,15 @@ static int generate_vhdl_process(vhdl_entity *ent, ivl_process_t proc)
|
|||
// However, if no statements were added to the container
|
||||
// by draw_stmt, don't bother adding a wait as `emit'
|
||||
// will optimise the process out of the output
|
||||
if (ivl_process_type(proc) == IVL_PR_INITIAL
|
||||
&& !vhdl_proc->get_container()->empty()) {
|
||||
vhdl_wait_stmt *wait = new vhdl_wait_stmt();
|
||||
vhdl_proc->get_container()->add_stmt(wait);
|
||||
if (ivl_process_type(proc) == IVL_PR_INITIAL) {
|
||||
// Get rid of any useless `wait for 0 ns's at the end of the process
|
||||
prune_wait_for_0(vhdl_proc->get_container());
|
||||
|
||||
// The above pruning might have removed all logic from the process
|
||||
if (!vhdl_proc->get_container()->empty()) {
|
||||
vhdl_wait_stmt *wait = new vhdl_wait_stmt();
|
||||
vhdl_proc->get_container()->add_stmt(wait);
|
||||
}
|
||||
}
|
||||
|
||||
// Add a comment indicating where it came from
|
||||
|
|
|
|||
|
|
@ -396,7 +396,7 @@ static int draw_assign(vhdl_procedural *proc, stmt_container *container,
|
|||
// the process
|
||||
if (!is_last)
|
||||
container->add_stmt
|
||||
(new vhdl_wait_stmt(VHDL_WAIT_FOR, new vhdl_const_time(0)));
|
||||
(new vhdl_wait_stmt(VHDL_WAIT_FOR0));
|
||||
}
|
||||
else
|
||||
make_assignment(proc, container, stmt, true);
|
||||
|
|
@ -404,6 +404,27 @@ static int draw_assign(vhdl_procedural *proc, stmt_container *container,
|
|||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* The VHDL code generator inserts `wait for 0 ns' after each
|
||||
* not-last-in-block blocking assignment.
|
||||
* If this is immediately followed by another `wait for ...' then
|
||||
* we might as well not emit the first zero-time wait.
|
||||
*/
|
||||
void prune_wait_for_0(stmt_container *container)
|
||||
{
|
||||
vhdl_wait_stmt *wait0;
|
||||
stmt_container::stmt_list_t &stmts = container->get_stmts();
|
||||
while (stmts.size() > 0
|
||||
&& (wait0 = dynamic_cast<vhdl_wait_stmt*>(stmts.back()))) {
|
||||
if (wait0->get_type() == VHDL_WAIT_FOR0) {
|
||||
delete wait0;
|
||||
stmts.pop_back();
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Delay statements are equivalent to the `wait for' form of the
|
||||
* VHDL wait statement.
|
||||
|
|
@ -429,6 +450,8 @@ static int draw_delay(vhdl_procedural *proc, stmt_container *container,
|
|||
return 1;
|
||||
}
|
||||
|
||||
prune_wait_for_0(container);
|
||||
|
||||
ivl_statement_t sub_stmt = ivl_stmt_sub_stmt(stmt);
|
||||
vhdl_wait_stmt *wait =
|
||||
new vhdl_wait_stmt(VHDL_WAIT_FOR, time);
|
||||
|
|
|
|||
|
|
@ -316,6 +316,9 @@ void vhdl_wait_stmt::emit(std::ostream &of, int level) const
|
|||
of << " for ";
|
||||
expr_->emit(of, level);
|
||||
break;
|
||||
case VHDL_WAIT_FOR0:
|
||||
of << " for 0 ns";
|
||||
break;
|
||||
case VHDL_WAIT_UNTIL:
|
||||
assert(expr_);
|
||||
of << " until ";
|
||||
|
|
|
|||
|
|
@ -335,8 +335,11 @@ public:
|
|||
void add_stmt(vhdl_seq_stmt *stmt);
|
||||
void emit(std::ostream &of, int level, bool newline=true) const;
|
||||
bool empty() const { return stmts_.empty(); }
|
||||
|
||||
typedef std::list<vhdl_seq_stmt*> stmt_list_t;
|
||||
stmt_list_t &get_stmts() { return stmts_; }
|
||||
private:
|
||||
std::list<vhdl_seq_stmt*> stmts_;
|
||||
stmt_list_t stmts_;
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -381,6 +384,7 @@ public:
|
|||
enum vhdl_wait_type_t {
|
||||
VHDL_WAIT_INDEF, // Suspend indefinitely
|
||||
VHDL_WAIT_FOR, // Wait for a constant amount of time
|
||||
VHDL_WAIT_FOR0, // Special wait for zero time
|
||||
VHDL_WAIT_UNTIL, // Wait on an expression
|
||||
VHDL_WAIT_ON, // Wait on a sensitivity list
|
||||
};
|
||||
|
|
@ -398,6 +402,7 @@ public:
|
|||
|
||||
void emit(std::ostream &of, int level) const;
|
||||
void add_sensitivity(const std::string &s) { sensitivity_.push_back(s); }
|
||||
vhdl_wait_type_t get_type() const { return type_; }
|
||||
private:
|
||||
vhdl_wait_type_t type_;
|
||||
vhdl_expr *expr_;
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ ivl_signal_t find_signal_named(const string &name, const vhdl_scope *scope);
|
|||
|
||||
int draw_stask_display(vhdl_procedural *proc, stmt_container *container,
|
||||
ivl_statement_t stmt, bool newline = true);
|
||||
|
||||
void prune_wait_for_0(stmt_container *container);
|
||||
void require_support_function(support_function_t f);
|
||||
|
||||
#endif /* #ifndef INC_VHDL_TARGET_H */
|
||||
|
|
|
|||
Loading…
Reference in New Issue