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));
|
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)
|
static vhdl_expr *translate_ufunc(ivl_expr_t e)
|
||||||
{
|
{
|
||||||
ivl_scope_t defscope = ivl_expr_def(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);
|
const char *funcname = ivl_scope_tname(defscope);
|
||||||
|
|
||||||
vhdl_type *rettype;
|
vhdl_type *rettype = expr_to_vhdl_type(e);
|
||||||
if (ivl_expr_signed(e))
|
|
||||||
rettype = vhdl_type::nsigned(ivl_expr_width(e));
|
|
||||||
else
|
|
||||||
rettype = vhdl_type::nunsigned(ivl_expr_width(e));
|
|
||||||
|
|
||||||
vhdl_fcall *fcall = new vhdl_fcall(funcname, rettype);
|
vhdl_fcall *fcall = new vhdl_fcall(funcname, rettype);
|
||||||
|
|
||||||
int nparams = ivl_expr_parms(e);
|
return translate_parms<vhdl_fcall>(fcall, 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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static vhdl_expr *translate_ternary(ivl_expr_t 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;
|
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.
|
* Generate a VHDL expression from a Verilog expression.
|
||||||
*/
|
*/
|
||||||
|
|
@ -284,6 +301,8 @@ vhdl_expr *translate_expr(ivl_expr_t e)
|
||||||
return translate_ufunc(e);
|
return translate_ufunc(e);
|
||||||
case IVL_EX_TERNARY:
|
case IVL_EX_TERNARY:
|
||||||
return translate_ternary(e);
|
return translate_ternary(e);
|
||||||
|
case IVL_EX_CONCAT:
|
||||||
|
return translate_concat(e);
|
||||||
default:
|
default:
|
||||||
error("No VHDL translation for expression at %s:%d (type = %d)",
|
error("No VHDL translation for expression at %s:%d (type = %d)",
|
||||||
ivl_expr_file(e), ivl_expr_lineno(e), type);
|
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[] = {
|
const char *vhdl_reserved[] = {
|
||||||
"in", "out", "entity", "architecture", "inout", "array",
|
"in", "out", "entity", "architecture", "inout", "array",
|
||||||
"is", "not", "and", "or", "bus", "bit", // Etc...
|
"is", "not", "and", "or", "bus", "bit", "line", // Etc...
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
for (const char **p = vhdl_reserved; *p != NULL; p++) {
|
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
|
// result of the expression and that is mapped to the port
|
||||||
// This is actually a bit stricter than necessary: but turns out
|
// This is actually a bit stricter than necessary: but turns out
|
||||||
// to be much easier to implement
|
// 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;
|
vhdl_var_ref *to_ref;
|
||||||
if ((to_ref = dynamic_cast<vhdl_var_ref*>(to_e))) {
|
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 {
|
else {
|
||||||
// Not a static expression
|
// Not a static expression
|
||||||
std::string tmpname(inst->get_inst_name().c_str());
|
std::string tmpname(inst->get_inst_name().c_str());
|
||||||
tmpname += "_";
|
tmpname += "_";
|
||||||
tmpname += basename;
|
tmpname += name;
|
||||||
tmpname += "_Expr";
|
tmpname += "_Expr";
|
||||||
|
|
||||||
vhdl_type *tmptype = new vhdl_type(*to_e->get_type());
|
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));
|
parent->get_arch()->add_stmt(new vhdl_cassign_stmt(tmp_ref1, to_e));
|
||||||
|
|
||||||
vhdl_var_ref *tmp_ref2 = new vhdl_var_ref(*tmp_ref1);
|
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()) {
|
while (++it != operands_.end()) {
|
||||||
const char* ops[] = {
|
const char* ops[] = {
|
||||||
"and", "or", "=", "/=", "+", "-", "*", "<",
|
"and", "or", "=", "/=", "+", "-", "*", "<",
|
||||||
">", "sll", "srl", "xor"
|
">", "sll", "srl", "xor", "&"
|
||||||
};
|
};
|
||||||
|
|
||||||
of << " " << ops[op_] << " ";
|
of << " " << ops[op_] << " ";
|
||||||
|
|
|
||||||
|
|
@ -76,6 +76,7 @@ enum vhdl_binop_t {
|
||||||
VHDL_BINOP_SL,
|
VHDL_BINOP_SL,
|
||||||
VHDL_BINOP_SR,
|
VHDL_BINOP_SR,
|
||||||
VHDL_BINOP_XOR,
|
VHDL_BINOP_XOR,
|
||||||
|
VHDL_BINOP_CONCAT,
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue