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 '^':
|
case '^':
|
||||||
case 'X':
|
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 'a':
|
||||||
case 'o':
|
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 'l':
|
||||||
case 'r':
|
case 'r':
|
||||||
case 'R':
|
case 'R':
|
||||||
emit_expr(scope, ivl_expr_oper1(expr), wid);
|
emit_expr(scope, ivl_expr_oper1(expr), wid);
|
||||||
fprintf(vlog_out, " %s ", oper);
|
fprintf(vlog_out, " %s ", oper);
|
||||||
emit_expr(scope, ivl_expr_oper2(expr), wid);
|
emit_expr(scope, ivl_expr_oper2(expr), 0);
|
||||||
break;
|
break;
|
||||||
case 'A':
|
case 'A':
|
||||||
case 'O':
|
case 'O':
|
||||||
|
|
@ -120,6 +126,20 @@ static void emit_expr_binary(ivl_scope_t scope, ivl_expr_t expr, unsigned wid)
|
||||||
fprintf(vlog_out, ")");
|
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)
|
static void emit_expr_number(ivl_scope_t scope, ivl_expr_t expr, unsigned wid)
|
||||||
{
|
{
|
||||||
const char *bits = ivl_expr_bits(expr);
|
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)
|
static void emit_expr_select(ivl_scope_t scope, ivl_expr_t expr, unsigned wid)
|
||||||
{
|
{
|
||||||
if (ivl_expr_oper2(expr)) {
|
if (ivl_expr_oper2(expr)) {
|
||||||
|
assert(0);
|
||||||
|
// HERE: Not finished.
|
||||||
} else {
|
} else {
|
||||||
|
// HERE: Should this sign extend if the expression is signed?
|
||||||
emit_expr(scope, ivl_expr_oper1(expr), wid);
|
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)
|
static void emit_expr_signal(ivl_scope_t scope, ivl_expr_t expr, unsigned wid)
|
||||||
{
|
{
|
||||||
ivl_signal_t sig = ivl_expr_signal(expr);
|
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));
|
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)
|
static void emit_expr_unary(ivl_scope_t scope, ivl_expr_t expr, unsigned wid)
|
||||||
{
|
{
|
||||||
char *oper = "invalid";
|
char *oper = "invalid";
|
||||||
|
|
@ -243,6 +290,9 @@ void emit_expr(ivl_scope_t scope, ivl_expr_t expr, unsigned wid)
|
||||||
case IVL_EX_BINARY:
|
case IVL_EX_BINARY:
|
||||||
emit_expr_binary(scope, expr, wid);
|
emit_expr_binary(scope, expr, wid);
|
||||||
break;
|
break;
|
||||||
|
case IVL_EX_CONCAT:
|
||||||
|
emit_expr_concat(scope, expr, wid);
|
||||||
|
break;
|
||||||
case IVL_EX_NUMBER:
|
case IVL_EX_NUMBER:
|
||||||
emit_expr_number(scope, expr, wid);
|
emit_expr_number(scope, expr, wid);
|
||||||
break;
|
break;
|
||||||
|
|
@ -252,12 +302,18 @@ void emit_expr(ivl_scope_t scope, ivl_expr_t expr, unsigned wid)
|
||||||
case IVL_EX_SELECT:
|
case IVL_EX_SELECT:
|
||||||
emit_expr_select(scope, expr, wid);
|
emit_expr_select(scope, expr, wid);
|
||||||
break;
|
break;
|
||||||
|
case IVL_EX_SFUNC:
|
||||||
|
emit_expr_sfunc(scope, expr, wid);
|
||||||
|
break;
|
||||||
case IVL_EX_SIGNAL:
|
case IVL_EX_SIGNAL:
|
||||||
emit_expr_signal(scope, expr, wid);
|
emit_expr_signal(scope, expr, wid);
|
||||||
break;
|
break;
|
||||||
case IVL_EX_STRING:
|
case IVL_EX_STRING:
|
||||||
fprintf(vlog_out, "\"%s\"", ivl_expr_string(expr));
|
fprintf(vlog_out, "\"%s\"", ivl_expr_string(expr));
|
||||||
break;
|
break;
|
||||||
|
case IVL_EX_TERNARY:
|
||||||
|
emit_expr_ternary(scope, expr, wid);
|
||||||
|
break;
|
||||||
case IVL_EX_UNARY:
|
case IVL_EX_UNARY:
|
||||||
emit_expr_unary(scope, expr, wid);
|
emit_expr_unary(scope, expr, wid);
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
|
|
@ -192,6 +192,9 @@ int emit_scope(ivl_scope_t scope, ivl_scope_t parent)
|
||||||
fprintf(vlog_out, "\n`timescale %s/%s\n",
|
fprintf(vlog_out, "\n`timescale %s/%s\n",
|
||||||
get_time_const(ivl_scope_time_units(scope)),
|
get_time_const(ivl_scope_time_units(scope)),
|
||||||
get_time_const(ivl_scope_time_precision(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));
|
fprintf(vlog_out, "module %s", ivl_scope_tname(scope));
|
||||||
// HERE: Still need to add port information.
|
// HERE: Still need to add port information.
|
||||||
break;
|
break;
|
||||||
|
|
@ -287,7 +290,6 @@ int emit_scope(ivl_scope_t scope, ivl_scope_t parent)
|
||||||
emit_net_def(sig);
|
emit_net_def(sig);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (count) fprintf(vlog_out, "\n");
|
|
||||||
|
|
||||||
/* Output the function/task body. */
|
/* Output the function/task body. */
|
||||||
if (sc_type == IVL_SCT_TASK || sc_type == IVL_SCT_FUNCTION) {
|
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:
|
case IVL_SCT_MODULE:
|
||||||
assert(indent == 0);
|
assert(indent == 0);
|
||||||
fprintf(vlog_out, "endmodule\n");
|
fprintf(vlog_out, "endmodule\n");
|
||||||
|
if (ivl_scope_is_cell(scope)) {
|
||||||
|
fprintf(vlog_out, "`endcelldefine\n");
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case IVL_SCT_FUNCTION:
|
case IVL_SCT_FUNCTION:
|
||||||
fprintf(vlog_out, "%*cendfunction\n", indent, ' ');
|
fprintf(vlog_out, "%*cendfunction\n", indent, ' ');
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue