112855Sgabeblack@google.com//----------------------------------------------------------------------
212855Sgabeblack@google.com//   Copyright 2009 Cadence Design Systems, Inc.
312855Sgabeblack@google.com//   All Rights Reserved Worldwide
412855Sgabeblack@google.com//   Copyright 2009 Forte Design Systems, Inc.
512855Sgabeblack@google.com//   Copyright 2010 OFFIS Institute for Information technology
612855Sgabeblack@google.com//
712855Sgabeblack@google.com// test06: test hierarchical kills
812855Sgabeblack@google.com//----------------------------------------------------------------------
912855Sgabeblack@google.com
1012855Sgabeblack@google.com#define SC_INCLUDE_DYNAMIC_PROCESSES
1112855Sgabeblack@google.com#include <systemc.h>
1212855Sgabeblack@google.com
1312855Sgabeblack@google.comSC_MODULE(top) {
1412855Sgabeblack@google.compublic:
1512855Sgabeblack@google.com  SC_CTOR(top) {
1612855Sgabeblack@google.com    SC_THREAD(parent);
1712855Sgabeblack@google.com      sensitive << clk.pos();
1812855Sgabeblack@google.com      dont_initialize();
1912855Sgabeblack@google.com  }
2012855Sgabeblack@google.com
2112855Sgabeblack@google.com  void proc_tree( unsigned depth, unsigned width, bool as_method, bool spawn_only )
2212855Sgabeblack@google.com  {
2312855Sgabeblack@google.com    unsigned w = width;
2412855Sgabeblack@google.com    if (sc_time_stamp() == SC_ZERO_TIME || spawn_only )
2512855Sgabeblack@google.com      while( depth && w --> 0 )
2612855Sgabeblack@google.com    {
2712855Sgabeblack@google.com      sc_spawn_options sp;
2812855Sgabeblack@google.com      sp.set_sensitivity( &clk.pos() );
2912855Sgabeblack@google.com
3012855Sgabeblack@google.com      if(as_method) // we are spawned as method, spawn a thread
3112855Sgabeblack@google.com      {
3212855Sgabeblack@google.com        sc_spawn( sc_bind( &top::proc_tree, this, depth-1, width, !as_method, false )
3312855Sgabeblack@google.com                , sc_gen_unique_name("thread"), &sp );
3412855Sgabeblack@google.com      }
3512855Sgabeblack@google.com      else // we are spawned as thread, spawn a method
3612855Sgabeblack@google.com      {
3712855Sgabeblack@google.com        sp.spawn_method();
3812855Sgabeblack@google.com        sc_spawn( sc_bind( &top::proc_tree, this, depth-1, width, !as_method, false )
3912855Sgabeblack@google.com                , sc_gen_unique_name("method"), &sp );
4012855Sgabeblack@google.com      }
4112855Sgabeblack@google.com    }
4212855Sgabeblack@google.com
4312855Sgabeblack@google.com    if(spawn_only) return;
4412855Sgabeblack@google.com
4512855Sgabeblack@google.com    std::cout << sc_get_current_process_handle().name()
4612855Sgabeblack@google.com              << " triggered "
4712855Sgabeblack@google.com                << "(" << sc_time_stamp() << " @ " << sc_delta_count() << ")"
4812855Sgabeblack@google.com              << std::endl;
4912855Sgabeblack@google.com
5012855Sgabeblack@google.com    // start thread
5112855Sgabeblack@google.com    if( !as_method ) thread_loop();
5212855Sgabeblack@google.com  }
5312855Sgabeblack@google.com
5412855Sgabeblack@google.com  void thread_loop()
5512855Sgabeblack@google.com  {
5612855Sgabeblack@google.com    struct local_ {
5712855Sgabeblack@google.com       ~local_(){
5812855Sgabeblack@google.com          std::cout
5912855Sgabeblack@google.com            << sc_get_current_process_handle().name()
6012855Sgabeblack@google.com            << " local deleted "
6112855Sgabeblack@google.com            << "(" << sc_time_stamp() << " @ " << sc_delta_count() << ")"
6212855Sgabeblack@google.com            << std::endl;
6312855Sgabeblack@google.com       }
6412855Sgabeblack@google.com    } l; l=l;
6512855Sgabeblack@google.com
6612855Sgabeblack@google.com    unsigned rounds = 5;
6712855Sgabeblack@google.com    while( rounds --> 0 )
6812855Sgabeblack@google.com    {
6912855Sgabeblack@google.com      wait();
7012855Sgabeblack@google.com      std::cout << sc_get_current_process_handle().name()
7112855Sgabeblack@google.com                << " triggered "
7212855Sgabeblack@google.com                << "(" << sc_time_stamp() << " @ " << sc_delta_count() << ")"
7312855Sgabeblack@google.com                << std::endl;
7412855Sgabeblack@google.com    }
7512855Sgabeblack@google.com    std::cout << sc_get_current_process_handle().name()
7612855Sgabeblack@google.com              << " ended "
7712855Sgabeblack@google.com              << "(" << sc_time_stamp() << " @ " << sc_delta_count() << ")"
7812855Sgabeblack@google.com              << std::endl;
7912855Sgabeblack@google.com  }
8012855Sgabeblack@google.com
8112855Sgabeblack@google.com  void parent()
8212855Sgabeblack@google.com  {
8312855Sgabeblack@google.com    proc_tree( 3, 1, true , true );
8412855Sgabeblack@google.com    proc_tree( 3, 1, false, true );
8512855Sgabeblack@google.com
8612855Sgabeblack@google.com    wait();
8712855Sgabeblack@google.com
8812855Sgabeblack@google.com    // copy children (needed, since children may get reordered)
8912855Sgabeblack@google.com    std::vector< sc_object* > children =
9012855Sgabeblack@google.com      sc_get_current_process_handle().get_child_objects();
9112855Sgabeblack@google.com
9212855Sgabeblack@google.com    std::vector< sc_object* >::const_iterator it = children.begin();
9312855Sgabeblack@google.com
9412855Sgabeblack@google.com    while( it != children.end() )
9512855Sgabeblack@google.com    {
9612855Sgabeblack@google.com      sc_process_handle h( *it++ );
9712855Sgabeblack@google.com      sc_assert( h.valid() );
9812855Sgabeblack@google.com
9912855Sgabeblack@google.com      std::cout << h.name() << " "
10012855Sgabeblack@google.com                << "kill requested "
10112855Sgabeblack@google.com                << "(" << h.get_process_object()->kind() << ") "
10212855Sgabeblack@google.com                << "(" << sc_time_stamp() << " @ " << sc_delta_count() << ")"
10312855Sgabeblack@google.com                << std::endl;
10412855Sgabeblack@google.com
10512855Sgabeblack@google.com      h.kill( SC_INCLUDE_DESCENDANTS );
10612855Sgabeblack@google.com    }
10712855Sgabeblack@google.com
10812855Sgabeblack@google.com    wait();
10912855Sgabeblack@google.com
11012855Sgabeblack@google.com    std::cout << sc_get_current_process_handle().name()
11112855Sgabeblack@google.com              << " ended "
11212855Sgabeblack@google.com              << "(" << sc_time_stamp() << " @ " << sc_delta_count() << ")"
11312855Sgabeblack@google.com              << std::endl;
11412855Sgabeblack@google.com
11512855Sgabeblack@google.com    wait();
11612855Sgabeblack@google.com    sc_stop();
11712855Sgabeblack@google.com    while(true) wait();
11812855Sgabeblack@google.com  }
11912855Sgabeblack@google.com
12012855Sgabeblack@google.com  sc_in<bool> clk;
12112855Sgabeblack@google.com};
12212855Sgabeblack@google.com
12312855Sgabeblack@google.comint sc_main (int argc, char *argv[])
12412855Sgabeblack@google.com{
12512855Sgabeblack@google.com  sc_clock clk("clk", 10, SC_NS, 0.5);
12612855Sgabeblack@google.com  top t("top");
12712855Sgabeblack@google.com  t.clk(clk);
12812855Sgabeblack@google.com  sc_start();
12912855Sgabeblack@google.com  return 0;
13012855Sgabeblack@google.com}
131