stepwise_simulation.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 stepwise_simulation.cpp -- Test step-wise simulation 23 24 Original Author: Philipp A. Hartmann, OFFIS, 2011-01-21 25 26 *****************************************************************************/ 27 28/***************************************************************************** 29 30 MODIFICATION LOG - modifiers, enter your name, affiliation, date and 31 changes you are making here. 32 33 Name, Affiliation, Date: 34 Description of Modification: 35 36 *****************************************************************************/ 37 38#include <systemc.h> 39 40const int num_events = 2; 41const sc_time delay( 10, SC_NS ); 42 43//#define EXPLICIT_DELTA // should not modify the trace 44#define DELAYED_EVENTS 45 46SC_MODULE(echo) 47{ 48 sc_event ev[num_events]; 49 SC_CTOR(echo) 50 : self_trigger(3) 51 { 52 SC_METHOD(do_print); 53# ifdef DELAYED_EVENTS 54 dont_initialize(); 55# endif 56 for( int i=0; i<num_events; ++i ) 57 sensitive << ev[i]; 58 } 59 60 void do_print() 61 { 62 std::cout << "`" << sc_get_current_process_handle().name() 63 << "' triggered at " << sc_time_stamp() 64 << " - delta: " << sc_delta_count() 65 << std::endl; 66 67 if( --self_trigger > 1 ) 68 next_trigger( delay/2 ); 69 else if( self_trigger == 1 ) 70 next_trigger( SC_ZERO_TIME ); 71 else 72 self_trigger = 3; 73 74 } 75 int self_trigger; 76}; 77 78void do_step( sc_time const & step ) 79{ 80 sc_dt::uint64 delta = sc_delta_count(); 81 static bool start_delta = ( delta == 0 ) && ( step == SC_ZERO_TIME ); 82 std::cout 83 << " ----- running for " 84 << ( ( step == SC_ZERO_TIME ) ? "delta" : step.to_string() ) 85 << std::endl; 86 87 sc_time start = sc_time_stamp(); 88 if( step > SC_ZERO_TIME ) 89 { 90 std::cout << " --- No-op start (warning) - "; 91 sc_start( step / 2, SC_EXIT_ON_STARVATION ); 92 sc_assert( start == sc_time_stamp() ); 93 94 sc_start( step / 2, SC_RUN_TO_TIME ); 95 sc_assert( start + step / 2 == sc_time_stamp() ); 96 97 sc_start( step / 2 ); // complete step 98 } 99 else 100 { 101 sc_start( SC_ZERO_TIME ); 102 } 103 sc_assert( start + step == sc_time_stamp() ); 104 105 std::cout 106 << " -- stopped at - " 107 << sc_time_stamp() << " - delta: " << sc_delta_count() 108 << std::endl; 109 110 // delta has only increased, when a delta has been run 111 sc_assert( sc_delta_count() 112 == delta + ( !start_delta && step == SC_ZERO_TIME ) ); 113 start_delta = false; 114} 115 116int sc_main(int, char*[]) 117{ 118 sc_assert( !sc_pending_activity() ); 119 sc_assert( sc_time_to_pending_activity() 120 == sc_max_time() - sc_time_stamp() ); 121 122 sc_signal<bool> toggle("toggle"); 123 echo dut("echo"); 124 125 // notify future events 126 for( int i=0; i<num_events; ++i ) 127 dut.ev[i].notify( (i+1) * delay ); 128 129 sc_assert( sc_pending_activity_at_future_time() ); 130 sc_assert( sc_time_to_pending_activity() == delay ); 131 132 do_step( SC_ZERO_TIME ); // elaborate 133 134 while( sc_pending_activity() ) 135 { 136 sc_assert( sc_pending_activity_at_current_time() 137 || sc_time_to_pending_activity() > SC_ZERO_TIME ); 138 139 sc_assert( sc_pending_activity_at_future_time() 140 || sc_time_to_pending_activity() == SC_ZERO_TIME ); 141 142 // run single (time) step 143 do_step( sc_time_to_pending_activity() ); 144 145# ifdef EXPLICIT_DELTA 146 // run remaining current deltas (optional) 147 while( sc_pending_activity_at_current_time() ) { 148 sc_assert( sc_time_to_pending_activity() == SC_ZERO_TIME ); 149 do_step( SC_ZERO_TIME ); 150 } 151# endif // EXPLICIT_DELTA 152 } 153 154 // force one empty evaluate (w/ non-empty update) 155 toggle.write( !toggle.read() ); 156 sc_assert( sc_pending_activity_at_current_time() ); 157 sc_start( SC_ZERO_TIME ); 158 159 sc_assert( !sc_pending_activity() ); 160 sc_assert( sc_time_to_pending_activity() 161 == sc_max_time() - sc_time_stamp() ); 162 163 std::cout << "Success" << std::endl; 164 return 0; 165} 166