vlog95: Add support for Verilog-A abs(), min(), max() and some SV types.
The Verilog-A abs(), min() and max() functions can be converted if the expressions do not have side effects. Also note the new, null and class property operators from SystemVerilog are not supported.
This commit is contained in:
parent
a581e0ef0e
commit
06ce23d9c2
|
|
@ -105,6 +105,8 @@ static void emit_expr_binary(ivl_scope_t scope, ivl_expr_t expr, unsigned wid)
|
|||
case 'l': oper = "<<"; break;
|
||||
case 'r': oper = ">>"; break;
|
||||
case 'R': oper = ">>>"; break;
|
||||
case 'm': oper = "<"; break;
|
||||
case 'M': oper = ">"; break;
|
||||
}
|
||||
|
||||
fprintf(vlog_out, "(");
|
||||
|
|
@ -174,6 +176,21 @@ 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. */
|
||||
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, "))");
|
||||
break;
|
||||
break;
|
||||
default:
|
||||
emit_expr(scope, ivl_expr_oper1(expr), wid);
|
||||
fprintf(vlog_out, "<unknown>");
|
||||
|
|
@ -561,6 +578,20 @@ 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. */
|
||||
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, "))");
|
||||
break;
|
||||
default:
|
||||
fprintf(vlog_out, "<unknown>");
|
||||
emit_expr(scope, ivl_expr_oper1(expr), wid);
|
||||
|
|
@ -600,11 +631,35 @@ void emit_expr(ivl_scope_t scope, ivl_expr_t expr, unsigned wid)
|
|||
case IVL_EX_EVENT:
|
||||
emit_expr_event(scope, expr, wid);
|
||||
break;
|
||||
case IVL_EX_NEW:
|
||||
fprintf(vlog_out, "<new>");
|
||||
fprintf(stderr, "%s:%u: vlog95 error: New operator "
|
||||
"is not supported.\n",
|
||||
ivl_expr_file(expr),
|
||||
ivl_expr_lineno(expr));
|
||||
vlog_errors += 1;
|
||||
break;
|
||||
case IVL_EX_NULL:
|
||||
fprintf(vlog_out, "<null>");
|
||||
fprintf(stderr, "%s:%u: vlog95 error: Null operator "
|
||||
"is not supported.\n",
|
||||
ivl_expr_file(expr),
|
||||
ivl_expr_lineno(expr));
|
||||
vlog_errors += 1;
|
||||
break;
|
||||
case IVL_EX_NUMBER:
|
||||
emit_number(ivl_expr_bits(expr), ivl_expr_width(expr),
|
||||
ivl_expr_signed(expr), ivl_expr_file(expr),
|
||||
ivl_expr_lineno(expr));
|
||||
break;
|
||||
case IVL_EX_PROPERTY:
|
||||
fprintf(vlog_out, "<class property>");
|
||||
fprintf(stderr, "%s:%u: vlog95 error: Class property expression "
|
||||
"is not supported.\n",
|
||||
ivl_expr_file(expr),
|
||||
ivl_expr_lineno(expr));
|
||||
vlog_errors += 1;
|
||||
break;
|
||||
case IVL_EX_REALNUM:
|
||||
emit_real_number(ivl_expr_dvalue(expr));
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -193,6 +193,7 @@ static ivl_nexus_t get_lpm_output(ivl_scope_t scope, ivl_lpm_t lpm)
|
|||
{
|
||||
ivl_nexus_t output = 0;
|
||||
switch (ivl_lpm_type(lpm)) {
|
||||
case IVL_LPM_ABS:
|
||||
case IVL_LPM_ADD:
|
||||
case IVL_LPM_ARRAY:
|
||||
case IVL_LPM_CAST_INT:
|
||||
|
|
@ -774,6 +775,19 @@ 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
|
||||
* argument has no side effect. */
|
||||
case IVL_LPM_ABS:
|
||||
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, ") : -(");
|
||||
emit_nexus_as_ca(scope, ivl_lpm_data(lpm, 0), 0);
|
||||
fprintf(vlog_out, "))");
|
||||
break;
|
||||
case IVL_LPM_ADD:
|
||||
fprintf(vlog_out, "(");
|
||||
emit_nexus_as_ca(scope, ivl_lpm_data(lpm, 0), 0);
|
||||
|
|
|
|||
Loading…
Reference in New Issue