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);