Skip Nav
Home » Forums » SystemC Forum

Icon - KMLM List KMLM List

View email archives for the history of this mailing list.

List Home All Archives Dates Threads Authors Subjects
systemc-forum - Re: [systemc-forum] an observation of sc_pause() Message Thread: Previous | Next
  • To: "Sun, Guanyi" <falcom.sgy@xxxxxxxxx>
  • From: "Philipp A. Hartmann" <philipp.hartmann@xxxxxxxx>
  • Date: Fri, 17 Feb 2012 14:37:43 +0100
  • Cc: systemc-forum@xxxxxxxxxxxxxxxxxxx
Send Email to systemc-forum@lists.accellera.org:
Send new message
Reply to this message
Ok, this use case warrants the use of sc_pause.

One question remains:
> In fact, I have basically gainned our propuse. I am just confused
> with why it does not work again when call sc_pause() in SC_THREAD.
> But in SC_METHOD it works well.

Why do you think, something is not working with SC_THREADs?  My brief
example has used an SC_THREAD and should work just fine (I haven't
tested it, though).  Do you have an example which does NOT call sc_start
from within a thread and still is "wrong" in your opinion?

Note, that sc_pause is non-blocking and immediately returns to the
calling process, which continues until the next "wait" (in case of an
SC_THREAD).  The effect of sc_pause is then even further delayed until
the end of the current delta cycle (see 1666-2011).

Greetings from Oldenburg,
  Philipp

