1//----------------------------------------------------------------------
2//   Copyright 2009 Cadence Design Systems, Inc.
3//   All Rights Reserved Worldwide
4//   Copyright 2009 Forte Design Systems, Inc.
5//   Copyright 2010 OFFIS Institute for Information technology
6//
7// test06: test hierarchical kills
8//----------------------------------------------------------------------
9
10#define SC_INCLUDE_DYNAMIC_PROCESSES
11#include <systemc.h>
12
13SC_MODULE(top) {
14public:
15  SC_CTOR(top) {
16    SC_THREAD(parent);
17      sensitive << clk.pos();
18      dont_initialize();
19  }
20
21  void proc_tree( unsigned depth, unsigned width, bool as_method, bool spawn_only )
22  {
23    unsigned w = width;
24    if (sc_time_stamp() == SC_ZERO_TIME || spawn_only )
25      while( depth && w --> 0 )
26    {
27      sc_spawn_options sp;
28      sp.set_sensitivity( &clk.pos() );
29
30      if(as_method) // we are spawned as method, spawn a thread
31      {
32        sc_spawn( sc_bind( &top::proc_tree, this, depth-1, width, !as_method, false )
33                , sc_gen_unique_name("thread"), &sp );
34      }
35      else // we are spawned as thread, spawn a method
36      {
37        sp.spawn_method();
38        sc_spawn( sc_bind( &top::proc_tree, this, depth-1, width, !as_method, false )
39                , sc_gen_unique_name("method"), &sp );
40      }
41    }
42
43    if(spawn_only) return;
44
45    std::cout << sc_get_current_process_handle().name()
46              << " triggered "
47                << "(" << sc_time_stamp() << " @ " << sc_delta_count() << ")"
48              << std::endl;
49
50    // start thread
51    if( !as_method ) thread_loop();
52  }
53
54  void thread_loop()
55  {
56    struct local_ {
57       ~local_(){
58          std::cout
59            << sc_get_current_process_handle().name()
60            << " local deleted "
61            << "(" << sc_time_stamp() << " @ " << sc_delta_count() << ")"
62            << std::endl;
63       }
64    } l; l=l;
65
66    unsigned rounds = 5;
67    while( rounds --> 0 )
68    {
69      wait();
70      std::cout << sc_get_current_process_handle().name()
71                << " triggered "
72                << "(" << sc_time_stamp() << " @ " << sc_delta_count() << ")"
73                << std::endl;
74    }
75    std::cout << sc_get_current_process_handle().name()
76              << " ended "
77              << "(" << sc_time_stamp() << " @ " << sc_delta_count() << ")"
78              << std::endl;
79  }
80
81  void parent()
82  {
83    proc_tree( 3, 1, true , true );
84    proc_tree( 3, 1, false, true );
85
86    wait();
87
88    // copy children (needed, since children may get reordered)
89    std::vector< sc_object* > children =
90      sc_get_current_process_handle().get_child_objects();
91
92    std::vector< sc_object* >::const_iterator it = children.begin();
93
94    while( it != children.end() )
95    {
96      sc_process_handle h( *it++ );
97      sc_assert( h.valid() );
98
99      std::cout << h.name() << " "
100                << "kill requested "
101                << "(" << h.get_process_object()->kind() << ") "
102                << "(" << sc_time_stamp() << " @ " << sc_delta_count() << ")"
103                << std::endl;
104
105      h.kill( SC_INCLUDE_DESCENDANTS );
106    }
107
108    wait();
109
110    std::cout << sc_get_current_process_handle().name()
111              << " ended "
112              << "(" << sc_time_stamp() << " @ " << sc_delta_count() << ")"
113              << std::endl;
114
115    wait();
116    sc_stop();
117    while(true) wait();
118  }
119
120  sc_in<bool> clk;
121};
122
123int sc_main (int argc, char *argv[])
124{
125  sc_clock clk("clk", 10, SC_NS, 0.5);
126  top t("top");
127  t.clk(clk);
128  sc_start();
129  return 0;
130}
131