2014-07-23 22:39:29 +02:00
|
|
|
#ifndef IVL_schedule_H
|
|
|
|
|
#define IVL_schedule_H
|
2001-03-11 01:29:38 +01:00
|
|
|
/*
|
2021-02-20 08:21:12 +01:00
|
|
|
* Copyright (c) 2001-2021 Stephen Williams (steve@icarus.com)
|
2001-03-11 01:29:38 +01:00
|
|
|
*
|
|
|
|
|
* 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
|
2012-08-29 03:41:23 +02:00
|
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
2001-03-11 01:29:38 +01:00
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
# include "vthread.h"
|
2004-12-11 03:31:25 +01:00
|
|
|
# include "vvp_net.h"
|
2007-01-16 06:44:14 +01:00
|
|
|
# include "array.h"
|
2001-03-11 01:29:38 +01:00
|
|
|
|
2001-03-11 23:42:11 +01:00
|
|
|
/*
|
|
|
|
|
* This causes a thread to be scheduled for execution. The schedule
|
|
|
|
|
* puts the event into the event queue after any existing events for a
|
|
|
|
|
* given time step. The delay is a relative time.
|
2002-05-13 01:44:41 +02:00
|
|
|
*
|
|
|
|
|
* If the delay is zero, the push_flag can be used to force the event
|
|
|
|
|
* to the front of the queue. %fork uses this to get the thread
|
|
|
|
|
* execution ahead of non-blocking assignments.
|
2001-03-11 23:42:11 +01:00
|
|
|
*/
|
2003-09-09 02:56:45 +02:00
|
|
|
extern void schedule_vthread(vthread_t thr, vvp_time64_t delay,
|
2002-05-13 01:44:41 +02:00
|
|
|
bool push_flag =false);
|
2001-03-11 01:29:38 +01:00
|
|
|
|
2017-12-04 05:13:24 +01:00
|
|
|
extern void schedule_inactive(vthread_t thr);
|
|
|
|
|
|
2016-03-19 14:46:09 +01:00
|
|
|
extern void schedule_init_vthread(vthread_t thr);
|
|
|
|
|
|
2011-03-30 08:42:26 +02:00
|
|
|
extern void schedule_final_vthread(vthread_t thr);
|
|
|
|
|
|
2001-03-11 23:42:11 +01:00
|
|
|
/*
|
|
|
|
|
* Create an assignment event. The val passed here will be assigned to
|
2005-01-29 18:53:25 +01:00
|
|
|
* the specified input when the delay times out. This is scheduled
|
|
|
|
|
* like a non-blocking assignment. This is in fact mostly used to
|
|
|
|
|
* implement the non-blocking assignment.
|
2001-03-11 23:42:11 +01:00
|
|
|
*/
|
2005-05-07 05:15:42 +02:00
|
|
|
extern void schedule_assign_vector(vvp_net_ptr_t ptr,
|
|
|
|
|
unsigned base, unsigned vwid,
|
2005-06-22 20:30:12 +02:00
|
|
|
const vvp_vector4_t&val,
|
2005-05-07 05:15:42 +02:00
|
|
|
vvp_time64_t delay);
|
|
|
|
|
|
2007-01-16 06:44:14 +01:00
|
|
|
extern void schedule_assign_array_word(vvp_array_t mem,
|
|
|
|
|
unsigned word_address,
|
|
|
|
|
unsigned off,
|
2021-01-01 09:19:27 +01:00
|
|
|
const vvp_vector4_t&val,
|
2007-01-16 06:44:14 +01:00
|
|
|
vvp_time64_t delay);
|
2009-04-07 06:47:21 +02:00
|
|
|
|
2009-09-03 05:04:34 +02:00
|
|
|
extern void schedule_assign_array_word(vvp_array_t mem,
|
|
|
|
|
unsigned word_address,
|
|
|
|
|
double val,
|
|
|
|
|
vvp_time64_t delay);
|
2016-05-10 23:16:40 +02:00
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Create an event to force the output of a net.
|
|
|
|
|
*/
|
|
|
|
|
extern void schedule_force_vector(vvp_net_t*net,
|
|
|
|
|
unsigned base, unsigned vwid,
|
|
|
|
|
const vvp_vector4_t&val,
|
|
|
|
|
vvp_time64_t delay);
|
|
|
|
|
|
2009-04-07 06:47:21 +02:00
|
|
|
/*
|
|
|
|
|
* Create an event to propagate the output of a net.
|
|
|
|
|
*/
|
2014-11-21 23:41:31 +01:00
|
|
|
extern void schedule_propagate_vector(vvp_net_t*ptr,
|
2021-02-20 08:21:12 +01:00
|
|
|
vvp_time64_t delay,
|
2014-11-21 23:41:31 +01:00
|
|
|
const vvp_vector4_t&val);
|
2009-04-07 06:47:21 +02:00
|
|
|
|
2021-02-20 08:21:12 +01:00
|
|
|
/*
|
|
|
|
|
* Create an event to propagate the output of an event.
|
|
|
|
|
*/
|
|
|
|
|
extern void schedule_propagate_event(vvp_net_t*ptr,
|
|
|
|
|
vvp_time64_t delay);
|
|
|
|
|
|
2005-01-29 18:53:25 +01:00
|
|
|
/*
|
|
|
|
|
* This is very similar to schedule_assign_vector, but generates an
|
2007-07-12 06:31:09 +02:00
|
|
|
* event in the active queue. It is used at link time to assign a
|
|
|
|
|
* constant value (i.e. C4<...>) to the input of a functor. This
|
2005-01-29 18:53:25 +01:00
|
|
|
* creates an event in the active queue.
|
|
|
|
|
*/
|
2008-06-16 22:40:20 +02:00
|
|
|
extern void schedule_set_vector(vvp_net_ptr_t ptr, const vvp_vector4_t&val);
|
2021-01-01 09:19:27 +01:00
|
|
|
extern void schedule_set_vector(vvp_net_ptr_t ptr, const vvp_vector8_t&val);
|
2005-07-06 06:29:25 +02:00
|
|
|
extern void schedule_set_vector(vvp_net_ptr_t ptr, double val);
|
2005-01-29 18:53:25 +01:00
|
|
|
|
2017-12-04 05:13:24 +01:00
|
|
|
/*
|
|
|
|
|
* Create a T0 event for always_comb/latch processes. This is the first
|
|
|
|
|
* event in the first inactive region.
|
|
|
|
|
*/
|
|
|
|
|
extern void schedule_t0_trigger(vvp_net_ptr_t ptr);
|
|
|
|
|
|
2007-07-12 06:31:09 +02:00
|
|
|
/*
|
|
|
|
|
* The schedule_init_vector function assigns an initial value to a
|
|
|
|
|
* functor. The assignment is put into a pre-simulation queue that is
|
|
|
|
|
* run before the rest of the simulation runs. This is used to assign
|
|
|
|
|
* initial values to variables and have them propagate through the
|
|
|
|
|
* net. Doing the init before the rest of the scheduler starts
|
|
|
|
|
* prevents threads being triggered by the initialization of the
|
|
|
|
|
* variable, but still allows the initial value to be driven
|
|
|
|
|
* (propagated as events) through the rest of the net.
|
|
|
|
|
*/
|
2021-01-01 09:19:27 +01:00
|
|
|
extern void schedule_init_vector(vvp_net_ptr_t ptr, const vvp_vector4_t&val);
|
|
|
|
|
extern void schedule_init_vector(vvp_net_ptr_t ptr, const vvp_vector8_t&val);
|
2007-07-12 06:31:09 +02:00
|
|
|
extern void schedule_init_vector(vvp_net_ptr_t ptr, double val);
|
2010-04-03 15:54:40 +02:00
|
|
|
/*
|
|
|
|
|
* The schedule_init_propagate function is similar to the above but
|
|
|
|
|
* propagates an initial value from a net output (i.e. without passing
|
|
|
|
|
* through the net functor).
|
|
|
|
|
*/
|
|
|
|
|
extern void schedule_init_propagate(vvp_net_t*net, vvp_vector4_t val);
|
|
|
|
|
extern void schedule_init_propagate(vvp_net_t*net, double val);
|
2001-05-02 03:38:13 +02:00
|
|
|
|
2001-05-01 03:09:39 +02:00
|
|
|
/*
|
2001-05-02 03:38:13 +02:00
|
|
|
* Create a generic event. This supports scheduled events that are not
|
|
|
|
|
* any of the specific types above. The vvp_get_event_t points to a
|
|
|
|
|
* function to be executed when the scheduler gets to the event. It is
|
|
|
|
|
* up to the user to allocate/free the vvp_get_event_s object. The
|
|
|
|
|
* object is never referenced by the scheduler after the run method is
|
|
|
|
|
* called.
|
2006-09-29 03:24:34 +02:00
|
|
|
*
|
|
|
|
|
* The sync_flag is true if this is intended to be a sync event. These
|
2008-01-29 21:19:59 +01:00
|
|
|
* are placed in the stratified event queue after nb assigns. If the
|
2006-09-29 03:24:34 +02:00
|
|
|
* ro_flag is true as well, then it is a Read-only sync event, with
|
|
|
|
|
* all that means.
|
|
|
|
|
*
|
|
|
|
|
* If the sync_flag is false, then the event is ACTIVE, and the
|
|
|
|
|
* ro_flag is ignored.
|
2001-05-01 03:09:39 +02:00
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
typedef struct vvp_gen_event_s *vvp_gen_event_t;
|
|
|
|
|
|
2005-06-09 07:04:45 +02:00
|
|
|
extern void schedule_generic(vvp_gen_event_t obj, vvp_time64_t delay,
|
2009-01-15 05:15:50 +01:00
|
|
|
bool sync_flag, bool ro_flag =true,
|
|
|
|
|
bool delete_obj_when_done =false);
|
2001-05-01 03:09:39 +02:00
|
|
|
|
2010-04-08 13:13:35 +02:00
|
|
|
/* Create a functor output event. This is placed in the pre-simulation
|
|
|
|
|
* event queue if the scheduler is still processing pre-simulation
|
|
|
|
|
* events, otherwise it is placed in the stratified event queue as an
|
|
|
|
|
* ACTIVE event with a delay of 0. It is up to the user to allocate/free
|
|
|
|
|
* the vvp_get_event_s object. The object is never referenced by the
|
|
|
|
|
* scheduler after the run method is called.
|
|
|
|
|
*/
|
|
|
|
|
extern void schedule_functor(vvp_gen_event_t obj);
|
|
|
|
|
|
2009-11-01 18:26:09 +01:00
|
|
|
extern void schedule_at_start_of_simtime(vvp_gen_event_t obj, vvp_time64_t delay);
|
2019-11-26 02:57:10 +01:00
|
|
|
extern void schedule_at_end_of_simtime(vvp_gen_event_t obj, vvp_time64_t delay);
|
2009-11-01 18:26:09 +01:00
|
|
|
|
2008-03-21 03:01:20 +01:00
|
|
|
/* Use this is schedule thread deletion (after rosync). */
|
|
|
|
|
extern void schedule_del_thr(vthread_t thr);
|
|
|
|
|
|
2001-05-01 03:09:39 +02:00
|
|
|
struct vvp_gen_event_s
|
|
|
|
|
{
|
2005-09-20 20:34:01 +02:00
|
|
|
virtual ~vvp_gen_event_s() =0;
|
2005-06-02 18:02:11 +02:00
|
|
|
virtual void run_run() =0;
|
2010-01-07 06:40:26 +01:00
|
|
|
virtual void single_step_display(void);
|
2001-05-01 03:09:39 +02:00
|
|
|
};
|
|
|
|
|
|
2001-03-11 23:42:11 +01:00
|
|
|
/*
|
2001-03-19 02:55:38 +01:00
|
|
|
* This runs the simulator. It runs until all the functors run out or
|
|
|
|
|
* the simulation is otherwise finished.
|
2001-03-11 23:42:11 +01:00
|
|
|
*/
|
2001-03-11 01:29:38 +01:00
|
|
|
extern void schedule_simulate(void);
|
|
|
|
|
|
2001-03-31 21:00:43 +02:00
|
|
|
/*
|
2003-02-10 00:33:26 +01:00
|
|
|
* Get the current absolute simulation time. This is not used
|
2001-03-31 21:00:43 +02:00
|
|
|
* internally by the scheduler (which uses time differences instead)
|
|
|
|
|
* but is used for printouts and stuff.
|
|
|
|
|
*/
|
2002-04-20 06:33:23 +02:00
|
|
|
extern vvp_time64_t schedule_simtime(void);
|
2001-03-31 21:00:43 +02:00
|
|
|
|
2016-06-09 22:27:20 +02:00
|
|
|
/*
|
|
|
|
|
* Indicate that the simulator is running the rosync callbacks. This is
|
|
|
|
|
* used to prevent the callbacks from performing any write operations
|
|
|
|
|
* in the current simulation time slot.
|
|
|
|
|
*/
|
|
|
|
|
extern bool schedule_at_rosync(void);
|
|
|
|
|
|
2001-03-19 02:55:38 +01:00
|
|
|
/*
|
2003-02-10 00:33:26 +01:00
|
|
|
* This function is the equivalent of the $finish system task. It
|
2001-03-19 02:55:38 +01:00
|
|
|
* tells the simulator that simulation is done, the current thread
|
|
|
|
|
* should be stopped, all remaining events abandoned and the
|
|
|
|
|
* schedule_simulate() function will return.
|
|
|
|
|
*
|
|
|
|
|
* The schedule_finished() function will return true if the
|
|
|
|
|
* schedule_finish() function has been called.
|
|
|
|
|
*/
|
|
|
|
|
extern void schedule_finish(int rc);
|
2003-02-21 04:40:35 +01:00
|
|
|
extern void schedule_stop(int rc);
|
2010-01-07 01:08:20 +01:00
|
|
|
extern void schedule_single_step(int flag);
|
2001-03-19 02:55:38 +01:00
|
|
|
extern bool schedule_finished(void);
|
2003-02-22 03:52:06 +01:00
|
|
|
extern bool schedule_stopped(void);
|
2001-03-19 02:55:38 +01:00
|
|
|
|
2003-02-21 04:40:35 +01:00
|
|
|
/*
|
|
|
|
|
* The scheduler calls this function to process stop events. When this
|
|
|
|
|
* function returns, the simulation resumes.
|
|
|
|
|
*/
|
|
|
|
|
extern void stop_handler(int rc);
|
|
|
|
|
|
2003-01-07 00:57:26 +01:00
|
|
|
/*
|
|
|
|
|
* These are event counters for the sake of performance measurements.
|
|
|
|
|
*/
|
|
|
|
|
extern unsigned long count_assign_events;
|
|
|
|
|
extern unsigned long count_gen_events;
|
|
|
|
|
extern unsigned long count_prop_events;
|
|
|
|
|
extern unsigned long count_thread_events;
|
|
|
|
|
extern unsigned long count_event_pool;
|
2001-03-19 02:55:38 +01:00
|
|
|
|
2014-07-23 22:39:29 +02:00
|
|
|
#endif /* IVL_schedule_H */
|