Rework named events and event/or.

This commit is contained in:
steve 2004-12-18 18:52:44 +00:00
parent 26d97558c4
commit 8939467ac5
3 changed files with 61 additions and 48 deletions

View File

@ -1,7 +1,7 @@
/*
* Copyright (c) 2001 Stephen Williams (steve@icarus.com)
*
* $Id: README.txt,v 1.48 2004/12/11 02:31:29 steve Exp $
* $Id: README.txt,v 1.49 2004/12/18 18:52:44 steve Exp $
*/
VVP SIMULATION ENGINE
@ -376,7 +376,7 @@ EVENT STATEMENTS
Threads need to interact with the functors of a netlist synchronously,
as well as asynchronously. There are cases where the web of functors
needs to wake up a waiting thread. The web of functors signals threads
through .event objects, that are declare like so:
through .event objects, that are declared like so:
<label> .event <type>, <symbols_list>;
<label> .event "name";

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2001 Stephen Williams (steve@icarus.com)
* Copyright (c) 2004 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: event.cc,v 1.15 2004/12/11 02:31:29 steve Exp $"
#ident "$Id: event.cc,v 1.16 2004/12/18 18:52:44 steve Exp $"
#endif
# include "event.h"
@ -33,6 +33,16 @@
# include <malloc.h>
#endif
void waitable_hooks_s::run_waiting_threads_()
{
if (threads == 0)
return;
vthread_t tmp = threads;
threads = 0;
vthread_schedule_list(tmp);
}
inline vvp_fun_edge::edge_t VVP_EDGE(vvp_bit4_t from, vvp_bit4_t to)
{
return 1 << ((from << 2) | to);
@ -69,22 +79,36 @@ vvp_fun_edge::~vvp_fun_edge()
void vvp_fun_edge::recv_vec4(vvp_net_ptr_t port, vvp_vector4_t bit)
{
// XXXX for now, only support first port.
assert(port.port() == 0);
/* See what kind of edge this represents. */
edge_t mask = VVP_EDGE(bits_.value(0), bit.value(0));
/* Save the current input for the next time around. */
bits_ = bit;
if (threads && (edge_ & mask)) {
vthread_t tmp = threads;
threads = 0;
vthread_schedule_list(tmp);
if ((edge_ == vvp_edge_none) || (edge_ & mask)) {
run_waiting_threads_();
vvp_net_t*net = port.ptr();
vvp_send_vec4(net->out, bit);
}
}
vvp_named_event::vvp_named_event(struct __vpiHandle*h)
{
handle_ = h;
}
vvp_named_event::~vvp_named_event()
{
}
void vvp_named_event::recv_vec4(vvp_net_ptr_t port, vvp_vector4_t bit)
{
run_waiting_threads_();
vvp_net_t*net = port.ptr();
vvp_send_vec4(net->out, bit);
}
/*
** Create an event functor
** edge: compile_event(label, type, argc, argv)
@ -128,12 +152,12 @@ void compile_event(char*label, char*type,
*/
void compile_named_event(char*label, char*name)
{
fprintf(stderr, "XXXX compile_named_event not implemented\n");
vvp_net_t*ptr = new vvp_net_t;
vvp_net_t*fdx = 0;
vpiHandle obj = vpip_make_named_event(name, fdx);
vpiHandle obj = vpip_make_named_event(name, ptr);
ptr->fun = new vvp_named_event(obj);
define_functor_symbol(label, ptr);
compile_vpi_symbol(label, obj);
vpip_attach_to_current_scope(obj);
@ -143,6 +167,9 @@ void compile_named_event(char*label, char*name)
/*
* $Log: event.cc,v $
* Revision 1.16 2004/12/18 18:52:44 steve
* Rework named events and event/or.
*
* Revision 1.15 2004/12/11 02:31:29 steve
* Rework of internals to carry vectors through nexus instead
* of single bits. Make the ivl, tgt-vvp and vvp initial changes

View File

@ -1,7 +1,7 @@
#ifndef __event_H
#define __event_H
/*
* Copyright (c) 2000 Stephen Williams (steve@icarus.com)
* Copyright (c) 2004 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: event.h,v 1.6 2004/12/11 02:31:29 steve Exp $"
#ident "$Id: event.h,v 1.7 2004/12/18 18:52:44 steve Exp $"
#endif
# include "vvp_net.h"
@ -34,7 +34,11 @@
* on. This includes the infrastructure needed to hold threads.
*/
struct waitable_hooks_s {
vthread_t threads;
protected:
void run_waiting_threads_();
};
/*
@ -62,50 +66,32 @@ extern const vvp_fun_edge::edge_t vvp_edge_negedge;
extern const vvp_fun_edge::edge_t vvp_edge_anyedge;
extern const vvp_fun_edge::edge_t vvp_edge_none;
#if 0
/*
* This is a functor to represent named events. This functor has no
* inputs, and no output. It is a functor so that the %wait and %set
* instructions can get at it.
* A named event is simpler then a vvp_fun_edge in that it triggers on
* any input at all to port-0. The idea here is that behavioral code
* can use a %set/v instruction to trigger the event.
*/
struct named_event_functor_s : public waitable_hooks_s, public functor_s {
class vvp_named_event : public vvp_net_fun_t, public waitable_hooks_s {
public:
explicit named_event_functor_s();
~named_event_functor_s();
void set(vvp_ipoint_t ipt, bool push, unsigned val, unsigned str =0);
explicit vvp_named_event(struct __vpiHandle*eh);
~vvp_named_event();
struct __vpiHandle* handle;
void recv_vec4(vvp_net_ptr_t port, vvp_vector4_t bit);
private:
struct __vpiHandle*handle_;
};
/*
* Callback functors.
*/
struct callback_functor_s *vvp_fvector_make_callback
(vvp_fvector_t, event_functor_s::edge_t = vvp_edge_none);
#endif
/*
* $Log: event.h,v $
* Revision 1.7 2004/12/18 18:52:44 steve
* Rework named events and event/or.
*
* Revision 1.6 2004/12/11 02:31:29 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.5 2004/10/04 01:10:59 steve
* Clean up spurious trailing white space.
*
* Revision 1.4 2002/08/12 01:35:08 steve
* conditional ident string using autoconfig.
*
* Revision 1.3 2002/07/17 18:30:01 steve
* Fix uninitialized thread pointer in named event.
*
* Revision 1.2 2002/05/19 05:18:16 steve
* Add callbacks for vpiNamedEvent objects.
*
* Revision 1.1 2001/11/06 03:07:22 steve
* Code rearrange. (Stephan Boettcher)
*
*/
#endif // __event_H