Jump to content

Questions about the timing relationship between sc_clock and sc_event_queue


whmmy

Recommended Posts

Hi!

I am quite curious about the timing relationship between sc_clock and sc_event_queue. I mean suppose I have a sc_event_queue eq, and a sc_clock clk. If eq is notified and clk.pos() occured at the same simulation time, which one is earlier?

Actually I have had an incomplete answer to it. I wrote the following test code:

SC_MODULE(delaytest)
{
  sc_in_clk clk;
  sc_event_queue eq;
  sc_int<32> value = 0;
  sc_signal<int> sigvalue;
  void eventnot()
  {
    while (true)
    {
      wait();
      eq.notify(sc_time(PERIOD, SC_NS));
      cout << "notified by clk.pos, will notify eq in 10ns, now is " << sc_time_stamp() << "\n";
    }
  }
  void updatevalue()
  {
    while (true)
    {
      wait(eq.default_event());
      cout << "notified by eq at time " << sc_time_stamp() << ", old value is " << value << ", old sigvalue is " << sigvalue << "\n";
      sigvalue = sigvalue + 1;
      cout << "notified by eq, after update sigvalue, value is " << value << ", sigvalue is " << sigvalue << " at time " << sc_time_stamp() << "\n";
      wait(SC_ZERO_TIME);
      value = value + 1;
      cout << "notified by eq, after SC_ZERO_TIME and update value, value is " << value << ", sigvalue is " << sigvalue << " at time " << sc_time_stamp() << "\n";
    }
  }
  void display()
  {
    while (true)
    {
      wait(clk.posedge_event());
      cout << "notified by clk.pos, value=" << value << ", sigvalue=" << sigvalue << " at time " << sc_time_stamp() << "\n";
      wait(SC_ZERO_TIME);
      cout << "notified by clk.pos, and after SC_ZERO_TIME, value=" << value << ", sigvalue=" << sigvalue << " at time " << sc_time_stamp() << "\n";
    }
  }

  delaytest(sc_module_name name_) : sc_module(name_)
  {
    SC_HAS_PROCESS(delaytest);
    SC_THREAD(eventnot);
    sensitive << clk.pos();
    SC_THREAD(updatevalue);
    SC_THREAD(display);
  }
};

and in main.cpp clock is created:

sc_clock clk("clk", PERIOD, SC_NS, 0.5, 0, SC_NS, false);

this is the output I get:

Quote

notified by clk.pos, will notify eq in 10ns, now is 5 ns
notified by clk.pos, value=0, sigvalue=0 at time 5 ns
notified by clk.pos, and after SC_ZERO_TIME, value=0, sigvalue=0 at time 5 ns
notified by eq at time 15 ns, old value is 0, old sigvalue is 0
notified by eq, after update sigvalue, value is 0, sigvalue is 0 at time 15 ns
notified by clk.pos, will notify eq in 10ns, now is 15 ns
notified by clk.pos, value=0, sigvalue=1 at time 15 ns
notified by eq, after SC_ZERO_TIME and update value, value is 1, sigvalue is 1 at time 15 ns
notified by clk.pos, and after SC_ZERO_TIME, value=1, sigvalue=1 at time 15 ns

From above, I think I can infer that when a sc_event_queue is notified at the same time as clk.pos, its notification is 1 SC_ZERO_TIME earlier than clk.pos (we can see that from sigvalue). I'm not sure if my inference is correct, please correct me.

 

