Handle functions with real values.
This commit is contained in:
parent
b094ccc3f7
commit
5bfdd52391
|
|
@ -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.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
|
SHELL = /bin/sh
|
||||||
|
|
@ -51,7 +51,7 @@ dep:
|
||||||
$(CC) $(CPPFLAGS) $(CFLAGS) -MD -c $< -o $*.o
|
$(CC) $(CPPFLAGS) $(CFLAGS) -MD -c $< -o $*.o
|
||||||
mv $*.d dep
|
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
|
vvp_process.o vvp_scope.o
|
||||||
|
|
||||||
ifeq (@WIN32@,yes)
|
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
|
* 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.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
|
#endif
|
||||||
|
|
||||||
# include "vvp_priv.h"
|
# include "vvp_priv.h"
|
||||||
|
|
@ -1752,77 +1752,6 @@ static struct vector_info draw_sfunc_expr(ivl_expr_t exp, unsigned wid)
|
||||||
return res;
|
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)
|
static struct vector_info draw_unary_expr(ivl_expr_t exp, unsigned wid)
|
||||||
{
|
{
|
||||||
struct vector_info res;
|
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 $
|
* $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
|
* Revision 1.118 2005/07/11 16:56:51 steve
|
||||||
* Remove NetVariable and ivl_variable_t structures.
|
* 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
|
* This source code is free software; you can redistribute it
|
||||||
* and/or modify it in source code form under the terms of the GNU
|
* 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
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_CVS_IDENT
|
#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
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -280,6 +280,10 @@ int draw_eval_real(ivl_expr_t exp)
|
||||||
res = draw_signal_real(exp);
|
res = draw_signal_real(exp);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case IVL_EX_UFUNC:
|
||||||
|
res = draw_ufunc_real(exp);
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
if (ivl_expr_value(exp) == IVL_VT_VECTOR) {
|
if (ivl_expr_value(exp) == IVL_VT_VECTOR) {
|
||||||
struct vector_info sv = draw_eval_expr(exp, 0);
|
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 $
|
* $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
|
* Revision 1.13 2005/07/11 16:56:51 steve
|
||||||
* Remove NetVariable and ivl_variable_t structures.
|
* Remove NetVariable and ivl_variable_t structures.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
#ifndef __vvp_priv_H
|
#ifndef __vvp_priv_H
|
||||||
#define __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
|
* This source code is free software; you can redistribute it
|
||||||
* and/or modify it in source code form under the terms of the GNU
|
* 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
|
* 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.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
|
#endif
|
||||||
|
|
||||||
# include "vvp_config.h"
|
# 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 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
|
* This function draws the execution of a vpi_call statement, along
|
||||||
* with the tricky handling of arguments. If this is called with a
|
* 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 $
|
* $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
|
* Revision 1.30 2005/07/11 16:56:51 steve
|
||||||
* Remove NetVariable and ivl_variable_t structures.
|
* Remove NetVariable and ivl_variable_t structures.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue