diff --git a/tgt-vhdl/cast.cc b/tgt-vhdl/cast.cc index 013bb52b6..ff1b799f9 100644 --- a/tgt-vhdl/cast.cc +++ b/tgt-vhdl/cast.cc @@ -106,6 +106,28 @@ vhdl_expr *vhdl_expr::cast(const vhdl_type *to) return ah; } + else if (to->get_name() == VHDL_TYPE_STD_LOGIC + && (type_->get_name() == VHDL_TYPE_SIGNED)) { + require_support_function(SF_SIGNED_TO_LOGIC); + + vhdl_fcall *ah = + new vhdl_fcall(support_function::function_name(SF_SIGNED_TO_LOGIC), + vhdl_type::std_logic()); + ah->add_expr(this); + + return ah; + } + else if (to->get_name() == VHDL_TYPE_STD_LOGIC + && (type_->get_name() == VHDL_TYPE_UNSIGNED)) { + require_support_function(SF_UNSIGNED_TO_LOGIC); + + vhdl_fcall *ah = + new vhdl_fcall(support_function::function_name(SF_UNSIGNED_TO_LOGIC), + vhdl_type::std_logic()); + ah->add_expr(this); + + return ah; + } else { // We have to cast the expression before resizing or the // wrong sign bit may be extended (i.e. when casting between diff --git a/tgt-vhdl/support.cc b/tgt-vhdl/support.cc index e9592fa06..9ad74a3ca 100644 --- a/tgt-vhdl/support.cc +++ b/tgt-vhdl/support.cc @@ -44,6 +44,8 @@ const char *support_function::function_name(support_function_t type) case SF_TERNARY_UNSIGNED: return "Ternary_Unsigned"; case SF_TERNARY_SIGNED: return "Ternary_Signed"; case SF_LOGIC_TO_INTEGER: return "Logic_To_Integer"; + case SF_SIGNED_TO_LOGIC: return "Signed_To_Logic"; + case SF_UNSIGNED_TO_LOGIC: return "Unsigned_To_Logic"; default: assert(false); } @@ -60,6 +62,8 @@ vhdl_type *support_function::function_type(support_function_t type) case SF_REDUCE_AND: case SF_REDUCE_XOR: case SF_TERNARY_LOGIC: + case SF_SIGNED_TO_LOGIC: + case SF_UNSIGNED_TO_LOGIC: return vhdl_type::std_logic(); case SF_TERNARY_SIGNED: return new vhdl_type(VHDL_TYPE_SIGNED); @@ -102,6 +106,16 @@ void support_function::emit(std::ostream &of, int level) const << "return '0';" << nl_string(indent(level)) << "end if;"; break; + case SF_UNSIGNED_TO_LOGIC: + of << "(X : unsigned) return std_logic is" << nl_string(level) + << "begin" << nl_string(indent(level)) + << "return X(0);"; + break; + case SF_SIGNED_TO_LOGIC: + of << "(X : signed) return std_logic is" << nl_string(level) + << "begin" << nl_string(indent(level)) + << "return X(0);"; + break; case SF_REDUCE_OR: of << "(X : std_logic_vector) return std_logic is" << nl_string(level) << "begin" << nl_string(indent(level)) diff --git a/tgt-vhdl/support.hh b/tgt-vhdl/support.hh index 2cbee0c7b..234831c24 100644 --- a/tgt-vhdl/support.hh +++ b/tgt-vhdl/support.hh @@ -34,6 +34,8 @@ enum support_function_t { SF_TERNARY_UNSIGNED, SF_TERNARY_SIGNED, SF_LOGIC_TO_INTEGER, + SF_SIGNED_TO_LOGIC, + SF_UNSIGNED_TO_LOGIC, }; class support_function : public vhdl_function {