But value is weird in the above output. value is not a systemc object but just int, so it should be immediately updated when the program run into value=value+1 (I mean it doesn't need to wait for the next SC_ZERO_TIME to update). However, at the same time when value is updated, clk.pos occurs and print value out. It seems that the printed value is the old data 0.

 

What determines the order of updating value and printing value, since they should be done at the same time?

Link to comment
Share on other sites

SystemC does not guarantee any order of method invocation/thread resume. Therefore it is some kind of random which thread gets resumed first.

This applies to your timed notifications: since all are triggered at the same time (e.g. 15ns) the get evaluated in the first delty cycle at 15ns. The order they are evaluated is arbitrary. Therefore it is a bad idea to use plain datatype for cimmunication between processes.

Link to comment
Share on other sites

  • 3 weeks later...
On 1/30/2023 at 1:45 AM, Eyck said:

SystemC does not guarantee any order of method invocation/thread resume. Therefore it is some kind of random which thread gets resumed first.

This applies to your timed notifications: since all are triggered at the same time (e.g. 15ns) the get evaluated in the first delty cycle at 15ns. The order they are evaluated is arbitrary. Therefore it is a bad idea to use plain datatype for cimmunication between processes.

Hi, Eyck. Thanks for your reply.

However, here's a more detailed example that makes me think that eq comes before clk:

SC_MODULE(delaytest)
{
  sc_in_clk clk;
  sc_event_queue eq;
  sc_signal<int> sigvalue;
  void eventnot()
  {
    while (true)
    {
      wait();
      eq.notify(sc_time(PERIOD, SC_NS));
      cout << "notified by clk.pos, will notify eq in 10ns, now is " << sc_time_stamp() << "\n";
    }
  }
  void updatevalue()
  {
    while (true)
    {
      wait(eq.default_event());
      cout << "notified by eq at time " << sc_time_stamp() << ", old sigvalue is " << sigvalue << "\n";
      sigvalue = sigvalue + 1;
      cout << "notified by eq, after update, sigvalue is " << sigvalue << " at time " << sc_time_stamp() << "\n";
      wait(SC_ZERO_TIME);
      cout << "notified by eq, after SC_ZERO_TIME, sigvalue is " << sigvalue << " at time " << sc_time_stamp() << "\n";
    }
  }
  void display()
  {
    while (true)
    {
      wait(clk.posedge_event());
      cout << "notified by clk.pos, sigvalue=" << sigvalue << " at time " << sc_time_stamp() << "\n";
      wait(SC_ZERO_TIME);
      cout << "notified by clk.pos, after SC_ZERO_TIME, sigvalue=" << sigvalue << " at time " << sc_time_stamp() << "\n";
    }
  }

  delaytest(sc_module_name name_) : sc_module(name_), fifo(10), bibo(10)
  {
    SC_HAS_PROCESS(delaytest);
    SC_THREAD(eventnot);
    sensitive << clk.pos();
    SC_THREAD(updatevalue);
    SC_THREAD(display);
  }
};

Its output is:

notified by clk.pos, will notify eq in 10ns, now is 5 ns
notified by clk.pos, sigvalue=0 at time 5 ns
notified by clk.pos, after SC_ZERO_TIME, sigvalue=0 at time 5 ns
notified by eq at time 15 ns, old sigvalue is 0
notified by eq, after update, sigvalue is 0 at time 15 ns
notified by clk.pos, will notify eq in 10ns, now is 15 ns
notified by clk.pos, sigvalue=1 at time 15 ns
notified by eq, after SC_ZERO_TIME, sigvalue is 1 at time 15 ns
notified by clk.pos, after SC_ZERO_TIME, sigvalue=1 at time 15 ns

Here, I let eq notify after 1 cycle for each clk. After sc_signal is notified by eq, the value of signal has been updated on the rising edge of clk at the same simulation time, which seems to indicate that eq and clk do not occur at the same time step. Does this mean that eq occurs 1 time step earlier than clk?

Thanks again for your answer!

Link to comment
Share on other sites

Here you use one particular implementation of SystemC. If you switch to another simulator (e.g. a commercial one) this might look completely different.

The events in your example occur at the same time:
 

notified by eq at time 15 ns, old sigvalue is 0
...
notified by clk.pos, will notify eq in 10ns, now is 15 ns

 

Link to comment
Share on other sites

2 hours ago, Eyck said:

Here you use one particular implementation of SystemC. If you switch to another simulator (e.g. a commercial one) this might look completely different.

The events in your example occur at the same time:
 

notified by eq at time 15 ns, old sigvalue is 0
...
notified by clk.pos, will notify eq in 10ns, now is 15 ns

 

I'm still confused about this: If eq and clk occur at the same time, why does the seen sigvalue have been updated to a new value when clk occurs?
According to the characteristics of sc_signal of systemc, sc_signal will be updated to a new value only when the simulation time moves to the next time stamp. I mean, if eq and clk occur at the same time, the value printed by sigvalue during clk should be the old value. I think this has nothing to do with the implementation version of systemc, because the simultaneous events should be in the same evaluation stage, and the signal value seen at this time Should be the previous value. I'm still very puzzled by this...
Thanks again for clearing my mind.

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...