register_phase_callbacks.cpp revision 12855:588919e0e4aa
1/***************************************************************************** 2 3 Licensed to Accellera Systems Initiative Inc. (Accellera) under one or 4 more contributor license agreements. See the NOTICE file distributed 5 with this work for additional information regarding copyright ownership. 6 Accellera licenses this file to you under the Apache License, Version 2.0 7 (the "License"); you may not use this file except in compliance with the 8 License. You may obtain a copy of the License at 9 10 http://www.apache.org/licenses/LICENSE-2.0 11 12 Unless required by applicable law or agreed to in writing, software 13 distributed under the License is distributed on an "AS IS" BASIS, 14 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 15 implied. See the License for the specific language governing 16 permissions and limitations under the License. 17 18 *****************************************************************************/ 19 20/***************************************************************************** 21 22 register_phase_callbacks.cpp -- Test for (un)registering dynamic callbacks 23 24 Note: requires simulation phase callback support enabled in the kernel 25 SC_ENABLE_SIMULATION_PHASE_CALLBACKS / --enable-phase-callbacks 26 27 Original Author: Philipp A. Hartmann, OFFIS, 2013-05-17 28 29 *****************************************************************************/ 30 31/***************************************************************************** 32 33 MODIFICATION LOG - modifiers, enter your name, affiliation, date and 34 changes you are making here. 35 36 Name, Affiliation, Date: 37 Description of Modification: 38 39 *****************************************************************************/ 40 41#include <systemc.h> 42 43#define VERBOSE 1 44 45SC_MODULE(phase_tracer) 46{ 47 SC_HAS_PROCESS(phase_tracer); 48 phase_tracer( sc_module_name nm 49 = sc_core::sc_gen_unique_name("phase_tracer") ) 50 : cb_count(0), timed_count(), delta_count() 51 { 52 SC_METHOD(timed); 53 SC_METHOD(delta); 54 sensitive << ev; 55 56 old_mask = SC_STATUS_ANY; 57 cb_mask = register_simulation_phase_callback( SC_STATUS_ANY ); 58 sc_assert( cb_mask == (old_mask & ~SC_ELABORATION & ~SC_RUNNING) ); 59 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( SC_ID_PHASE_CALLBACKS_UNSUPPORTED_ 216 , SC_DEFAULT_ERROR_ACTIONS ); 217 218 phase_tracer pt; 219 sc_start(); 220 return 0; 221} 222