vlog95: Fix the passing of the sign extend information in a CA
This commit is contained in:
parent
7fa4cf5a34
commit
0e8a257ec2
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 2011 Cary R. (cygcary@yahoo.com)
|
||||
* Copyright (C) 2011-2013 Cary R. (cygcary@yahoo.com)
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
|
@ -36,7 +36,7 @@ void emit_event(ivl_scope_t scope, ivl_statement_t stmt)
|
|||
for (idx = 0; idx < count; idx += 1) {
|
||||
if (first) first = 0;
|
||||
else fprintf(vlog_out, " or ");
|
||||
emit_nexus_as_ca(scope, ivl_event_any(event, idx), 0);
|
||||
emit_nexus_as_ca(scope, ivl_event_any(event, idx), 0, 0);
|
||||
}
|
||||
|
||||
/* Check for positive edge events. */
|
||||
|
|
@ -46,7 +46,7 @@ void emit_event(ivl_scope_t scope, ivl_statement_t stmt)
|
|||
if (first) first = 0;
|
||||
else fprintf(vlog_out, " or ");
|
||||
fprintf(vlog_out, "posedge ");
|
||||
emit_nexus_as_ca(scope, ivl_event_pos(event, idx), 0);
|
||||
emit_nexus_as_ca(scope, ivl_event_pos(event, idx), 0, 0);
|
||||
}
|
||||
|
||||
/* Check for negative edge events. */
|
||||
|
|
@ -56,7 +56,7 @@ void emit_event(ivl_scope_t scope, ivl_statement_t stmt)
|
|||
if (first) first = 0;
|
||||
else fprintf(vlog_out, " or ");
|
||||
fprintf(vlog_out, "negedge ");
|
||||
emit_nexus_as_ca(scope, ivl_event_neg(event, idx), 0);
|
||||
emit_nexus_as_ca(scope, ivl_event_neg(event, idx), 0, 0);
|
||||
}
|
||||
|
||||
/* We have a named event if there were no edge events. */
|
||||
|
|
|
|||
|
|
@ -21,9 +21,6 @@
|
|||
# include "config.h"
|
||||
# include "vlog95_priv.h"
|
||||
|
||||
/* This variable lets a select know it is really a >>> operator. */
|
||||
static unsigned sign_extend = 0;
|
||||
|
||||
static unsigned emit_drive(ivl_drive_t drive)
|
||||
{
|
||||
switch (drive) {
|
||||
|
|
@ -289,7 +286,8 @@ static ivl_nexus_t get_lpm_output(ivl_scope_t scope, ivl_lpm_t lpm)
|
|||
}
|
||||
|
||||
static void emit_logic_as_ca(ivl_scope_t scope, ivl_net_logic_t nlogic);
|
||||
static void emit_lpm_as_ca(ivl_scope_t scope, ivl_lpm_t lpm);
|
||||
static void emit_lpm_as_ca(ivl_scope_t scope, ivl_lpm_t lpm,
|
||||
unsigned sign_extend);
|
||||
|
||||
/* For an undriven port look for the local signal to get the nexus name. */
|
||||
static void emit_nexus_port_signal(ivl_scope_t scope, ivl_nexus_t nex)
|
||||
|
|
@ -308,7 +306,7 @@ static void emit_nexus_port_signal(ivl_scope_t scope, ivl_nexus_t nex)
|
|||
}
|
||||
}
|
||||
/* There will not be a signal for an empty port. */
|
||||
if (sig) emit_nexus_as_ca(scope, ivl_signal_nex(sig, 0), 0);
|
||||
if (sig) emit_nexus_as_ca(scope, ivl_signal_nex(sig, 0), 0, 0);
|
||||
else fprintf(vlog_out, "/* Empty */");
|
||||
}
|
||||
|
||||
|
|
@ -378,8 +376,8 @@ void emit_nexus_port_driver_as_ca(ivl_scope_t scope, ivl_nexus_t nex)
|
|||
/* If there is a signal in this scope that is also driven by
|
||||
* the LPM then use the signal instead. */
|
||||
sig = find_local_signal(scope, ivl_lpm_q(lpm), &word);
|
||||
if (sig) emit_nexus_as_ca(scope, ivl_signal_nex(sig, word), 0);
|
||||
else emit_lpm_as_ca(scope, lpm);
|
||||
if (sig) emit_nexus_as_ca(scope, ivl_signal_nex(sig, word), 0, 0);
|
||||
else emit_lpm_as_ca(scope, lpm, 0);
|
||||
/* A constant is driving the nexus. */
|
||||
} else if (net_const) {
|
||||
assert( !nlogic);
|
||||
|
|
@ -387,7 +385,7 @@ void emit_nexus_port_driver_as_ca(ivl_scope_t scope, ivl_nexus_t nex)
|
|||
/* If there is a signal in this scope that is also driven by
|
||||
* the constant then use the signal instead. */
|
||||
sig = find_local_signal(scope, ivl_const_nex(net_const), &word);
|
||||
if (sig) emit_nexus_as_ca(scope, ivl_signal_nex(sig, word), 0);
|
||||
if (sig) emit_nexus_as_ca(scope, ivl_signal_nex(sig, word), 0, 0);
|
||||
else emit_const_nexus(scope, net_const);
|
||||
/* A logic gate is driving the nexus. */
|
||||
} else if (nlogic) {
|
||||
|
|
@ -395,11 +393,11 @@ void emit_nexus_port_driver_as_ca(ivl_scope_t scope, ivl_nexus_t nex)
|
|||
/* If there is a signal in this scope that is also driven by
|
||||
* the logic then use the signal instead. */
|
||||
sig = find_local_signal(scope, ivl_logic_pin(nlogic, 0), &word);
|
||||
if (sig) emit_nexus_as_ca(scope, ivl_signal_nex(sig, word), 0);
|
||||
if (sig) emit_nexus_as_ca(scope, ivl_signal_nex(sig, word), 0, 0);
|
||||
else emit_logic_as_ca(scope, nlogic);
|
||||
/* A signal is driving the nexus. */
|
||||
} else if (sig) {
|
||||
emit_nexus_as_ca(scope, ivl_signal_nex(sig, word), 0);
|
||||
emit_nexus_as_ca(scope, ivl_signal_nex(sig, word), 0, 0);
|
||||
/* If there is no driver then look for a single signal that is
|
||||
* driven by this nexus that has the correct scope. This is needed
|
||||
* to translate top level ports. */
|
||||
|
|
@ -408,7 +406,8 @@ void emit_nexus_port_driver_as_ca(ivl_scope_t scope, ivl_nexus_t nex)
|
|||
}
|
||||
}
|
||||
|
||||
void emit_nexus_as_ca(ivl_scope_t scope, ivl_nexus_t nex, unsigned allow_UD)
|
||||
void emit_nexus_as_ca(ivl_scope_t scope, ivl_nexus_t nex, unsigned allow_UD,
|
||||
unsigned sign_extend)
|
||||
{
|
||||
/* If there is no nexus then there is nothing to print. */
|
||||
if (! nex) return;
|
||||
|
|
@ -468,10 +467,10 @@ void emit_nexus_as_ca(ivl_scope_t scope, ivl_nexus_t nex, unsigned allow_UD)
|
|||
/* If there is a signal in this scope that is also driven by
|
||||
* the LPM then use the signal instead. */
|
||||
sig = find_local_signal(scope, ivl_lpm_q(lpm), &word);
|
||||
if (sig) emit_nexus_as_ca(scope, ivl_signal_nex(sig, word), 0);
|
||||
else emit_lpm_as_ca(scope, lpm);
|
||||
if (sig) emit_nexus_as_ca(scope, ivl_signal_nex(sig, word), 0, 0);
|
||||
else emit_lpm_as_ca(scope, lpm, sign_extend);
|
||||
#endif
|
||||
emit_lpm_as_ca(scope, lpm);
|
||||
emit_lpm_as_ca(scope, lpm, sign_extend);
|
||||
} else if (net_const) {
|
||||
assert( !nlogic);
|
||||
assert(! sig);
|
||||
|
|
@ -492,7 +491,8 @@ void emit_nexus_as_ca(ivl_scope_t scope, ivl_nexus_t nex, unsigned allow_UD)
|
|||
} else if (sig) {
|
||||
// HERE: should these be allow_UD?
|
||||
if (must_be_sig) {
|
||||
emit_nexus_as_ca(scope, ivl_signal_nex(sig, word), 0);
|
||||
emit_nexus_as_ca(scope, ivl_signal_nex(sig, word),
|
||||
0, 0);
|
||||
} else emit_name_of_nexus(scope, nex, 0);
|
||||
// HERE: The assert causes pr1703959 to fail.
|
||||
// } else assert(0);
|
||||
|
|
@ -523,61 +523,61 @@ static void emit_logic_as_ca(ivl_scope_t scope, ivl_net_logic_t nlogic)
|
|||
case IVL_LO_AND:
|
||||
assert(inputs == 2);
|
||||
fprintf(vlog_out, "(");
|
||||
emit_nexus_as_ca(scope, ivl_logic_pin(nlogic, 1), 0);
|
||||
emit_nexus_as_ca(scope, ivl_logic_pin(nlogic, 1), 0, 0);
|
||||
fprintf(vlog_out, " & ");
|
||||
emit_nexus_as_ca(scope, ivl_logic_pin(nlogic, 2), 0);
|
||||
emit_nexus_as_ca(scope, ivl_logic_pin(nlogic, 2), 0, 0);
|
||||
fprintf(vlog_out, ")");
|
||||
break;
|
||||
case IVL_LO_BUF:
|
||||
case IVL_LO_BUFT:
|
||||
case IVL_LO_BUFZ:
|
||||
assert(inputs == 1);
|
||||
emit_nexus_as_ca(scope, ivl_logic_pin(nlogic, 1), 0);
|
||||
emit_nexus_as_ca(scope, ivl_logic_pin(nlogic, 1), 0, 0);
|
||||
break;
|
||||
case IVL_LO_NAND:
|
||||
assert(inputs == 2);
|
||||
fprintf(vlog_out, "~(");
|
||||
emit_nexus_as_ca(scope, ivl_logic_pin(nlogic, 1), 0);
|
||||
emit_nexus_as_ca(scope, ivl_logic_pin(nlogic, 1), 0, 0);
|
||||
fprintf(vlog_out, " & ");
|
||||
emit_nexus_as_ca(scope, ivl_logic_pin(nlogic, 2), 0);
|
||||
emit_nexus_as_ca(scope, ivl_logic_pin(nlogic, 2), 0, 0);
|
||||
fprintf(vlog_out, ")");
|
||||
break;
|
||||
case IVL_LO_NOR:
|
||||
assert(inputs == 2);
|
||||
fprintf(vlog_out, "~(");
|
||||
emit_nexus_as_ca(scope, ivl_logic_pin(nlogic, 1), 0);
|
||||
emit_nexus_as_ca(scope, ivl_logic_pin(nlogic, 1), 0, 0);
|
||||
fprintf(vlog_out, " | ");
|
||||
emit_nexus_as_ca(scope, ivl_logic_pin(nlogic, 2), 0);
|
||||
emit_nexus_as_ca(scope, ivl_logic_pin(nlogic, 2), 0, 0);
|
||||
fprintf(vlog_out, ")");
|
||||
break;
|
||||
case IVL_LO_NOT:
|
||||
assert(inputs == 1);
|
||||
fprintf(vlog_out, "(~ ");
|
||||
emit_nexus_as_ca(scope, ivl_logic_pin(nlogic, 1), 0);
|
||||
emit_nexus_as_ca(scope, ivl_logic_pin(nlogic, 1), 0, 0);
|
||||
fprintf(vlog_out, ")");
|
||||
break;
|
||||
case IVL_LO_OR:
|
||||
assert(inputs == 2);
|
||||
fprintf(vlog_out, "(");
|
||||
emit_nexus_as_ca(scope, ivl_logic_pin(nlogic, 1), 0);
|
||||
emit_nexus_as_ca(scope, ivl_logic_pin(nlogic, 1), 0, 0);
|
||||
fprintf(vlog_out, " | ");
|
||||
emit_nexus_as_ca(scope, ivl_logic_pin(nlogic, 2), 0);
|
||||
emit_nexus_as_ca(scope, ivl_logic_pin(nlogic, 2), 0, 0);
|
||||
fprintf(vlog_out, ")");
|
||||
break;
|
||||
case IVL_LO_XNOR:
|
||||
assert(inputs == 2);
|
||||
fprintf(vlog_out, "(");
|
||||
emit_nexus_as_ca(scope, ivl_logic_pin(nlogic, 1), 0);
|
||||
emit_nexus_as_ca(scope, ivl_logic_pin(nlogic, 1), 0, 0);
|
||||
fprintf(vlog_out, " ~^ ");
|
||||
emit_nexus_as_ca(scope, ivl_logic_pin(nlogic, 2), 0);
|
||||
emit_nexus_as_ca(scope, ivl_logic_pin(nlogic, 2), 0, 0);
|
||||
fprintf(vlog_out, ")");
|
||||
break;
|
||||
case IVL_LO_XOR:
|
||||
assert(inputs == 2);
|
||||
fprintf(vlog_out, "(");
|
||||
emit_nexus_as_ca(scope, ivl_logic_pin(nlogic, 1), 0);
|
||||
emit_nexus_as_ca(scope, ivl_logic_pin(nlogic, 1), 0, 0);
|
||||
fprintf(vlog_out, " ^ ");
|
||||
emit_nexus_as_ca(scope, ivl_logic_pin(nlogic, 2), 0);
|
||||
emit_nexus_as_ca(scope, ivl_logic_pin(nlogic, 2), 0, 0);
|
||||
fprintf(vlog_out, ")");
|
||||
break;
|
||||
/* A pull up/down at this point has been turned into an assignment
|
||||
|
|
@ -605,7 +605,7 @@ static void emit_lpm_array(ivl_scope_t scope, ivl_lpm_t lpm)
|
|||
emit_id(ivl_signal_basename(sig));
|
||||
fprintf(vlog_out, "[");
|
||||
// HERE: Need to remove the scale to match array base instead of adding it back.
|
||||
emit_nexus_as_ca(scope, ivl_lpm_select(lpm), 0);
|
||||
emit_nexus_as_ca(scope, ivl_lpm_select(lpm), 0, 0);
|
||||
fprintf(vlog_out, " + %d]", ivl_signal_array_base(sig));
|
||||
}
|
||||
|
||||
|
|
@ -623,17 +623,17 @@ static void emit_lpm_concat(ivl_scope_t scope, ivl_lpm_t lpm)
|
|||
/* If all the nexus match then we have a repeat. */
|
||||
if ((idx == count) && (count > 1)) {
|
||||
fprintf(vlog_out, "%u{", count);
|
||||
emit_nexus_as_ca(scope, ivl_lpm_data(lpm, 0), 0);
|
||||
emit_nexus_as_ca(scope, ivl_lpm_data(lpm, 0), 0, 0);
|
||||
fprintf(vlog_out, "}");
|
||||
/* Icarus uses a concat to combine the output from multiple devices
|
||||
* into a single vector, because of this we need to also look for
|
||||
* the nexus driver outside the scope. emit_nexus_as_ca( , , 1) */
|
||||
* the nexus driver outside the scope. emit_nexus_as_ca( , , 1, ) */
|
||||
} else {
|
||||
for (idx = count-1; idx > 0; idx -= 1) {
|
||||
emit_nexus_as_ca(scope, ivl_lpm_data(lpm, idx), 1);
|
||||
emit_nexus_as_ca(scope, ivl_lpm_data(lpm, idx), 1, 0);
|
||||
fprintf(vlog_out, ", ");
|
||||
}
|
||||
emit_nexus_as_ca(scope, ivl_lpm_data(lpm, 0), 1);
|
||||
emit_nexus_as_ca(scope, ivl_lpm_data(lpm, 0), 1, 0);
|
||||
}
|
||||
fprintf(vlog_out, "}");
|
||||
}
|
||||
|
|
@ -720,7 +720,8 @@ static ivl_signal_t nexus_is_signal(ivl_scope_t scope, ivl_nexus_t nex,
|
|||
return sig;
|
||||
}
|
||||
|
||||
static void emit_lpm_part_select(ivl_scope_t scope, ivl_lpm_t lpm)
|
||||
static void emit_lpm_part_select(ivl_scope_t scope, ivl_lpm_t lpm,
|
||||
unsigned sign_extend)
|
||||
{
|
||||
unsigned width = ivl_lpm_width(lpm);
|
||||
unsigned array_word = 0;
|
||||
|
|
@ -741,13 +742,12 @@ static void emit_lpm_part_select(ivl_scope_t scope, ivl_lpm_t lpm)
|
|||
/* Check if the compiler used a select for a shift. */
|
||||
assert(base >= 0);
|
||||
if (base) fprintf(vlog_out, "(");
|
||||
emit_nexus_as_ca(scope, ivl_lpm_data(lpm, 0), 0);
|
||||
emit_nexus_as_ca(scope, ivl_lpm_data(lpm, 0), 0, 0);
|
||||
if (base) {
|
||||
fprintf(vlog_out, " ");
|
||||
if (sign_extend) fprintf(vlog_out, ">");
|
||||
fprintf(vlog_out, ">> %d)", base);
|
||||
}
|
||||
sign_extend = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -765,7 +765,6 @@ static void emit_lpm_part_select(ivl_scope_t scope, ivl_lpm_t lpm)
|
|||
if (msb >= lsb) base += lsb;
|
||||
else base = lsb - base;
|
||||
fprintf(vlog_out, " >>> %d)", base);
|
||||
sign_extend = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -775,7 +774,7 @@ static void emit_lpm_part_select(ivl_scope_t scope, ivl_lpm_t lpm)
|
|||
fprintf(vlog_out, "[");
|
||||
// HERE: Need to scale the select nexus.
|
||||
if ((msb >= lsb) && (lsb == 0)) {
|
||||
emit_nexus_as_ca(scope, sel, 0);
|
||||
emit_nexus_as_ca(scope, sel, 0, 0);
|
||||
} else {
|
||||
fprintf(stderr, "%s:%u: vlog95 sorry: Non-zero based "
|
||||
"variable part selects are not "
|
||||
|
|
@ -824,15 +823,16 @@ static void emit_lpm_func(ivl_scope_t scope, ivl_lpm_t lpm)
|
|||
count -= 1;
|
||||
fprintf(vlog_out, "(");
|
||||
for (idx = 0; idx < count; idx += 1) {
|
||||
emit_nexus_as_ca(scope, ivl_lpm_data(lpm, idx), 0);
|
||||
emit_nexus_as_ca(scope, ivl_lpm_data(lpm, idx), 0, 0);
|
||||
fprintf(vlog_out, ", ");
|
||||
}
|
||||
emit_nexus_as_ca(scope, ivl_lpm_data(lpm, count), 0);
|
||||
emit_nexus_as_ca(scope, ivl_lpm_data(lpm, count), 0, 0);
|
||||
fprintf(vlog_out, ")");
|
||||
}
|
||||
}
|
||||
|
||||
static void emit_lpm_as_ca(ivl_scope_t scope, ivl_lpm_t lpm)
|
||||
static void emit_lpm_as_ca(ivl_scope_t scope, ivl_lpm_t lpm,
|
||||
unsigned sign_extend)
|
||||
{
|
||||
switch (ivl_lpm_type(lpm)) {
|
||||
/* Convert the Verilog-A abs() function. This only works when the
|
||||
|
|
@ -841,19 +841,19 @@ static void emit_lpm_as_ca(ivl_scope_t scope, ivl_lpm_t lpm)
|
|||
// HERE: If this is a real net then use the $abs() function to get nan to
|
||||
// work correctly. See the expr code.
|
||||
fprintf(vlog_out, "((");
|
||||
emit_nexus_as_ca(scope, ivl_lpm_data(lpm, 0), 0);
|
||||
emit_nexus_as_ca(scope, ivl_lpm_data(lpm, 0), 0, 0);
|
||||
fprintf(vlog_out, ") > ");
|
||||
fprintf(vlog_out, "0 ? (");
|
||||
emit_nexus_as_ca(scope, ivl_lpm_data(lpm, 0), 0);
|
||||
emit_nexus_as_ca(scope, ivl_lpm_data(lpm, 0), 0, 0);
|
||||
fprintf(vlog_out, ") : -(");
|
||||
emit_nexus_as_ca(scope, ivl_lpm_data(lpm, 0), 0);
|
||||
emit_nexus_as_ca(scope, ivl_lpm_data(lpm, 0), 0, 0);
|
||||
fprintf(vlog_out, "))");
|
||||
break;
|
||||
case IVL_LPM_ADD:
|
||||
fprintf(vlog_out, "(");
|
||||
emit_nexus_as_ca(scope, ivl_lpm_data(lpm, 0), 0);
|
||||
emit_nexus_as_ca(scope, ivl_lpm_data(lpm, 0), 0, 0);
|
||||
fprintf(vlog_out, " + ");
|
||||
emit_nexus_as_ca(scope, ivl_lpm_data(lpm, 1), 0);
|
||||
emit_nexus_as_ca(scope, ivl_lpm_data(lpm, 1), 0, 0);
|
||||
fprintf(vlog_out, ")");
|
||||
break;
|
||||
case IVL_LPM_ARRAY:
|
||||
|
|
@ -862,48 +862,48 @@ static void emit_lpm_as_ca(ivl_scope_t scope, ivl_lpm_t lpm)
|
|||
case IVL_LPM_CAST_INT:
|
||||
case IVL_LPM_CAST_INT2:
|
||||
case IVL_LPM_CAST_REAL:
|
||||
emit_nexus_as_ca(scope, ivl_lpm_data(lpm, 0), 0);
|
||||
emit_nexus_as_ca(scope, ivl_lpm_data(lpm, 0), 0, 0);
|
||||
break;
|
||||
case IVL_LPM_CMP_EEQ:
|
||||
fprintf(vlog_out, "(");
|
||||
emit_nexus_as_ca(scope, ivl_lpm_data(lpm, 0), 0);
|
||||
emit_nexus_as_ca(scope, ivl_lpm_data(lpm, 0), 0, 0);
|
||||
fprintf(vlog_out, " === ");
|
||||
emit_nexus_as_ca(scope, ivl_lpm_data(lpm, 1), 0);
|
||||
emit_nexus_as_ca(scope, ivl_lpm_data(lpm, 1), 0, 0);
|
||||
fprintf(vlog_out, ")");
|
||||
break;
|
||||
case IVL_LPM_CMP_EQ:
|
||||
fprintf(vlog_out, "(");
|
||||
emit_nexus_as_ca(scope, ivl_lpm_data(lpm, 0), 0);
|
||||
emit_nexus_as_ca(scope, ivl_lpm_data(lpm, 0), 0, 0);
|
||||
fprintf(vlog_out, " == ");
|
||||
emit_nexus_as_ca(scope, ivl_lpm_data(lpm, 1), 0);
|
||||
emit_nexus_as_ca(scope, ivl_lpm_data(lpm, 1), 0, 0);
|
||||
fprintf(vlog_out, ")");
|
||||
break;
|
||||
case IVL_LPM_CMP_GE:
|
||||
fprintf(vlog_out, "(");
|
||||
emit_nexus_as_ca(scope, ivl_lpm_data(lpm, 0), 0);
|
||||
emit_nexus_as_ca(scope, ivl_lpm_data(lpm, 0), 0, 0);
|
||||
fprintf(vlog_out, " >= ");
|
||||
emit_nexus_as_ca(scope, ivl_lpm_data(lpm, 1), 0);
|
||||
emit_nexus_as_ca(scope, ivl_lpm_data(lpm, 1), 0, 0);
|
||||
fprintf(vlog_out, ")");
|
||||
break;
|
||||
case IVL_LPM_CMP_GT:
|
||||
fprintf(vlog_out, "(");
|
||||
emit_nexus_as_ca(scope, ivl_lpm_data(lpm, 0), 0);
|
||||
emit_nexus_as_ca(scope, ivl_lpm_data(lpm, 0), 0, 0);
|
||||
fprintf(vlog_out, " > ");
|
||||
emit_nexus_as_ca(scope, ivl_lpm_data(lpm, 1), 0);
|
||||
emit_nexus_as_ca(scope, ivl_lpm_data(lpm, 1), 0, 0);
|
||||
fprintf(vlog_out, ")");
|
||||
break;
|
||||
case IVL_LPM_CMP_NE:
|
||||
fprintf(vlog_out, "(");
|
||||
emit_nexus_as_ca(scope, ivl_lpm_data(lpm, 0), 0);
|
||||
emit_nexus_as_ca(scope, ivl_lpm_data(lpm, 0), 0, 0);
|
||||
fprintf(vlog_out, " != ");
|
||||
emit_nexus_as_ca(scope, ivl_lpm_data(lpm, 1), 0);
|
||||
emit_nexus_as_ca(scope, ivl_lpm_data(lpm, 1), 0, 0);
|
||||
fprintf(vlog_out, ")");
|
||||
break;
|
||||
case IVL_LPM_CMP_NEE:
|
||||
fprintf(vlog_out, "(");
|
||||
emit_nexus_as_ca(scope, ivl_lpm_data(lpm, 0), 0);
|
||||
emit_nexus_as_ca(scope, ivl_lpm_data(lpm, 0), 0, 0);
|
||||
fprintf(vlog_out, " !== ");
|
||||
emit_nexus_as_ca(scope, ivl_lpm_data(lpm, 1), 0);
|
||||
emit_nexus_as_ca(scope, ivl_lpm_data(lpm, 1), 0, 0);
|
||||
fprintf(vlog_out, ")");
|
||||
break;
|
||||
/* A concat-Z should never be generated, but report it as an
|
||||
|
|
@ -918,9 +918,9 @@ static void emit_lpm_as_ca(ivl_scope_t scope, ivl_lpm_t lpm)
|
|||
break;
|
||||
case IVL_LPM_DIVIDE:
|
||||
fprintf(vlog_out, "(");
|
||||
emit_nexus_as_ca(scope, ivl_lpm_data(lpm, 0), 0);
|
||||
emit_nexus_as_ca(scope, ivl_lpm_data(lpm, 0), 0, 0);
|
||||
fprintf(vlog_out, " / ");
|
||||
emit_nexus_as_ca(scope, ivl_lpm_data(lpm, 1), 0);
|
||||
emit_nexus_as_ca(scope, ivl_lpm_data(lpm, 1), 0, 0);
|
||||
fprintf(vlog_out, ")");
|
||||
break;
|
||||
case IVL_LPM_MOD:
|
||||
|
|
@ -932,38 +932,38 @@ static void emit_lpm_as_ca(ivl_scope_t scope, ivl_lpm_t lpm)
|
|||
vlog_errors += 1;
|
||||
}
|
||||
fprintf(vlog_out, "(");
|
||||
emit_nexus_as_ca(scope, ivl_lpm_data(lpm, 0), 0);
|
||||
emit_nexus_as_ca(scope, ivl_lpm_data(lpm, 0), 0, 0);
|
||||
fprintf(vlog_out, " %% ");
|
||||
emit_nexus_as_ca(scope, ivl_lpm_data(lpm, 1), 0);
|
||||
emit_nexus_as_ca(scope, ivl_lpm_data(lpm, 1), 0, 0);
|
||||
fprintf(vlog_out, ")");
|
||||
break;
|
||||
case IVL_LPM_MULT:
|
||||
fprintf(vlog_out, "(");
|
||||
emit_nexus_as_ca(scope, ivl_lpm_data(lpm, 0), 0);
|
||||
emit_nexus_as_ca(scope, ivl_lpm_data(lpm, 0), 0, 0);
|
||||
fprintf(vlog_out, " * ");
|
||||
emit_nexus_as_ca(scope, ivl_lpm_data(lpm, 1), 0);
|
||||
emit_nexus_as_ca(scope, ivl_lpm_data(lpm, 1), 0, 0);
|
||||
fprintf(vlog_out, ")");
|
||||
break;
|
||||
case IVL_LPM_MUX:
|
||||
fprintf(vlog_out, "(");
|
||||
emit_nexus_as_ca(scope, ivl_lpm_select(lpm), 0);
|
||||
emit_nexus_as_ca(scope, ivl_lpm_select(lpm), 0, 0);
|
||||
fprintf(vlog_out, " ? ");
|
||||
emit_nexus_as_ca(scope, ivl_lpm_data(lpm, 1), 0);
|
||||
emit_nexus_as_ca(scope, ivl_lpm_data(lpm, 1), 0, 0);
|
||||
fprintf(vlog_out, " : ");
|
||||
emit_nexus_as_ca(scope, ivl_lpm_data(lpm, 0), 0);
|
||||
emit_nexus_as_ca(scope, ivl_lpm_data(lpm, 0), 0, 0);
|
||||
fprintf(vlog_out, ")");
|
||||
break;
|
||||
case IVL_LPM_PART_PV:
|
||||
emit_nexus_as_ca(scope, ivl_lpm_data(lpm, 0), 1);
|
||||
emit_nexus_as_ca(scope, ivl_lpm_data(lpm, 0), 1, 0);
|
||||
break;
|
||||
case IVL_LPM_PART_VP:
|
||||
emit_lpm_part_select(scope, lpm);
|
||||
emit_lpm_part_select(scope, lpm, sign_extend);
|
||||
break;
|
||||
case IVL_LPM_POW:
|
||||
fprintf(vlog_out, "(");
|
||||
emit_nexus_as_ca(scope, ivl_lpm_data(lpm, 0), 0);
|
||||
emit_nexus_as_ca(scope, ivl_lpm_data(lpm, 0), 0, 0);
|
||||
fprintf(vlog_out, " ** ");
|
||||
emit_nexus_as_ca(scope, ivl_lpm_data(lpm, 1), 0);
|
||||
emit_nexus_as_ca(scope, ivl_lpm_data(lpm, 1), 0, 0);
|
||||
fprintf(vlog_out, ")");
|
||||
fprintf(stderr, "%s:%u: vlog95 error: Power operator is not "
|
||||
"supported.\n",
|
||||
|
|
@ -972,37 +972,37 @@ static void emit_lpm_as_ca(ivl_scope_t scope, ivl_lpm_t lpm)
|
|||
break;
|
||||
case IVL_LPM_RE_AND:
|
||||
fprintf(vlog_out, "(&");
|
||||
emit_nexus_as_ca(scope, ivl_lpm_data(lpm, 0), 0);
|
||||
emit_nexus_as_ca(scope, ivl_lpm_data(lpm, 0), 0, 0);
|
||||
fprintf(vlog_out, ")");
|
||||
break;
|
||||
case IVL_LPM_RE_NAND:
|
||||
fprintf(vlog_out, "(~&");
|
||||
emit_nexus_as_ca(scope, ivl_lpm_data(lpm, 0), 0);
|
||||
emit_nexus_as_ca(scope, ivl_lpm_data(lpm, 0), 0, 0);
|
||||
fprintf(vlog_out, ")");
|
||||
break;
|
||||
case IVL_LPM_RE_NOR:
|
||||
fprintf(vlog_out, "(~|");
|
||||
emit_nexus_as_ca(scope, ivl_lpm_data(lpm, 0), 0);
|
||||
emit_nexus_as_ca(scope, ivl_lpm_data(lpm, 0), 0, 0);
|
||||
fprintf(vlog_out, ")");
|
||||
break;
|
||||
case IVL_LPM_RE_OR:
|
||||
fprintf(vlog_out, "(|");
|
||||
emit_nexus_as_ca(scope, ivl_lpm_data(lpm, 0), 0);
|
||||
emit_nexus_as_ca(scope, ivl_lpm_data(lpm, 0), 0, 0);
|
||||
fprintf(vlog_out, ")");
|
||||
break;
|
||||
case IVL_LPM_RE_XOR:
|
||||
fprintf(vlog_out, "(^");
|
||||
emit_nexus_as_ca(scope, ivl_lpm_data(lpm, 0), 0);
|
||||
emit_nexus_as_ca(scope, ivl_lpm_data(lpm, 0), 0, 0);
|
||||
fprintf(vlog_out, ")");
|
||||
break;
|
||||
case IVL_LPM_RE_XNOR:
|
||||
fprintf(vlog_out, "(~^");
|
||||
emit_nexus_as_ca(scope, ivl_lpm_data(lpm, 0), 0);
|
||||
emit_nexus_as_ca(scope, ivl_lpm_data(lpm, 0), 0, 0);
|
||||
fprintf(vlog_out, ")");
|
||||
break;
|
||||
case IVL_LPM_REPEAT:
|
||||
fprintf(vlog_out, "{%u{", ivl_lpm_size(lpm));
|
||||
emit_nexus_as_ca(scope, ivl_lpm_data(lpm, 0), 0);
|
||||
emit_nexus_as_ca(scope, ivl_lpm_data(lpm, 0), 0, 0);
|
||||
fprintf(vlog_out, "}}");
|
||||
break;
|
||||
case IVL_LPM_SFUNC:
|
||||
|
|
@ -1011,15 +1011,14 @@ static void emit_lpm_as_ca(ivl_scope_t scope, ivl_lpm_t lpm)
|
|||
break;
|
||||
case IVL_LPM_SHIFTL:
|
||||
fprintf(vlog_out, "(");
|
||||
emit_nexus_as_ca(scope, ivl_lpm_data(lpm, 0), 0);
|
||||
emit_nexus_as_ca(scope, ivl_lpm_data(lpm, 0), 0, 0);
|
||||
fprintf(vlog_out, " << ");
|
||||
emit_nexus_as_ca(scope, ivl_lpm_data(lpm, 1), 0);
|
||||
emit_nexus_as_ca(scope, ivl_lpm_data(lpm, 1), 0, 0);
|
||||
fprintf(vlog_out, ")");
|
||||
break;
|
||||
case IVL_LPM_SHIFTR:
|
||||
fprintf(vlog_out, "(");
|
||||
emit_nexus_as_ca(scope, ivl_lpm_data(lpm, 0), 0);
|
||||
assert(! sign_extend);
|
||||
emit_nexus_as_ca(scope, ivl_lpm_data(lpm, 0), 0, 0);
|
||||
fprintf(vlog_out, " ");
|
||||
if (ivl_lpm_signed(lpm)) {
|
||||
if (! allow_signed) {
|
||||
|
|
@ -1032,22 +1031,17 @@ static void emit_lpm_as_ca(ivl_scope_t scope, ivl_lpm_t lpm)
|
|||
fprintf(vlog_out, ">");
|
||||
}
|
||||
fprintf(vlog_out, ">> ");
|
||||
emit_nexus_as_ca(scope, ivl_lpm_data(lpm, 1), 0);
|
||||
emit_nexus_as_ca(scope, ivl_lpm_data(lpm, 1), 0, 0);
|
||||
fprintf(vlog_out, ")");
|
||||
break;
|
||||
case IVL_LPM_SIGN_EXT:
|
||||
// HERE: pr1002 and one other test fails if this assert is used. A more
|
||||
// robust method is needed to make sure things work as expected.
|
||||
// assert(! sign_extend);
|
||||
sign_extend = 1;
|
||||
emit_nexus_as_ca(scope, ivl_lpm_data(lpm, 0), 1);
|
||||
sign_extend = 0;
|
||||
emit_nexus_as_ca(scope, ivl_lpm_data(lpm, 0), 1, 1);
|
||||
break;
|
||||
case IVL_LPM_SUB:
|
||||
fprintf(vlog_out, "(");
|
||||
emit_nexus_as_ca(scope, ivl_lpm_data(lpm, 0), 0);
|
||||
emit_nexus_as_ca(scope, ivl_lpm_data(lpm, 0), 0, 0);
|
||||
fprintf(vlog_out, " - ");
|
||||
emit_nexus_as_ca(scope, ivl_lpm_data(lpm, 1), 0);
|
||||
emit_nexus_as_ca(scope, ivl_lpm_data(lpm, 1), 0, 0);
|
||||
fprintf(vlog_out, ")");
|
||||
break;
|
||||
case IVL_LPM_UFUNC:
|
||||
|
|
@ -1186,26 +1180,26 @@ static void emit_lpm_ff(ivl_scope_t scope, ivl_lpm_t lpm)
|
|||
emit_name_of_nexus(scope, ivl_lpm_q(lpm), 0);
|
||||
fprintf(vlog_out, ", ");
|
||||
/* Emit the clock pin. */
|
||||
emit_nexus_as_ca(scope, ivl_lpm_clk(lpm), 0);
|
||||
emit_nexus_as_ca(scope, ivl_lpm_clk(lpm), 0, 0);
|
||||
fprintf(vlog_out, ", ");
|
||||
/* Emit the enable pin expression(s) if needed. */
|
||||
emitted = 0;
|
||||
nex = ivl_lpm_enable(lpm);
|
||||
if (nex) {
|
||||
emit_nexus_as_ca(scope, nex, 0);
|
||||
emit_nexus_as_ca(scope, nex, 0, 0);
|
||||
emitted = 1;
|
||||
}
|
||||
nex = ivl_lpm_sync_clr(lpm);
|
||||
if (nex) {
|
||||
if (emitted) fprintf(vlog_out, " | ");
|
||||
emit_nexus_as_ca(scope, nex, 0);
|
||||
emit_nexus_as_ca(scope, nex, 0, 0);
|
||||
emitted = 1;
|
||||
}
|
||||
have_sset = 0;
|
||||
nex = ivl_lpm_sync_set(lpm);
|
||||
if (nex) {
|
||||
if (emitted) fprintf(vlog_out, " | ");
|
||||
emit_nexus_as_ca(scope, nex, 0);
|
||||
emit_nexus_as_ca(scope, nex, 0, 0);
|
||||
emitted = 1;
|
||||
have_sset = 1;
|
||||
}
|
||||
|
|
@ -1215,37 +1209,37 @@ static void emit_lpm_ff(ivl_scope_t scope, ivl_lpm_t lpm)
|
|||
have_data = ivl_lpm_data(lpm, 0) != 0;
|
||||
nex = ivl_lpm_sync_clr(lpm);
|
||||
if (nex) {
|
||||
emit_nexus_as_ca(scope, nex, 0);
|
||||
emit_nexus_as_ca(scope, nex, 0, 0);
|
||||
if (have_data | have_sset) fprintf(vlog_out, " & ");
|
||||
if (have_data & have_sset) fprintf(vlog_out, "(");
|
||||
}
|
||||
nex = ivl_lpm_sync_set(lpm);
|
||||
if (nex) {
|
||||
if (! sset_bits || (sset_bits && (sset_bits[0] == '1'))) {
|
||||
emit_nexus_as_ca(scope, nex, 0);
|
||||
emit_nexus_as_ca(scope, nex, 0, 0);
|
||||
if (have_data) fprintf(vlog_out, " | ");
|
||||
} else {
|
||||
fprintf(vlog_out, "~");
|
||||
emit_nexus_as_ca(scope, nex, 0);
|
||||
emit_nexus_as_ca(scope, nex, 0, 0);
|
||||
if (have_data) fprintf(vlog_out, " & ");
|
||||
}
|
||||
}
|
||||
nex = ivl_lpm_data(lpm, 0);
|
||||
if (nex) emit_nexus_as_ca(scope, nex, 0);
|
||||
if (nex) emit_nexus_as_ca(scope, nex, 0, 0);
|
||||
if (have_data & have_sset) fprintf(vlog_out, ")");
|
||||
fprintf(vlog_out, ", ");
|
||||
/* Emit the clear pin expression(s) if needed. */
|
||||
emitted = 0;
|
||||
nex = ivl_lpm_async_clr(lpm);
|
||||
if (nex) {
|
||||
emit_nexus_as_ca(scope, nex, 0);
|
||||
emit_nexus_as_ca(scope, nex, 0, 0);
|
||||
emitted = 1;
|
||||
}
|
||||
nex = ivl_lpm_async_set(lpm);
|
||||
if (aset_bits && (aset_bits[0] != '0')) nex = 0;
|
||||
if (nex) {
|
||||
if (emitted) fprintf(vlog_out, " | ");
|
||||
emit_nexus_as_ca(scope, nex, 0);
|
||||
emit_nexus_as_ca(scope, nex, 0, 0);
|
||||
emitted = 1;
|
||||
}
|
||||
if (!emitted) fprintf(vlog_out, "1'b0");
|
||||
|
|
@ -1253,7 +1247,7 @@ static void emit_lpm_ff(ivl_scope_t scope, ivl_lpm_t lpm)
|
|||
/* Emit the set pin expression(s) if needed. */
|
||||
nex = ivl_lpm_async_set(lpm);
|
||||
if (aset_bits && (aset_bits[0] != '1')) nex = 0;
|
||||
if (nex) emit_nexus_as_ca(scope, nex, 0);
|
||||
if (nex) emit_nexus_as_ca(scope, nex, 0, 0);
|
||||
else fprintf(vlog_out, "1'b0");
|
||||
fprintf(vlog_out, ");\n");
|
||||
/* We need to emit a primitive for this instance. */
|
||||
|
|
@ -1397,7 +1391,7 @@ void emit_lpm(ivl_scope_t scope, ivl_lpm_t lpm)
|
|||
if (type == IVL_LPM_PART_PV) emit_lpm_part_pv(scope, lpm);
|
||||
else emit_name_of_nexus(scope, output, 0);
|
||||
fprintf(vlog_out, " = ");
|
||||
emit_lpm_as_ca(scope, lpm);
|
||||
emit_lpm_as_ca(scope, lpm, 0);
|
||||
fprintf(vlog_out, ";");
|
||||
if (emit_file_line) {
|
||||
fprintf(vlog_out, " /* %s:%u */",
|
||||
|
|
@ -1432,7 +1426,7 @@ static void emit_bufz(ivl_scope_t scope, ivl_net_logic_t nlogic)
|
|||
fprintf(vlog_out, " ");
|
||||
emit_name_of_nexus(scope, ivl_logic_pin(nlogic, 0), 0);
|
||||
fprintf(vlog_out, " = ");
|
||||
emit_nexus_as_ca(scope, ivl_logic_pin(nlogic, 1), 0);
|
||||
emit_nexus_as_ca(scope, ivl_logic_pin(nlogic, 1), 0, 0);
|
||||
fprintf(vlog_out, ";");
|
||||
emit_logic_file_line(nlogic);
|
||||
fprintf(vlog_out, "\n");
|
||||
|
|
@ -1643,11 +1637,11 @@ void emit_logic(ivl_scope_t scope, ivl_net_logic_t nlogic)
|
|||
fprintf(vlog_out, ", ");
|
||||
}
|
||||
for (/* None */; idx < count; idx += 1) {
|
||||
emit_nexus_as_ca(scope, ivl_logic_pin(nlogic, idx), 0);
|
||||
emit_nexus_as_ca(scope, ivl_logic_pin(nlogic, idx), 0, 0);
|
||||
fprintf(vlog_out, ", ");
|
||||
}
|
||||
if (strength_type == 2) {
|
||||
emit_nexus_as_ca(scope, ivl_logic_pin(nlogic, idx), 0);
|
||||
emit_nexus_as_ca(scope, ivl_logic_pin(nlogic, idx), 0, 0);
|
||||
} else {
|
||||
/* A pull gate only has a single output connection. */
|
||||
assert(count == 0);
|
||||
|
|
@ -1738,7 +1732,7 @@ void emit_tran(ivl_scope_t scope, ivl_switch_t tran)
|
|||
emit_name_of_nexus(scope, ivl_switch_b(tran), 0);
|
||||
if (pins == 3) {
|
||||
fprintf(vlog_out, ", ");
|
||||
emit_nexus_as_ca(scope, ivl_switch_enable(tran), 0);
|
||||
emit_nexus_as_ca(scope, ivl_switch_enable(tran), 0, 0);
|
||||
}
|
||||
fprintf(vlog_out, ");");
|
||||
if (emit_file_line) {
|
||||
|
|
|
|||
|
|
@ -70,7 +70,7 @@ static void emit_delay(ivl_scope_t scope, ivl_expr_t expr, unsigned is_stmt)
|
|||
ivl_signal_t sig = ivl_expr_signal(expr);
|
||||
if (ivl_signal_local(sig)) {
|
||||
assert(! is_stmt);
|
||||
emit_nexus_as_ca(scope, ivl_signal_nex(sig, 0), 0);
|
||||
emit_nexus_as_ca(scope, ivl_signal_nex(sig, 0), 0, 0);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -378,10 +378,10 @@ static void emit_module_ports(ivl_scope_t scope)
|
|||
if (count == 0) return;
|
||||
|
||||
fprintf(vlog_out, "(");
|
||||
emit_nexus_as_ca(scope, ivl_scope_mod_port(scope, 0), 0);
|
||||
emit_nexus_as_ca(scope, ivl_scope_mod_port(scope, 0), 0, 0);
|
||||
for (idx = 1; idx < count; idx += 1) {
|
||||
fprintf(vlog_out, ", ");
|
||||
emit_nexus_as_ca(scope, ivl_scope_mod_port(scope, idx), 0);
|
||||
emit_nexus_as_ca(scope, ivl_scope_mod_port(scope, idx), 0, 0);
|
||||
}
|
||||
fprintf(vlog_out, ")");
|
||||
}
|
||||
|
|
@ -537,7 +537,7 @@ static void emit_module_call_expr(ivl_scope_t scope, unsigned idx)
|
|||
/* For an output we need to emit the signal the output is driving. */
|
||||
} else {
|
||||
emit_nexus_as_ca(ivl_scope_parent(scope),
|
||||
ivl_signal_nex(port, word), 0);
|
||||
ivl_signal_nex(port, word), 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -726,7 +726,7 @@ static void emit_specify_paths(ivl_scope_t scope, ivl_signal_t sig)
|
|||
fprintf(vlog_out, "%*c", indent, ' ');
|
||||
if (cond) {
|
||||
fprintf(vlog_out, "if (");
|
||||
emit_nexus_as_ca(scope, cond, 0);
|
||||
emit_nexus_as_ca(scope, cond, 0, 0);
|
||||
fprintf(vlog_out, ") ");
|
||||
} else if (ivl_path_is_condit(dpath)) {
|
||||
fprintf(vlog_out, "ifnone ");
|
||||
|
|
@ -740,7 +740,7 @@ static void emit_specify_paths(ivl_scope_t scope, ivl_signal_t sig)
|
|||
fprintf(vlog_out, "negedge ");
|
||||
has_edge = 1;
|
||||
}
|
||||
emit_nexus_as_ca(scope, source, 0);
|
||||
emit_nexus_as_ca(scope, source, 0, 0);
|
||||
fprintf(vlog_out, " =>");
|
||||
/* The compiler does not keep the source expression for an edge
|
||||
* sensitive path so add a constant to get the syntax right. */
|
||||
|
|
|
|||
|
|
@ -89,7 +89,7 @@ extern void emit_scope_module_path(ivl_scope_t scope, ivl_scope_t call_scope);
|
|||
extern void emit_name_of_nexus(ivl_scope_t scope, ivl_nexus_t nex,
|
||||
unsigned allow_UD);
|
||||
extern void emit_nexus_as_ca(ivl_scope_t scope, ivl_nexus_t nex,
|
||||
unsigned allow_UD);
|
||||
unsigned allow_UD, unsigned sign_extend);
|
||||
extern void emit_nexus_port_driver_as_ca(ivl_scope_t scope, ivl_nexus_t nex);
|
||||
extern void emit_const_nexus(ivl_scope_t scope, ivl_net_const_t const_net);
|
||||
extern void emit_signal_net_const_as_ca(ivl_scope_t scope, ivl_signal_t sig);
|
||||
|
|
|
|||
Loading…
Reference in New Issue