Jump to content

When exactly events are created?

Recommended Posts

I want to simulate a memory, that when accessed replies with some delay. During the initial setting up the event handling I wanted to test if it works as expected. After setting up the main program, creating the MWE object and starting event handling, I wanted to create an event, with notify. The MWE below produces the output

Requested 0 s
Replied 0 s
Replied 20 ns
MWE created
INFO: Exiting simulation

This said to me that during initialization the two methods are executed correctly, the reply event correctly notified. However, the text "MWE created" is printed only after no more events in the system.

My questions:

1./ Does it actually mean that there is no programmed way to "inject" an event for the simulator? (even just for debugging like this)

2./ The name of sc_start() suggests that after initiating the system, the control returns to the instruction following the call. Actually, what it makes, is sc_do_simulation(), and that is the mistake in my approach?

3./ What is the "best" way to simulate what I want, i.e. that the memory is accessed (with address and access attributes), and after some delay returns the required content? (A simulator must run with minimum offset activity. My best idea is that the requesting processor runs a thread which waits for the 'reply' event from the memory, which itself runs two threads for receiving request and reply. It seems to me too complicated, and maybe slow.)

4./ Is there any essential performance difference to implement as thread or method what I want?

5./ Is there any "trick" to "embed" some event handling in a normal (parametrized) method?

6./ As the MWE is, it processes all available events, the event triggered after that produces no error message, and sc_stop() does nothing with that event. Is it by design?

7./ Is there any way to force printing correct time units, even when the value is zero?

// File main.cpp

#include <systemc>
#include "MWE.h"
using namespace sc_core;

unsigned errors = 0;
const char* simulation_name = "EMPA_processor";

int sc_main(int argc, char* argv[])
  MWE MyMWE("The_MWE");
  std::cerr << "MWE created\n";
  if (not sc_end_of_simulation_invoked()) sc_stop();
  std::cerr << "Exiting simulation\n";
  return errors?1:0;

// File MWE.h

#ifndef MWE_H
#define MWE_H

#include <systemc>
#include <iostream>

    MWE(sc_core::sc_module_name nm);
    void  request_method(void);
    void  reply_method(void);
    sc_core::sc_event m_request;
    sc_core::sc_event m_reply;
#endif // MWE_H

// File mwe.cpp
#include "MWE.h"
using namespace sc_core;
MWE::MWE(sc_core::sc_module_name nm )
: sc_core::sc_module(nm){
      sensitive << m_request;
//      dont_initialize();
      sensitive << m_reply;
//      dont_initialize();

void MWE::request_method(void){
  std::cerr << "Requested " << sc_time_stamp() << "\n";
void MWE::reply_method(void){
  std::cerr << "Replied " << sc_time_stamp() << "\n";


Share this post

Link to post
Share on other sites

The output exposes a misconception you have about the semantics of sc_start(). Once you call sc_start(), you completely hand over control to the DE simulation kernel of SystemC to process all events, which are created by the SC_METHODs and SC_THREADs. Execution of sc_main() only continues *after* sc_start() returns because there are no events to process anymore. Because you don't call dont_initialize() after registering your SC_METHODs, they get executed right after start of simulation at 0 ns. Your request method then notifies the event with a 20 ns delay, which triggers your reply method at 20 ns. You notify from sc_main has no effect as you don't hand over control to the simulation kernel. Your message "MWE created" gets executed after the simulation finished.

To generate stimuli for your model, it is common practice to create a custom module with SC_THREAD(s) that generate the stimuli. You may also do some monitoring from this thread. Conceptually cleaner is to separate stimuli generation and monitoring into separate modules.

From your modeling goals, it seems that you could benefit from using Transaction Level Modeling (TLM), which is part of the IEEE Std 1666-2011. However, I suggest that you get first a bit more familiar with the basic concepts of SystemC and TLM by reading a good introductory book on SystemC(/TLM), e.g., SystemC from the ground up. There also some good introductory presentations, which you can find in the archives of the different SystemC User Groups.

Share this post

Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now