VHDL: ensure with-select statement choices completely cover input space

Newer versions of GHDL seem to be stricter when checking this than
older versions. ModelSim still accepts an incomplete with-select,
however.

This patch makes the output 'U' if none of the conditions match.
(cherry picked from commit 9c568d8f47)
This commit is contained in:
Nick Gasson 2009-12-13 19:29:21 +00:00 committed by Stephen Williams
parent 8139551908
commit d35d542b9e
3 changed files with 18 additions and 2 deletions

View File

@ -145,6 +145,10 @@ static void comb_udp_logic(vhdl_arch *arch, ivl_net_logic_t log)
vhdl_var_ref *out = nexus_to_var_ref(arch->get_scope(), output_nex);
vhdl_with_select_stmt *ws =
new vhdl_with_select_stmt(new vhdl_var_ref(*tmp_ref), out);
// Ensure the select statement completely covers the input space
// or some strict VHDL compilers will complain
ws->add_default(new vhdl_const_bit('X'));
int nrows = ivl_udp_rows(udp);
for (int i = 0; i < nrows; i++) {

View File

@ -1005,13 +1005,18 @@ void vhdl_with_select_stmt::emit(std::ostream &of, int level) const
of << " when ";
(*it).cond->emit(of, level);
if (++it != whens_.end()) {
if (++it != whens_.end() || others_ != NULL) {
of << ",";
newline(of, indent(level));
}
else
of << ";";
}
if (others_) {
others_->emit(of, level);
of << " when others;";
}
}
void vhdl_with_select_stmt::add_condition(vhdl_expr *value, vhdl_expr *cond, vhdl_expr *delay)
@ -1019,3 +1024,8 @@ void vhdl_with_select_stmt::add_condition(vhdl_expr *value, vhdl_expr *cond, vhd
when_part_t when = { value, cond, delay };
whens_.push_back(when);
}
void vhdl_with_select_stmt::add_default(vhdl_expr* value)
{
others_ = value;
}

View File

@ -311,15 +311,17 @@ private:
class vhdl_with_select_stmt : public vhdl_conc_stmt {
public:
vhdl_with_select_stmt(vhdl_expr *test, vhdl_var_ref *out)
: test_(test), out_(out) {}
: test_(test), out_(out), others_(NULL) {}
~vhdl_with_select_stmt();
void emit(std::ostream &of, int level) const;
void add_condition(vhdl_expr *value, vhdl_expr *cond, vhdl_expr *delay=NULL);
void add_default(vhdl_expr* value);
private:
vhdl_expr *test_;
vhdl_var_ref *out_;
when_list_t whens_;
vhdl_expr* others_;
};