SystemC: passing events between modules

2.6k views Asked by At

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.

3

There are 3 answers

0
AudioBubble On

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 */ }
0
Giovanni Funchal On

You are doing it right, I'd just use void preempt() which calls notify, instead of returning the event through the interface.

0
kenny-liu On

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.