Merge vpi_call and vpi_func draw functions.
This commit is contained in:
parent
feee40603c
commit
970c4950f4
|
|
@ -16,7 +16,7 @@
|
||||||
# 59 Temple Place - Suite 330
|
# 59 Temple Place - Suite 330
|
||||||
# Boston, MA 02111-1307, USA
|
# 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
|
SHELL = /bin/sh
|
||||||
|
|
@ -52,7 +52,8 @@ dep:
|
||||||
$(CC) -Wall @ident_support@ -I$(srcdir)/.. $(CPPFLAGS) $(CFLAGS) -MD -c $< -o $*.o
|
$(CC) -Wall @ident_support@ -I$(srcdir)/.. $(CPPFLAGS) $(CFLAGS) -MD -c $< -o $*.o
|
||||||
mv $*.d dep
|
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)
|
ifeq (@WIN32@,yes)
|
||||||
TGTLDFLAGS=-L.. -livl
|
TGTLDFLAGS=-L.. -livl
|
||||||
|
|
|
||||||
|
|
@ -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 <string.h>
|
||||||
|
#ifdef HAVE_MALLOC_H
|
||||||
|
# include <malloc.h>
|
||||||
|
#endif
|
||||||
|
# include <stdlib.h>
|
||||||
|
# include <assert.h>
|
||||||
|
|
||||||
|
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.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
@ -17,7 +17,7 @@
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_CVS_IDENT
|
#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
|
#endif
|
||||||
|
|
||||||
# include "vvp_priv.h"
|
# 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)
|
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);
|
unsigned parm_count = ivl_expr_parms(exp);
|
||||||
struct vector_info res;
|
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
|
res = draw_vpi_taskfunc_call(0, exp, wid);
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* New basic block starts after VPI calls. */
|
/* New basic block starts after VPI calls. */
|
||||||
clear_expression_lookaside();
|
clear_expression_lookaside();
|
||||||
|
|
||||||
fprintf(vvp_out, ";\n");
|
|
||||||
|
|
||||||
|
|
||||||
return res;
|
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 $
|
* $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
|
* Revision 1.91 2003/02/07 02:46:16 steve
|
||||||
* Handle real value subtract and comparisons.
|
* Handle real value subtract and comparisons.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_CVS_IDENT
|
#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
|
#endif
|
||||||
|
|
||||||
# include "ivl_target.h"
|
# 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);
|
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
|
* 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
|
* 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 $
|
* $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
|
* Revision 1.23 2003/01/26 21:16:00 steve
|
||||||
* Rework expression parsing and elaboration to
|
* Rework expression parsing and elaboration to
|
||||||
* accommodate real/realtime values and expressions.
|
* accommodate real/realtime values and expressions.
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_CVS_IDENT
|
#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
|
#endif
|
||||||
|
|
||||||
# include "vvp_priv.h"
|
# 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)
|
static int show_system_task_call(ivl_statement_t net)
|
||||||
{
|
{
|
||||||
unsigned idx;
|
|
||||||
unsigned parm_count = ivl_stmt_parm_count(net);
|
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) {
|
if (parm_count == 0) {
|
||||||
fprintf(vvp_out, " %%vpi_call \"%s\";\n", ivl_stmt_name(net));
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Figure out how many expressions are going to be evaluated
|
(void) draw_vpi_taskfunc_call(net, 0, 0);
|
||||||
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");
|
|
||||||
|
|
||||||
/* VPI calls can manipulate anything, so clear the expression
|
/* VPI calls can manipulate anything, so clear the expression
|
||||||
lookahead table after the call. */
|
lookahead table after the call. */
|
||||||
|
|
@ -1606,6 +1437,9 @@ int draw_func_definition(ivl_scope_t scope)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: vvp_process.c,v $
|
* $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
|
* Revision 1.80 2003/02/27 20:38:12 steve
|
||||||
* Handle assign of real values to vectors.
|
* Handle assign of real values to vectors.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue