diff --git a/tgt-vhdl/expr.cc b/tgt-vhdl/expr.cc index 2685bbfb9..4910310d0 100644 --- a/tgt-vhdl/expr.cc +++ b/tgt-vhdl/expr.cc @@ -212,8 +212,12 @@ static vhdl_expr *translate_binary(ivl_expr_t e) return translate_logical(lhs, rhs, VHDL_BINOP_OR); case '<': return translate_relation(lhs, rhs, VHDL_BINOP_LT); + case 'L': + return translate_relation(lhs, rhs, VHDL_BINOP_LEQ); case '>': return translate_relation(lhs, rhs, VHDL_BINOP_GT); + case 'G': + return translate_relation(lhs, rhs, VHDL_BINOP_GEQ); case 'l': return translate_shift(lhs, rhs, VHDL_BINOP_SL); case 'r': @@ -231,12 +235,23 @@ static vhdl_expr *translate_binary(ivl_expr_t e) static vhdl_expr *translate_select(ivl_expr_t e) { - vhdl_expr *from = translate_expr(ivl_expr_oper1(e)); + vhdl_var_ref *from = + dynamic_cast(translate_expr(ivl_expr_oper1(e))); if (NULL == from) - return NULL; - - // Hack: resize it to the correct size - return from->resize(ivl_expr_width(e)); + return NULL; + + ivl_expr_t o2 = ivl_expr_oper2(e); + if (o2) { + vhdl_expr *base = translate_expr(ivl_expr_oper2(e)); + if (NULL == base) + return NULL; + + vhdl_type integer(VHDL_TYPE_INTEGER); + from->set_slice(base->cast(&integer), ivl_expr_width(e) - 1); + return from; + } + else + return from->resize(ivl_expr_width(e)); } static vhdl_type *expr_to_vhdl_type(ivl_expr_t e) diff --git a/tgt-vhdl/stmt.cc b/tgt-vhdl/stmt.cc index 559fa0ac8..302833b75 100644 --- a/tgt-vhdl/stmt.cc +++ b/tgt-vhdl/stmt.cc @@ -194,9 +194,10 @@ static T *make_vhdl_assignment(vhdl_procedural *proc, stmt_container *container, // The signal may have been renamed by the above call signame = get_renamed_signal(sig); } - - // The type here can be null as it is never actually needed - vhdl_var_ref *lval_ref = new vhdl_var_ref(signame.c_str(), NULL); + + vhdl_type *ltype = + new vhdl_type(*proc->get_scope()->get_decl(signame)->get_type()); + vhdl_var_ref *lval_ref = new vhdl_var_ref(signame.c_str(), ltype); if (base) lval_ref->set_slice(base, lval_width-1); diff --git a/tgt-vhdl/vhdl.cc b/tgt-vhdl/vhdl.cc index 4ef96119a..c8563c488 100644 --- a/tgt-vhdl/vhdl.cc +++ b/tgt-vhdl/vhdl.cc @@ -102,8 +102,6 @@ void remember_signal(ivl_signal_t sig, const vhdl_scope *scope) { assert(!seen_signal_before(sig)); - std::cout << "remember_signal " << ivl_signal_name(sig) << std::endl; - signal_defn_t defn = { ivl_signal_basename(sig), scope }; g_known_signals[sig] = defn; } diff --git a/tgt-vhdl/vhdl_syntax.cc b/tgt-vhdl/vhdl_syntax.cc index df07bff65..a937135d0 100644 --- a/tgt-vhdl/vhdl_syntax.cc +++ b/tgt-vhdl/vhdl_syntax.cc @@ -482,6 +482,25 @@ vhdl_var_ref::~vhdl_var_ref() delete slice_; } +void vhdl_var_ref::set_slice(vhdl_expr *s, int w) +{ + assert(type_); + + vhdl_type_name_t tname = type_->get_name(); + assert(tname == VHDL_TYPE_UNSIGNED || tname == VHDL_TYPE_SIGNED); + + slice_ = s; + slice_width_ = w; + + if (type_) + delete type_; + + if (w > 0) + type_ = new vhdl_type(tname, w); + else + type_ = vhdl_type::std_logic(); +} + void vhdl_var_ref::emit(std::ostream &of, int level) const { of << name_; @@ -719,7 +738,7 @@ void vhdl_binop_expr::emit(std::ostream &of, int level) const while (++it != operands_.end()) { const char* ops[] = { "and", "or", "=", "/=", "+", "-", "*", "<", - ">", "sll", "srl", "xor", "&" + ">", "<=", ">=", "sll", "srl", "xor", "&" }; of << " " << ops[op_] << " "; diff --git a/tgt-vhdl/vhdl_syntax.hh b/tgt-vhdl/vhdl_syntax.hh index 0e3968327..89b26d217 100644 --- a/tgt-vhdl/vhdl_syntax.hh +++ b/tgt-vhdl/vhdl_syntax.hh @@ -38,7 +38,7 @@ public: bool constant() const { return isconst_; } virtual vhdl_expr *cast(const vhdl_type *to); virtual vhdl_expr *resize(int newwidth); -private: +protected: vhdl_type *type_; bool isconst_; }; @@ -56,7 +56,7 @@ public: void emit(std::ostream &of, int level) const; const std::string &get_name() const { return name_; } - void set_slice(vhdl_expr *s, int w=0) { slice_ = s; slice_width_ = w; } + void set_slice(vhdl_expr *s, int w=0); private: std::string name_; vhdl_expr *slice_; @@ -74,6 +74,8 @@ enum vhdl_binop_t { VHDL_BINOP_MULT, VHDL_BINOP_LT, VHDL_BINOP_GT, + VHDL_BINOP_LEQ, + VHDL_BINOP_GEQ, VHDL_BINOP_SL, VHDL_BINOP_SR, VHDL_BINOP_XOR,