test1.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// test01.cpp -- test self suspends on processes 23// 24// Original Author: Andy Goodrich, Forte Design Systems, Inc. 25// 26// CVS MODIFICATION LOG - modifiers, enter your name, affiliation, date and 27// changes you are making here. 28// 29// $Log: test1.cpp,v $ 30// Revision 1.4 2011/04/02 00:07:44 acg 31// Andy Goodrich: new message format. 32// 33// Revision 1.3 2011/03/07 19:32:07 acg 34// Andy Goodrich: addition to set sc_core::sc_allow_process_control_corners 35// to true so that this test avoids corner case error messages. 36// 37// Revision 1.2 2009/07/28 18:43:50 acg 38// Andy Goodrich: new standard test bench version of this test. 39// 40// Revision 1.2 2009/07/28 01:09:48 acg 41// Andy Goodrich: replacement test using standardized environment. 42// 43//***************************************************************************** 44 45#define SC_INCLUDE_DYNAMIC_PROCESSES 46#include "systemc.h" 47 48enum my_process_states { 49 ST_DISABLED, 50 ST_NORMAL, 51 ST_SUSPENDED 52}; 53 54inline ostream& time_stamp( ostream& os ) 55{ 56 os << dec << sc_time_stamp() << "[" << sc_delta_count() << "]: "; 57 return os; 58} 59 60SC_MODULE(top) { 61 // constructor: 62 63 SC_CTOR(top) : 64 m_state_cthread0(ST_NORMAL), 65 m_state_method0(ST_NORMAL), 66 m_state_thread0(ST_NORMAL) 67 { 68 SC_THREAD(stimulator0); 69 70 SC_CTHREAD( target_cthread0, m_clk.pos() ); 71 m_target_cthread0 = sc_get_current_process_handle(); 72 73 SC_METHOD(target_method0); 74 sensitive << m_clk.pos(); 75 m_target_method0 = sc_get_current_process_handle(); 76 77 SC_THREAD(target_thread0); 78 m_target_thread0 = sc_get_current_process_handle(); 79 } 80 81 // processes: 82 83 void stimulator0(); 84 void target_cthread0(); 85 void target_method0(); 86 void target_thread0(); 87 88 // Storage: 89 90 sc_in<bool> m_clk; 91 int m_state_cthread0; 92 int m_state_method0; 93 int m_state_thread0; 94 sc_process_handle m_target_cthread0; 95 sc_process_handle m_target_method0; 96 sc_process_handle m_target_thread0; 97}; 98 99void top::stimulator0() 100{ 101 const char* name = "stimulator"; 102 wait(10, SC_NS); 103 cout << endl; 104 time_stamp(cout) << name << ": resuming target_cthread0" << endl; 105 cout << endl; 106 m_state_cthread0 = ST_NORMAL; 107 m_target_cthread0.resume(); 108 wait(10, SC_NS); 109 110 cout << endl; 111 time_stamp(cout) << name << ": resuming target_method0" << endl; 112 cout << endl; 113 m_state_method0 = ST_NORMAL; 114 m_target_method0.resume(); 115 wait(10, SC_NS); 116 117 cout << endl; 118 time_stamp(cout) << name << ": resuming target_thread0" << endl; 119 cout << endl; 120 m_state_thread0 = ST_NORMAL; 121 m_target_thread0.resume(); 122 ::sc_core::wait(1000, SC_NS); 123 124 cout << endl; 125 time_stamp(cout) << name << ": terminating" << endl; 126 sc_stop(); 127} 128 129void top::target_cthread0() 130{ 131 int i; 132 const char* name = "target_cthread0"; 133 134 time_stamp(cout) << name << ": starting" << endl; 135 time_stamp(cout) << name << ": issuing self suspend" << endl; 136 cout << endl; 137 m_state_cthread0 = ST_SUSPENDED; 138 m_target_cthread0.suspend(); 139 time_stamp(cout) << name << ": back from self suspend" << endl; 140 for ( i = 0; i < 100; i++ ) 141 { 142 if ( m_state_cthread0 == ST_SUSPENDED ) 143 { 144 time_stamp(cout) << name << ": ERROR should not see this" << endl; 145 } 146 wait(); 147 } 148 time_stamp(cout) << name << ": terminating" << endl; 149} 150 151void top::target_method0() 152{ 153 const char* name = "target_method0"; 154 static int state = 0; 155 switch( state ) 156 { 157 case 0: 158 time_stamp(cout) << name << ": starting" << endl; 159 time_stamp(cout) << name << ": issuing self suspend" << endl; 160 m_state_method0 = ST_SUSPENDED; 161 m_target_method0.suspend(); 162 time_stamp(cout) << name << ": after issuing self suspend" << endl; 163 cout << endl; 164 break; 165 case 1: 166 time_stamp(cout) << name << ": back from self suspend" << endl; 167 // fall through 168 default: 169 if ( m_state_method0 == ST_SUSPENDED ) 170 { 171 time_stamp(cout) << name << ": ERROR should not see this" << endl; 172 } 173 break; 174 case 99: 175 time_stamp(cout) << name << ": terminating" << endl; 176 break; 177 } 178 state++; 179} 180 181void top::target_thread0() 182{ 183 const char* name = "target_thread0"; 184 185 time_stamp(cout) << name << ": starting" << endl; 186 time_stamp(cout) << name << ": issuing self suspend" << endl; 187 cout << endl; 188 m_state_thread0 = ST_SUSPENDED; 189 m_target_thread0.suspend(); 190 time_stamp(cout) << name << ": back from self suspend" << endl; 191 192 // We wait a long enough time that our event will not occur until 193 // after we are resumed. Otherwise this thread will just go away 194 // quietly when the suspend cancels the event. 195 196 ::sc_core::wait(80, SC_NS); 197 if ( m_state_thread0 == ST_SUSPENDED ) 198 { 199 time_stamp(cout) << name << ": ERROR should not see this" << endl; 200 } 201 time_stamp(cout) << name << ": terminating" << endl; 202} 203 204int sc_main (int argc, char *argv[]) 205{ 206 sc_core::sc_allow_process_control_corners = true; 207 sc_clock clock( "clock", 1.0, SC_NS ); 208 209 top* top_p = new top("top"); 210 top_p->m_clk(clock); 211 212 sc_core::sc_allow_process_control_corners = true; 213 sc_start(); 214 return 0; 215} 216 217