On 17/02/12 13:55, Sun, Guanyi wrote:
> In our model, we want to use sc_pause for two reasons.
> 
> 1> we want to change whole simulation key configurations during run time.
> At each update point, we need to pause the whole simulation to avoid some
> tricky issues.
> 2> systemc model needs to consume input content produced from other binary.
> When the interal buffer is empty, the systemc model needs to stop and wait
> for enough new input. At the same time the internal status of systemc model
> need to keep.
> 
> In fact, I have basically gainned our propuse. I am just confused with why
> it does not work again when call sc_pause() in SC_THREAD. But in SC_METHOD
> it works well. At the same time, I also want to know one standard usage
> scenario of sc_pause() since I do not find example code in systemc-2.3
> package.
> 
> I think your latest mail have solve my most of questions. Thanks a lot
> 
> Guanyi
> 
> 
> 
> On Fri, Feb 17, 2012 at 8:29 PM, Philipp A. Hartmann <
> philipp.hartmann@xxxxxxxx> wrote:
> 
>> Guanyi,
>>
>> what is the exact problem you want to solve with sc_pause?
>>
>>  sc_pause is only useful in quite advanced situations, where you need
>> fine-grained control over the simulation progress, e.g. when
>> synchronising with external software.
>>
>> An off-the-cuff example (untested) could be something like the
>> following, where you return to sc_main by issuing sc_pause from within
>> an endless process.
>>
>> Greetings from Oldenburg,
>>  Philipp
>>
>> ---8<---
>>
>> SC_MODULE(forever)
>> {
>>  SC_CTOR(forever)
>>    : count(0), pause_count(5)
>>  {
>>    SC_THREAD(run);
>>  }
>>
>>  void run()
>>  {
>>    while(true) {
>>      count++;
>>
>>      if( count == pause_count ) {
>>        std::cout << "--- requesting pause - "
>>                  << sc_time_stamp()
>>                  << std::endl;
>>        sc_pause();
>>        // continues until next wait()!
>>      }
>>
>>      std::cout << "--- run - #" << count
>>                << " - " << sc_time_stamp()
>>                << std::endl;
>>
>>      wait( 10, SC_NS );
>>    }
>>  }
>>  int count;
>>  int pause_count;
>> };
>>
>> int sc_main( int, char*[] )
>> {
>>  forever m("m");
>>
>>  for( int i=0; i<5; ++i ) {
>>
>>    std::cout << "--- (re)start simulation\n";
>>    sc_start(); // would continue forever without sc_pause
>>
>>    std::cout << "--- simulation paused - "
>>              << sc_time_stamp() << std::endl;
>>
>>    m.pause_count -= 1; // pause earlier next time
>>    m.count = 0;
>>  }
>>  return 0;
>> }
>>
>> On 17/02/12 07:41, Sun, Guanyi wrote:
>>> Hi Philipp,
>>>
>>> According to your previous mail. In my understand, you mean I should
>>> call sc_start in sc_main instead of my existed method to resum the
>>> whole scheduler. Therefore i write code like following
>>> sc_main()
>>> {
>>>      sc_start();
>>>      while (sc_core::sc_get_status() == SC_PAUSED)
>>>      {
>>>          sc_start();
>>>      }
>>> }
>>>
>>> It can not work. I think i still have some mis-understanding of
>>> SystemC working principle and your meaning.  Could you give me some
>>> example code to explain how to use sc_pause().
>>>
>>> Thanks
>>> Guanyi
>>>
>>> On Thu, Feb 16, 2012 at 5:28 PM, Philipp A. Hartmann
>>> <philipp.hartmann@xxxxxxxx> wrote:
>>>> Guanyi,
>>>>
>>>> have a look at 1666-2011, section 4.3.4.2 (sc_start):
>>>>  ...
>>>>  "Function sc_start may be called from function sc_main, and only from
>>>>  function sc_main."
>>>>
>>>> You are calling sc_start() from within a process.  It may be a bug in
>>>> the proof-of-concept simulator to not detect this corner case, but you
>>>> are definitely not supposed to do this.
>>>>
>>>> sc_pause() is meant to return control to sc_main() during the simulation
>>>> to restart the simulation later (from sc_main).
>>>>
>>>> I did not check the rest of the code.
>>>>
>>>> Greetings from Oldenburg,
>>>>  Philipp
>>>>
>>>> On 16/02/12 09:14, Sun, Guanyi wrote:
>>>>> Hi all,
>>>>>
>>>>> Recently, i do an experiment of sc_pause(). I write following code
>>>>>
>>>>> // ===============example =====================//
>>>>> SC_MODULE (TEST) {
>>>>>    SC_CTOR (TEST) {
>>>>>
>>>>>      SC_METHOD(pause);
>>>>>      sensitive << pause_event;
>>>>>      dont_initialize();
>>>>>
>>>>>      SC_THREAD(test_thread_1);
>>>>>      SC_THREAD(test_thread_2);
>>>>>    }
>>>>>
>>>>>    void pause()
>>>>>    {
>>>>>         sc_pause();
>>>>>         sc_start();
>>>>>    }
>>>>>
>>>>>
>>>>>    void test_thread_1()
>>>>>    {
>>>>>       for (int i = 0; i < 10; i++)
>>>>>       {
>>>>>           printf("in thread_1 @ %d ns\n",
>>>>> sc_core::sc_time_stamp().value()/1000);
>>>>>           wait(5,sc_core::SC_NS);
>>>>>       }
>>>>>    }
>>>>>
>>>>>    void test_thread_2()
>>>>>    {
>>>>>       for (int i = 0; i < 5; i++)
>>>>>       {
>>>>>           printf("in thread_2 @ %d ns\n",
>>>>> sc_core::sc_time_stamp().value()/1000);
>>>>>           wait(10,sc_core::SC_NS);
>>>>>           sc_pause();
>>>>>           printf("thread_2 pause @ %d ns\n",
>>>>> sc_core::sc_time_stamp().value()/1000);
>>>>>           sc_start();
>>>>>           printf("thread_2 work again @ %d ns\n",
>>>>> sc_core::sc_time_stamp().value()/1000);
>>>>>       }
>>>>>    }
>>>>> // ===============example=====================//
>>>>>
>>>>> The result shows following
>>>>>
>>>>> in thread_1 @ 0 ns
>>>>> in thread_2 @ 0 ns
>>>>> in thread_1 @ 5 ns
>>>>> thread_2 pause @ 10 ns
>>>>> in thread_1 @ 10 ns
>>>>> in thread_1 @ 15 ns
>>>>> in thread_1 @ 20 ns
>>>>> in thread_1 @ 25 ns
>>>>> in thread_1 @ 30 ns
>>>>> in thread_1 @ 35 ns
>>>>> in thread_1 @ 40 ns
>>>>> in thread_1 @ 45 ns
>>>>>
>>>>> The thread_2 does work again after first sc_pause() called.
>>>>>
>>>>> Then, i change the design
>>>>>
>>>>> // ==============new code =====================//
>>>>>    void test_thread_2()
>>>>>    {
>>>>>       for (int i = 0; i < 5; i++)
>>>>>       {
>>>>>           printf("in thread_2 @ %d ns\n",
>>>>> sc_core::sc_time_stamp().value()/1000);
>>>>>           wait(10,sc_core::SC_NS);
>>>>>           printf("thread_2 pause @ %d ns\n",
>>>>> sc_core::sc_time_stamp().value()/1000);
>>>>>           b_event.notify();
>>>>>           printf("thread_2 work again @ %d ns\n",
>>>>> sc_core::sc_time_stamp().value()/1000);
>>>>>       }
>>>>>    }
>>>>> //===============new code ====================//
>>>>>
>>>>> This time the result like
>>>>>
>>>>> in thread_1 @ 0 ns
>>>>> in thread_2 @ 0 ns
>>>>> in thread_1 @ 5 ns
>>>>> thread_2 pause @ 10 ns
>>>>> thread_2 work again @ 10 ns
>>>>> in thread_2 @ 10 ns
>>>>> in thread_1 @ 10 ns
>>>>> in thread_1 @ 15 ns
>>>>> thread_2 pause @ 20 ns
>>>>> thread_2 work again @ 20 ns
>>>>> in thread_2 @ 20 ns
>>>>> in thread_1 @ 20 ns
>>>>> in thread_1 @ 25 ns
>>>>> thread_2 pause @ 30 ns
>>>>> thread_2 work again @ 30 ns
>>>>> in thread_2 @ 30 ns
>>>>> in thread_1 @ 30 ns
>>>>> in thread_1 @ 35 ns
>>>>> thread_2 pause @ 40 ns
>>>>> thread_2 work again @ 40 ns
>>>>> in thread_2 @ 40 ns
>>>>> in thread_1 @ 40 ns
>>>>> in thread_1 @ 45 ns
>>>>> thread_2 pause @ 50 ns
>>>>> thread_2 work again @ 50 ns
>>>>>
>>>>> This time, thread-2 can work normally. I still have no idea about this
>>>>> after check the IEEE1666-2011 document. I want to know why and which
>>>>> key information i am missing.



-- 
Philipp A. Hartmann
Hardware/Software Design Methodology Group

OFFIS Institute for Information Technology
R&D Division Transportation · FuE-Bereich Verkehr
Escherweg 2 · 26121 Oldenburg · Germany · http://offis.de/en/
Phone/Fax: +49-441-9722-420/282 · PGP: 0x9161A5C0 · Skype: phi.har


By Date: Previous | Next Current Thread By Thread: Previous | Next