vlog95: add support for a scope and user function call expression.
This patch adds support for using a scope in an expression and calling a user function. It also fixes an issue in the module name mangling and calling a system task/function with multiple arguments.
This commit is contained in:
parent
3c10eb2956
commit
6581b13005
|
|
@ -203,6 +203,11 @@ static void emit_expr_number(ivl_scope_t scope, ivl_expr_t expr, unsigned wid)
|
|||
}
|
||||
}
|
||||
|
||||
static void emit_expr_scope(ivl_scope_t scope, ivl_expr_t expr, unsigned wid)
|
||||
{
|
||||
fprintf(vlog_out, "%s", ivl_scope_name(ivl_expr_scope(expr)));
|
||||
}
|
||||
|
||||
static void emit_expr_select(ivl_scope_t scope, ivl_expr_t expr, unsigned wid)
|
||||
{
|
||||
if (ivl_expr_oper2(expr)) {
|
||||
|
|
@ -214,19 +219,30 @@ static void emit_expr_select(ivl_scope_t scope, ivl_expr_t expr, unsigned wid)
|
|||
}
|
||||
}
|
||||
|
||||
static void emit_expr_sfunc(ivl_scope_t scope, ivl_expr_t expr, unsigned wid)
|
||||
/*
|
||||
* This routine is used to emit both system and user functions.
|
||||
*/
|
||||
static void emit_expr_func(ivl_scope_t scope, ivl_expr_t expr, const char* name)
|
||||
{
|
||||
unsigned idx, count = ivl_expr_parms(expr);
|
||||
fprintf(vlog_out, "%s", ivl_expr_name(expr));
|
||||
fprintf(vlog_out, "%s", name);
|
||||
if (count != 0) {
|
||||
fprintf(vlog_out, "(");
|
||||
count -= 1;
|
||||
for (idx = 0; idx < count; idx += 1) {
|
||||
emit_expr(scope, ivl_expr_parm(expr, idx), 0);
|
||||
fprintf(vlog_out, ", ");
|
||||
}
|
||||
emit_expr(scope, ivl_expr_parm(expr, count), 0);
|
||||
fprintf(vlog_out, ")");
|
||||
}
|
||||
}
|
||||
|
||||
static void emit_expr_sfunc(ivl_scope_t scope, ivl_expr_t expr, unsigned wid)
|
||||
{
|
||||
emit_expr_func(scope, expr, ivl_expr_name(expr));
|
||||
}
|
||||
|
||||
static void emit_expr_signal(ivl_scope_t scope, ivl_expr_t expr, unsigned wid)
|
||||
{
|
||||
ivl_signal_t sig = ivl_expr_signal(expr);
|
||||
|
|
@ -246,6 +262,12 @@ static void emit_expr_ternary(ivl_scope_t scope, ivl_expr_t expr, unsigned wid)
|
|||
fprintf(vlog_out, ")");
|
||||
}
|
||||
|
||||
static void emit_expr_ufunc(ivl_scope_t scope, ivl_expr_t expr, unsigned wid)
|
||||
{
|
||||
ivl_scope_t ufunc_def = ivl_expr_def(expr);
|
||||
emit_expr_func(scope, expr, ivl_scope_tname(ufunc_def));
|
||||
}
|
||||
|
||||
static void emit_expr_unary(ivl_scope_t scope, ivl_expr_t expr, unsigned wid)
|
||||
{
|
||||
char *oper = "invalid";
|
||||
|
|
@ -307,6 +329,9 @@ void emit_expr(ivl_scope_t scope, ivl_expr_t expr, unsigned wid)
|
|||
case IVL_EX_REALNUM:
|
||||
fprintf(vlog_out, "%#g", ivl_expr_dvalue(expr));
|
||||
break;
|
||||
case IVL_EX_SCOPE:
|
||||
emit_expr_scope(scope, expr, wid);
|
||||
break;
|
||||
case IVL_EX_SELECT:
|
||||
emit_expr_select(scope, expr, wid);
|
||||
break;
|
||||
|
|
@ -322,6 +347,9 @@ void emit_expr(ivl_scope_t scope, ivl_expr_t expr, unsigned wid)
|
|||
case IVL_EX_TERNARY:
|
||||
emit_expr_ternary(scope, expr, wid);
|
||||
break;
|
||||
case IVL_EX_UFUNC:
|
||||
emit_expr_ufunc(scope, expr, wid);
|
||||
break;
|
||||
case IVL_EX_UNARY:
|
||||
emit_expr_unary(scope, expr, wid);
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -177,12 +177,12 @@ void emit_net_def(ivl_signal_t sig)
|
|||
}
|
||||
}
|
||||
|
||||
static char *get_mangled_name(ivl_scope_t scope)
|
||||
static char *get_mangled_name(ivl_scope_t scope, unsigned root)
|
||||
{
|
||||
char *name;
|
||||
/* If the module has parameters than it may not be unique
|
||||
* so we create a mangled name version instead. */
|
||||
if (ivl_scope_params(scope)) {
|
||||
/* If the module has parameters and it's not a root module than it
|
||||
* may not be unique so we create a mangled name version instead. */
|
||||
if (ivl_scope_params(scope) && ! root) {
|
||||
unsigned idx;
|
||||
size_t len = strlen(ivl_scope_name(scope)) +
|
||||
strlen(ivl_scope_tname(scope)) + 2;
|
||||
|
|
@ -252,7 +252,7 @@ int emit_scope(ivl_scope_t scope, ivl_scope_t parent)
|
|||
switch (sc_type) {
|
||||
case IVL_SCT_MODULE:
|
||||
assert(!is_auto);
|
||||
name = get_mangled_name(scope);
|
||||
name = get_mangled_name(scope, !parent && !emitting_scopes);
|
||||
/* This is an instantiation. */
|
||||
if (parent) {
|
||||
assert(indent != 0);
|
||||
|
|
|
|||
|
|
@ -291,9 +291,12 @@ static void emit_stmt_stask(ivl_scope_t scope, ivl_statement_t stmt)
|
|||
fprintf(vlog_out, "%*c%s", get_indent(), ' ', ivl_stmt_name(stmt));
|
||||
if (count != 0) {
|
||||
fprintf(vlog_out, "(");
|
||||
count -= 1;
|
||||
for (idx = 0; idx < count; idx += 1) {
|
||||
emit_expr(scope, ivl_stmt_parm(stmt, idx), 0);
|
||||
fprintf(vlog_out, ", ");
|
||||
}
|
||||
emit_expr(scope, ivl_stmt_parm(stmt, count), 0);
|
||||
fprintf(vlog_out, ")");
|
||||
}
|
||||
fprintf(vlog_out, ";\n");
|
||||
|
|
|
|||
Loading…
Reference in New Issue