vlog95: convert real Verilog-A abs/min/max to $abs/$min/$max
Converting these Verilog-A functions to use the $ version allows nan to be handled correct. This still needs to be done for the LPM code.
This commit is contained in:
parent
c4386da666
commit
27b8738d06
|
|
@ -176,19 +176,29 @@ static void emit_expr_binary(ivl_scope_t scope, ivl_expr_t expr, unsigned wid)
|
|||
vlog_errors += 1;
|
||||
}
|
||||
break;
|
||||
/* Convert Verilog-A min() or max() functions. This only works
|
||||
* when the arguments have no side effect. */
|
||||
/* Convert the Verilog-A min() or max() functions. */
|
||||
case 'm':
|
||||
case 'M':
|
||||
fprintf(vlog_out, "((");
|
||||
emit_expr(scope, ivl_expr_oper1(expr), wid);
|
||||
fprintf(vlog_out, ") %s (", oper);
|
||||
emit_expr(scope, ivl_expr_oper2(expr), wid);
|
||||
fprintf(vlog_out, ") ? (");
|
||||
emit_expr(scope, ivl_expr_oper1(expr), wid);
|
||||
fprintf(vlog_out, ") : (");
|
||||
emit_expr(scope, ivl_expr_oper2(expr), wid);
|
||||
fprintf(vlog_out, "))");
|
||||
if (ivl_expr_value(expr) == IVL_VT_REAL) {
|
||||
/* For a real expression use the $min()/$max() function. */
|
||||
if (ivl_expr_opcode(expr) == 'm') fprintf(vlog_out, "$min(");
|
||||
else fprintf(vlog_out, "$max(");
|
||||
emit_expr(scope, ivl_expr_oper1(expr), wid);
|
||||
fprintf(vlog_out, ",");
|
||||
emit_expr(scope, ivl_expr_oper2(expr), wid);
|
||||
fprintf(vlog_out, ")");
|
||||
} else {
|
||||
/* This only works when the argument has no side effect. */
|
||||
fprintf(vlog_out, "((");
|
||||
emit_expr(scope, ivl_expr_oper1(expr), wid);
|
||||
fprintf(vlog_out, ") %s (", oper);
|
||||
emit_expr(scope, ivl_expr_oper2(expr), wid);
|
||||
fprintf(vlog_out, ") ? (");
|
||||
emit_expr(scope, ivl_expr_oper1(expr), wid);
|
||||
fprintf(vlog_out, ") : (");
|
||||
emit_expr(scope, ivl_expr_oper2(expr), wid);
|
||||
fprintf(vlog_out, "))");
|
||||
}
|
||||
break;
|
||||
default:
|
||||
emit_expr(scope, ivl_expr_oper1(expr), wid);
|
||||
|
|
@ -587,19 +597,23 @@ static void emit_expr_unary(ivl_scope_t scope, ivl_expr_t expr, unsigned wid)
|
|||
ivl_expr_lineno(expr));
|
||||
vlog_errors += 1;
|
||||
break;
|
||||
/* Convert Verilog-A abs() function. This only works when the
|
||||
* argument has no side effect. */
|
||||
/* Convert the Verilog-A abs() function. */
|
||||
case 'm':
|
||||
fprintf(vlog_out, "((");
|
||||
emit_expr(scope, ivl_expr_oper1(expr), wid);
|
||||
fprintf(vlog_out, ") > ");
|
||||
if (ivl_expr_value(expr) == IVL_VT_REAL) fprintf(vlog_out, "0.0");
|
||||
else fprintf(vlog_out, "0");
|
||||
fprintf(vlog_out, " ? (");
|
||||
emit_expr(scope, ivl_expr_oper1(expr), wid);
|
||||
fprintf(vlog_out, ") : -(");
|
||||
emit_expr(scope, ivl_expr_oper1(expr), wid);
|
||||
fprintf(vlog_out, "))");
|
||||
if (ivl_expr_value(expr) == IVL_VT_REAL) {
|
||||
/* For a real expression use the $abs() function. */
|
||||
fprintf(vlog_out, "$abs(");
|
||||
emit_expr(scope, ivl_expr_oper1(expr), wid);
|
||||
fprintf(vlog_out, ")");
|
||||
} else {
|
||||
/* This only works when the argument has no side effect. */
|
||||
fprintf(vlog_out, "((");
|
||||
emit_expr(scope, ivl_expr_oper1(expr), wid);
|
||||
fprintf(vlog_out, ") > 0 ? (");
|
||||
emit_expr(scope, ivl_expr_oper1(expr), wid);
|
||||
fprintf(vlog_out, ") : -(");
|
||||
emit_expr(scope, ivl_expr_oper1(expr), wid);
|
||||
fprintf(vlog_out, "))");
|
||||
}
|
||||
break;
|
||||
default:
|
||||
fprintf(vlog_out, "<unknown>");
|
||||
|
|
|
|||
|
|
@ -818,13 +818,14 @@ static void emit_lpm_func(ivl_scope_t scope, ivl_lpm_t lpm)
|
|||
static void emit_lpm_as_ca(ivl_scope_t scope, ivl_lpm_t lpm)
|
||||
{
|
||||
switch (ivl_lpm_type(lpm)) {
|
||||
/* Convert Verilog-A abs() function. This only works when the
|
||||
/* Convert the Verilog-A abs() function. This only works when the
|
||||
* argument has no side effect. */
|
||||
case IVL_LPM_ABS:
|
||||
// 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);
|
||||
fprintf(vlog_out, ") > ");
|
||||
// HERE: If this is a real net then use 0.0. See the expr code.
|
||||
fprintf(vlog_out, "0 ? (");
|
||||
emit_nexus_as_ca(scope, ivl_lpm_data(lpm, 0), 0);
|
||||
fprintf(vlog_out, ") : -(");
|
||||
|
|
|
|||
Loading…
Reference in New Issue