tgt-vhdl: Improve temporary signal name generation to avoid collisions
Fixes regression of simple_gen test. Also extended ivl_lpm_size API call to support all LPM types. This simplifies some of the VHDL LPM generation code a little.
This commit is contained in:
parent
186a677f4a
commit
9a48166855
30
t-dll-api.cc
30
t-dll-api.cc
|
|
@ -1424,6 +1424,36 @@ extern "C" unsigned ivl_lpm_size(ivl_lpm_t net)
|
|||
return net->u_.repeat.count;
|
||||
case IVL_LPM_CONCAT:
|
||||
return net->u_.concat.inputs;
|
||||
case IVL_LPM_ABS:
|
||||
case IVL_LPM_CAST_INT:
|
||||
case IVL_LPM_CAST_INT2:
|
||||
case IVL_LPM_CAST_REAL:
|
||||
case IVL_LPM_RE_AND:
|
||||
case IVL_LPM_RE_OR:
|
||||
case IVL_LPM_RE_XOR:
|
||||
case IVL_LPM_RE_NAND:
|
||||
case IVL_LPM_RE_NOR:
|
||||
case IVL_LPM_RE_XNOR:
|
||||
case IVL_LPM_SIGN_EXT:
|
||||
case IVL_LPM_FF:
|
||||
return 1;
|
||||
case IVL_LPM_ADD:
|
||||
case IVL_LPM_CMP_EEQ:
|
||||
case IVL_LPM_CMP_EQ:
|
||||
case IVL_LPM_CMP_GE:
|
||||
case IVL_LPM_CMP_GT:
|
||||
case IVL_LPM_CMP_NE:
|
||||
case IVL_LPM_CMP_NEE:
|
||||
case IVL_LPM_DIVIDE:
|
||||
case IVL_LPM_MOD:
|
||||
case IVL_LPM_MULT:
|
||||
case IVL_LPM_POW:
|
||||
case IVL_LPM_SUB:
|
||||
case IVL_LPM_SHIFTL:
|
||||
case IVL_LPM_SHIFTR:
|
||||
case IVL_LPM_PART_VP:
|
||||
case IVL_LPM_PART_PV:
|
||||
return 2;
|
||||
default:
|
||||
assert(0);
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -41,26 +41,6 @@ static vhdl_expr *part_select_base(vhdl_scope *scope, ivl_lpm_t lpm)
|
|||
return off->cast(&integer);
|
||||
}
|
||||
|
||||
static vhdl_expr *concat_lpm_to_expr(vhdl_scope *scope, ivl_lpm_t lpm)
|
||||
{
|
||||
vhdl_type *result_type =
|
||||
vhdl_type::type_for(ivl_lpm_width(lpm), ivl_lpm_signed(lpm) != 0);
|
||||
vhdl_binop_expr *expr =
|
||||
new vhdl_binop_expr(VHDL_BINOP_CONCAT, result_type);
|
||||
|
||||
for (int i = ivl_lpm_size(lpm) - 1; i >= 0; i--) {
|
||||
vhdl_expr *e = readable_ref(scope, ivl_lpm_data(lpm, i));
|
||||
if (NULL == e) {
|
||||
delete expr;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
expr->add_expr(e);
|
||||
}
|
||||
|
||||
return expr;
|
||||
}
|
||||
|
||||
static vhdl_expr *binop_lpm_to_expr(vhdl_scope *scope, ivl_lpm_t lpm, vhdl_binop_t op)
|
||||
{
|
||||
unsigned out_width = ivl_lpm_width(lpm);
|
||||
|
|
@ -68,14 +48,21 @@ static vhdl_expr *binop_lpm_to_expr(vhdl_scope *scope, ivl_lpm_t lpm, vhdl_binop
|
|||
vhdl_type::type_for(out_width, ivl_lpm_signed(lpm) != 0);
|
||||
vhdl_binop_expr *expr = new vhdl_binop_expr(op, result_type);
|
||||
|
||||
for (int i = 0; i < 2; i++) {
|
||||
for (unsigned i = 0; i < ivl_lpm_size(lpm); i++) {
|
||||
vhdl_expr *e = readable_ref(scope, ivl_lpm_data(lpm, i));
|
||||
if (NULL == e) {
|
||||
delete expr;
|
||||
if (NULL == e)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
expr->add_expr(e->cast(result_type));
|
||||
// It's possible that the inputs are a mixture of signed and unsigned
|
||||
// in which case we must cast them to the output type
|
||||
e = e->cast(vhdl_type::type_for(e->get_type()->get_width(),
|
||||
ivl_lpm_signed(lpm) != 0));
|
||||
|
||||
// Bit of a hack: the LPM inputs are in the wrong order for concatenation
|
||||
if (op == VHDL_BINOP_CONCAT)
|
||||
expr->add_expr_front(e);
|
||||
else
|
||||
expr->add_expr(e);
|
||||
}
|
||||
|
||||
if (op == VHDL_BINOP_MULT) {
|
||||
|
|
@ -256,7 +243,7 @@ static vhdl_expr *lpm_to_expr(vhdl_scope *scope, ivl_lpm_t lpm)
|
|||
case IVL_LPM_MOD:
|
||||
return binop_lpm_to_expr(scope, lpm, VHDL_BINOP_MOD);
|
||||
case IVL_LPM_CONCAT:
|
||||
return concat_lpm_to_expr(scope, lpm);
|
||||
return binop_lpm_to_expr(scope, lpm, VHDL_BINOP_CONCAT);
|
||||
case IVL_LPM_CMP_GE:
|
||||
return rel_lpm_to_expr(scope, lpm, VHDL_BINOP_GEQ);
|
||||
case IVL_LPM_CMP_GT:
|
||||
|
|
|
|||
|
|
@ -239,7 +239,16 @@ void draw_nexus(ivl_nexus_t nexus)
|
|||
vhdl_type *type = vhdl_type::type_for(lpm_temp_width,
|
||||
ivl_lpm_signed(lpm) != 0);
|
||||
ostringstream ss;
|
||||
ss << "LPM" << ivl_lpm_basename(lpm);
|
||||
ss << "LPM";
|
||||
if (nexus == ivl_lpm_q(lpm))
|
||||
ss << "_q";
|
||||
else {
|
||||
for (unsigned d = 0; d < ivl_lpm_size(lpm); d++) {
|
||||
if (nexus == ivl_lpm_data(lpm, d))
|
||||
ss << "_d" << d;
|
||||
}
|
||||
}
|
||||
ss << ivl_lpm_basename(lpm);
|
||||
|
||||
if (!vhdl_scope->have_declared(ss.str()))
|
||||
vhdl_scope->add_decl(new vhdl_signal_decl(ss.str().c_str(), type));
|
||||
|
|
|
|||
|
|
@ -940,6 +940,11 @@ void vhdl_binop_expr::add_expr(vhdl_expr *e)
|
|||
operands_.push_back(e);
|
||||
}
|
||||
|
||||
void vhdl_binop_expr::add_expr_front(vhdl_expr *e)
|
||||
{
|
||||
operands_.push_front(e);
|
||||
}
|
||||
|
||||
void vhdl_binop_expr::find_vars(vhdl_var_set_t& read)
|
||||
{
|
||||
for (list<vhdl_expr*>::const_iterator it = operands_.begin();
|
||||
|
|
|
|||
|
|
@ -126,6 +126,7 @@ public:
|
|||
~vhdl_binop_expr();
|
||||
|
||||
void add_expr(vhdl_expr *e);
|
||||
void add_expr_front(vhdl_expr *e);
|
||||
void emit(std::ostream &of, int level) const;
|
||||
void find_vars(vhdl_var_set_t& read);
|
||||
private:
|
||||
|
|
|
|||
Loading…
Reference in New Issue