diff --git a/tgt-vhdl/cast.cc b/tgt-vhdl/cast.cc index 1612e6514..e1568929f 100644 --- a/tgt-vhdl/cast.cc +++ b/tgt-vhdl/cast.cc @@ -28,10 +28,12 @@ vhdl_expr *vhdl_expr::cast(const vhdl_type *to) { - //std::cout << "Cast: from=" << type_->get_string() - // << " (" << type_->get_width() << ") " - // << " to=" << to->get_string() << " (" - // << to->get_width() << ")" << std::endl; +#if 0 + std::cout << "Cast: from=" << type_->get_string() + << " (" << type_->get_width() << ") " + << " to=" << to->get_string() << " (" + << to->get_width() << ")" << std::endl; +#endif // If this expression hasn't been given a type then // we can't generate any type conversion code @@ -58,6 +60,8 @@ vhdl_expr *vhdl_expr::cast(const vhdl_type *to) return to_std_logic(); case VHDL_TYPE_STRING: return to_string(); + case VHDL_TYPE_STD_ULOGIC: + return to_std_ulogic(); default: assert(false); } @@ -206,6 +210,17 @@ vhdl_expr *vhdl_expr::to_std_logic() return NULL; } +vhdl_expr *vhdl_expr::to_std_ulogic() +{ + if (type_->get_name() == VHDL_TYPE_STD_LOGIC) { + vhdl_fcall *f = new vhdl_fcall("std_logic", vhdl_type::std_logic()); + f->add_expr(this); + return f; + } + else + assert(false); +} + /* * Change the width of a signed/unsigned type. */ @@ -325,6 +340,11 @@ vhdl_expr *vhdl_const_bit::to_boolean() return new vhdl_const_bool(bit_ == '1'); } +vhdl_expr *vhdl_const_bit::to_std_ulogic() +{ + return this; +} + vhdl_expr *vhdl_const_bit::to_vector(vhdl_type_name_t name, int w) { // Zero-extend this bit to the correct width diff --git a/tgt-vhdl/scope.cc b/tgt-vhdl/scope.cc index bb932e374..c7caa9716 100644 --- a/tgt-vhdl/scope.cc +++ b/tgt-vhdl/scope.cc @@ -277,6 +277,7 @@ void draw_nexus(ivl_nexus_t nexus) switch (signal_type_of_nexus(nexus, width)) { case IVL_SIT_TRI: + case IVL_SIT_UWIRE: def = 'Z'; break; case IVL_SIT_TRI0: @@ -556,9 +557,13 @@ static void declare_one_signal(vhdl_entity *ent, ivl_signal_t sig, sig_type = new vhdl_type(*array_type); } - else - sig_type = - vhdl_type::type_for(ivl_signal_width(sig), ivl_signal_signed(sig) != 0); + else { + sig_type = vhdl_type::type_for(ivl_signal_width(sig), + ivl_signal_signed(sig) != 0, + 0, ivl_signal_type(sig) == IVL_SIT_UWIRE); + + + } ivl_signal_port_t mode = ivl_signal_port(sig); switch (mode) { diff --git a/tgt-vhdl/vhdl_syntax.hh b/tgt-vhdl/vhdl_syntax.hh index 5d8ab2f83..80076f1c1 100644 --- a/tgt-vhdl/vhdl_syntax.hh +++ b/tgt-vhdl/vhdl_syntax.hh @@ -50,6 +50,7 @@ public: virtual vhdl_expr *to_boolean(); virtual vhdl_expr *to_integer(); virtual vhdl_expr *to_std_logic(); + virtual vhdl_expr *to_std_ulogic(); virtual vhdl_expr *to_vector(vhdl_type_name_t name, int w); virtual vhdl_expr *to_string(); virtual void find_vars(vhdl_var_set_t& read) {} @@ -211,6 +212,7 @@ public: vhdl_expr *to_boolean(); vhdl_expr *to_integer(); vhdl_expr *to_vector(vhdl_type_name_t name, int w); + vhdl_expr *to_std_ulogic(); private: char bit_; }; diff --git a/tgt-vhdl/vhdl_type.cc b/tgt-vhdl/vhdl_type.cc index 9442826c3..c448f6a5e 100644 --- a/tgt-vhdl/vhdl_type.cc +++ b/tgt-vhdl/vhdl_type.cc @@ -24,12 +24,16 @@ #include #include - vhdl_type *vhdl_type::std_logic() { return new vhdl_type(VHDL_TYPE_STD_LOGIC); } +vhdl_type *vhdl_type::std_ulogic() +{ + return new vhdl_type(VHDL_TYPE_STD_ULOGIC); +} + vhdl_type *vhdl_type::string() { return new vhdl_type(VHDL_TYPE_STRING); @@ -79,6 +83,8 @@ std::string vhdl_type::get_string() const switch (name_) { case VHDL_TYPE_STD_LOGIC: return std::string("std_logic"); + case VHDL_TYPE_STD_ULOGIC: + return std::string("std_ulogic"); case VHDL_TYPE_STD_LOGIC_VECTOR: return std::string("std_logic_vector"); case VHDL_TYPE_STRING: @@ -167,10 +173,15 @@ vhdl_type *vhdl_type::std_logic_vector(int msb, int lsb) return new vhdl_type(VHDL_TYPE_STD_LOGIC_VECTOR, msb, lsb); } -vhdl_type *vhdl_type::type_for(int width, bool issigned, int lsb) +vhdl_type *vhdl_type::type_for(int width, bool issigned, + int lsb, bool unresolved) { - if (width == 1) - return vhdl_type::std_logic(); + if (width == 1) { + if (unresolved) + return vhdl_type::std_ulogic(); + else + return vhdl_type::std_logic(); + } else if (issigned) return vhdl_type::nsigned(width, lsb); else diff --git a/tgt-vhdl/vhdl_type.hh b/tgt-vhdl/vhdl_type.hh index 3d551a3f2..9786ab9ad 100644 --- a/tgt-vhdl/vhdl_type.hh +++ b/tgt-vhdl/vhdl_type.hh @@ -25,6 +25,7 @@ enum vhdl_type_name_t { VHDL_TYPE_STD_LOGIC, + VHDL_TYPE_STD_ULOGIC, VHDL_TYPE_STD_LOGIC_VECTOR, VHDL_TYPE_STRING, VHDL_TYPE_LINE, @@ -71,6 +72,7 @@ public: // Common types static vhdl_type *std_logic(); + static vhdl_type *std_ulogic(); static vhdl_type *string(); static vhdl_type *line(); static vhdl_type *std_logic_vector(int msb, int lsb); @@ -80,7 +82,8 @@ public: static vhdl_type *boolean(); static vhdl_type *time(); - static vhdl_type *type_for(int width, bool issigned, int lsb=0); + static vhdl_type *type_for(int width, bool issigned, + int lsb=0, bool unresolved=false); static vhdl_type *array_of(vhdl_type *b, std::string &n, int m, int l); protected: vhdl_type_name_t name_;