Skip to content

Commit

Permalink
tgt-vhdl: Improve temporary signal name generation to avoid collisions
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
nickg authored and steveicarus committed Apr 7, 2011
1 parent 186a677 commit 9a48166
Show file tree
Hide file tree
Showing 5 changed files with 59 additions and 27 deletions.
30 changes: 30 additions & 0 deletions t-dll-api.cc
Expand Up @@ -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;
Expand Down
39 changes: 13 additions & 26 deletions tgt-vhdl/lpm.cc
Expand Up @@ -41,41 +41,28 @@ 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);
vhdl_type *result_type =
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) {
Expand Down Expand Up @@ -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:
Expand Down
11 changes: 10 additions & 1 deletion tgt-vhdl/scope.cc
Expand Up @@ -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));
Expand Down
5 changes: 5 additions & 0 deletions tgt-vhdl/vhdl_syntax.cc
Expand Up @@ -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();
Expand Down
1 change: 1 addition & 0 deletions tgt-vhdl/vhdl_syntax.hh
Expand Up @@ -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:
Expand Down

0 comments on commit 9a48166

Please sign in to comment.