112855Sgabeblack@google.com/*****************************************************************************
212855Sgabeblack@google.com
312855Sgabeblack@google.com  Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
412855Sgabeblack@google.com  more contributor license agreements.  See the NOTICE file distributed
512855Sgabeblack@google.com  with this work for additional information regarding copyright ownership.
612855Sgabeblack@google.com  Accellera licenses this file to you under the Apache License, Version 2.0
712855Sgabeblack@google.com  (the "License"); you may not use this file except in compliance with the
812855Sgabeblack@google.com  License.  You may obtain a copy of the License at
912855Sgabeblack@google.com
1012855Sgabeblack@google.com    http://www.apache.org/licenses/LICENSE-2.0
1112855Sgabeblack@google.com
1212855Sgabeblack@google.com  Unless required by applicable law or agreed to in writing, software
1312855Sgabeblack@google.com  distributed under the License is distributed on an "AS IS" BASIS,
1412855Sgabeblack@google.com  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
1512855Sgabeblack@google.com  implied.  See the License for the specific language governing
1612855Sgabeblack@google.com  permissions and limitations under the License.
1712855Sgabeblack@google.com
1812855Sgabeblack@google.com *****************************************************************************/
1912855Sgabeblack@google.com
2012855Sgabeblack@google.com// immed_self_notif.cpp -- test for
2112855Sgabeblack@google.com//
2212855Sgabeblack@google.com//  Original Author: John Aynsley, Doulos, Inc.
2312855Sgabeblack@google.com//
2412855Sgabeblack@google.com// MODIFICATION LOG - modifiers, enter your name, affiliation, date and
2512855Sgabeblack@google.com//
2612855Sgabeblack@google.com// $Log: immed_self_notif.cpp,v $
2712855Sgabeblack@google.com// Revision 1.2  2011/05/08 19:18:46  acg
2812855Sgabeblack@google.com//  Andy Goodrich: remove extraneous + prefixes from git diff.
2912855Sgabeblack@google.com//
3012855Sgabeblack@google.com
3112855Sgabeblack@google.com// Change to the semantics of immediate self-notification to match Verilog semantics
3212855Sgabeblack@google.com
3312855Sgabeblack@google.com#define SC_INCLUDE_DYNAMIC_PROCESSES
3412855Sgabeblack@google.com#include <systemc>
3512855Sgabeblack@google.com
3612855Sgabeblack@google.comusing namespace sc_core;
3712855Sgabeblack@google.comusing std::cout;
3812855Sgabeblack@google.comusing std::endl;
3912855Sgabeblack@google.com
4012855Sgabeblack@google.comstruct Top: sc_module
4112855Sgabeblack@google.com{
4212855Sgabeblack@google.com  Top(sc_module_name _name)
4312855Sgabeblack@google.com  {
4412855Sgabeblack@google.com    SC_THREAD(T1);
4512855Sgabeblack@google.com      sensitive << ev1;
4612855Sgabeblack@google.com
4712855Sgabeblack@google.com    SC_THREAD(T2);
4812855Sgabeblack@google.com      sensitive << ev1;
4912855Sgabeblack@google.com
5012855Sgabeblack@google.com    SC_THREAD(T3);
5112855Sgabeblack@google.com
5212855Sgabeblack@google.com    SC_THREAD(T4);
5312855Sgabeblack@google.com      sensitive << ev3;
5412855Sgabeblack@google.com
5512855Sgabeblack@google.com    SC_METHOD(M1);
5612855Sgabeblack@google.com      sensitive << ev5;
5712855Sgabeblack@google.com
5812855Sgabeblack@google.com    SC_METHOD(M2);
5912855Sgabeblack@google.com
6012855Sgabeblack@google.com    SC_METHOD(M3);
6112855Sgabeblack@google.com
6212855Sgabeblack@google.com    SC_THREAD(yield_test);
6312855Sgabeblack@google.com
6412855Sgabeblack@google.com    end_of_t2   = false;
6512855Sgabeblack@google.com    m1_run      = false;
6612855Sgabeblack@google.com    m2_run      = false;
6712855Sgabeblack@google.com    m3_run      = false;
6812855Sgabeblack@google.com    first_yield = true;
6912855Sgabeblack@google.com    yield_count = 0;
7012855Sgabeblack@google.com    yield_test_run = false;
7112855Sgabeblack@google.com  }
7212855Sgabeblack@google.com
7312855Sgabeblack@google.com  sc_event ev1, ev2, ev3, ev4, ev5, ev6, ev7;
7412855Sgabeblack@google.com  bool end_of_t2;
7512855Sgabeblack@google.com  bool m1_run;
7612855Sgabeblack@google.com  bool m2_run;
7712855Sgabeblack@google.com  bool m3_run;
7812855Sgabeblack@google.com
7912855Sgabeblack@google.com  sc_event yield_event_1, yield_event_2;
8012855Sgabeblack@google.com  bool first_yield;
8112855Sgabeblack@google.com  int yield_count;
8212855Sgabeblack@google.com  bool yield_test_run;
8312855Sgabeblack@google.com
8412855Sgabeblack@google.com  void T1()
8512855Sgabeblack@google.com  {
8612855Sgabeblack@google.com    wait(SC_ZERO_TIME);
8712855Sgabeblack@google.com    ev1.notify();
8812855Sgabeblack@google.com    sc_assert( sc_delta_count() == 1 );
8912855Sgabeblack@google.com    wait(ev1);
9012855Sgabeblack@google.com    sc_assert( false );
9112855Sgabeblack@google.com  }
9212855Sgabeblack@google.com
9312855Sgabeblack@google.com  void T2()
9412855Sgabeblack@google.com  {
9512855Sgabeblack@google.com    wait(ev1);
9612855Sgabeblack@google.com    sc_assert( sc_delta_count() == 1 );
9712855Sgabeblack@google.com    end_of_t2 = true;
9812855Sgabeblack@google.com  }
9912855Sgabeblack@google.com
10012855Sgabeblack@google.com  void T3()
10112855Sgabeblack@google.com  {
10212855Sgabeblack@google.com    wait(SC_ZERO_TIME);
10312855Sgabeblack@google.com    ev2.notify();
10412855Sgabeblack@google.com    sc_assert( sc_delta_count() == 1 );
10512855Sgabeblack@google.com    wait(ev2);
10612855Sgabeblack@google.com    sc_assert( false );
10712855Sgabeblack@google.com  }
10812855Sgabeblack@google.com
10912855Sgabeblack@google.com  void T4()
11012855Sgabeblack@google.com  {
11112855Sgabeblack@google.com    wait(SC_ZERO_TIME);
11212855Sgabeblack@google.com    ev3.notify();
11312855Sgabeblack@google.com    sc_assert( sc_delta_count() == 1 );
11412855Sgabeblack@google.com    wait(ev4);
11512855Sgabeblack@google.com    sc_assert( false );
11612855Sgabeblack@google.com  }
11712855Sgabeblack@google.com
11812855Sgabeblack@google.com  void M1()
11912855Sgabeblack@google.com  {
12012855Sgabeblack@google.com    sc_assert( !m1_run );
12112855Sgabeblack@google.com    ev5.notify();
12212855Sgabeblack@google.com    m1_run = true;
12312855Sgabeblack@google.com  }
12412855Sgabeblack@google.com
12512855Sgabeblack@google.com  void M2()
12612855Sgabeblack@google.com  {
12712855Sgabeblack@google.com    sc_assert( !m2_run );
12812855Sgabeblack@google.com    ev6.notify();
12912855Sgabeblack@google.com    next_trigger(ev6);
13012855Sgabeblack@google.com    m2_run = true;
13112855Sgabeblack@google.com  }
13212855Sgabeblack@google.com
13312855Sgabeblack@google.com  void M3()
13412855Sgabeblack@google.com  {
13512855Sgabeblack@google.com    sc_assert( !m3_run );
13612855Sgabeblack@google.com    next_trigger(ev7);
13712855Sgabeblack@google.com    ev7.notify();
13812855Sgabeblack@google.com    m3_run = true;
13912855Sgabeblack@google.com  }
14012855Sgabeblack@google.com
14112855Sgabeblack@google.com  void yield_test()
14212855Sgabeblack@google.com  {
14312855Sgabeblack@google.com    sc_assert( sc_delta_count() == 0 );
14412855Sgabeblack@google.com    wait(SC_ZERO_TIME);
14512855Sgabeblack@google.com    sc_assert( sc_delta_count() == 1 );
14612855Sgabeblack@google.com
14712855Sgabeblack@google.com    yield();
14812855Sgabeblack@google.com    sc_spawn(sc_bind( &Top::yield_test_child, this));
14912855Sgabeblack@google.com    yield();
15012855Sgabeblack@google.com    sc_spawn(sc_bind( &Top::yield_test_child, this));
15112855Sgabeblack@google.com    yield();
15212855Sgabeblack@google.com
15312855Sgabeblack@google.com    sc_assert( sc_delta_count() == 1 );
15412855Sgabeblack@google.com    wait(1, SC_MS);
15512855Sgabeblack@google.com    unsigned int delta_count = sc_delta_count();
15612855Sgabeblack@google.com
15712855Sgabeblack@google.com    yield();
15812855Sgabeblack@google.com    sc_spawn(sc_bind( &Top::yield_test_child, this));
15912855Sgabeblack@google.com    yield();
16012855Sgabeblack@google.com    sc_spawn(sc_bind( &Top::yield_test_child, this));
16112855Sgabeblack@google.com    yield();
16212855Sgabeblack@google.com
16312855Sgabeblack@google.com    sc_assert( sc_delta_count() == delta_count );
16412855Sgabeblack@google.com    yield_test_run = true;
16512855Sgabeblack@google.com  }
16612855Sgabeblack@google.com
16712855Sgabeblack@google.com  void yield_test_child()
16812855Sgabeblack@google.com  {
16912855Sgabeblack@google.com    yield();
17012855Sgabeblack@google.com  }
17112855Sgabeblack@google.com
17212855Sgabeblack@google.com  void yield()
17312855Sgabeblack@google.com  {
17412855Sgabeblack@google.com    ++yield_count;
17512855Sgabeblack@google.com    if (first_yield)
17612855Sgabeblack@google.com    {
17712855Sgabeblack@google.com      sc_spawn(sc_bind(&Top::yield_helper, this));
17812855Sgabeblack@google.com      first_yield = false;
17912855Sgabeblack@google.com    }
18012855Sgabeblack@google.com    else
18112855Sgabeblack@google.com      yield_event_1.notify();
18212855Sgabeblack@google.com    wait(yield_event_2);
18312855Sgabeblack@google.com  }
18412855Sgabeblack@google.com
18512855Sgabeblack@google.com  void yield_helper()
18612855Sgabeblack@google.com  {
18712855Sgabeblack@google.com    yield_event_2.notify();
18812855Sgabeblack@google.com    while (true)
18912855Sgabeblack@google.com    {
19012855Sgabeblack@google.com      wait(yield_event_1);
19112855Sgabeblack@google.com      yield_event_2.notify();
19212855Sgabeblack@google.com    }
19312855Sgabeblack@google.com  }
19412855Sgabeblack@google.com
19512855Sgabeblack@google.com  SC_HAS_PROCESS(Top);
19612855Sgabeblack@google.com};
19712855Sgabeblack@google.com
19812855Sgabeblack@google.com
19912855Sgabeblack@google.comint sc_main(int argc, char* argv[])
20012855Sgabeblack@google.com{
20112855Sgabeblack@google.com  Top top("top");
20212855Sgabeblack@google.com
20312855Sgabeblack@google.com  sc_start();
20412855Sgabeblack@google.com
20512855Sgabeblack@google.com  sc_assert( top.end_of_t2 );
20612855Sgabeblack@google.com  sc_assert( top.m1_run );
20712855Sgabeblack@google.com  sc_assert( top.m2_run );
20812855Sgabeblack@google.com  sc_assert( top.m3_run );
20912855Sgabeblack@google.com  sc_assert( top.first_yield == false );
21012855Sgabeblack@google.com  sc_assert( top.yield_count == 10 );
21112855Sgabeblack@google.com  sc_assert( top.yield_test_run );
21212855Sgabeblack@google.com
21312855Sgabeblack@google.com  cout << endl << "Success" << endl;
21412855Sgabeblack@google.com  return 0;
21512855Sgabeblack@google.com}
21612855Sgabeblack@google.com
217