From 970c4950f46d508c50a71bc4b5f60c4e4f39e881 Mon Sep 17 00:00:00 2001 From: steve Date: Fri, 28 Feb 2003 20:21:13 +0000 Subject: [PATCH] Merge vpi_call and vpi_func draw functions. --- tgt-vvp/Makefile.in | 5 +- tgt-vvp/draw_vpi.c | 236 ++++++++++++++++++++++++++++++++++++++++++ tgt-vvp/eval_expr.c | 119 +-------------------- tgt-vvp/vvp_priv.h | 15 ++- tgt-vvp/vvp_process.c | 176 +------------------------------ 5 files changed, 263 insertions(+), 288 deletions(-) create mode 100644 tgt-vvp/draw_vpi.c diff --git a/tgt-vvp/Makefile.in b/tgt-vvp/Makefile.in index d0630eb65..b7a71d92a 100644 --- a/tgt-vvp/Makefile.in +++ b/tgt-vvp/Makefile.in @@ -16,7 +16,7 @@ # 59 Temple Place - Suite 330 # Boston, MA 02111-1307, USA # -#ident "$Id: Makefile.in,v 1.14 2003/02/27 22:13:22 steve Exp $" +#ident "$Id: Makefile.in,v 1.15 2003/02/28 20:21:13 steve Exp $" # # SHELL = /bin/sh @@ -52,7 +52,8 @@ dep: $(CC) -Wall @ident_support@ -I$(srcdir)/.. $(CPPFLAGS) $(CFLAGS) -MD -c $< -o $*.o mv $*.d dep -O = vvp.o draw_mux.o eval_expr.o eval_real.o vector.o vvp_process.o vvp_scope.o +O = vvp.o draw_mux.o draw_vpi.o eval_expr.o eval_real.o vector.o \ +vvp_process.o vvp_scope.o ifeq (@WIN32@,yes) TGTLDFLAGS=-L.. -livl diff --git a/tgt-vvp/draw_vpi.c b/tgt-vvp/draw_vpi.c new file mode 100644 index 000000000..54393f0be --- /dev/null +++ b/tgt-vvp/draw_vpi.c @@ -0,0 +1,236 @@ +/* + * Copyright (c) 2003 Stephen Williams (steve@icarus.com) + * + * This source code is free software; you can redistribute it + * and/or modify it in source code form under the terms of the GNU + * General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ +#ifdef HAVE_CVS_IDENT +#ident "$Id: draw_vpi.c,v 1.1 2003/02/28 20:21:13 steve Exp $" +#endif + +# include "vvp_priv.h" +# include +#ifdef HAVE_MALLOC_H +# include +#endif +# include +# include + +struct vector_info draw_vpi_taskfunc_call(ivl_statement_t tnet, + ivl_expr_t fnet, unsigned wid) +{ + unsigned idx; + unsigned parm_count = tnet + ? ivl_stmt_parm_count(tnet) + : ivl_expr_parms(fnet); + struct vector_info res; + struct vector_info *vec = 0x0; + unsigned int vecs= 0; + unsigned int veci= 0; + + + /* Figure out how many expressions are going to be evaluated + for this task call. I won't need to evaluate expressions + for items that are VPI objects directly. */ + for (idx = 0 ; idx < parm_count ; idx += 1) { + ivl_expr_t expr = tnet + ? ivl_stmt_parm(tnet, idx) + : ivl_expr_parm(fnet, idx); + + switch (ivl_expr_type(expr)) { + + /* These expression types can be handled directly, + with VPI handles of their own. Therefore, skip + them in the process of evaluating expressions. */ + case IVL_EX_NONE: + case IVL_EX_NUMBER: + case IVL_EX_STRING: + case IVL_EX_SCOPE: + case IVL_EX_SFUNC: + case IVL_EX_VARIABLE: + continue; + + case IVL_EX_SIGNAL: + /* If the signal node is narrower then the signal + itself, then this is a part select so I'm going + to need to evaluate the expression. + + If I don't need to do any evaluating, then skip + it as I'll be passing the handle to the signal + itself. */ + if (ivl_expr_width(expr) != + ivl_signal_pins(ivl_expr_signal(expr))) { + break; + } else { + continue; + } + + + case IVL_EX_MEMORY: + if (!ivl_expr_oper1(expr)) { + continue; + } + + /* Everything else will need to be evaluated and + passed as a constant to the vpi task. */ + default: + break; + } + + vec = (struct vector_info *) + realloc(vec, (vecs+1)*sizeof(struct vector_info)); + + switch (ivl_expr_value(expr)) { + case IVL_VT_VECTOR: + vec[vecs] = draw_eval_expr(expr, 0); + break; + case IVL_VT_REAL: + vec[vecs].base = draw_eval_real(expr); + vec[vecs].wid = 0; + break; + default: + assert(0); + } + vecs++; + } + + if (tnet != 0) { + /* for task calls, the res vector is not used. */ + res.base = 0; + res.wid = 0; + fprintf(vvp_out, " %%vpi_call \"%s\"", ivl_stmt_name(tnet)); + + } else { + res.base = allocate_vector(wid); + res.wid = wid; + fprintf(vvp_out, " %%vpi_func \"%s\", %u, %u", + ivl_expr_name(fnet), res.base, res.wid); + } + + for (idx = 0 ; idx < parm_count ; idx += 1) { + ivl_expr_t expr = tnet + ? ivl_stmt_parm(tnet, idx) + : ivl_expr_parm(fnet, idx); + + switch (ivl_expr_type(expr)) { + case IVL_EX_NONE: + fprintf(vvp_out, ", \" \""); + continue; + + case IVL_EX_NUMBER: { + unsigned bit, wid = ivl_expr_width(expr); + const char*bits = ivl_expr_bits(expr); + + fprintf(vvp_out, ", %u'%sb", wid, + ivl_expr_signed(expr)? "s" : ""); + for (bit = wid ; bit > 0 ; bit -= 1) + fputc(bits[bit-1], vvp_out); + continue; + } + + case IVL_EX_SIGNAL: + /* If this is a part select, then the value was + calculated above. Otherwise, just pass the + signal. */ + if (ivl_expr_width(expr) != + ivl_signal_pins(ivl_expr_signal(expr))) { + break; + } else { + fprintf(vvp_out, ", V_%s", + vvp_signal_label(ivl_expr_signal(expr))); + continue; + } + + case IVL_EX_VARIABLE: { + ivl_variable_t var = ivl_expr_variable(expr); + fprintf(vvp_out, ", W_%s", vvp_word_label(var)); + continue; + } + + case IVL_EX_STRING: + fprintf(vvp_out, ", \"%s\"", + ivl_expr_string(expr)); + continue; + + case IVL_EX_SCOPE: + fprintf(vvp_out, ", S_%s", + vvp_mangle_id(ivl_scope_name(ivl_expr_scope(expr)))); + continue; + + case IVL_EX_SFUNC: + if (strcmp("$time", ivl_expr_name(expr)) == 0) + fprintf(vvp_out, ", $time"); + else if (strcmp("$stime", ivl_expr_name(expr)) == 0) + fprintf(vvp_out, ", $stime"); + else if (strcmp("$realtime", ivl_expr_name(expr)) == 0) + fprintf(vvp_out, ", $realtime"); + else if (strcmp("$simtime", ivl_expr_name(expr)) == 0) + fprintf(vvp_out, ", $simtime"); + else + fprintf(vvp_out, ", ?%s?", ivl_expr_name(expr)); + continue; + + case IVL_EX_MEMORY: + if (!ivl_expr_oper1(expr)) { + fprintf(vvp_out, ", M_%s", + vvp_memory_label(ivl_expr_memory(expr))); + continue; + } + break; + + default: + break; + } + assert(veci < vecs); + + switch (ivl_expr_value(expr)) { + + case IVL_VT_VECTOR: + fprintf(vvp_out, ", T<%u,%u,%s>", vec[veci].base, + vec[veci].wid, ivl_expr_signed(expr)? "s" : "u"); + break; + + case IVL_VT_REAL: + fprintf(vvp_out, ", W<%u,r>", vec[veci].base); + break; + + default: + assert(0); + } + veci++; + } + + assert(veci == vecs); + + if (vecs) { + for (idx = 0; idx < vecs; idx++) { + if (vec[idx].wid > 0) + clr_vector(vec[idx]); + } + free(vec); + } + + fprintf(vvp_out, ";\n"); + + return res; +} + +/* + * $Log: draw_vpi.c,v $ + * Revision 1.1 2003/02/28 20:21:13 steve + * Merge vpi_call and vpi_func draw functions. + * + */ + diff --git a/tgt-vvp/eval_expr.c b/tgt-vvp/eval_expr.c index f9c644240..69e02eb1a 100644 --- a/tgt-vvp/eval_expr.c +++ b/tgt-vvp/eval_expr.c @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifdef HAVE_CVS_IDENT -#ident "$Id: eval_expr.c,v 1.91 2003/02/07 02:46:16 steve Exp $" +#ident "$Id: eval_expr.c,v 1.92 2003/02/28 20:21:13 steve Exp $" #endif # include "vvp_priv.h" @@ -1604,11 +1604,6 @@ static struct vector_info draw_ternary_expr(ivl_expr_t exp, unsigned wid) static struct vector_info draw_sfunc_expr(ivl_expr_t exp, unsigned wid) { - unsigned idx; - struct vector_info *vec = 0x0; - unsigned int vecs= 0; - unsigned int veci= 0; - unsigned parm_count = ivl_expr_parms(exp); struct vector_info res; @@ -1624,118 +1619,11 @@ static struct vector_info draw_sfunc_expr(ivl_expr_t exp, unsigned wid) } - /* Evaluate any expressions that need to be evaluated by the - run-time before passed to the system task. The results are - stored in the vec array. */ - for (idx = 0 ; idx < parm_count ; idx += 1) { - ivl_expr_t expr = ivl_expr_parm(exp, idx); - - switch (ivl_expr_type(expr)) { - case IVL_EX_NONE: - case IVL_EX_NUMBER: - case IVL_EX_SIGNAL: - case IVL_EX_STRING: - case IVL_EX_SCOPE: - case IVL_EX_SFUNC: - continue; - case IVL_EX_MEMORY: - if (!ivl_expr_oper1(expr)) { - continue; - } - default: - break; - } - - vec = (struct vector_info *) - realloc(vec, (vecs+1)*sizeof(struct vector_info)); - vec[vecs] = draw_eval_expr(expr, 0); - vecs++; - } - - /* Start the complicated expression. */ - - res.base = allocate_vector(wid); - res.wid = wid; - fprintf(vvp_out, " %%vpi_func \"%s\", %u, %u", - ivl_expr_name(exp), res.base, res.wid); - - /* Now draw all the parameters to the function. */ - for (idx = 0 ; idx < parm_count ; idx += 1) { - ivl_expr_t expr = ivl_expr_parm(exp, idx); - - switch (ivl_expr_type(expr)) { - case IVL_EX_NONE: - fprintf(vvp_out, ", \" \""); - continue; - - case IVL_EX_NUMBER: { - unsigned bit, wid = ivl_expr_width(expr); - const char*bits = ivl_expr_bits(expr); - - fprintf(vvp_out, ", %u'b", wid); - for (bit = wid ; bit > 0 ; bit -= 1) - fputc(bits[bit-1], vvp_out); - continue; - } - - case IVL_EX_SIGNAL: - fprintf(vvp_out, ", V_%s", - vvp_signal_label(ivl_expr_signal(expr))); - continue; - - case IVL_EX_STRING: - fprintf(vvp_out, ", \"%s\"", - ivl_expr_string(expr)); - continue; - - case IVL_EX_SCOPE: - fprintf(vvp_out, ", S_%s", - vvp_mangle_id(ivl_scope_name(ivl_expr_scope(expr)))); - continue; - - case IVL_EX_SFUNC: - if (strcmp("$time", ivl_expr_name(expr)) == 0) - fprintf(vvp_out, ", $time"); - else if (strcmp("$stime", ivl_expr_name(expr)) == 0) - fprintf(vvp_out, ", $stime"); - else if (strcmp("$realtime", ivl_expr_name(expr)) == 0) - fprintf(vvp_out, ", $realtime"); - else - fprintf(vvp_out, ", ?%s?", ivl_expr_name(expr)); - continue; - - case IVL_EX_MEMORY: - if (!ivl_expr_oper1(expr)) { - fprintf(vvp_out, ", M_%s", - vvp_memory_label(ivl_expr_memory(expr))); - continue; - } - break; - - default: - break; - } - - fprintf(vvp_out, ", T<%u,%u>", - vec[veci].base, - vec[veci].wid); - veci++; - } - - assert(veci == vecs); - - if (vecs) { - for (idx = 0; idx < vecs; idx++) - clr_vector(vec[idx]); - free(vec); - } + res = draw_vpi_taskfunc_call(0, exp, wid); /* New basic block starts after VPI calls. */ clear_expression_lookaside(); - fprintf(vvp_out, ";\n"); - - return res; } @@ -2114,6 +2002,9 @@ struct vector_info draw_eval_expr(ivl_expr_t exp, int stuff_ok_flag) /* * $Log: eval_expr.c,v $ + * Revision 1.92 2003/02/28 20:21:13 steve + * Merge vpi_call and vpi_func draw functions. + * * Revision 1.91 2003/02/07 02:46:16 steve * Handle real value subtract and comparisons. * diff --git a/tgt-vvp/vvp_priv.h b/tgt-vvp/vvp_priv.h index 92c36e0bc..17a8289d9 100644 --- a/tgt-vvp/vvp_priv.h +++ b/tgt-vvp/vvp_priv.h @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifdef HAVE_CVS_IDENT -#ident "$Id: vvp_priv.h,v 1.23 2003/01/26 21:16:00 steve Exp $" +#ident "$Id: vvp_priv.h,v 1.24 2003/02/28 20:21:13 steve Exp $" #endif # include "ivl_target.h" @@ -64,6 +64,16 @@ extern int draw_scope(ivl_scope_t scope, ivl_scope_t parent); extern void draw_lpm_mux(ivl_lpm_t net); +/* + * This function draws the execution of a vpi_call statement, along + * with the tricky handling of arguments. If this is called with a + * statement handle, it will generate a %vpi_call + * instruction. Otherwise, it will generate a %vpi_func instruction. + */ +extern struct vector_info draw_vpi_taskfunc_call(ivl_statement_t net, + ivl_expr_t exp, + unsigned wid); + /* * Given a nexus, draw a string that represents the functor output * that feeds the nexus. This function can be used to get the input to @@ -181,6 +191,9 @@ extern unsigned thread_count; /* * $Log: vvp_priv.h,v $ + * Revision 1.24 2003/02/28 20:21:13 steve + * Merge vpi_call and vpi_func draw functions. + * * Revision 1.23 2003/01/26 21:16:00 steve * Rework expression parsing and elaboration to * accommodate real/realtime values and expressions. diff --git a/tgt-vvp/vvp_process.c b/tgt-vvp/vvp_process.c index a73ed2978..56d5c7c57 100644 --- a/tgt-vvp/vvp_process.c +++ b/tgt-vvp/vvp_process.c @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifdef HAVE_CVS_IDENT -#ident "$Id: vvp_process.c,v 1.80 2003/02/27 20:38:12 steve Exp $" +#ident "$Id: vvp_process.c,v 1.81 2003/02/28 20:21:13 steve Exp $" #endif # include "vvp_priv.h" @@ -1224,11 +1224,7 @@ static int show_stmt_while(ivl_statement_t net, ivl_scope_t sscope) static int show_system_task_call(ivl_statement_t net) { - unsigned idx; unsigned parm_count = ivl_stmt_parm_count(net); - struct vector_info *vec = 0x0; - unsigned int vecs= 0; - unsigned int veci= 0; if (parm_count == 0) { fprintf(vvp_out, " %%vpi_call \"%s\";\n", ivl_stmt_name(net)); @@ -1236,172 +1232,7 @@ static int show_system_task_call(ivl_statement_t net) return 0; } - /* Figure out how many expressions are going to be evaluated - for this task call. I won't need to evaluate expressions - for items that are VPI objects directly. */ - for (idx = 0 ; idx < parm_count ; idx += 1) { - ivl_expr_t expr = ivl_stmt_parm(net, idx); - - switch (ivl_expr_type(expr)) { - - /* These expression types can be handled directly, - with VPI handles of their own. Therefore, skip - them in the process of evaluating expressions. */ - case IVL_EX_NONE: - case IVL_EX_NUMBER: - case IVL_EX_STRING: - case IVL_EX_SCOPE: - case IVL_EX_SFUNC: - case IVL_EX_VARIABLE: - continue; - - case IVL_EX_SIGNAL: - /* If the signal node is narrower then the signal - itself, then this is a part select so I'm going - to need to evaluate the expression. - - If I don't need to do any evaluating, then skip - it as I'll be passing the handle to the signal - itself. */ - if (ivl_expr_width(expr) != - ivl_signal_pins(ivl_expr_signal(expr))) { - break; - } else { - continue; - } - - - case IVL_EX_MEMORY: - if (!ivl_expr_oper1(expr)) { - continue; - } - - /* Everything else will need to be evaluated and - passed as a constant to the vpi task. */ - default: - break; - } - - vec = (struct vector_info *) - realloc(vec, (vecs+1)*sizeof(struct vector_info)); - - switch (ivl_expr_value(expr)) { - case IVL_VT_VECTOR: - vec[vecs] = draw_eval_expr(expr, 0); - break; - case IVL_VT_REAL: - vec[vecs].base = draw_eval_real(expr); - vec[vecs].wid = 0; - break; - default: - assert(0); - } - vecs++; - } - - fprintf(vvp_out, " %%vpi_call \"%s\"", ivl_stmt_name(net)); - for (idx = 0 ; idx < parm_count ; idx += 1) { - ivl_expr_t expr = ivl_stmt_parm(net, idx); - - switch (ivl_expr_type(expr)) { - case IVL_EX_NONE: - fprintf(vvp_out, ", \" \""); - continue; - - case IVL_EX_NUMBER: { - unsigned bit, wid = ivl_expr_width(expr); - const char*bits = ivl_expr_bits(expr); - - fprintf(vvp_out, ", %u'%sb", wid, - ivl_expr_signed(expr)? "s" : ""); - for (bit = wid ; bit > 0 ; bit -= 1) - fputc(bits[bit-1], vvp_out); - continue; - } - - case IVL_EX_SIGNAL: - /* If this is a part select, then the value was - calculated above. Otherwise, just pass the - signal. */ - if (ivl_expr_width(expr) != - ivl_signal_pins(ivl_expr_signal(expr))) { - break; - } else { - fprintf(vvp_out, ", V_%s", - vvp_signal_label(ivl_expr_signal(expr))); - continue; - } - - case IVL_EX_VARIABLE: { - ivl_variable_t var = ivl_expr_variable(expr); - fprintf(vvp_out, ", W_%s", vvp_word_label(var)); - continue; - } - - case IVL_EX_STRING: - fprintf(vvp_out, ", \"%s\"", - ivl_expr_string(expr)); - continue; - - case IVL_EX_SCOPE: - fprintf(vvp_out, ", S_%s", - vvp_mangle_id(ivl_scope_name(ivl_expr_scope(expr)))); - continue; - - case IVL_EX_SFUNC: - if (strcmp("$time", ivl_expr_name(expr)) == 0) - fprintf(vvp_out, ", $time"); - else if (strcmp("$stime", ivl_expr_name(expr)) == 0) - fprintf(vvp_out, ", $stime"); - else if (strcmp("$realtime", ivl_expr_name(expr)) == 0) - fprintf(vvp_out, ", $realtime"); - else if (strcmp("$simtime", ivl_expr_name(expr)) == 0) - fprintf(vvp_out, ", $simtime"); - else - fprintf(vvp_out, ", ?%s?", ivl_expr_name(expr)); - continue; - - case IVL_EX_MEMORY: - if (!ivl_expr_oper1(expr)) { - fprintf(vvp_out, ", M_%s", - vvp_memory_label(ivl_expr_memory(expr))); - continue; - } - break; - - default: - break; - } - assert(veci < vecs); - - switch (ivl_expr_value(expr)) { - - case IVL_VT_VECTOR: - fprintf(vvp_out, ", T<%u,%u,%s>", vec[veci].base, - vec[veci].wid, ivl_expr_signed(expr)? "s" : "u"); - break; - - case IVL_VT_REAL: - fprintf(vvp_out, ", W<%u,r>", vec[veci].base); - break; - - default: - assert(0); - } - veci++; - } - - assert(veci == vecs); - - if (vecs) { - for (idx = 0; idx < vecs; idx++) { - if (vec[idx].wid > 0) - clr_vector(vec[idx]); - } - free(vec); - } - - fprintf(vvp_out, ";\n"); + (void) draw_vpi_taskfunc_call(net, 0, 0); /* VPI calls can manipulate anything, so clear the expression lookahead table after the call. */ @@ -1606,6 +1437,9 @@ int draw_func_definition(ivl_scope_t scope) /* * $Log: vvp_process.c,v $ + * Revision 1.81 2003/02/28 20:21:13 steve + * Merge vpi_call and vpi_func draw functions. + * * Revision 1.80 2003/02/27 20:38:12 steve * Handle assign of real values to vectors. *