#ifndef __sc_core_sc_process_tracer_h__ #define __sc_core_sc_process_tracer_h__ /** * Title: SystemC Process and Event Tracing Interface. * =================================================== * Submitter: Mentor Graphics Corp. * =================================================== * Purpose: * =================================================== * The proposed interface is to be used by an observer code * to trace invocation of SystemC processes, for the purposes of * performance analysis and debugging. * =================================================== * Description: * =================================================== * User code will register an instance of sc_process_tracer interface, * using the new method add_process_tracer(sc_process_tracer *) in class sc_simcontext. * * For all such registered instances, the following virtual methods * will be called by SystemC core: * * -- void event_notified(sc_event *) * after one of notify or notify_delayed methods was called on the event. * * -- void event_cancelled(sc_event *) * before the event is cancelled. * * -- void event_triggered(sc_event *) * when the event is triggered. * The event is actually dispatched at the next delta cycle. * * -- void method_created(sc_process_b *) * for static methods, at the end of elaboration; * for dynamic methods, after the method is created. * * -- void method_started(sc_process_b *) * before invoking a method. * * -- void method_finished(sc_process_b *) * after a method has finished normally. * * -- void thread_created(sc_process_b *) * for static threads, at the end of elaboration; * for dynamic threads, after the thread is created. * * -- void thread_started(sc_process_b *) * before invoking a thread. * * -- void thread_finished(sc_process_b *) * after a thread has finished normally. * * -- void thread_suspended(sc_process_b *) * before suspending a thread. * * -- void thread_resumed(sc_process_b *) * after resuming a thread. * * -- void thread_reset(sc_process_b *) * after a thread was reset. * * -- void process_terminated(sc_process_b *, sc_process_tracer::termination_reason_t) * after the process is terminated. * The enumeration sc_process_tracer::termination_reason_t is defined as follows: * * enum termination_reason_t { THREAD_FINISHED, THREAD_HALTED, PROCESS_KILLED, PROCESS_ERROR_EXIT }; * * * The following methods will be added to class sc_simcontext: * * -- void add_process_tracer(sc_process_tracer *) * If the same tracer is added again, it is silently ignored. * All tracers, which were added to the sc_simcontext, * and not removed before the end of simulation, will be deleted by sc_simcontext. * * -- void remove_process_tracer(sc_process_tracer *) * If the tracer was not found, it is ignored. * * * The following enumeration type will be made public in class sc_event: * * enum notify_t { NONE, DELTA, TIMED }; * * The following method will be available for instances of class sc_event. * * -- sc_event::notify_t get_notification_type(sc_time ¬ify_time) const * This method will return valid information if called from the following methods of a sc_process_tracer subclass: * * event_notified(sc_event *) * event_cancelled(sc_event *) * event_triggered(sc_event *) * * The return value is the current notification type of the event. * The following are current possible values (see class sc_event): * * sc_event::NONE * sc_event::DELTA * sc_event::TIMED * * The parameter notify_time will be filled for TIMED notification type * with the event notification time, or the current simulation time for delta cycle notification. * * * The following class will be added to SystemC core: * * class sc_event_iterator { * public: * const sc_event *operator *() const; * const sc_event *operator->() const; * sc_event_iterator &operator++(); // prefix operator ++ * sc_event_iterator operator++(int); // postfix operator ++ * bool operator==(const sc_event_iterator &other) const; * bool operator!=(const sc_event_iterator &other) const; * public: * sc_event_iterator(const sc_event_iterator &other); * sc_event_iterator &operator=(const sc_event_iterator &other); * }; * This is a regular STL-style iterator. * * The following methods will be available for instances of class sc_event_list: * * -- sc_event_iterator begin() const; * -- sc_event_iterator end() const; * * These will be used to iterate over the events in list. * * The following methods will be available for instances of class sc_process_b. * * -- sc_process_b::trigger_t get_dynamic_sensitivity(sc_event const *&event_p, * sc_event_list const *&event_list_p, * sc_time ¬ify_time) const * This method will return valid information if called from the following methods of a sc_process_tracer subclass: * * method_finished(sc_process_b *) * thread_suspended(sc_process_b *) * * The return value is the current trigger type of the process. * The following are current possible values (see class sc_process_b): * * sc_process_b::STATIC * sc_process_b::EVENT * sc_process_b::OR_LIST * sc_process_b::AND_LIST * sc_process_b::TIMEOUT * sc_process_b::EVENT_TIMEOUT * sc_process_b::OR_LIST_TIMEOUT * sc_process_b::AND_LIST_TIMEOUT * * All the method's parameters are output-only parameters. * The parameters will be filled by the method according to the current trigger type of the process: * The parameter event_p will be filled for EVENT or EVENT_TIMEOUT sensitivity * with the pointer to the event on which the process is waiting. * The parameter event_list_p will be filled for OR_LIST, AND_LIST, OR_LIST_TIMEOUT or AND_LIST_TIMEOUT sensitivity * with the pointer to the event list on which the process is waiting. * The parameter notify_time will be filled for TIMEOUT, EVENT_TIMEOUT, OR_LIST_TIMEOUT or AND_LIST_TIMEOUT sensitivity * with the timeout time, or the current simulation time for delta cycle timeout. * * -- sc_event_iterator static_sensitivity_begin_iterator() const; * -- sc_event_iterator static_sensitivity_end_iterator() const; * * These two methods will be used to iterate over the static sensitivity events. * */ namespace sc_core { class sc_simcontext /* ... */ { /* ... */ public: /** * If the same tracer is added again, it is silently ignored. * All tracers, which were added to the sc_simcontext, * and not removed before the end of simulation, will be deleted by sc_simcontext. */ void add_process_tracer(sc_process_tracer *tracer); /** * If the tracer was not found, it is ignored. */ void remove_process_tracer(sc_process_tracer *tracer); /* ... */ }; class sc_event /* ... */ { public: enum notify_t { NONE, DELTA, TIMED }; /* ... */ public: /* * This method will return valid information if called from the following methods of a sc_process_tracer subclass: * * event_notified(sc_event *) * event_cancelled(sc_event *) * event_triggered(sc_event *) * * The return value is the current notification type of the event. * The parameter notify_time will be filled for TIMED notification type * with the event notification time, or the current simulation time for delta cycle notification. * */ notify_t get_notification_type(sc_time ¬ify_time) const; /* ... */ }; class sc_event_iterator { public: const sc_event *operator *() const; const sc_event *operator->() const; sc_event_iterator &operator++(); // prefix operator ++ sc_event_iterator operator++(int); // postfix operator ++ bool operator==(const sc_event_iterator &other) const; bool operator!=(const sc_event_iterator &other) const; public: sc_event_iterator(const sc_event_iterator &other); sc_event_iterator &operator=(const sc_event_iterator &other); }; class sc_event_list /* ... */ { /* ... */ public: sc_event_iterator begin() const; sc_event_iterator end() const; /*... */ }; class sc_process_b /*...*/ { /* .... */ public: /** * This method will return valid information if called from the following of a sc_process_tracer subclass: * * method_finished() * thread_suspended() * * The return value is the current trigger type of the process. * All the method's parameters are output-only parameters. * The parameters will be filled by the method according to the current trigger type of the process: * The parameter event_p will be filled for EVENT or EVENT_TIMEOUT sensitivity * with the pointer to the event on which the process is waiting. * The parameter event_list_p will be filled for OR_LIST, AND_LIST, OR_LIST_TIMEOUT or AND_LIST_TIMEOUT sensitivity * with the pointer to the event list on which the process is waiting. * The parameter notify_time will be filled for EVENT_TIMEOUT, OR_LIST_TIMEOUT or AND_LIST_TIMEOUT sensitivity * with the timeout time, or the current simulation time for delta cycle timeout. */ trigger_t get_dynamic_sensitivity(sc_event const *&event_p, sc_event_list const *&event_list_p, sc_time ¬ify_time) const; sc_event_iterator static_sensitivity_begin_iterator() const; sc_event_iterator static_sensitivity_end_iterator() const; /* ... */ }; class sc_process_tracer { public: /** * Called after one of notify or notify_delayed methods was called on the event. */ virtual void event_notified(sc_event *event) = 0; /** * Called before the event is cancelled. */ virtual void event_cancelled(sc_event *event) = 0; /** * Called when the event is triggered. * The event is actually dispatched at the next delta cycle. */ virtual void event_triggered(sc_event *event) = 0; public: /** * Called: * for static methods, at the end of elaboration; * for dynamic methods, after the method is created. */ virtual void method_created(sc_process_b *method) = 0; /** * Called before invoking a method. */ virtual void method_started(sc_process_b *method) = 0; /** * Called after a method has finished normally. */ virtual void method_finished(sc_process_b *method) = 0; public: /** * Called: * for static threads, at the end of elaboration; * for dynamic threads, after the thread is created. */ virtual void thread_created(sc_process_b *thread) = 0; /** * Called before invoking a thread. */ virtual void thread_started(sc_process_b *thread) = 0; /** * Called after a thread has finished normally. */ virtual void thread_finished(sc_process_b *thread) = 0; /** * Called before suspending a thread. */ virtual void thread_suspended(sc_process_b *thread) = 0; /** * Called after resuming a thread. */ virtual void thread_resumed(sc_process_b *thread) = 0; /** * Called after a thread was reset. */ virtual void thread_reset(sc_process_b *thread) = 0; public: enum termination_reason_t { THREAD_FINISHED, THREAD_HALTED, PROCESS_KILLED, PROCESS_ERROR_EXIT }; /** * Called after the process is terminated. */ virtual void process_terminated(sc_process_b *process, termination_reason_t reason) = 0; public: /** * Add a virtual destructor to avoid compilation warnings. */ virtual ~sc_process_tracer() {} }; } #endif