vlog95: Fix some bugs when emitting a logical device as a CA, etc.
When emitting a logical device as part of a continuous assignment we need to use the actual inputs (not the output). We also do not need to emit anything if the nexus is NULL. Also skip logical gates that have a local output since they are part of a continuous assignment and the inputs to a logical gate can be an expression so emit them as a continuous assignment.
This commit is contained in:
parent
bfb04998c5
commit
2a9e15e8d8
|
|
@ -217,6 +217,8 @@ static void emit_lpm_as_ca(ivl_scope_t scope, ivl_lpm_t lpm);
|
||||||
|
|
||||||
static void emit_nexus_as_ca(ivl_scope_t scope, ivl_nexus_t nex)
|
static void emit_nexus_as_ca(ivl_scope_t scope, ivl_nexus_t nex)
|
||||||
{
|
{
|
||||||
|
/* If there is no nexus then there is nothing to print. */
|
||||||
|
if (! nex) return;
|
||||||
/* A local nexus only has a single driver. */
|
/* A local nexus only has a single driver. */
|
||||||
if (is_local_nexus(scope, nex)) {
|
if (is_local_nexus(scope, nex)) {
|
||||||
unsigned idx, count = ivl_nexus_ptrs(nex);
|
unsigned idx, count = ivl_nexus_ptrs(nex);
|
||||||
|
|
@ -280,42 +282,43 @@ static void emit_logic_as_ca(ivl_scope_t scope, ivl_net_logic_t nlogic)
|
||||||
// HERE: Do we need to check that the pin count is correct for these?
|
// HERE: Do we need to check that the pin count is correct for these?
|
||||||
switch (ivl_logic_type(nlogic)) {
|
switch (ivl_logic_type(nlogic)) {
|
||||||
case IVL_LO_AND:
|
case IVL_LO_AND:
|
||||||
emit_nexus_as_ca(scope, ivl_logic_pin(nlogic, 0));
|
|
||||||
fprintf(vlog_out, " & ");
|
|
||||||
emit_nexus_as_ca(scope, ivl_logic_pin(nlogic, 1));
|
emit_nexus_as_ca(scope, ivl_logic_pin(nlogic, 1));
|
||||||
|
fprintf(vlog_out, " & ");
|
||||||
|
emit_nexus_as_ca(scope, ivl_logic_pin(nlogic, 2));
|
||||||
break;
|
break;
|
||||||
case IVL_LO_BUF:
|
case IVL_LO_BUF:
|
||||||
// case IVL_LO_BUFT:
|
// case IVL_LO_BUFT:
|
||||||
case IVL_LO_BUFZ:
|
case IVL_LO_BUFZ:
|
||||||
emit_nexus_as_ca(scope, ivl_logic_pin(nlogic, 0));
|
emit_nexus_as_ca(scope, ivl_logic_pin(nlogic, 1));
|
||||||
break;
|
break;
|
||||||
case IVL_LO_NAND:
|
case IVL_LO_NAND:
|
||||||
emit_nexus_as_ca(scope, ivl_logic_pin(nlogic, 0));
|
|
||||||
fprintf(vlog_out, " ~& ");
|
|
||||||
emit_nexus_as_ca(scope, ivl_logic_pin(nlogic, 1));
|
emit_nexus_as_ca(scope, ivl_logic_pin(nlogic, 1));
|
||||||
|
fprintf(vlog_out, " ~& ");
|
||||||
|
emit_nexus_as_ca(scope, ivl_logic_pin(nlogic, 2));
|
||||||
break;
|
break;
|
||||||
case IVL_LO_NOR:
|
case IVL_LO_NOR:
|
||||||
emit_nexus_as_ca(scope, ivl_logic_pin(nlogic, 0));
|
|
||||||
fprintf(vlog_out, " ~| ");
|
|
||||||
emit_nexus_as_ca(scope, ivl_logic_pin(nlogic, 1));
|
emit_nexus_as_ca(scope, ivl_logic_pin(nlogic, 1));
|
||||||
|
fprintf(vlog_out, " ~| ");
|
||||||
|
emit_nexus_as_ca(scope, ivl_logic_pin(nlogic, 2));
|
||||||
break;
|
break;
|
||||||
case IVL_LO_NOT:
|
case IVL_LO_NOT:
|
||||||
fprintf(vlog_out, "~ ");
|
fprintf(vlog_out, "~ ");
|
||||||
emit_nexus_as_ca(scope, ivl_logic_pin(nlogic, 0));
|
|
||||||
case IVL_LO_OR:
|
|
||||||
emit_nexus_as_ca(scope, ivl_logic_pin(nlogic, 0));
|
|
||||||
fprintf(vlog_out, " | ");
|
|
||||||
emit_nexus_as_ca(scope, ivl_logic_pin(nlogic, 1));
|
emit_nexus_as_ca(scope, ivl_logic_pin(nlogic, 1));
|
||||||
break;
|
break;
|
||||||
|
case IVL_LO_OR:
|
||||||
|
emit_nexus_as_ca(scope, ivl_logic_pin(nlogic, 1));
|
||||||
|
fprintf(vlog_out, " | ");
|
||||||
|
emit_nexus_as_ca(scope, ivl_logic_pin(nlogic, 2));
|
||||||
|
break;
|
||||||
case IVL_LO_XNOR:
|
case IVL_LO_XNOR:
|
||||||
emit_nexus_as_ca(scope, ivl_logic_pin(nlogic, 0));
|
|
||||||
fprintf(vlog_out, " ~^ ");
|
|
||||||
emit_nexus_as_ca(scope, ivl_logic_pin(nlogic, 1));
|
emit_nexus_as_ca(scope, ivl_logic_pin(nlogic, 1));
|
||||||
|
fprintf(vlog_out, " ~^ ");
|
||||||
|
emit_nexus_as_ca(scope, ivl_logic_pin(nlogic, 2));
|
||||||
break;
|
break;
|
||||||
case IVL_LO_XOR:
|
case IVL_LO_XOR:
|
||||||
emit_nexus_as_ca(scope, ivl_logic_pin(nlogic, 0));
|
|
||||||
fprintf(vlog_out, " ^ ");
|
|
||||||
emit_nexus_as_ca(scope, ivl_logic_pin(nlogic, 1));
|
emit_nexus_as_ca(scope, ivl_logic_pin(nlogic, 1));
|
||||||
|
fprintf(vlog_out, " ^ ");
|
||||||
|
emit_nexus_as_ca(scope, ivl_logic_pin(nlogic, 2));
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
fprintf(vlog_out, "<unknown>");
|
fprintf(vlog_out, "<unknown>");
|
||||||
|
|
@ -770,6 +773,10 @@ void emit_logic(ivl_scope_t scope, ivl_net_logic_t nlogic)
|
||||||
// compiler to support logical 'and' and logical 'or' since they
|
// compiler to support logical 'and' and logical 'or' since they
|
||||||
// short circuit.
|
// short circuit.
|
||||||
unsigned idx, count, dly_count, strength_type = 2;
|
unsigned idx, count, dly_count, strength_type = 2;
|
||||||
|
unsigned outputs = 1;
|
||||||
|
/* Skip gates that have a local nexus as the output since they are
|
||||||
|
* part of a continuous assignment. */
|
||||||
|
if (is_local_nexus(scope, ivl_logic_pin(nlogic, 0))) return;
|
||||||
fprintf(vlog_out, "%*c", indent, ' ');
|
fprintf(vlog_out, "%*c", indent, ' ');
|
||||||
switch (ivl_logic_type(nlogic)) {
|
switch (ivl_logic_type(nlogic)) {
|
||||||
case IVL_LO_AND:
|
case IVL_LO_AND:
|
||||||
|
|
@ -779,6 +786,7 @@ void emit_logic(ivl_scope_t scope, ivl_net_logic_t nlogic)
|
||||||
case IVL_LO_BUF:
|
case IVL_LO_BUF:
|
||||||
fprintf(vlog_out, "buf");
|
fprintf(vlog_out, "buf");
|
||||||
dly_count = 2;
|
dly_count = 2;
|
||||||
|
outputs = 0;
|
||||||
break;
|
break;
|
||||||
case IVL_LO_BUFIF0:
|
case IVL_LO_BUFIF0:
|
||||||
fprintf(vlog_out, "bufif0");
|
fprintf(vlog_out, "bufif0");
|
||||||
|
|
@ -811,6 +819,7 @@ void emit_logic(ivl_scope_t scope, ivl_net_logic_t nlogic)
|
||||||
case IVL_LO_NOT:
|
case IVL_LO_NOT:
|
||||||
fprintf(vlog_out, "not");
|
fprintf(vlog_out, "not");
|
||||||
dly_count = 2;
|
dly_count = 2;
|
||||||
|
outputs = 0;
|
||||||
break;
|
break;
|
||||||
case IVL_LO_NOTIF0:
|
case IVL_LO_NOTIF0:
|
||||||
fprintf(vlog_out, "notif0");
|
fprintf(vlog_out, "notif0");
|
||||||
|
|
@ -884,11 +893,16 @@ void emit_logic(ivl_scope_t scope, ivl_net_logic_t nlogic)
|
||||||
fprintf(vlog_out, " (");
|
fprintf(vlog_out, " (");
|
||||||
count = ivl_logic_pins(nlogic);
|
count = ivl_logic_pins(nlogic);
|
||||||
count -= 1;
|
count -= 1;
|
||||||
for (idx = 0; idx < count; idx += 1) {
|
if (outputs == 0) outputs = count;
|
||||||
|
for (idx = 0; idx < outputs; idx += 1) {
|
||||||
emit_name_of_logic_nexus(scope, nlogic, ivl_logic_pin(nlogic, idx));
|
emit_name_of_logic_nexus(scope, nlogic, ivl_logic_pin(nlogic, idx));
|
||||||
fprintf(vlog_out, ", ");
|
fprintf(vlog_out, ", ");
|
||||||
}
|
}
|
||||||
emit_name_of_logic_nexus(scope, nlogic, ivl_logic_pin(nlogic, count));
|
for (/* None */; idx < count; idx += 1) {
|
||||||
|
emit_nexus_as_ca(scope, ivl_logic_pin(nlogic, idx));
|
||||||
|
fprintf(vlog_out, ", ");
|
||||||
|
}
|
||||||
|
emit_nexus_as_ca(scope, ivl_logic_pin(nlogic, count));
|
||||||
fprintf(vlog_out, ");\n");
|
fprintf(vlog_out, ");\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -953,7 +967,7 @@ void emit_tran(ivl_scope_t scope, ivl_switch_t tran)
|
||||||
emit_name_of_nexus(scope, ivl_switch_b(tran));
|
emit_name_of_nexus(scope, ivl_switch_b(tran));
|
||||||
if (pins == 3) {
|
if (pins == 3) {
|
||||||
fprintf(vlog_out, ", ");
|
fprintf(vlog_out, ", ");
|
||||||
emit_name_of_nexus(scope, ivl_switch_enable(tran));
|
emit_nexus_as_ca(scope, ivl_switch_enable(tran));
|
||||||
}
|
}
|
||||||
fprintf(vlog_out, ");\n");
|
fprintf(vlog_out, ");\n");
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue