register_phase_callbacks.cpp revision 12876:e332bbd21d47
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;
60
61    cb_mask = unregister_simulation_phase_callback(SC_STOPPED);
62    sc_assert( cb_mask == (old_mask & ~SC_STOPPED) );
63    old_mask = cb_mask;
64
65    cb_mask = register_simulation_phase_callback( SC_UNITIALIZED );
66    sc_assert( cb_mask == old_mask );
67
68    cb_mask = unregister_simulation_phase_callback(SC_UNITIALIZED);
69    sc_assert( cb_mask == old_mask );
70
71    cb_mask = unregister_simulation_phase_callback(SC_RUNNING);
72    sc_assert( cb_mask == (old_mask & ~SC_END_OF_INITIALIZATION
73//                                  & ~SC_END_OF_EVALUATION
74                                    & ~SC_END_OF_UPDATE
75                                    & ~SC_BEFORE_TIMESTEP) );
76    old_mask = cb_mask;
77
78    cb_mask = unregister_simulation_phase_callback(SC_ELABORATION);
79    sc_assert( cb_mask == (old_mask & ~SC_BEFORE_END_OF_ELABORATION
80                                    & ~SC_END_OF_ELABORATION ) );
81    old_mask = cb_mask;
82
83    cb_mask = unregister_simulation_phase_callback( SC_STATUS_ANY );
84    sc_assert( cb_mask == SC_UNITIALIZED );
85    old_mask = cb_mask;
86
87    cb_mask = register_simulation_phase_callback( SC_RUNNING );
88    sc_assert( cb_mask == ( SC_END_OF_INITIALIZATION
89//                            | SC_END_OF_EVALUATION
90                            | SC_END_OF_UPDATE | SC_BEFORE_TIMESTEP ) );
91
92    cb_mask = register_simulation_phase_callback( SC_STATUS_ANY );
93    sc_assert( cb_mask == (SC_STATUS_ANY & ~SC_ELABORATION & ~SC_RUNNING) );
94  }
95
96  void timed()
97  {
98    std::cout
99      << sc_get_current_process_handle().name()
100      << ": " << sc_time_stamp()
101      << ": " << timed_count
102      << std::endl;
103    if( timed_count++ < 5 ) {
104      next_trigger( 100, SC_NS );
105    }
106    if( delta_count < 5 )
107      ev.notify( SC_ZERO_TIME );
108
109    if( timed_count>=6 )
110      sc_stop();
111  }
112  void delta()
113  {
114    std::cout
115      << sc_get_current_process_handle().name()
116      << ": " << sc_time_stamp()
117      << ": " << delta_count
118      << std::endl;
119    delta_count++;
120  }
121
122  virtual void simulation_phase_callback()
123  {
124    cb_count++;
125
126#   if VERBOSE
127    {
128      std::string ttp;
129      if( !sc_pending_activity() ) {
130        ttp = "MAX";
131      } else {
132        ttp = sc_time_to_pending_activity().to_string();
133      }
134      std::cout << name()
135                << ": phase callback "
136                << sc_get_status()
137                << ": " << sc_time_stamp()
138                << " -> pending activity: " << ttp
139                << std::endl;
140    }
141#   endif
142    sc_assert( cb_mask & sc_get_status() );
143
144    switch( sc_get_status() )
145    {
146    case SC_END_OF_UPDATE:
147    case SC_BEFORE_TIMESTEP:
148      if( timed_count == 3 )
149        ev.cancel();
150      if( delta_count == 2 )
151        ev.notify(SC_ZERO_TIME);
152      if( timed_count == 2 )
153        ev.notify( 1, SC_NS );
154      break;
155    default:
156      // do nothing
157      break;
158    }
159  }
160
161  ~phase_tracer()
162      { print_static_phase_stats( "[destructor]" ); }
163
164  void print_static_phase_stats( const char* phase )
165  {
166#if VERBOSE
167      std::cout << name()
168                << ": " << phase << ": "
169                << cb_count << " callbacks called."
170                << std::endl;
171#endif
172  }
173
174private:
175
176  virtual void before_end_of_elaboration()
177  {
178    sc_assert( sc_get_status() == SC_BEFORE_END_OF_ELABORATION );
179    print_static_phase_stats( "before_end_of_elaboration" );
180  }
181
182  virtual void end_of_elaboration()
183  {
184    sc_assert( sc_get_status() == SC_END_OF_ELABORATION );
185    print_static_phase_stats( "end_of_elaboration" );
186  }
187
188  virtual void start_of_simulation()
189  {
190    sc_assert( sc_get_status() == SC_START_OF_SIMULATION );
191    print_static_phase_stats( "start_of_simulation" );
192
193    // ignored - issues warning
194    register_simulation_phase_callback( SC_ELABORATION );
195  }
196
197  virtual void end_of_simulation()
198  {
199    sc_assert( sc_get_status() == SC_END_OF_SIMULATION );
200    print_static_phase_stats( "end_of_simulation" );
201  }
202
203
204
205private:
206  phase_cb_mask cb_mask, old_mask;
207  sc_dt::uint64 cb_count, timed_count, delta_count;
208  sc_event ev;
209};
210
211
212int sc_main(int, char*[])
213{
214  // don't run without callbacks enabled
215  sc_report_handler::set_actions( "simulation phase callbacks not enabled"
216                                , SC_DEFAULT_ERROR_ACTIONS );
217
218  phase_tracer pt;
219  sc_start();
220  return 0;
221}
222