vlog95: add expression support for ternary, concat and system functions.
This patch adds support to the vlog95 convert for the ternary operator, the concat/repeat operator and calling a system function. It also adds the `celldefine information when appropriate.
This commit is contained in:
parent
50106547e3
commit
428c1f3222
|
|
@ -76,16 +76,22 @@ static void emit_expr_binary(ivl_scope_t scope, ivl_expr_t expr, unsigned wid)
|
|||
case '|':
|
||||
case '^':
|
||||
case 'X':
|
||||
// HERE: Do these two need to be done differently (wid = 0)?
|
||||
emit_expr(scope, ivl_expr_oper1(expr), wid);
|
||||
fprintf(vlog_out, " %s ", oper);
|
||||
emit_expr(scope, ivl_expr_oper2(expr), wid);
|
||||
break;
|
||||
case 'a':
|
||||
case 'o':
|
||||
// HERE: Do these two need to be done differently (r-value wid = 0)?
|
||||
emit_expr(scope, ivl_expr_oper1(expr), 0);
|
||||
fprintf(vlog_out, " %s ", oper);
|
||||
emit_expr(scope, ivl_expr_oper2(expr), 0);
|
||||
break;
|
||||
case 'l':
|
||||
case 'r':
|
||||
case 'R':
|
||||
emit_expr(scope, ivl_expr_oper1(expr), wid);
|
||||
fprintf(vlog_out, " %s ", oper);
|
||||
emit_expr(scope, ivl_expr_oper2(expr), wid);
|
||||
emit_expr(scope, ivl_expr_oper2(expr), 0);
|
||||
break;
|
||||
case 'A':
|
||||
case 'O':
|
||||
|
|
@ -120,6 +126,20 @@ static void emit_expr_binary(ivl_scope_t scope, ivl_expr_t expr, unsigned wid)
|
|||
fprintf(vlog_out, ")");
|
||||
}
|
||||
|
||||
static void emit_expr_concat(ivl_scope_t scope, ivl_expr_t expr, unsigned wid)
|
||||
{
|
||||
unsigned repeat = ivl_expr_repeat(expr);
|
||||
unsigned idx, count = ivl_expr_parms(expr);
|
||||
|
||||
if (repeat != 1) fprintf(vlog_out, "{%u", repeat);
|
||||
fprintf(vlog_out, "{");
|
||||
for (idx = 0; idx < count; idx += 1) {
|
||||
emit_expr(scope, ivl_expr_parm(expr, idx), 0);
|
||||
}
|
||||
fprintf(vlog_out, "}");
|
||||
if (repeat != 1) fprintf(vlog_out, "}");
|
||||
}
|
||||
|
||||
static void emit_expr_number(ivl_scope_t scope, ivl_expr_t expr, unsigned wid)
|
||||
{
|
||||
const char *bits = ivl_expr_bits(expr);
|
||||
|
|
@ -181,11 +201,27 @@ static void emit_expr_number(ivl_scope_t scope, ivl_expr_t expr, unsigned wid)
|
|||
static void emit_expr_select(ivl_scope_t scope, ivl_expr_t expr, unsigned wid)
|
||||
{
|
||||
if (ivl_expr_oper2(expr)) {
|
||||
assert(0);
|
||||
// HERE: Not finished.
|
||||
} else {
|
||||
// HERE: Should this sign extend if the expression is signed?
|
||||
emit_expr(scope, ivl_expr_oper1(expr), wid);
|
||||
}
|
||||
}
|
||||
|
||||
static void emit_expr_sfunc(ivl_scope_t scope, ivl_expr_t expr, unsigned wid)
|
||||
{
|
||||
unsigned idx, count = ivl_expr_parms(expr);
|
||||
fprintf(vlog_out, "%s", ivl_expr_name(expr));
|
||||
if (count != 0) {
|
||||
fprintf(vlog_out, "(");
|
||||
for (idx = 0; idx < count; idx += 1) {
|
||||
emit_expr(scope, ivl_expr_parm(expr, idx), 0);
|
||||
}
|
||||
fprintf(vlog_out, ")");
|
||||
}
|
||||
}
|
||||
|
||||
static void emit_expr_signal(ivl_scope_t scope, ivl_expr_t expr, unsigned wid)
|
||||
{
|
||||
ivl_signal_t sig = ivl_expr_signal(expr);
|
||||
|
|
@ -194,6 +230,17 @@ static void emit_expr_signal(ivl_scope_t scope, ivl_expr_t expr, unsigned wid)
|
|||
fprintf(vlog_out, "%s", ivl_signal_basename(sig));
|
||||
}
|
||||
|
||||
static void emit_expr_ternary(ivl_scope_t scope, ivl_expr_t expr, unsigned wid)
|
||||
{
|
||||
fprintf(vlog_out, "(");
|
||||
emit_expr(scope, ivl_expr_oper1(expr), 0);
|
||||
fprintf(vlog_out, " ? ");
|
||||
emit_expr(scope, ivl_expr_oper2(expr), wid);
|
||||
fprintf(vlog_out, " : ");
|
||||
emit_expr(scope, ivl_expr_oper3(expr), wid);
|
||||
fprintf(vlog_out, ")");
|
||||
}
|
||||
|
||||
static void emit_expr_unary(ivl_scope_t scope, ivl_expr_t expr, unsigned wid)
|
||||
{
|
||||
char *oper = "invalid";
|
||||
|
|
@ -243,6 +290,9 @@ void emit_expr(ivl_scope_t scope, ivl_expr_t expr, unsigned wid)
|
|||
case IVL_EX_BINARY:
|
||||
emit_expr_binary(scope, expr, wid);
|
||||
break;
|
||||
case IVL_EX_CONCAT:
|
||||
emit_expr_concat(scope, expr, wid);
|
||||
break;
|
||||
case IVL_EX_NUMBER:
|
||||
emit_expr_number(scope, expr, wid);
|
||||
break;
|
||||
|
|
@ -252,12 +302,18 @@ void emit_expr(ivl_scope_t scope, ivl_expr_t expr, unsigned wid)
|
|||
case IVL_EX_SELECT:
|
||||
emit_expr_select(scope, expr, wid);
|
||||
break;
|
||||
case IVL_EX_SFUNC:
|
||||
emit_expr_sfunc(scope, expr, wid);
|
||||
break;
|
||||
case IVL_EX_SIGNAL:
|
||||
emit_expr_signal(scope, expr, wid);
|
||||
break;
|
||||
case IVL_EX_STRING:
|
||||
fprintf(vlog_out, "\"%s\"", ivl_expr_string(expr));
|
||||
break;
|
||||
case IVL_EX_TERNARY:
|
||||
emit_expr_ternary(scope, expr, wid);
|
||||
break;
|
||||
case IVL_EX_UNARY:
|
||||
emit_expr_unary(scope, expr, wid);
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -192,6 +192,9 @@ int emit_scope(ivl_scope_t scope, ivl_scope_t parent)
|
|||
fprintf(vlog_out, "\n`timescale %s/%s\n",
|
||||
get_time_const(ivl_scope_time_units(scope)),
|
||||
get_time_const(ivl_scope_time_precision(scope)));
|
||||
if (ivl_scope_is_cell(scope)) {
|
||||
fprintf(vlog_out, "`celldefine\n");
|
||||
}
|
||||
fprintf(vlog_out, "module %s", ivl_scope_tname(scope));
|
||||
// HERE: Still need to add port information.
|
||||
break;
|
||||
|
|
@ -287,7 +290,6 @@ int emit_scope(ivl_scope_t scope, ivl_scope_t parent)
|
|||
emit_net_def(sig);
|
||||
}
|
||||
}
|
||||
if (count) fprintf(vlog_out, "\n");
|
||||
|
||||
/* Output the function/task body. */
|
||||
if (sc_type == IVL_SCT_TASK || sc_type == IVL_SCT_FUNCTION) {
|
||||
|
|
@ -304,6 +306,9 @@ int emit_scope(ivl_scope_t scope, ivl_scope_t parent)
|
|||
case IVL_SCT_MODULE:
|
||||
assert(indent == 0);
|
||||
fprintf(vlog_out, "endmodule\n");
|
||||
if (ivl_scope_is_cell(scope)) {
|
||||
fprintf(vlog_out, "`endcelldefine\n");
|
||||
}
|
||||
break;
|
||||
case IVL_SCT_FUNCTION:
|
||||
fprintf(vlog_out, "%*cendfunction\n", indent, ' ');
|
||||
|
|
|
|||
Loading…
Reference in New Issue