Jump to content

External events


Erick

Recommended Posts

Hi,

Perhaps this is not the best approach to achieve the synchronization but, here it is what I want to achieve.

From two modules or more I want to be able to trigger functions from other modules.

Suppose moduleA has an event internally defined and a simple function that does a processing and then does a wait according to the computation and it that is sensitive to the mentioned event.
The same for one more moduleB, or multiple more (moduleC, moduleD, etc.).
The goal is to schedule events from each other's modules' functions.
However, since the modules are defined in separated files and instantiated in a 3rd file(top), I dont see a way to link/bind the modules events.

I have tried using fifos, but does not work under the following scenario:
If moduleA triggers moduleB's function which turns out to compute a big delay(10ns) compared to the wait time moduleA it will be doing at the beggining(5ns), moduleA will trigger again moduleB but cannot interrupt the wait it is already under.

Is there a way to synch/link/bind these modules' events when instantiating each module in a top file?
Or is there another way to schedule/trigger a module's function from an external module that can interrupt a wait()?

 

Thanks in advance!

Link to comment
Share on other sites

Would something like the program below do what you want? The output is:

 

        SystemC 3.0.0_pub_rev_20231124-Accellera --- Jan 17 2024 11:06:11

        Copyright (c) 1996-2023 by all Contributors,

        ALL RIGHTS RESERVED

A 0 s

B 5 ns

A 7 ns

B 12 ns

A 14 ns

B 19 ns

A 21 ns

B 26 ns

A 28 ns

 

//------------------------------------ fileA.h

#include "systemc.h"

 

SC_MODULE(A)

{

    sc_in<bool>    m_trigger_a;

    sc_inout<bool> m_trigger_b;

    

    SC_CTOR(A)

    {

        SC_THREAD(my_thread);

    }

    void my_thread()

    {

        for (;;) {

            wait(m_trigger_a.value_changed_event());

            std::cout << "A " << sc_time_stamp() << std::endl;

            wait(5, SC_NS);

            m_trigger_b = !m_trigger_b;

        }

    }

};

 

//------------------------------------ fileB.h

#include "systemc.h"

 

SC_MODULE(B)

{

    sc_inout<bool> m_trigger_a;

    sc_in<bool>    m_trigger_b;

 

    SC_CTOR(B)

    {       

         SC_THREAD(my_thread);

    }

    void my_thread()

    {

        for (;;) {

            // Fire off module A (someone has to start the process...)

            m_trigger_a = !m_trigger_a;

            wait(m_trigger_b.value_changed_event());

            std::cout << "B " << sc_time_stamp() << std::endl;

            wait(2, SC_NS);

        }

    }

};

 

//------------------------------------ main.cpp

#include "systemc.h"

// #include "fileA.h"

// #include "fileB.h"

 

int sc_main(int argc, char* argv[])

{

    sc_signal<bool> triggerA;

    sc_signal<bool> triggerB;

    A mod_a("mod_a");

    B mod_b("mod_b");

 

    mod_a.m_trigger_a(triggerA);

    mod_a.m_trigger_b(triggerB);

 

    mod_b.m_trigger_a(triggerA);

    mod_b.m_trigger_b(triggerB);

 

    sc_start(30, SC_NS);

 

    return 0;

}

Link to comment
Share on other sites

There are three ways to communicate between modules with varying degrees of "niceness":

  1. Use channels (either predefined or custom) - this is the preferred mechanism for 99% of SystemC
  2. Global access to a shared item - this can be useful for a global clock or reset signal
  3. Direct hierarchical access - this is frowned upon because it makes code too fragile

The channel approach is quite nice, but does require ports, interfaces, and channel objects. It is explicit and portable. You could create a simple event channel:

I have an example event channel here -> https://github.com/dcblack/systemc-event-channel

Globals are potentially dangerous; however, you can protect them through use of a singleton class design and accessors. This enables checking usage against abuse and facilitates debug if something goes wrong. I would only recommend globals for items that are truly global in scope such as a distributed reset signal. Do not use globals to share point-to-point communications. Port/channel connections make it much more clear where things are going and coming from.

Edited by David Black
typo
Link to comment
Share on other sites

Some folks use sc_signal<int>, sc_buffer<bool> or sc_signal_resolved<1> as an inexpensive (less to code) alternative to a custom channel. Keep in mind that sc_signal only sends an event  on changes to the underlying value. sc_buffer provides an event on every write.

 

 

 

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...