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:
Cary R 2011-01-13 21:01:04 -08:00 committed by Stephen Williams
parent 3c10eb2956
commit 6581b13005
3 changed files with 38 additions and 7 deletions

View File

@ -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;

View File

@ -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);

View File

@ -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");