112855Sgabeblack@google.com/*****************************************************************************
212855Sgabeblack@google.com
312855Sgabeblack@google.com  Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
412855Sgabeblack@google.com  more contributor license agreements.  See the NOTICE file distributed
512855Sgabeblack@google.com  with this work for additional information regarding copyright ownership.
612855Sgabeblack@google.com  Accellera licenses this file to you under the Apache License, Version 2.0
712855Sgabeblack@google.com  (the "License"); you may not use this file except in compliance with the
812855Sgabeblack@google.com  License.  You may obtain a copy of the License at
912855Sgabeblack@google.com
1012855Sgabeblack@google.com    http://www.apache.org/licenses/LICENSE-2.0
1112855Sgabeblack@google.com
1212855Sgabeblack@google.com  Unless required by applicable law or agreed to in writing, software
1312855Sgabeblack@google.com  distributed under the License is distributed on an "AS IS" BASIS,
1412855Sgabeblack@google.com  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
1512855Sgabeblack@google.com  implied.  See the License for the specific language governing
1612855Sgabeblack@google.com  permissions and limitations under the License.
1712855Sgabeblack@google.com
1812855Sgabeblack@google.com *****************************************************************************/
1912855Sgabeblack@google.com
2012855Sgabeblack@google.com// sc_pause.cpp -- test for
2112855Sgabeblack@google.com//
2212855Sgabeblack@google.com//  Original Author: John Aynsley, Doulos, Inc.
2312855Sgabeblack@google.com//
2412855Sgabeblack@google.com// MODIFICATION LOG - modifiers, enter your name, affiliation, date and
2512855Sgabeblack@google.com//
2612855Sgabeblack@google.com// $Log: sc_pause.cpp,v $
2712855Sgabeblack@google.com// Revision 1.2  2011/05/08 19:18:46  acg
2812855Sgabeblack@google.com//  Andy Goodrich: remove extraneous + prefixes from git diff.
2912855Sgabeblack@google.com//
3012855Sgabeblack@google.com
3112855Sgabeblack@google.com// sc_pause, sc_get_status, sc_is_running
3212855Sgabeblack@google.com
3312855Sgabeblack@google.com#define SC_INCLUDE_DYNAMIC_PROCESSES
3412855Sgabeblack@google.com
3512855Sgabeblack@google.com#include <systemc>
3612855Sgabeblack@google.comusing namespace sc_core;
3712855Sgabeblack@google.comusing std::cout;
3812855Sgabeblack@google.comusing std::endl;
3912855Sgabeblack@google.comusing std::hex;
4012855Sgabeblack@google.com
4112855Sgabeblack@google.comstruct my_interface: virtual sc_interface
4212855Sgabeblack@google.com{
4312855Sgabeblack@google.com  virtual void schedule_events_while_paused() = 0;
4412855Sgabeblack@google.com};
4512855Sgabeblack@google.com
4612855Sgabeblack@google.comstruct M: sc_module, private my_interface
4712855Sgabeblack@google.com{
4812855Sgabeblack@google.com  sc_export<my_interface> xport;
4912855Sgabeblack@google.com
5012855Sgabeblack@google.com  SC_CTOR(M)
5112855Sgabeblack@google.com  {
5212855Sgabeblack@google.com    cout << "sc_get_status() == " << hex << sc_get_status() << " CTOR in " << name() << endl;
5312855Sgabeblack@google.com    sc_assert( sc_get_status() == SC_BEFORE_END_OF_ELABORATION );
5412855Sgabeblack@google.com    sc_assert( sc_is_running() == false );
5512855Sgabeblack@google.com
5612855Sgabeblack@google.com    xport.bind(*this);
5712855Sgabeblack@google.com
5812855Sgabeblack@google.com    sc_spawn(sc_bind(&M::T, this));
5912855Sgabeblack@google.com
6012855Sgabeblack@google.com    SC_THREAD(on_immed_event);
6112855Sgabeblack@google.com    SC_THREAD(on_delta_event);
6212855Sgabeblack@google.com    SC_THREAD(on_timed_event);
6312855Sgabeblack@google.com  }
6412855Sgabeblack@google.com
6512855Sgabeblack@google.com  sc_signal<int> sig1, sig2, sig3, sig4;
6612855Sgabeblack@google.com  sc_event immed_event;
6712855Sgabeblack@google.com  sc_event delta_event;
6812855Sgabeblack@google.com  sc_event timed_event;
6912855Sgabeblack@google.com
7012855Sgabeblack@google.com  void before_end_of_elaboration()
7112855Sgabeblack@google.com  {
7212855Sgabeblack@google.com    cout << "sc_get_status() == " << hex << sc_get_status() << " before_end_of_elaboration in " << name() << endl;
7312855Sgabeblack@google.com    sc_assert( sc_get_status() == SC_BEFORE_END_OF_ELABORATION );
7412855Sgabeblack@google.com    sc_assert( sc_is_running() == false );
7512855Sgabeblack@google.com    sig1.write(1);
7612855Sgabeblack@google.com    timed_event.notify(1234, SC_NS);
7712855Sgabeblack@google.com    sc_pause();  // Should be ignored
7812855Sgabeblack@google.com  }
7912855Sgabeblack@google.com
8012855Sgabeblack@google.com  void end_of_elaboration()
8112855Sgabeblack@google.com  {
8212855Sgabeblack@google.com    cout << "sc_get_status() == " << hex << sc_get_status() << " end_of_elaboration in " << name() << endl;
8312855Sgabeblack@google.com    sc_assert( sc_get_status() == SC_END_OF_ELABORATION );
8412855Sgabeblack@google.com    sc_assert( sc_is_running() == false );
8512855Sgabeblack@google.com    sig2.write(2);
8612855Sgabeblack@google.com    sc_pause();  // Should be ignored
8712855Sgabeblack@google.com  }
8812855Sgabeblack@google.com
8912855Sgabeblack@google.com  void start_of_simulation()
9012855Sgabeblack@google.com  {
9112855Sgabeblack@google.com    cout << "sc_get_status() == " << hex << sc_get_status() << " start_of_simulation in " << name() << endl;
9212855Sgabeblack@google.com    sc_assert( sc_get_status() == SC_START_OF_SIMULATION );
9312855Sgabeblack@google.com    sc_assert( sc_is_running() == false );
9412855Sgabeblack@google.com    sig3.write(3);
9512855Sgabeblack@google.com    sig4.write(0);
9612855Sgabeblack@google.com    sc_pause();  // Should be ignored
9712855Sgabeblack@google.com  }
9812855Sgabeblack@google.com
9912855Sgabeblack@google.com  void end_of_simulation()
10012855Sgabeblack@google.com  {
10112855Sgabeblack@google.com    cout << "sc_get_status() == " << hex << sc_get_status() << " end_of_simulation in " << name() << endl;;
10212855Sgabeblack@google.com    sc_assert( sc_get_status() == SC_END_OF_SIMULATION );
10312855Sgabeblack@google.com    sc_assert( sc_is_running() == false );
10412855Sgabeblack@google.com  }
10512855Sgabeblack@google.com
10612855Sgabeblack@google.com  void T()
10712855Sgabeblack@google.com  {
10812855Sgabeblack@google.com    sc_assert( sig1.read() == 1 );
10912855Sgabeblack@google.com    sc_assert( sig2.read() == 2 );
11012855Sgabeblack@google.com    sc_assert( sig3.read() == 3 );
11112855Sgabeblack@google.com  }
11212855Sgabeblack@google.com
11312855Sgabeblack@google.com  void on_immed_event()
11412855Sgabeblack@google.com  {
11512855Sgabeblack@google.com    wait(immed_event);
11612855Sgabeblack@google.com    cout << "on_immed_event() awoke\n";
11712855Sgabeblack@google.com
11812855Sgabeblack@google.com    // Should run in 1st eval phase after pause
11912855Sgabeblack@google.com    sc_assert( sig4.read() == 0 );
12012855Sgabeblack@google.com  }
12112855Sgabeblack@google.com
12212855Sgabeblack@google.com  void on_delta_event()
12312855Sgabeblack@google.com  {
12412855Sgabeblack@google.com    wait(delta_event);
12512855Sgabeblack@google.com    cout << "on_delta_event() awoke\n";
12612855Sgabeblack@google.com
12712855Sgabeblack@google.com    // Should run in 2nd eval phase after pause
12812855Sgabeblack@google.com    sc_assert( sig4.read() == 4 );
12912855Sgabeblack@google.com  }
13012855Sgabeblack@google.com
13112855Sgabeblack@google.com  void on_timed_event()
13212855Sgabeblack@google.com  {
13312855Sgabeblack@google.com    wait(timed_event);
13412855Sgabeblack@google.com    cout << "on_timed_event() awoke\n";
13512855Sgabeblack@google.com
13612855Sgabeblack@google.com    sc_assert( sig1.read() == 1 );
13712855Sgabeblack@google.com    sc_assert( sig2.read() == 2 );
13812855Sgabeblack@google.com    sc_assert( sig3.read() == 3 );
13912855Sgabeblack@google.com    sc_assert( sig4.read() == 0 );
14012855Sgabeblack@google.com    sc_assert( sc_time_stamp() == sc_time(1234, SC_NS) );
14112855Sgabeblack@google.com  }
14212855Sgabeblack@google.com
14312855Sgabeblack@google.comprivate:
14412855Sgabeblack@google.com
14512855Sgabeblack@google.com  void schedule_events_while_paused()
14612855Sgabeblack@google.com  {
14712855Sgabeblack@google.com    sig4.write(4);
14812855Sgabeblack@google.com    immed_event.notify();
14912855Sgabeblack@google.com    delta_event.notify(SC_ZERO_TIME);
15012855Sgabeblack@google.com
15112855Sgabeblack@google.com    // Should be able to instantiate an sc_object while paused
15212855Sgabeblack@google.com    mut = new sc_mutex("mut");
15312855Sgabeblack@google.com    sem = new sc_semaphore("sem", 1);
15412855Sgabeblack@google.com  }
15512855Sgabeblack@google.com
15612855Sgabeblack@google.com  sc_mutex* mut;
15712855Sgabeblack@google.com  sc_semaphore* sem;
15812855Sgabeblack@google.com};
15912855Sgabeblack@google.com
16012855Sgabeblack@google.comSC_MODULE(Top)
16112855Sgabeblack@google.com{
16212855Sgabeblack@google.com  SC_CTOR(Top)
16312855Sgabeblack@google.com  {
16412855Sgabeblack@google.com    cout << "sc_get_status() == " << hex << sc_get_status() << " CTOR in " << name() << endl;
16512855Sgabeblack@google.com    sc_assert( sc_get_status() == SC_ELABORATION );
16612855Sgabeblack@google.com    sc_assert( sc_is_running() == false );
16712855Sgabeblack@google.com    SC_THREAD(T);
16812855Sgabeblack@google.com
16912855Sgabeblack@google.com    sc_spawn_options opt;
17012855Sgabeblack@google.com      opt.spawn_method();
17112855Sgabeblack@google.com      opt.set_sensitivity( &timed_ev );
17212855Sgabeblack@google.com      opt.set_sensitivity( &delta_ev );
17312855Sgabeblack@google.com      opt.dont_initialize();
17412855Sgabeblack@google.com    sc_spawn(sc_bind(&Top::ev_handler, this), "ev_handler", &opt);
17512855Sgabeblack@google.com
17612855Sgabeblack@google.com    SC_METHOD(immed_ev_handler);
17712855Sgabeblack@google.com      sensitive << immed_ev;
17812855Sgabeblack@google.com      dont_initialize();
17912855Sgabeblack@google.com
18012855Sgabeblack@google.com    immed_ev_delta = 0;
18112855Sgabeblack@google.com    sc_assert( sc_delta_count() == 0 );
18212855Sgabeblack@google.com  }
18312855Sgabeblack@google.com
18412855Sgabeblack@google.com  ~Top()
18512855Sgabeblack@google.com  {
18612855Sgabeblack@google.com    sc_assert( sc_get_status() == SC_STOPPED );
18712855Sgabeblack@google.com    sc_assert( sc_is_running() == false );
18812855Sgabeblack@google.com  }
18912855Sgabeblack@google.com
19012855Sgabeblack@google.com  M* m;
19112855Sgabeblack@google.com  sc_event timed_ev;
19212855Sgabeblack@google.com  sc_event delta_ev;
19312855Sgabeblack@google.com  sc_event immed_ev;
19412855Sgabeblack@google.com  unsigned immed_ev_delta;
19512855Sgabeblack@google.com  sc_signal<int> sig;
19612855Sgabeblack@google.com
19712855Sgabeblack@google.com  void before_end_of_elaboration()
19812855Sgabeblack@google.com  {
19912855Sgabeblack@google.com    cout << "sc_get_status() == " << hex << sc_get_status() << " before_end_of_elaboration in " << name() << endl;
20012855Sgabeblack@google.com    sc_assert( sc_get_status() == SC_BEFORE_END_OF_ELABORATION );
20112855Sgabeblack@google.com    sc_assert( sc_is_running() == false );
20212855Sgabeblack@google.com
20312855Sgabeblack@google.com    m = new M("m");
20412855Sgabeblack@google.com  }
20512855Sgabeblack@google.com
20612855Sgabeblack@google.com  void end_of_elaboration()
20712855Sgabeblack@google.com  {
20812855Sgabeblack@google.com    cout << "sc_get_status() == " << hex << sc_get_status() << " end_of_elaboration in " << name() << endl;
20912855Sgabeblack@google.com    sc_assert( sc_get_status() == SC_END_OF_ELABORATION );
21012855Sgabeblack@google.com    sc_assert( sc_is_running() == false );
21112855Sgabeblack@google.com  }
21212855Sgabeblack@google.com
21312855Sgabeblack@google.com  void start_of_simulation()
21412855Sgabeblack@google.com  {
21512855Sgabeblack@google.com    cout << "sc_get_status() == " << hex << sc_get_status() << " start_of_simulation in " << name() << endl;
21612855Sgabeblack@google.com    sc_assert( sc_get_status() == SC_START_OF_SIMULATION );
21712855Sgabeblack@google.com    sc_assert( sc_is_running() == false );
21812855Sgabeblack@google.com  }
21912855Sgabeblack@google.com
22012855Sgabeblack@google.com  void end_of_simulation()
22112855Sgabeblack@google.com  {
22212855Sgabeblack@google.com    cout << "sc_get_status() == " << hex << sc_get_status() << " end_of_simulation in " << name() << endl;
22312855Sgabeblack@google.com    sc_assert( sc_get_status() == SC_END_OF_SIMULATION );
22412855Sgabeblack@google.com    sc_assert( sc_is_running() == false );
22512855Sgabeblack@google.com    sc_assert( immed_ev_delta == 999 );
22612855Sgabeblack@google.com  }
22712855Sgabeblack@google.com
22812855Sgabeblack@google.com  void T()
22912855Sgabeblack@google.com  {
23012855Sgabeblack@google.com    cout << "sc_get_status() == " << hex << sc_get_status() << " PROCESS in " << name() << endl;
23112855Sgabeblack@google.com    sc_assert( sc_delta_count() == 0 );
23212855Sgabeblack@google.com    sc_assert( sig.read()      == 42 );
23312855Sgabeblack@google.com    sc_assert( sc_get_status() == SC_RUNNING );
23412855Sgabeblack@google.com    sc_assert( sc_is_running() == true );
23512855Sgabeblack@google.com    wait(timed_ev);
23612855Sgabeblack@google.com    sc_assert( sc_time_stamp() == sc_time(42, SC_US) );
23712855Sgabeblack@google.com    sc_assert( sc_get_status() == SC_RUNNING );
23812855Sgabeblack@google.com    sc_assert( sc_is_running() == true );
23912855Sgabeblack@google.com
24012855Sgabeblack@google.com    sc_pause();
24112855Sgabeblack@google.com    cout << "sc_get_status() == " << hex << sc_get_status() << " PROCESS after sc_pause in " << name() << endl;
24212855Sgabeblack@google.com    sc_assert( sc_time_stamp() == sc_time(42, SC_US) );
24312855Sgabeblack@google.com    sc_assert( sc_get_status() == SC_RUNNING );
24412855Sgabeblack@google.com    sc_assert( sc_is_running() == true );
24512855Sgabeblack@google.com    wait(SC_ZERO_TIME);
24612855Sgabeblack@google.com    sc_assert( sc_get_status() == SC_RUNNING );
24712855Sgabeblack@google.com    sc_assert( sc_is_running() == true );
24812855Sgabeblack@google.com
24912855Sgabeblack@google.com    sc_pause();
25012855Sgabeblack@google.com    cout << "sc_get_status() == " << hex << sc_get_status() << " PROCESS after sc_pause in " << name() << endl;
25112855Sgabeblack@google.com    sc_assert( sc_time_stamp() == sc_time(42, SC_US) );
25212855Sgabeblack@google.com    sc_assert( sc_get_status() == SC_RUNNING );
25312855Sgabeblack@google.com    sc_assert( sc_is_running() == true );
25412855Sgabeblack@google.com    wait(2, SC_US);
25512855Sgabeblack@google.com    sc_assert( sc_time_stamp() == sc_time(44, SC_US) );
25612855Sgabeblack@google.com    sc_assert( sc_get_status() == SC_RUNNING );
25712855Sgabeblack@google.com    sc_assert( sc_is_running() == true );
25812855Sgabeblack@google.com
25912855Sgabeblack@google.com    sc_stop();
26012855Sgabeblack@google.com    cout << "sc_get_status() == " << hex << sc_get_status() << " PROCESS after sc_stop() in " << name() << endl;;
26112855Sgabeblack@google.com    sc_assert( sc_time_stamp() == sc_time(44, SC_US) );
26212855Sgabeblack@google.com    sc_assert( sc_get_status() == SC_RUNNING );
26312855Sgabeblack@google.com    sc_assert( sc_is_running() == true );
26412855Sgabeblack@google.com
26512855Sgabeblack@google.com    sc_pause();
26612855Sgabeblack@google.com    sc_assert( sc_get_status() == SC_RUNNING );
26712855Sgabeblack@google.com  }
26812855Sgabeblack@google.com
26912855Sgabeblack@google.com  void ev_handler()
27012855Sgabeblack@google.com  {
27112855Sgabeblack@google.com    cout << "sc_get_status() == " << hex << sc_get_status() << " METHOD in " << name() << endl;
27212855Sgabeblack@google.com    sc_assert( sc_get_status() == SC_RUNNING );
27312855Sgabeblack@google.com    sc_assert( sig.read()      == 42 );
27412855Sgabeblack@google.com
27512855Sgabeblack@google.com    static bool first = true;
27612855Sgabeblack@google.com    if (first)
27712855Sgabeblack@google.com    {
27812855Sgabeblack@google.com      sc_assert( sc_time_stamp() == SC_ZERO_TIME );
27912855Sgabeblack@google.com      first = false;
28012855Sgabeblack@google.com    }
28112855Sgabeblack@google.com    else
28212855Sgabeblack@google.com      sc_assert( sc_time_stamp() == sc_time(42, SC_US) );
28312855Sgabeblack@google.com  }
28412855Sgabeblack@google.com
28512855Sgabeblack@google.com  void immed_ev_handler()
28612855Sgabeblack@google.com  {
28712855Sgabeblack@google.com    sc_assert( sc_time_stamp() == sc_time(42, SC_US) );
28812855Sgabeblack@google.com    sc_assert( sc_delta_count() == immed_ev_delta );
28912855Sgabeblack@google.com    immed_ev_delta = 999;
29012855Sgabeblack@google.com  }
29112855Sgabeblack@google.com};
29212855Sgabeblack@google.com
29312855Sgabeblack@google.comvoid spawned_while_paused()
29412855Sgabeblack@google.com{
29512855Sgabeblack@google.com  cout << "spawned_while_paused() awoke" << endl;
29612855Sgabeblack@google.com  sc_assert( sc_time_stamp() == sc_time(42, SC_US) );
29712855Sgabeblack@google.com  sc_assert( sc_get_status() == SC_RUNNING );
29812855Sgabeblack@google.com  sc_assert( sc_pending_activity() == true );
29912855Sgabeblack@google.com}
30012855Sgabeblack@google.com
30112855Sgabeblack@google.comint sc_main(int argc, char* argv[])
30212855Sgabeblack@google.com{
30312855Sgabeblack@google.com  sc_assert( sc_delta_count() == 0 );
30412855Sgabeblack@google.com  cout << "sc_get_status() == " << hex << sc_get_status() << " ELAB" << endl;
30512855Sgabeblack@google.com  sc_assert( sc_get_status() == SC_ELABORATION );
30612855Sgabeblack@google.com  sc_assert( sc_is_running() == false );
30712855Sgabeblack@google.com  Top top("top");
30812855Sgabeblack@google.com
30912855Sgabeblack@google.com  sc_pause();  // Should be ignored
31012855Sgabeblack@google.com
31112855Sgabeblack@google.com  // Schedule some update requests and events
31212855Sgabeblack@google.com  top.sig.write(42);
31312855Sgabeblack@google.com  top.timed_ev.notify(42, SC_US);
31412855Sgabeblack@google.com  top.delta_ev.notify(SC_ZERO_TIME);
31512855Sgabeblack@google.com  sc_assert( sc_get_status() == SC_ELABORATION );
31612855Sgabeblack@google.com  sc_assert( sc_delta_count() == 0 );
31712855Sgabeblack@google.com
31812855Sgabeblack@google.com  sc_start();
31912855Sgabeblack@google.com  cout << "sc_get_status() == " << hex << sc_get_status() << " PAUSED" << endl;
32012855Sgabeblack@google.com  sc_assert( sc_get_status() == SC_PAUSED );
32112855Sgabeblack@google.com  sc_assert( sc_is_running() == true );
32212855Sgabeblack@google.com  sc_assert( sc_time_stamp() == sc_time(42, SC_US) );
32312855Sgabeblack@google.com
32412855Sgabeblack@google.com  sc_start(1, SC_US);
32512855Sgabeblack@google.com  cout << "sc_get_status() == " << hex << sc_get_status() << " PAUSED" << endl;
32612855Sgabeblack@google.com  sc_assert( sc_get_status() == SC_PAUSED );
32712855Sgabeblack@google.com  sc_assert( sc_is_running() == true );
32812855Sgabeblack@google.com  sc_assert( sc_time_stamp() == sc_time(42, SC_US) );
32912855Sgabeblack@google.com
33012855Sgabeblack@google.com  // Schedule an immediate notification
33112855Sgabeblack@google.com  top.immed_ev.notify();
33212855Sgabeblack@google.com  top.immed_ev_delta = sc_delta_count();
33312855Sgabeblack@google.com
33412855Sgabeblack@google.com  // IMC while paused
33512855Sgabeblack@google.com  top.m->xport->schedule_events_while_paused();
33612855Sgabeblack@google.com
33712855Sgabeblack@google.com  sc_process_handle h = sc_spawn(&spawned_while_paused);
33812855Sgabeblack@google.com  sc_assert( h.valid() );
33912855Sgabeblack@google.com
34012855Sgabeblack@google.com  sc_start();
34112855Sgabeblack@google.com  cout << "sc_get_status() == " << hex << sc_get_status() << " STOPPED" << endl;
34212855Sgabeblack@google.com  sc_assert( sc_get_status() == SC_STOPPED );
34312855Sgabeblack@google.com  sc_assert( sc_is_running() == false );
34412855Sgabeblack@google.com  sc_assert( sc_time_stamp() == sc_time(44, SC_US) );
34512855Sgabeblack@google.com
34612855Sgabeblack@google.com  cout << endl << "Success" << endl;
34712855Sgabeblack@google.com  return 0;
34812855Sgabeblack@google.com}
349