test2.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//  test02.cpp -- test that suspended processes with static sensitivity
23//                wake up when resumed.
24//
25//  Original Author: Andy Goodrich, Forte Design Systems, Inc.
26//
27//  CVS MODIFICATION LOG - modifiers, enter your name, affiliation, date and
28//  changes you are making here.
29//
30// $Log: test2.cpp,v $
31// Revision 1.5  2011/04/02 00:08:19  acg
32//  Andy Goodrich: turn off corner case error checking.
33//
34// Revision 1.4  2011/03/07 19:32:09  acg
35//  Andy Goodrich: addition to set sc_core::sc_allow_process_control_corners
36//  to true so that this test avoids corner case error messages.
37//
38// Revision 1.3  2011/02/20 13:43:49  acg
39//  Andy Goodrich: updates for IEEE 1666 2011.
40//
41// Revision 1.2  2011/02/04 15:26:52  acg
42//  Andy Goodrich: changes for process control semantics.
43//
44// Revision 1.1  2009/07/28 18:43:55  acg
45//  Andy Goodrich: new standard test bench version of this test.
46//
47//*****************************************************************************
48
49#define SC_INCLUDE_DYNAMIC_PROCESSES
50#include "systemc.h"
51
52enum my_process_states {
53    ST_SUSPENDD,
54    ST_NORMAL,
55    ST_SUSPENDED
56};
57
58inline ostream& time_stamp( ostream& os )
59{
60    os << dec << sc_time_stamp() << "[" << sc_delta_count() << "]: ";
61    return os;
62}
63
64SC_MODULE(top) {
65    // constructor:
66
67    SC_CTOR(top)
68    {
69        m_state_cthread0 = ST_NORMAL;
70	m_state_method0 = ST_NORMAL;
71        m_state_thread0 = ST_NORMAL;
72
73        SC_THREAD(stimulator0);
74
75        SC_CTHREAD( target_cthread0, m_clk.pos() );
76        m_target_cthread0 = sc_get_current_process_handle();
77
78        SC_METHOD(target_method0);
79	sensitive << m_clk.pos();
80        m_target_method0 = sc_get_current_process_handle();
81
82        SC_THREAD(target_thread0);
83	sensitive << m_clk.neg();
84        m_target_thread0 = sc_get_current_process_handle();
85    }
86
87    // processes:
88
89    void stimulator0();
90    void target_cthread0();
91    void target_method0();
92    void target_thread0();
93
94    // Storage:
95
96    sc_in<bool>       m_clk;
97    int               m_state_cthread0;
98    int               m_state_method0;
99    int               m_state_thread0;
100    sc_process_handle m_target_cthread0;
101    sc_process_handle m_target_method0;
102    sc_process_handle m_target_thread0;
103};
104
105#define SUSPEND(TARGET) \
106    cout << endl; \
107    time_stamp(cout) << name << ": suspending target_" << #TARGET << endl; \
108    m_state_##TARGET = ST_SUSPENDD; \
109    m_target_##TARGET.suspend(); \
110    cout << endl;
111
112#define RESUME(TARGET) \
113    cout << endl; \
114    time_stamp(cout) << name << ": resuming target_" << #TARGET << endl; \
115    m_state_##TARGET = ST_NORMAL; \
116    m_target_##TARGET.resume(); \
117    cout << endl;
118
119void top::stimulator0()
120{
121    const char* name = "stimulator";
122
123    wait(2, SC_NS);
124
125    SUSPEND(cthread0)
126    wait(3, SC_NS);
127    SUSPEND(method0)
128    wait(3, SC_NS);
129    SUSPEND(thread0)
130    wait(3, SC_NS);
131
132    RESUME(cthread0)
133    wait(3, SC_NS);
134    RESUME(method0)
135    wait(3, SC_NS);
136    RESUME(thread0)
137    wait(3, SC_NS);
138
139    SUSPEND(cthread0)
140    wait(3, SC_NS);
141    SUSPEND(method0)
142    wait(3, SC_NS);
143    SUSPEND(thread0)
144    wait(3, SC_NS);
145
146    RESUME(cthread0)
147    wait(3, SC_NS);
148    RESUME(method0)
149    wait(3, SC_NS);
150    RESUME(thread0)
151    wait(3, SC_NS);
152
153    ::sc_core::wait(1000, SC_NS);
154    cout << endl;
155    time_stamp(cout) << name << ": terminating" << endl;
156    sc_stop();
157}
158
159void top::target_cthread0()
160{
161    const char* name = "target_cthread0";
162
163    time_stamp(cout) << name  << ": starting" << endl;
164    for (int i = 0; i < 12; i++)
165    {
166	wait();
167	if ( m_state_cthread0 == ST_SUSPENDD )
168	{
169	    time_stamp(cout) << name  << ": ERROR should not see this" << endl;
170	}
171	else
172	{
173	    time_stamp(cout) << name  << ": active" << endl;
174	}
175    }
176    time_stamp(cout) << name  << ": terminating" << endl;
177}
178
179void top::target_method0()
180{
181    const char* name = "target_method0";
182    static int  state = 0;
183    switch( state )
184    {
185      case 0:
186        time_stamp(cout) << name  << ": starting" << endl;
187        break;
188      default:
189	if ( m_state_method0 == ST_SUSPENDD )
190	{
191	    time_stamp(cout) << name  << ": ERROR should not see this" << endl;
192	}
193	else if ( state < 20 )
194	{
195	    time_stamp(cout) << name  << ": active" << endl;
196	}
197        break;
198      case 21:
199        time_stamp(cout) << name  << ": terminating" << endl;
200        break;
201    }
202    state++;
203}
204
205void top::target_thread0()
206{
207    const char* name = "target_thread0";
208
209    time_stamp(cout) << name  << ": starting" << endl;
210    for (int i = 0; i < 12; i++)
211    {
212	wait();
213	if ( m_state_thread0 == ST_SUSPENDD )
214	{
215	    time_stamp(cout) << name  << ": ERROR should not see this" << endl;
216	}
217	else
218	{
219	    time_stamp(cout) << name  << ": active" << endl;
220	}
221    }
222    time_stamp(cout) << name  << ": terminating" << endl;
223}
224
225int sc_main (int argc, char *argv[])
226{
227    sc_core::sc_allow_process_control_corners = true;
228    sc_clock clock( "clock", 2.0, SC_NS );
229
230    top* top_p = new top("top");
231    top_p->m_clk(clock);
232
233    sc_core::sc_allow_process_control_corners = true;
234    sc_start();
235    return 0;
236}
237
238