Add concatenation operator
This commit is contained in:
parent
85d2cc78d6
commit
c33600bcc3
|
|
@ -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 <class T>
|
||||
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<vhdl_fcall>(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<vhdl_binop_expr>(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);
|
||||
|
|
|
|||
|
|
@ -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<vhdl_var_ref*>(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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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_] << " ";
|
||||
|
|
|
|||
|
|
@ -76,6 +76,7 @@ enum vhdl_binop_t {
|
|||
VHDL_BINOP_SL,
|
||||
VHDL_BINOP_SR,
|
||||
VHDL_BINOP_XOR,
|
||||
VHDL_BINOP_CONCAT,
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
|
|||
Loading…
Reference in New Issue