SystemC: passing events between modules
In SystemC, what is the syntax to use events as module input/outputs.
I have a worker module and I want to send it an event to preempt what it's currently doing from a scheduler module.
sc_port<preempt_event_if> preempt_event;
I'm declaring an interface within the worker module shown above.
The interface is 开发者_如何转开发defined as the following:
class preempt_event_if : virtual public sc_interface
{
public:
virtual const sc_event& preempt_event() const = 0;
};
The channel which uses the event defines it as the following:
const sc_event& preempt_event() const { return preempt_interrupt; }
Which where preempt_interrupt
is a SystemC event that gets notified from within the channel's functions.
You are doing it right, I'd just use void preempt()
which calls notify, instead of returning the event through the interface.
In the woker module, you can use static sensitivity list to create a dynamic process in the overridden end_of_elaboration() kernel callback function:
SC_METHOD(do_something);
sensitive << preempt_event->preempt_event();
Because only in the end of elaboration phase, you are sure that the port is already bound to an existing preempt_event
channel.
Another way to react the event in the woker module is that you can just use wait(preempt_event->preempt_event())
in your normal SC_THREAD
or next_trigger(preempt_event->preempt_event())
in your normal SC_METHOD
. Both ways allow your process to be sensitive to the event dynamically. Then in your scheduler module, you can again create a sc_port<preempt_event_if>
and access the preempt_event().notify()
to send an event to the worker module.
SystemC events are used mainly to schedule a process for execution and do not hold any state that can be queried, so there is nothing for you to know if the event has occurred or not.
You need to use a sc_buffer
for that purpose. Just declare an input port of bool
type in the worker:
sc_in<bool> i_preempt;
and an output port of bool
type in the scheduler:
sc_out<bool> o_preempt;
and bind both to a buffer instance:
sc_buffer<bool> preempt;
scheduler.i_preempt.bind(preempt);
worker.o_preempt.bind(preempt);
In the scheduler module you can write a value of true
to that buffer:
o_preempt->write(true);
and in the worker you can check for posedge
condition or wait for posedge_event
:
wait(event1 | i_preempt->posedge_event());
if (i_preempt->posedge()) { /* do preemption */ }
精彩评论