test09.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  test09.cpp -- Test for hierarchical reset, try/catch and individual kill
23                processes
24
25  Original Author: Andy Goodrich
26
27 *****************************************************************************/
28
29/*****************************************************************************
30
31  MODIFICATION LOG - modifiers, enter your name, affiliation, date and
32  changes you are making here.
33
34      Name, Affiliation, Date:
35  Description of Modification:
36
37 *****************************************************************************/
38// $Log: test09.cpp,v $
39// Revision 1.4  2011/02/01 17:17:40  acg
40//  Andy Goodrich: update of copyright notice, added visible CVS logging.
41//
42// Revision 1.3  2011/01/14 14:23:46  acg
43//  Andy Goodrich: Fixes for 1666_2011
44//
45// Revision 1.2  2009/10/14 19:13:27  acg
46//  Andy Goodrich: changes for SystemC 2.3
47//
48// Revision 1.1.1.1  2006/12/15 20:26:03  acg
49// systemc_tests-2.3
50//
51// Revision 1.1  2006/04/17 20:10:04  acg
52//  Andy Goodrich: first inclusion of test for expanded process support.
53//
54
55
56#define SC_INCLUDE_DYNAMIC_PROCESSES
57#include "systemc.h"
58
59SC_MODULE(DUT)
60{
61    SC_CTOR(DUT)
62    {
63        SC_CTHREAD(stimulus,m_clk.pos());
64        reset_signal_is(m_reset, true);
65        SC_THREAD(grand_parent);
66        sensitive << m_clk.pos();
67    }
68
69    void child()
70    {
71        sc_process_handle my_handle = sc_get_current_process_handle();
72        cout << sc_time_stamp() << " " << my_handle.name()
73             << " initialization" << endl;
74        try {
75            for (;;)
76            {
77                wait();
78            }
79        }
80        catch(sc_core::sc_unwind_exception& ex)
81        {
82	    if ( !ex.is_reset() )
83	    {
84		cout << sc_time_stamp() << " " << my_handle.name()
85		     << " got kill" << endl;
86	    }
87	    throw ex;
88        }
89    }
90
91    void grand_parent()
92    {
93        static bool       initialize = true;
94        cout << sc_time_stamp() << " " << "dut.grand_parent initialization"
95             << endl;
96        cout << endl;
97        if ( initialize )
98        {
99            m_grand_parent_handle = sc_get_current_process_handle();
100            sc_spawn( sc_bind(&DUT::parent1, this), "parent1" );
101            sc_spawn( sc_bind(&DUT::parent2, this), "parent2" );
102            initialize = false;
103        }
104
105        for (;;)
106        {
107            wait();
108        }
109    }
110
111    void parent1()
112    {
113        static bool initialize = true;
114        sc_process_handle m_child1;
115        sc_process_handle m_child2;
116        sc_process_handle m_child3;
117        sc_process_handle my_handle = sc_get_current_process_handle();
118        cout << sc_time_stamp() << " " << my_handle.name()
119             << " initialization" << endl;
120        if ( initialize )
121        {
122            m_child1 = sc_spawn( sc_bind(&DUT::child, this), "child1" );
123            m_child2 = sc_spawn( sc_bind(&DUT::child, this), "child2" );
124            m_child3 = sc_spawn( sc_bind(&DUT::child, this), "child3" );
125            initialize = false;
126        }
127
128        for (;;)
129        {
130            wait();
131        }
132    }
133
134    void parent2()
135    {
136        sc_process_handle m_child1;
137        sc_process_handle m_child2;
138        sc_process_handle m_child3;
139        sc_process_handle my_handle;
140        for (;;)
141        {
142            try
143            {
144                my_handle = sc_get_current_process_handle();
145                cout << sc_time_stamp() << " " << my_handle.name()
146                     << " initialization" << endl;
147                m_child1 = sc_spawn( sc_bind(&DUT::child, this), "child1" );
148                m_child2 = sc_spawn( sc_bind(&DUT::child, this), "child2" );
149                m_child3 = sc_spawn( sc_bind(&DUT::child, this), "child3" );
150
151                for (;;)
152                {
153                    wait();
154                }
155            }
156            catch ( sc_core::sc_unwind_exception& ex )
157            {
158		if ( ex.is_reset() )
159		{
160		    cout << sc_time_stamp() << " " << my_handle.name()
161			 << " removing children" << endl;
162		    m_child1.kill();
163		    m_child2.kill();
164		    m_child3.kill();
165		}
166		throw ex;
167            }
168        }
169    }
170
171    void stimulus()
172    {
173        for (;;)
174        {
175            wait();
176            wait();
177            wait();
178            wait();
179	    cout << sc_time_stamp() << " stimulus issuing reset" << endl;
180            m_grand_parent_handle.reset(SC_INCLUDE_DESCENDANTS);
181        }
182    }
183
184    sc_in<bool>       m_clk;
185    sc_process_handle m_grand_parent_handle;
186    sc_in<bool>       m_reset;
187};
188
189int sc_main(int argc, char* argv[])
190{
191    sc_clock        clock;
192    DUT             dut("dut");
193    sc_signal<bool> reset;
194
195    dut.m_clk(clock);
196    dut.m_reset(reset);
197
198    reset = true;
199    sc_start(1, SC_NS);
200    reset = false;
201    sc_start(20, SC_NS);
202
203    cout << "Program completed" << endl;
204    return 0;
205}
206