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 sc_prim_channel.h -- Abstract base class of all primitive channel classes. 23 24 Original Author: Martin Janssen, Synopsys, Inc., 2001-05-21 25 26 CHANGE LOG AT THE END OF THE FILE 27 *****************************************************************************/ 28 29#ifndef SC_PRIM_CHANNEL_H 30#define SC_PRIM_CHANNEL_H 31 32#include "sysc/kernel/sc_object.h" 33#include "sysc/kernel/sc_wait.h" 34#include "sysc/kernel/sc_wait_cthread.h" 35 36namespace sc_core { 37 38// ---------------------------------------------------------------------------- 39// CLASS : sc_prim_channel 40// 41// Abstract base class of all primitive channel classes. 42// ---------------------------------------------------------------------------- 43 44class sc_prim_channel 45: public sc_object 46{ 47 friend class sc_prim_channel_registry; 48 49public: 50 enum { list_end = 0xdb }; 51public: 52 virtual const char* kind() const 53 { return "sc_prim_channel"; } 54 55 inline bool update_requested() 56 { return m_update_next_p != (sc_prim_channel*)list_end; } 57 58 // request the update method to be executed during the update phase 59 inline void request_update(); 60 61 // request the update method to be executed during the update phase 62 // from a process external to the simulator. 63 void async_request_update(); 64 65protected: 66 67 // constructors 68 sc_prim_channel(); 69 explicit sc_prim_channel( const char* ); 70 71 // destructor 72 virtual ~sc_prim_channel(); 73 74 // the update method (does nothing by default) 75 virtual void update(); 76 77 // called by construction_done (does nothing by default) 78 virtual void before_end_of_elaboration(); 79 80 // called by elaboration_done (does nothing by default) 81 virtual void end_of_elaboration(); 82 83 // called by start_simulation (does nothing by default) 84 virtual void start_of_simulation(); 85 86 // called by simulation_done (does nothing by default) 87 virtual void end_of_simulation(); 88 89protected: 90 91 // to avoid calling sc_get_curr_simcontext() 92 93 // static sensitivity for SC_THREADs and SC_CTHREADs 94 95 void wait() 96 { sc_core::wait( simcontext() ); } 97 98 99 // dynamic sensitivity for SC_THREADs and SC_CTHREADs 100 101 void wait( const sc_event& e ) 102 { sc_core::wait( e, simcontext() ); } 103 104 void wait( const sc_event_or_list& el ) 105 { sc_core::wait( el, simcontext() ); } 106 107 void wait( const sc_event_and_list& el ) 108 { sc_core::wait( el, simcontext() ); } 109 110 void wait( const sc_time& t ) 111 { sc_core::wait( t, simcontext() ); } 112 113 void wait( double v, sc_time_unit tu ) 114 { sc_core::wait( sc_time( v, tu, simcontext() ), simcontext() ); } 115 116 void wait( const sc_time& t, const sc_event& e ) 117 { sc_core::wait( t, e, simcontext() ); } 118 119 void wait( double v, sc_time_unit tu, const sc_event& e ) 120 { sc_core::wait( sc_time( v, tu, simcontext() ), e, simcontext() ); } 121 122 void wait( const sc_time& t, const sc_event_or_list& el ) 123 { sc_core::wait( t, el, simcontext() ); } 124 125 void wait( double v, sc_time_unit tu, const sc_event_or_list& el ) 126 { sc_core::wait( sc_time( v, tu, simcontext() ), el, simcontext() ); } 127 128 void wait( const sc_time& t, const sc_event_and_list& el ) 129 { sc_core::wait( t, el, simcontext() ); } 130 131 void wait( double v, sc_time_unit tu, const sc_event_and_list& el ) 132 { sc_core::wait( sc_time( v, tu, simcontext() ), el, simcontext() ); } 133 134 void wait( int n ) 135 { sc_core::wait( n, simcontext() ); } 136 137 138 // static sensitivity for SC_METHODs 139 140 void next_trigger() 141 { sc_core::next_trigger( simcontext() ); } 142 143 144 // dynamic sensitivity for SC_METHODs 145 146 void next_trigger( const sc_event& e ) 147 { sc_core::next_trigger( e, simcontext() ); } 148 149 void next_trigger( const sc_event_or_list& el ) 150 { sc_core::next_trigger( el, simcontext() ); } 151 152 void next_trigger( const sc_event_and_list& el ) 153 { sc_core::next_trigger( el, simcontext() ); } 154 155 void next_trigger( const sc_time& t ) 156 { sc_core::next_trigger( t, simcontext() ); } 157 158 void next_trigger( double v, sc_time_unit tu ) 159 {sc_core::next_trigger( sc_time( v, tu, simcontext() ), simcontext() );} 160 161 void next_trigger( const sc_time& t, const sc_event& e ) 162 { sc_core::next_trigger( t, e, simcontext() ); } 163 164 void next_trigger( double v, sc_time_unit tu, const sc_event& e ) 165 { sc_core::next_trigger( 166 sc_time( v, tu, simcontext() ), e, simcontext() ); } 167 168 void next_trigger( const sc_time& t, const sc_event_or_list& el ) 169 { sc_core::next_trigger( t, el, simcontext() ); } 170 171 void next_trigger( double v, sc_time_unit tu, const sc_event_or_list& el ) 172 { sc_core::next_trigger( 173 sc_time( v, tu, simcontext() ), el, simcontext() ); } 174 175 void next_trigger( const sc_time& t, const sc_event_and_list& el ) 176 { sc_core::next_trigger( t, el, simcontext() ); } 177 178 void next_trigger( double v, sc_time_unit tu, const sc_event_and_list& el ) 179 { sc_core::next_trigger( 180 sc_time( v, tu, simcontext() ), el, simcontext() ); } 181 182 183 // for SC_METHODs and SC_THREADs and SC_CTHREADs 184 185 bool timed_out() 186 { return sc_core::timed_out( simcontext() ); } 187 188 189#if 0 // @@@@#### 190 // delta count maintenance 191 sc_dt::uint64 delta_count() 192 { return simcontext()->m_delta_count; } 193#endif 194 195private: 196 197 // called during the update phase of a delta cycle (if requested) 198 void perform_update(); 199 200 // called when construction is done 201 void construction_done(); 202 203 // called when elaboration is done 204 void elaboration_done(); 205 206 // called before simulation starts 207 void start_simulation(); 208 209 // called after simulation ends 210 void simulation_done(); 211 212 // disabled 213 sc_prim_channel( const sc_prim_channel& ); 214 sc_prim_channel& operator = ( const sc_prim_channel& ); 215 216private: 217 218 sc_prim_channel_registry* m_registry; // Update list manager. 219 sc_prim_channel* m_update_next_p; // Next entry in update list. 220}; 221 222 223// ---------------------------------------------------------------------------- 224// CLASS : sc_prim_channel_registry 225// 226// Registry for all primitive channels. 227// FOR INTERNAL USE ONLY! 228// ---------------------------------------------------------------------------- 229 230class sc_prim_channel_registry 231{ 232 friend class sc_simcontext; 233 234public: 235 236 void insert( sc_prim_channel& ); 237 void remove( sc_prim_channel& ); 238 239 240 int size() const 241 { return m_prim_channel_vec.size(); } 242 243 inline void request_update( sc_prim_channel& ); 244 void async_request_update( sc_prim_channel& ); 245 246 bool pending_updates() const 247 { 248 return m_update_list_p != (sc_prim_channel*)sc_prim_channel::list_end 249 || pending_async_updates(); 250 } 251 252 bool pending_async_updates() const; 253 254private: 255 256 // constructor 257 explicit sc_prim_channel_registry( sc_simcontext& simc_ ); 258 259 // destructor 260 ~sc_prim_channel_registry(); 261 262 // called during the update phase of a delta cycle 263 void perform_update(); 264 265 // called when construction is done 266 bool construction_done(); 267 268 // called when elaboration is done 269 void elaboration_done(); 270 271 // called before simulation starts 272 void start_simulation(); 273 274 // called after simulation ends 275 void simulation_done(); 276 277 // disabled 278 sc_prim_channel_registry(); 279 sc_prim_channel_registry( const sc_prim_channel_registry& ); 280 sc_prim_channel_registry& operator = ( const sc_prim_channel_registry& ); 281 282private: 283 class async_update_list; 284 285 async_update_list* m_async_update_list_p; // external updates. 286 int m_construction_done; // # of constructs. 287 std::vector<sc_prim_channel*> m_prim_channel_vec; // existing channels. 288 sc_simcontext* m_simc; // simulator context. 289 sc_prim_channel* m_update_list_p; // internal updates. 290}; 291 292 293// IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII 294 295// ---------------------------------------------------------------------------- 296// CLASS : sc_prim_channel_registry 297// 298// Registry for all primitive channels. 299// FOR INTERNAL USE ONLY! 300// ---------------------------------------------------------------------------- 301 302inline 303void 304sc_prim_channel_registry::request_update( sc_prim_channel& prim_channel_ ) 305{ 306 prim_channel_.m_update_next_p = m_update_list_p; 307 m_update_list_p = &prim_channel_; 308} 309 310// ---------------------------------------------------------------------------- 311// CLASS : sc_prim_channel 312// 313// Abstract base class of all primitive channel classes. 314// ---------------------------------------------------------------------------- 315 316// request the update method (to be executed during the update phase) 317 318inline 319void 320sc_prim_channel::request_update() 321{ 322 if( ! m_update_next_p ) { 323 m_registry->request_update( *this ); 324 } 325} 326 327// request the update method from external to the simulator (to be executed 328// during the update phase) 329 330inline 331void 332sc_prim_channel::async_request_update() 333{ 334 m_registry->async_request_update(*this); 335} 336 337 338// called during the update phase of a delta cycle (if requested) 339 340inline 341void 342sc_prim_channel::perform_update() 343{ 344 update(); 345 m_update_next_p = 0; 346} 347 348 349} // namespace sc_core 350 351 352/***************************************************************************** 353 354 MODIFICATION LOG - modifiers, enter your name, affiliation, date and 355 changes you are making here. 356 357 Name, Affiliation, Date: Andy Goodrich, Forte, 358 Bishnupriya Bhattacharya, Cadence Design Systems, 359 25 August, 2003 360 Description of Modification: phase callbacks 361 362 *****************************************************************************/ 363//$Log: sc_prim_channel.h,v $ 364//Revision 1.10 2011/08/26 21:38:32 acg 365// Philipp A. Hartmann: removed unused switch m_construction_done. 366// 367//Revision 1.9 2011/08/07 19:08:01 acg 368// Andy Goodrich: moved logs to end of file so line number synching works 369// better between versions. 370// 371//Revision 1.8 2011/05/09 04:07:37 acg 372// Philipp A. Hartmann: 373// (1) Restore hierarchy in all phase callbacks. 374// (2) Ensure calls to before_end_of_elaboration. 375// 376//Revision 1.7 2011/05/05 17:44:01 acg 377// Philip A. Hartmann: change in the name of pending_async_updates. 378// 379//Revision 1.6 2011/04/19 15:03:48 acg 380// Philipp A. Hartmann: remove ASYNC_UPDATE preprocessor check from header. 381// 382//Revision 1.5 2011/04/19 02:36:26 acg 383// Philipp A. Hartmann: new aysnc_update and mutex support. 384// 385//Revision 1.4 2011/04/05 20:48:09 acg 386// Andy Goodrich: changes to make sure that event(), posedge() and negedge() 387// only return true if the clock has not moved. 388// 389//Revision 1.3 2011/02/18 20:23:45 acg 390// Andy Goodrich: Copyright update. 391// 392//Revision 1.2 2011/01/20 16:52:15 acg 393// Andy Goodrich: changes for IEEE 1666 2011. 394// 395//Revision 1.1.1.1 2006/12/15 20:20:04 acg 396//SystemC 2.3 397// 398//Revision 1.3 2006/05/08 17:52:47 acg 399// Andy Goodrich: 400// (1) added David Long's forward declarations for friend functions, 401// methods, and operators to keep the Microsoft compiler happy. 402// (2) Added delta_count() method to sc_prim_channel for use by 403// sc_signal so that the friend declaration in sc_simcontext.h 404// can be for a non-templated class (i.e., sc_prim_channel.) 405// 406//Revision 1.2 2006/01/03 23:18:26 acg 407//Changed copyright to include 2006. 408// 409//Revision 1.1.1.1 2005/12/19 23:16:43 acg 410//First check in of SystemC 2.1 into its own archive. 411// 412//Revision 1.10 2005/07/30 03:44:11 acg 413//Changes from 2.1. 414// 415//Revision 1.9 2005/06/10 22:43:55 acg 416//Added CVS change log annotation. 417 418#endif 419 420// Taf! 421