From abfccb65e954ac5e8342682c4864a40036a1d5af Mon Sep 17 00:00:00 2001 From: Stephen Williams Date: Mon, 28 Jan 2008 18:57:55 -0800 Subject: [PATCH] User defined functions take real arguments Allow user defined functions to take real value arguments and return real value results in net contexts. Use the data type of the nets attached to the ports to define the data types of the arguments and return value. --- elab_net.cc | 8 ------- net_func.cc | 18 +++++++++++++++ netlist.h | 1 + vvp/ufunc.cc | 60 ++++++++++++++++++-------------------------------- vvp/ufunc.h | 22 +++++------------- vvp/vvp_net.cc | 11 +++++++++ vvp/vvp_net.h | 1 + 7 files changed, 57 insertions(+), 64 deletions(-) diff --git a/elab_net.cc b/elab_net.cc index aff27fac3..27c47137a 100644 --- a/elab_net.cc +++ b/elab_net.cc @@ -1357,14 +1357,6 @@ NetNet* PECallFunction::elaborate_net(Design*des, NetScope*scope, if (errors > 0) return 0; - if (def->return_sig()->data_type() == IVL_VT_REAL) { - cerr << get_fileline() << ": sorry: real user functions are" - " not currently supported in continuous assignments." - << endl; - des->errors += 1; - return 0; - } - NetUserFunc*net = new NetUserFunc(scope, scope->local_symbol(), dscope); diff --git a/net_func.cc b/net_func.cc index 5d270475e..5a4d4e5bb 100644 --- a/net_func.cc +++ b/net_func.cc @@ -49,6 +49,24 @@ NetUserFunc::~NetUserFunc() { } +ivl_variable_type_t NetUserFunc::data_type(unsigned port) const +{ + NetFuncDef*def = def_->func_def(); + + /* Port 0 is the return port. */ + if (port == 0) { + const NetNet*sig = def->return_sig(); + assert(sig); + return sig->data_type(); + } + + port -= 1; + assert(port < def->port_count()); + const NetNet*port_sig = def->port(port); + + return port_sig->data_type(); +} + unsigned NetUserFunc::port_width(unsigned port) const { NetFuncDef*def = def_->func_def(); diff --git a/netlist.h b/netlist.h index f54f99907..3923b9258 100644 --- a/netlist.h +++ b/netlist.h @@ -1024,6 +1024,7 @@ class NetUserFunc : public NetNode { NetUserFunc(NetScope*s, perm_string n, NetScope*def); ~NetUserFunc(); + ivl_variable_type_t data_type(unsigned port) const; unsigned port_width(unsigned port) const; const NetScope* def() const; diff --git a/vvp/ufunc.cc b/vvp/ufunc.cc index 55e48fdaf..0d769cc0c 100644 --- a/vvp/ufunc.cc +++ b/vvp/ufunc.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002-2005 Stephen Williams (steve@icarus.com) + * Copyright (c) 2002-2008 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 @@ -16,9 +16,6 @@ * 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: ufunc.cc,v 1.8 2005/06/12 01:10:26 steve Exp $" -#endif # include "compile.h" # include "symbols.h" @@ -67,7 +64,10 @@ void ufunc_core::assign_bits_to_ports(void) for (unsigned idx = 0 ; idx < port_count() ; idx += 1) { vvp_net_t*net = ports_[idx]; vvp_net_ptr_t pp (net, 0); - net->fun->recv_vec4(pp, value(idx)); + if (vvp_fun_signal_real*tmp = dynamic_cast(net->fun)) + tmp->recv_real(pp, value_r(idx)); + if (vvp_fun_signal_vec*tmp = dynamic_cast(net->fun)) + tmp->recv_vec4(pp, value(idx)); } } @@ -79,8 +79,12 @@ void ufunc_core::assign_bits_to_ports(void) void ufunc_core::finish_thread(vthread_t thr) { thread_ = 0; - vvp_fun_signal*sig = reinterpret_cast(result_->fun); - propagate_vec4(sig->vec4_value()); + if (vvp_fun_signal_real*sig = dynamic_cast(result_->fun)) + + propagate_real(sig->real_value()); + + if (vvp_fun_signal_vec*sig = dynamic_cast(result_->fun)) + propagate_vec4(sig->vec4_value()); } /* @@ -89,6 +93,16 @@ void ufunc_core::finish_thread(vthread_t thr) * arrange for the function to be called. */ void ufunc_core::recv_vec4_from_inputs(unsigned port) +{ + invoke_thread_(); +} + +void ufunc_core::recv_real_from_inputs(unsigned port) +{ + invoke_thread_(); +} + +void ufunc_core::invoke_thread_() { if (thread_ == 0) { thread_ = vthread_new(code_, scope_); @@ -179,35 +193,3 @@ void compile_ufunc(char*label, char*code, unsigned wid, free(argv); free(portv); } - - -/* - * $Log: ufunc.cc,v $ - * Revision 1.8 2005/06/12 01:10:26 steve - * Remove useless references to functor.h - * - * Revision 1.7 2005/04/01 06:02:45 steve - * Reimplement combinational UDPs. - * - * Revision 1.6 2005/03/18 02:56:04 steve - * Add support for LPM_UFUNC user defined functions. - * - * Revision 1.5 2004/12/11 02:31:30 steve - * Rework of internals to carry vectors through nexus instead - * of single bits. Make the ivl, tgt-vvp and vvp initial changes - * down this path. - * - * Revision 1.4 2003/07/03 20:03:36 steve - * Remove the vvp_cpoint_t indirect code pointer. - * - * Revision 1.3 2003/05/07 03:39:12 steve - * ufunc calls to functions can have scheduling complexities. - * - * Revision 1.2 2002/08/12 01:35:08 steve - * conditional ident string using autoconfig. - * - * Revision 1.1 2002/03/18 00:19:34 steve - * Add the .ufunc statement. - * - */ - diff --git a/vvp/ufunc.h b/vvp/ufunc.h index 5efffa299..44faada0e 100644 --- a/vvp/ufunc.h +++ b/vvp/ufunc.h @@ -1,7 +1,7 @@ #ifndef __ufunc_H #define __ufunc_H /* - * Copyright (c) 2002-2005 Stephen Williams (steve@icarus.com) + * Copyright (c) 2002-2008 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 @@ -18,9 +18,6 @@ * 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: ufunc.h,v 1.6 2005/06/22 00:04:49 steve Exp $" -#endif # include "pointers.h" @@ -67,6 +64,10 @@ class ufunc_core : public vvp_wide_fun_core { private: void recv_vec4_from_inputs(unsigned port); + void recv_real_from_inputs(unsigned port); + + void invoke_thread_(void); + private: // output width of the function node. @@ -86,17 +87,4 @@ class ufunc_core : public vvp_wide_fun_core { vvp_net_t*result_; }; - -/* - * $Log: ufunc.h,v $ - * Revision 1.6 2005/06/22 00:04:49 steve - * Reduce vvp_vector4 copies by using const references. - * - * Revision 1.5 2005/04/01 06:02:45 steve - * Reimplement combinational UDPs. - * - * Revision 1.4 2005/03/18 02:56:04 steve - * Add support for LPM_UFUNC user defined functions. - * - */ #endif diff --git a/vvp/vvp_net.cc b/vvp/vvp_net.cc index d9cf949c3..ff017d28d 100644 --- a/vvp/vvp_net.cc +++ b/vvp/vvp_net.cc @@ -1997,6 +1997,17 @@ void vvp_wide_fun_core::propagate_vec4(const vvp_vector4_t&bit, vvp_send_vec4(ptr_->out, bit); } +void vvp_wide_fun_core::propagate_real(double bit, + vvp_time64_t delay) +{ + if (delay) { + // schedule_assign_vector(ptr_->out, bit, delay); + assert(0); // Need a real-value version of assign_vector. + } else { + vvp_send_real(ptr_->out, bit); + } +} + unsigned vvp_wide_fun_core::port_count() const { diff --git a/vvp/vvp_net.h b/vvp/vvp_net.h index d4627fddd..c338b6055 100644 --- a/vvp/vvp_net.h +++ b/vvp/vvp_net.h @@ -957,6 +957,7 @@ class vvp_wide_fun_core : public vvp_net_fun_t { protected: void propagate_vec4(const vvp_vector4_t&bit, vvp_time64_t delay =0); + void propagate_real(double bit, vvp_time64_t delay =0); unsigned port_count() const; vvp_vector4_t& value(unsigned);