diff --git a/tgt-vhdl/expr.cc b/tgt-vhdl/expr.cc index 07cd703cb..447857bf6 100644 --- a/tgt-vhdl/expr.cc +++ b/tgt-vhdl/expr.cc @@ -218,6 +218,29 @@ static vhdl_expr *translate_select(ivl_expr_t e) return from->resize(ivl_expr_width(e)); } +static vhdl_type *expr_to_vhdl_type(ivl_expr_t e) +{ + if (ivl_expr_signed(e)) + return vhdl_type::nsigned(ivl_expr_width(e)); + else + return vhdl_type::nunsigned(ivl_expr_width(e)); +} + +template +static T *translate_parms(T *t, ivl_expr_t e) +{ + int nparams = ivl_expr_parms(e); + for (int i = 0; i < nparams; i++) { + vhdl_expr *param = translate_expr(ivl_expr_parm(e, i)); + if (NULL == param) + return NULL; + + t->add_expr(param); + } + + return t; +} + static vhdl_expr *translate_ufunc(ivl_expr_t e) { ivl_scope_t defscope = ivl_expr_def(e); @@ -232,24 +255,10 @@ static vhdl_expr *translate_ufunc(ivl_expr_t e) const char *funcname = ivl_scope_tname(defscope); - vhdl_type *rettype; - if (ivl_expr_signed(e)) - rettype = vhdl_type::nsigned(ivl_expr_width(e)); - else - rettype = vhdl_type::nunsigned(ivl_expr_width(e)); - + vhdl_type *rettype = expr_to_vhdl_type(e); vhdl_fcall *fcall = new vhdl_fcall(funcname, rettype); - int nparams = ivl_expr_parms(e); - for (int i = 0; i < nparams; i++) { - vhdl_expr *param = translate_expr(ivl_expr_parm(e, i)); - if (NULL == param) - return NULL; - - fcall->add_expr(param); - } - - return fcall; + return translate_parms(fcall, e); } static vhdl_expr *translate_ternary(ivl_expr_t e) @@ -259,6 +268,14 @@ static vhdl_expr *translate_ternary(ivl_expr_t e) return NULL; } +static vhdl_expr *translate_concat(ivl_expr_t e) +{ + vhdl_type *rtype = expr_to_vhdl_type(e); + vhdl_binop_expr *concat = new vhdl_binop_expr(VHDL_BINOP_CONCAT, rtype); + + return translate_parms(concat, e); +} + /* * Generate a VHDL expression from a Verilog expression. */ @@ -284,6 +301,8 @@ vhdl_expr *translate_expr(ivl_expr_t e) return translate_ufunc(e); case IVL_EX_TERNARY: return translate_ternary(e); + case IVL_EX_CONCAT: + return translate_concat(e); default: error("No VHDL translation for expression at %s:%d (type = %d)", ivl_expr_file(e), ivl_expr_lineno(e), type); diff --git a/tgt-vhdl/scope.cc b/tgt-vhdl/scope.cc index 0d6b8dd88..da0375d95 100644 --- a/tgt-vhdl/scope.cc +++ b/tgt-vhdl/scope.cc @@ -185,7 +185,7 @@ static std::string make_safe_name(ivl_signal_t sig) const char *vhdl_reserved[] = { "in", "out", "entity", "architecture", "inout", "array", - "is", "not", "and", "or", "bus", "bit", // Etc... + "is", "not", "and", "or", "bus", "bit", "line", // Etc... NULL }; for (const char **p = vhdl_reserved; *p != NULL; p++) { @@ -354,16 +354,16 @@ static void map_signal(ivl_signal_t to, vhdl_entity *parent, // result of the expression and that is mapped to the port // This is actually a bit stricter than necessary: but turns out // to be much easier to implement - const char *basename = ivl_signal_basename(to); + std::string name = make_safe_name(to); vhdl_var_ref *to_ref; if ((to_ref = dynamic_cast(to_e))) { - inst->map_port(basename, to_ref); + inst->map_port(name.c_str(), to_ref); } else { // Not a static expression std::string tmpname(inst->get_inst_name().c_str()); tmpname += "_"; - tmpname += basename; + tmpname += name; tmpname += "_Expr"; vhdl_type *tmptype = new vhdl_type(*to_e->get_type()); @@ -374,7 +374,7 @@ static void map_signal(ivl_signal_t to, vhdl_entity *parent, parent->get_arch()->add_stmt(new vhdl_cassign_stmt(tmp_ref1, to_e)); vhdl_var_ref *tmp_ref2 = new vhdl_var_ref(*tmp_ref1); - inst->map_port(basename, tmp_ref2); + inst->map_port(name.c_str(), tmp_ref2); } } diff --git a/tgt-vhdl/vhdl_syntax.cc b/tgt-vhdl/vhdl_syntax.cc index 764898033..d4773fa97 100644 --- a/tgt-vhdl/vhdl_syntax.cc +++ b/tgt-vhdl/vhdl_syntax.cc @@ -705,7 +705,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 c87eea284..c45351d18 100644 --- a/tgt-vhdl/vhdl_syntax.hh +++ b/tgt-vhdl/vhdl_syntax.hh @@ -76,6 +76,7 @@ enum vhdl_binop_t { VHDL_BINOP_SL, VHDL_BINOP_SR, VHDL_BINOP_XOR, + VHDL_BINOP_CONCAT, }; /*