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/*****************************************************************************
2112855Sgabeblack@google.com
2212855Sgabeblack@google.com  register_phase_callbacks.cpp -- Test for (un)registering dynamic callbacks
2312855Sgabeblack@google.com
2412855Sgabeblack@google.com  Note: requires simulation phase callback support enabled in the kernel
2512855Sgabeblack@google.com        SC_ENABLE_SIMULATION_PHASE_CALLBACKS / --enable-phase-callbacks
2612855Sgabeblack@google.com
2712855Sgabeblack@google.com  Original Author: Philipp A. Hartmann, OFFIS, 2013-05-17
2812855Sgabeblack@google.com
2912855Sgabeblack@google.com *****************************************************************************/
3012855Sgabeblack@google.com
3112855Sgabeblack@google.com/*****************************************************************************
3212855Sgabeblack@google.com
3312855Sgabeblack@google.com  MODIFICATION LOG - modifiers, enter your name, affiliation, date and
3412855Sgabeblack@google.com  changes you are making here.
3512855Sgabeblack@google.com
3612855Sgabeblack@google.com      Name, Affiliation, Date:
3712855Sgabeblack@google.com  Description of Modification:
3812855Sgabeblack@google.com
3912855Sgabeblack@google.com *****************************************************************************/
4012855Sgabeblack@google.com
4112855Sgabeblack@google.com#include <systemc.h>
4212855Sgabeblack@google.com
4312855Sgabeblack@google.com#define VERBOSE 1
4412855Sgabeblack@google.com
4512855Sgabeblack@google.comSC_MODULE(phase_tracer)
4612855Sgabeblack@google.com{
4712855Sgabeblack@google.com  SC_HAS_PROCESS(phase_tracer);
4812855Sgabeblack@google.com  phase_tracer( sc_module_name nm
4912855Sgabeblack@google.com                  = sc_core::sc_gen_unique_name("phase_tracer") )
5012855Sgabeblack@google.com    : cb_count(0), timed_count(), delta_count()
5112855Sgabeblack@google.com  {
5212855Sgabeblack@google.com    SC_METHOD(timed);
5312855Sgabeblack@google.com    SC_METHOD(delta);
5412855Sgabeblack@google.com      sensitive << ev;
5512855Sgabeblack@google.com
5612855Sgabeblack@google.com    old_mask = SC_STATUS_ANY;
5712855Sgabeblack@google.com    cb_mask = register_simulation_phase_callback( SC_STATUS_ANY );
5812855Sgabeblack@google.com    sc_assert( cb_mask == (old_mask & ~SC_ELABORATION & ~SC_RUNNING) );
5912855Sgabeblack@google.com    old_mask = cb_mask;
6012855Sgabeblack@google.com
6112855Sgabeblack@google.com    cb_mask = unregister_simulation_phase_callback(SC_STOPPED);
6212855Sgabeblack@google.com    sc_assert( cb_mask == (old_mask & ~SC_STOPPED) );
6312855Sgabeblack@google.com    old_mask = cb_mask;
6412855Sgabeblack@google.com
6512855Sgabeblack@google.com    cb_mask = register_simulation_phase_callback( SC_UNITIALIZED );
6612855Sgabeblack@google.com    sc_assert( cb_mask == old_mask );
6712855Sgabeblack@google.com
6812855Sgabeblack@google.com    cb_mask = unregister_simulation_phase_callback(SC_UNITIALIZED);
6912855Sgabeblack@google.com    sc_assert( cb_mask == old_mask );
7012855Sgabeblack@google.com
7112855Sgabeblack@google.com    cb_mask = unregister_simulation_phase_callback(SC_RUNNING);
7212855Sgabeblack@google.com    sc_assert( cb_mask == (old_mask & ~SC_END_OF_INITIALIZATION
7312855Sgabeblack@google.com//                                  & ~SC_END_OF_EVALUATION
7412855Sgabeblack@google.com                                    & ~SC_END_OF_UPDATE
7512855Sgabeblack@google.com                                    & ~SC_BEFORE_TIMESTEP) );
7612855Sgabeblack@google.com    old_mask = cb_mask;
7712855Sgabeblack@google.com
7812855Sgabeblack@google.com    cb_mask = unregister_simulation_phase_callback(SC_ELABORATION);
7912855Sgabeblack@google.com    sc_assert( cb_mask == (old_mask & ~SC_BEFORE_END_OF_ELABORATION
8012855Sgabeblack@google.com                                    & ~SC_END_OF_ELABORATION ) );
8112855Sgabeblack@google.com    old_mask = cb_mask;
8212855Sgabeblack@google.com
8312855Sgabeblack@google.com    cb_mask = unregister_simulation_phase_callback( SC_STATUS_ANY );
8412855Sgabeblack@google.com    sc_assert( cb_mask == SC_UNITIALIZED );
8512855Sgabeblack@google.com    old_mask = cb_mask;
8612855Sgabeblack@google.com
8712855Sgabeblack@google.com    cb_mask = register_simulation_phase_callback( SC_RUNNING );
8812855Sgabeblack@google.com    sc_assert( cb_mask == ( SC_END_OF_INITIALIZATION
8912855Sgabeblack@google.com//                            | SC_END_OF_EVALUATION
9012855Sgabeblack@google.com                            | SC_END_OF_UPDATE | SC_BEFORE_TIMESTEP ) );
9112855Sgabeblack@google.com
9212855Sgabeblack@google.com    cb_mask = register_simulation_phase_callback( SC_STATUS_ANY );
9312855Sgabeblack@google.com    sc_assert( cb_mask == (SC_STATUS_ANY & ~SC_ELABORATION & ~SC_RUNNING) );
9412855Sgabeblack@google.com  }
9512855Sgabeblack@google.com
9612855Sgabeblack@google.com  void timed()
9712855Sgabeblack@google.com  {
9812855Sgabeblack@google.com    std::cout
9912855Sgabeblack@google.com      << sc_get_current_process_handle().name()
10012855Sgabeblack@google.com      << ": " << sc_time_stamp()
10112855Sgabeblack@google.com      << ": " << timed_count
10212855Sgabeblack@google.com      << std::endl;
10312855Sgabeblack@google.com    if( timed_count++ < 5 ) {
10412855Sgabeblack@google.com      next_trigger( 100, SC_NS );
10512855Sgabeblack@google.com    }
10612855Sgabeblack@google.com    if( delta_count < 5 )
10712855Sgabeblack@google.com      ev.notify( SC_ZERO_TIME );
10812855Sgabeblack@google.com
10912855Sgabeblack@google.com    if( timed_count>=6 )
11012855Sgabeblack@google.com      sc_stop();
11112855Sgabeblack@google.com  }
11212855Sgabeblack@google.com  void delta()
11312855Sgabeblack@google.com  {
11412855Sgabeblack@google.com    std::cout
11512855Sgabeblack@google.com      << sc_get_current_process_handle().name()
11612855Sgabeblack@google.com      << ": " << sc_time_stamp()
11712855Sgabeblack@google.com      << ": " << delta_count
11812855Sgabeblack@google.com      << std::endl;
11912855Sgabeblack@google.com    delta_count++;
12012855Sgabeblack@google.com  }
12112855Sgabeblack@google.com
12212855Sgabeblack@google.com  virtual void simulation_phase_callback()
12312855Sgabeblack@google.com  {
12412855Sgabeblack@google.com    cb_count++;
12512855Sgabeblack@google.com
12612855Sgabeblack@google.com#   if VERBOSE
12712855Sgabeblack@google.com    {
12812855Sgabeblack@google.com      std::string ttp;
12912855Sgabeblack@google.com      if( !sc_pending_activity() ) {
13012855Sgabeblack@google.com        ttp = "MAX";
13112855Sgabeblack@google.com      } else {
13212855Sgabeblack@google.com        ttp = sc_time_to_pending_activity().to_string();
13312855Sgabeblack@google.com      }
13412855Sgabeblack@google.com      std::cout << name()
13512855Sgabeblack@google.com                << ": phase callback "
13612855Sgabeblack@google.com                << sc_get_status()
13712855Sgabeblack@google.com                << ": " << sc_time_stamp()
13812855Sgabeblack@google.com                << " -> pending activity: " << ttp
13912855Sgabeblack@google.com                << std::endl;
14012855Sgabeblack@google.com    }
14112855Sgabeblack@google.com#   endif
14212855Sgabeblack@google.com    sc_assert( cb_mask & sc_get_status() );
14312855Sgabeblack@google.com
14412855Sgabeblack@google.com    switch( sc_get_status() )
14512855Sgabeblack@google.com    {
14612855Sgabeblack@google.com    case SC_END_OF_UPDATE:
14712855Sgabeblack@google.com    case SC_BEFORE_TIMESTEP:
14812855Sgabeblack@google.com      if( timed_count == 3 )
14912855Sgabeblack@google.com        ev.cancel();
15012855Sgabeblack@google.com      if( delta_count == 2 )
15112855Sgabeblack@google.com        ev.notify(SC_ZERO_TIME);
15212855Sgabeblack@google.com      if( timed_count == 2 )
15312855Sgabeblack@google.com        ev.notify( 1, SC_NS );
15412855Sgabeblack@google.com      break;
15512855Sgabeblack@google.com    default:
15612855Sgabeblack@google.com      // do nothing
15712855Sgabeblack@google.com      break;
15812855Sgabeblack@google.com    }
15912855Sgabeblack@google.com  }
16012855Sgabeblack@google.com
16112855Sgabeblack@google.com  ~phase_tracer()
16212855Sgabeblack@google.com      { print_static_phase_stats( "[destructor]" ); }
16312855Sgabeblack@google.com
16412855Sgabeblack@google.com  void print_static_phase_stats( const char* phase )
16512855Sgabeblack@google.com  {
16612855Sgabeblack@google.com#if VERBOSE
16712855Sgabeblack@google.com      std::cout << name()
16812855Sgabeblack@google.com                << ": " << phase << ": "
16912855Sgabeblack@google.com                << cb_count << " callbacks called."
17012855Sgabeblack@google.com                << std::endl;
17112855Sgabeblack@google.com#endif
17212855Sgabeblack@google.com  }
17312855Sgabeblack@google.com
17412855Sgabeblack@google.comprivate:
17512855Sgabeblack@google.com
17612855Sgabeblack@google.com  virtual void before_end_of_elaboration()
17712855Sgabeblack@google.com  {
17812855Sgabeblack@google.com    sc_assert( sc_get_status() == SC_BEFORE_END_OF_ELABORATION );
17912855Sgabeblack@google.com    print_static_phase_stats( "before_end_of_elaboration" );
18012855Sgabeblack@google.com  }
18112855Sgabeblack@google.com
18212855Sgabeblack@google.com  virtual void end_of_elaboration()
18312855Sgabeblack@google.com  {
18412855Sgabeblack@google.com    sc_assert( sc_get_status() == SC_END_OF_ELABORATION );
18512855Sgabeblack@google.com    print_static_phase_stats( "end_of_elaboration" );
18612855Sgabeblack@google.com  }
18712855Sgabeblack@google.com
18812855Sgabeblack@google.com  virtual void start_of_simulation()
18912855Sgabeblack@google.com  {
19012855Sgabeblack@google.com    sc_assert( sc_get_status() == SC_START_OF_SIMULATION );
19112855Sgabeblack@google.com    print_static_phase_stats( "start_of_simulation" );
19212855Sgabeblack@google.com
19312855Sgabeblack@google.com    // ignored - issues warning
19412855Sgabeblack@google.com    register_simulation_phase_callback( SC_ELABORATION );
19512855Sgabeblack@google.com  }
19612855Sgabeblack@google.com
19712855Sgabeblack@google.com  virtual void end_of_simulation()
19812855Sgabeblack@google.com  {
19912855Sgabeblack@google.com    sc_assert( sc_get_status() == SC_END_OF_SIMULATION );
20012855Sgabeblack@google.com    print_static_phase_stats( "end_of_simulation" );
20112855Sgabeblack@google.com  }
20212855Sgabeblack@google.com
20312855Sgabeblack@google.com
20412855Sgabeblack@google.com
20512855Sgabeblack@google.comprivate:
20612855Sgabeblack@google.com  phase_cb_mask cb_mask, old_mask;
20712855Sgabeblack@google.com  sc_dt::uint64 cb_count, timed_count, delta_count;
20812855Sgabeblack@google.com  sc_event ev;
20912855Sgabeblack@google.com};
21012855Sgabeblack@google.com
21112855Sgabeblack@google.com
21212855Sgabeblack@google.comint sc_main(int, char*[])
21312855Sgabeblack@google.com{
21412855Sgabeblack@google.com  // don't run without callbacks enabled
21512876Sgabeblack@google.com  sc_report_handler::set_actions( "simulation phase callbacks not enabled"
21612855Sgabeblack@google.com                                , SC_DEFAULT_ERROR_ACTIONS );
21712855Sgabeblack@google.com
21812855Sgabeblack@google.com  phase_tracer pt;
21912855Sgabeblack@google.com  sc_start();
22012855Sgabeblack@google.com  return 0;
22112855Sgabeblack@google.com}
222