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:
Nick Gasson 2011-04-06 21:27:24 +01:00 committed by Stephen Williams
parent 186a677f4a
commit 9a48166855
5 changed files with 59 additions and 27 deletions

View File

@ -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;

View File

@ -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:

View File

@ -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));

View File

@ -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();

View File

@ -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: