From d35d542b9e7947a9e67f70f16540c5985ed004e6 Mon Sep 17 00:00:00 2001 From: Nick Gasson Date: Sun, 13 Dec 2009 19:29:21 +0000 Subject: [PATCH] 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 9c568d8f470bb994b4ee2f85a7058196d9d64e0c) --- tgt-vhdl/logic.cc | 4 ++++ tgt-vhdl/vhdl_syntax.cc | 12 +++++++++++- tgt-vhdl/vhdl_syntax.hh | 4 +++- 3 files changed, 18 insertions(+), 2 deletions(-) diff --git a/tgt-vhdl/logic.cc b/tgt-vhdl/logic.cc index 178dce899..b27f69ce2 100644 --- a/tgt-vhdl/logic.cc +++ b/tgt-vhdl/logic.cc @@ -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++) { diff --git a/tgt-vhdl/vhdl_syntax.cc b/tgt-vhdl/vhdl_syntax.cc index cfb181871..753da7b37 100644 --- a/tgt-vhdl/vhdl_syntax.cc +++ b/tgt-vhdl/vhdl_syntax.cc @@ -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; +} diff --git a/tgt-vhdl/vhdl_syntax.hh b/tgt-vhdl/vhdl_syntax.hh index d1a278aae..2b596a227 100644 --- a/tgt-vhdl/vhdl_syntax.hh +++ b/tgt-vhdl/vhdl_syntax.hh @@ -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_; };