Handle functions with real values.
This commit is contained in:
parent
b094ccc3f7
commit
5bfdd52391
|
|
@ -16,7 +16,7 @@
|
|||
# 59 Temple Place - Suite 330
|
||||
# Boston, MA 02111-1307, USA
|
||||
#
|
||||
#ident "$Id: Makefile.in,v 1.22 2004/02/10 19:25:01 steve Exp $"
|
||||
#ident "$Id: Makefile.in,v 1.23 2005/07/13 04:52:31 steve Exp $"
|
||||
#
|
||||
#
|
||||
SHELL = /bin/sh
|
||||
|
|
@ -51,7 +51,7 @@ dep:
|
|||
$(CC) $(CPPFLAGS) $(CFLAGS) -MD -c $< -o $*.o
|
||||
mv $*.d dep
|
||||
|
||||
O = vvp.o draw_mux.o draw_vpi.o eval_expr.o eval_real.o vector.o \
|
||||
O = vvp.o draw_mux.o draw_ufunc.o draw_vpi.o eval_expr.o eval_real.o vector.o \
|
||||
vvp_process.o vvp_scope.o
|
||||
|
||||
ifeq (@WIN32@,yes)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,158 @@
|
|||
/*
|
||||
* Copyright (c) 2005 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_ufunc.c,v 1.1 2005/07/13 04:52:31 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "vvp_priv.h"
|
||||
# include <string.h>
|
||||
#ifdef HAVE_MALLOC_H
|
||||
# include <malloc.h>
|
||||
#endif
|
||||
# include <stdlib.h>
|
||||
# include <assert.h>
|
||||
|
||||
static void function_argument_logic(ivl_signal_t port, ivl_expr_t exp)
|
||||
{
|
||||
struct vector_info res;
|
||||
|
||||
res = draw_eval_expr_wid(exp, ivl_signal_width(port), 0);
|
||||
assert(res.wid <= ivl_signal_width(port));
|
||||
fprintf(vvp_out, " %%set/v V_%s, %u, %u;\n",
|
||||
vvp_signal_label(port), res.base, res.wid);
|
||||
|
||||
clr_vector(res);
|
||||
}
|
||||
|
||||
static void function_argument_real(ivl_signal_t port, ivl_expr_t exp)
|
||||
{
|
||||
int res = draw_eval_real(exp);
|
||||
|
||||
fprintf(vvp_out, " %%set/wr V_%s, %d;\n",
|
||||
vvp_signal_label(port), res);
|
||||
}
|
||||
|
||||
static void draw_function_argument(ivl_signal_t port, ivl_expr_t exp)
|
||||
{
|
||||
ivl_variable_type_t dtype = ivl_signal_data_type(port);
|
||||
switch (dtype) {
|
||||
case IVL_VT_LOGIC:
|
||||
function_argument_logic(port, exp);
|
||||
break;
|
||||
case IVL_VT_REAL:
|
||||
function_argument_real(port, exp);
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "XXXX function argument %s type=%d?!\n",
|
||||
ivl_signal_basename(port), dtype);
|
||||
assert(0);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* A call to a user defined function generates a result that is the
|
||||
* result of this expression.
|
||||
*
|
||||
* The result of the function is placed by the function execution into
|
||||
* a signal within the scope of the function that also has a basename
|
||||
* the same as the function. The ivl_target API handled the result
|
||||
* mapping already, and we get the name of the result signal as
|
||||
* parameter 0 of the function definition.
|
||||
*/
|
||||
|
||||
struct vector_info draw_ufunc_expr(ivl_expr_t exp, unsigned wid)
|
||||
{
|
||||
unsigned idx;
|
||||
unsigned swid = ivl_expr_width(exp);
|
||||
ivl_scope_t def = ivl_expr_def(exp);
|
||||
ivl_signal_t retval = ivl_scope_port(def, 0);
|
||||
struct vector_info res;
|
||||
|
||||
/* evaluate the expressions and send the results to the
|
||||
function ports. */
|
||||
|
||||
assert(ivl_expr_parms(exp) == (ivl_scope_ports(def)-1));
|
||||
for (idx = 0 ; idx < ivl_expr_parms(exp) ; idx += 1) {
|
||||
ivl_signal_t port = ivl_scope_port(def, idx+1);
|
||||
draw_function_argument(port, ivl_expr_parm(exp,idx));
|
||||
}
|
||||
|
||||
|
||||
/* Call the function */
|
||||
fprintf(vvp_out, " %%fork TD_%s", vvp_mangle_id(ivl_scope_name(def)));
|
||||
fprintf(vvp_out, ", S_%p;\n", def);
|
||||
fprintf(vvp_out, " %%join;\n");
|
||||
|
||||
/* Fresh basic block starts after the join. */
|
||||
clear_expression_lookaside();
|
||||
|
||||
/* The return value is in a signal that has the name of the
|
||||
expression. Load that into the thread and return the
|
||||
vector result. */
|
||||
|
||||
res.base = allocate_vector(wid);
|
||||
res.wid = wid;
|
||||
|
||||
{ unsigned load_wid = swid;
|
||||
if (load_wid > ivl_signal_width(retval))
|
||||
load_wid = ivl_signal_width(retval);
|
||||
|
||||
fprintf(vvp_out, " %%load/v %u, V_%s, %u;\n",
|
||||
res.base, vvp_signal_label(retval), load_wid);
|
||||
|
||||
if (load_wid < swid)
|
||||
fprintf(vvp_out, " %%mov %u, 0, %u;\n",
|
||||
res.base+load_wid, swid-load_wid);
|
||||
}
|
||||
|
||||
/* Pad the signal value with zeros. */
|
||||
if (swid < wid)
|
||||
fprintf(vvp_out, " %%mov %u, 0, %u;\n",
|
||||
res.base+swid, wid-swid);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
int draw_ufunc_real(ivl_expr_t exp)
|
||||
{
|
||||
ivl_scope_t def = ivl_expr_def(exp);
|
||||
ivl_signal_t retval = ivl_scope_port(def, 0);
|
||||
int res = 0;
|
||||
int idx;
|
||||
|
||||
assert(ivl_expr_parms(exp) == (ivl_scope_ports(def)-1));
|
||||
for (idx = 0 ; idx < ivl_expr_parms(exp) ; idx += 1) {
|
||||
ivl_signal_t port = ivl_scope_port(def, idx+1);
|
||||
draw_function_argument(port, ivl_expr_parm(exp,idx));
|
||||
}
|
||||
|
||||
|
||||
/* Call the function */
|
||||
fprintf(vvp_out, " %%fork TD_%s", vvp_mangle_id(ivl_scope_name(def)));
|
||||
fprintf(vvp_out, ", S_%p;\n", def);
|
||||
fprintf(vvp_out, " %%join;\n");
|
||||
|
||||
/* Load the result into a word. */
|
||||
res = allocate_word();
|
||||
fprintf(vvp_out, " %%load/wr %d, V_%s;\n",
|
||||
res, vvp_signal_label(retval));
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
|
@ -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.118 2005/07/11 16:56:51 steve Exp $"
|
||||
#ident "$Id: eval_expr.c,v 1.119 2005/07/13 04:52:31 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "vvp_priv.h"
|
||||
|
|
@ -1752,77 +1752,6 @@ static struct vector_info draw_sfunc_expr(ivl_expr_t exp, unsigned wid)
|
|||
return res;
|
||||
}
|
||||
|
||||
/*
|
||||
* A call to a user defined function generates a result that is the
|
||||
* result of this expression.
|
||||
*
|
||||
* The result of the function is placed by the function execution into
|
||||
* a signal within the scope of the function that also has a basename
|
||||
* the same as the function. The ivl_target API handled the result
|
||||
* mapping already, and we get the name of the result signal as
|
||||
* parameter 0 of the function definition.
|
||||
*/
|
||||
|
||||
static struct vector_info draw_ufunc_expr(ivl_expr_t exp, unsigned wid)
|
||||
{
|
||||
unsigned idx;
|
||||
unsigned swid = ivl_expr_width(exp);
|
||||
ivl_scope_t def = ivl_expr_def(exp);
|
||||
ivl_signal_t retval = ivl_scope_port(def, 0);
|
||||
struct vector_info res;
|
||||
|
||||
/* evaluate the expressions and send the results to the
|
||||
function ports. */
|
||||
|
||||
assert(ivl_expr_parms(exp) == (ivl_scope_ports(def)-1));
|
||||
for (idx = 0 ; idx < ivl_expr_parms(exp) ; idx += 1) {
|
||||
ivl_signal_t port = ivl_scope_port(def, idx+1);
|
||||
|
||||
res = draw_eval_expr_wid(ivl_expr_parm(exp, idx),
|
||||
ivl_signal_width(port), 0);
|
||||
assert(res.wid <= ivl_signal_width(port));
|
||||
fprintf(vvp_out, " %%set/v V_%s, %u, %u;\n",
|
||||
vvp_signal_label(port), res.base, res.wid);
|
||||
|
||||
clr_vector(res);
|
||||
}
|
||||
|
||||
|
||||
/* Call the function */
|
||||
fprintf(vvp_out, " %%fork TD_%s", vvp_mangle_id(ivl_scope_name(def)));
|
||||
fprintf(vvp_out, ", S_%p;\n", def);
|
||||
fprintf(vvp_out, " %%join;\n");
|
||||
|
||||
/* Fresh basic block starts after the join. */
|
||||
clear_expression_lookaside();
|
||||
|
||||
/* The return value is in a signal that has the name of the
|
||||
expression. Load that into the thread and return the
|
||||
vector result. */
|
||||
|
||||
res.base = allocate_vector(wid);
|
||||
res.wid = wid;
|
||||
|
||||
{ unsigned load_wid = swid;
|
||||
if (load_wid > ivl_signal_width(retval))
|
||||
load_wid = ivl_signal_width(retval);
|
||||
|
||||
fprintf(vvp_out, " %%load/v %u, V_%s, %u;\n",
|
||||
res.base, vvp_signal_label(retval), load_wid);
|
||||
|
||||
if (load_wid < swid)
|
||||
fprintf(vvp_out, " %%mov %u, 0, %u;\n",
|
||||
res.base+load_wid, swid-load_wid);
|
||||
}
|
||||
|
||||
/* Pad the signal value with zeros. */
|
||||
if (swid < wid)
|
||||
fprintf(vvp_out, " %%mov %u, 0, %u;\n",
|
||||
res.base+swid, wid-swid);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static struct vector_info draw_unary_expr(ivl_expr_t exp, unsigned wid)
|
||||
{
|
||||
struct vector_info res;
|
||||
|
|
@ -2101,6 +2030,9 @@ struct vector_info draw_eval_expr(ivl_expr_t exp, int stuff_ok_flag)
|
|||
|
||||
/*
|
||||
* $Log: eval_expr.c,v $
|
||||
* Revision 1.119 2005/07/13 04:52:31 steve
|
||||
* Handle functions with real values.
|
||||
*
|
||||
* Revision 1.118 2005/07/11 16:56:51 steve
|
||||
* Remove NetVariable and ivl_variable_t structures.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2003 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2003-2005 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
|
||||
|
|
@ -17,7 +17,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: eval_real.c,v 1.13 2005/07/11 16:56:51 steve Exp $"
|
||||
#ident "$Id: eval_real.c,v 1.14 2005/07/13 04:52:31 steve Exp $"
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
|
@ -280,6 +280,10 @@ int draw_eval_real(ivl_expr_t exp)
|
|||
res = draw_signal_real(exp);
|
||||
break;
|
||||
|
||||
case IVL_EX_UFUNC:
|
||||
res = draw_ufunc_real(exp);
|
||||
break;
|
||||
|
||||
default:
|
||||
if (ivl_expr_value(exp) == IVL_VT_VECTOR) {
|
||||
struct vector_info sv = draw_eval_expr(exp, 0);
|
||||
|
|
@ -308,6 +312,9 @@ int draw_eval_real(ivl_expr_t exp)
|
|||
|
||||
/*
|
||||
* $Log: eval_real.c,v $
|
||||
* Revision 1.14 2005/07/13 04:52:31 steve
|
||||
* Handle functions with real values.
|
||||
*
|
||||
* Revision 1.13 2005/07/11 16:56:51 steve
|
||||
* Remove NetVariable and ivl_variable_t structures.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
#ifndef __vvp_priv_H
|
||||
#define __vvp_priv_H
|
||||
/*
|
||||
* Copyright (c) 2001 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2001-2005 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
|
||||
|
|
@ -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.30 2005/07/11 16:56:51 steve Exp $"
|
||||
#ident "$Id: vvp_priv.h,v 1.31 2005/07/13 04:52:31 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "vvp_config.h"
|
||||
|
|
@ -63,6 +63,9 @@ extern int draw_scope(ivl_scope_t scope, ivl_scope_t parent);
|
|||
|
||||
extern void draw_lpm_mux(ivl_lpm_t net);
|
||||
|
||||
extern struct vector_info draw_ufunc_expr(ivl_expr_t exp, unsigned wid);
|
||||
extern int draw_ufunc_real(ivl_expr_t exp);
|
||||
|
||||
/*
|
||||
* This function draws the execution of a vpi_call statement, along
|
||||
* with the tricky handling of arguments. If this is called with a
|
||||
|
|
@ -191,6 +194,9 @@ extern unsigned thread_count;
|
|||
|
||||
/*
|
||||
* $Log: vvp_priv.h,v $
|
||||
* Revision 1.31 2005/07/13 04:52:31 steve
|
||||
* Handle functions with real values.
|
||||
*
|
||||
* Revision 1.30 2005/07/11 16:56:51 steve
|
||||
* Remove NetVariable and ivl_variable_t structures.
|
||||
*
|
||||
|
|
|
|||
Loading…
Reference in New Issue