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// sc_writer_policy.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: sc_writer_policy.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// sc_writer_policy template argument of class sc_signal
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 namespace sc_dt;
3812855Sgabeblack@google.comusing std::cout;
3912855Sgabeblack@google.comusing std::endl;
4012855Sgabeblack@google.comusing std::string;
4112855Sgabeblack@google.com
4212855Sgabeblack@google.com
4312855Sgabeblack@google.comstruct M: sc_module
4412855Sgabeblack@google.com{
4512855Sgabeblack@google.com  sc_inout<bool> port;
4612855Sgabeblack@google.com
4712855Sgabeblack@google.com  sc_time delay;
4812855Sgabeblack@google.com  sc_signal<int>                  one_sig;
4912855Sgabeblack@google.com  sc_signal<int, SC_MANY_WRITERS> many_sig;
5012855Sgabeblack@google.com
5112855Sgabeblack@google.com  bool first_run;
5212855Sgabeblack@google.com  int g0, g1, g2, g3;
5312855Sgabeblack@google.com
5412855Sgabeblack@google.com  M(sc_module_name _name, sc_time _delay)
5512855Sgabeblack@google.com  : port("port")
5612855Sgabeblack@google.com  , delay(_delay)
5712855Sgabeblack@google.com  , first_run(true)
5812855Sgabeblack@google.com  {
5912855Sgabeblack@google.com    sc_assert( one_sig.get_writer_policy() == SC_ONE_WRITER );
6012855Sgabeblack@google.com    sc_assert( many_sig.get_writer_policy() == SC_MANY_WRITERS );
6112855Sgabeblack@google.com
6212855Sgabeblack@google.com    SC_THREAD(T);
6312855Sgabeblack@google.com    SC_METHOD(method_process_1);
6412855Sgabeblack@google.com    SC_METHOD(method_process_2);
6512855Sgabeblack@google.com
6612855Sgabeblack@google.com    one_sig.write(-1);
6712855Sgabeblack@google.com    many_sig.write(-1);
6812855Sgabeblack@google.com
6912855Sgabeblack@google.com    g0 = g1 = g2 = g3 = 0;
7012855Sgabeblack@google.com  }
7112855Sgabeblack@google.com
7212855Sgabeblack@google.com  void end_of_elaboration()
7312855Sgabeblack@google.com  {
7412855Sgabeblack@google.com    sc_assert( port->get_writer_policy() == SC_MANY_WRITERS );
7512855Sgabeblack@google.com    one_sig.write(1);
7612855Sgabeblack@google.com    many_sig.write(1);
7712855Sgabeblack@google.com    g0 = 1;
7812855Sgabeblack@google.com  }
7912855Sgabeblack@google.com
8012855Sgabeblack@google.com  void start_of_simulation()
8112855Sgabeblack@google.com  {
8212855Sgabeblack@google.com    one_sig.write(2);
8312855Sgabeblack@google.com    many_sig.write(2);
8412855Sgabeblack@google.com    g1 = 1;
8512855Sgabeblack@google.com  }
8612855Sgabeblack@google.com
8712855Sgabeblack@google.com  void T()
8812855Sgabeblack@google.com  {
8912855Sgabeblack@google.com    wait(delay);
9012855Sgabeblack@google.com    port.write(true);
9112855Sgabeblack@google.com    g2 = 1;
9212855Sgabeblack@google.com  }
9312855Sgabeblack@google.com
9412855Sgabeblack@google.com  void method_process_1()
9512855Sgabeblack@google.com  {
9612855Sgabeblack@google.com    one_sig.write(3);
9712855Sgabeblack@google.com    many_sig.write(3);
9812855Sgabeblack@google.com  }
9912855Sgabeblack@google.com
10012855Sgabeblack@google.com  void method_process_2()
10112855Sgabeblack@google.com  {
10212855Sgabeblack@google.com    if (first_run)
10312855Sgabeblack@google.com    {
10412855Sgabeblack@google.com      first_run = false;
10512855Sgabeblack@google.com      next_trigger(SC_ZERO_TIME);
10612855Sgabeblack@google.com    }
10712855Sgabeblack@google.com    else
10812855Sgabeblack@google.com    {
10912855Sgabeblack@google.com      try {
11012855Sgabeblack@google.com        one_sig = 4;
11112855Sgabeblack@google.com      }
11212855Sgabeblack@google.com      catch (const std::exception& e) {
11312855Sgabeblack@google.com        g3 = 1;
11412855Sgabeblack@google.com      }
11512855Sgabeblack@google.com      many_sig.write(4);
11612855Sgabeblack@google.com    }
11712855Sgabeblack@google.com  }
11812855Sgabeblack@google.com
11912855Sgabeblack@google.com  SC_HAS_PROCESS(M);
12012855Sgabeblack@google.com};
12112855Sgabeblack@google.com
12212855Sgabeblack@google.comstruct Top: sc_module
12312855Sgabeblack@google.com{
12412855Sgabeblack@google.com  M *m1;
12512855Sgabeblack@google.com  M *m2;
12612855Sgabeblack@google.com
12712855Sgabeblack@google.com  sc_signal<bool,SC_MANY_WRITERS> many_sig_1;
12812855Sgabeblack@google.com  sc_signal<int,SC_MANY_WRITERS>  many_sig_2;
12912855Sgabeblack@google.com  sc_signal<int,SC_ONE_WRITER>    one_sig_1;
13012855Sgabeblack@google.com  sc_signal<int>                  one_sig_2;
13112855Sgabeblack@google.com
13212855Sgabeblack@google.com  sc_buffer<sc_logic, SC_MANY_WRITERS> buffy;
13312855Sgabeblack@google.com
13412855Sgabeblack@google.com  sc_signal_resolved              resolved;
13512855Sgabeblack@google.com  sc_signal_rv<2>                 rv;
13612855Sgabeblack@google.com
13712855Sgabeblack@google.com  Top(sc_module_name _name)
13812855Sgabeblack@google.com  : many_sig_1("many_sig_1")
13912855Sgabeblack@google.com  , many_sig_2("many_sig_2")
14012855Sgabeblack@google.com  , one_sig_1("one_sig_1")
14112855Sgabeblack@google.com  , buffy("buffy")
14212855Sgabeblack@google.com  , resolved("resolved")
14312855Sgabeblack@google.com  , rv("rv")
14412855Sgabeblack@google.com  {
14512855Sgabeblack@google.com    m1 = new M("m1", sc_time(1, SC_PS));
14612855Sgabeblack@google.com    m2 = new M("m2", sc_time(2, SC_PS));
14712855Sgabeblack@google.com
14812855Sgabeblack@google.com    m1->port.bind(many_sig_1);
14912855Sgabeblack@google.com    m2->port.bind(many_sig_1);
15012855Sgabeblack@google.com
15112855Sgabeblack@google.com    SC_THREAD(T1);
15212855Sgabeblack@google.com    SC_THREAD(T2);
15312855Sgabeblack@google.com    sc_spawn(sc_bind(&Top::T3, this));
15412855Sgabeblack@google.com
15512855Sgabeblack@google.com    sc_assert( many_sig_1.get_writer_policy() == SC_MANY_WRITERS );
15612855Sgabeblack@google.com    sc_assert( many_sig_2.get_writer_policy() == SC_MANY_WRITERS );
15712855Sgabeblack@google.com    sc_assert( one_sig_1 .get_writer_policy() == SC_ONE_WRITER );
15812855Sgabeblack@google.com    sc_assert( one_sig_2 .get_writer_policy() == SC_ONE_WRITER );
15912855Sgabeblack@google.com    sc_assert( buffy     .get_writer_policy() == SC_MANY_WRITERS );
16012855Sgabeblack@google.com    sc_assert( resolved  .get_writer_policy() == SC_MANY_WRITERS );
16112855Sgabeblack@google.com    sc_assert( rv        .get_writer_policy() == SC_MANY_WRITERS );
16212855Sgabeblack@google.com
16312855Sgabeblack@google.com    one_sig_1 = 0;
16412855Sgabeblack@google.com    buffy = SC_LOGIC_X;
16512855Sgabeblack@google.com    resolved = SC_LOGIC_Z;
16612855Sgabeblack@google.com    rv = sc_lv<2>("ZZ");
16712855Sgabeblack@google.com
16812855Sgabeblack@google.com    // Writes outside of a process should not count as manyple writers
16912855Sgabeblack@google.com    many_sig_1.write(true);
17012855Sgabeblack@google.com    many_sig_2.write(0);
17112855Sgabeblack@google.com    one_sig_1.write(0);
17212855Sgabeblack@google.com    one_sig_2.write(0);
17312855Sgabeblack@google.com    buffy.write(SC_LOGIC_0);
17412855Sgabeblack@google.com
17512855Sgabeblack@google.com    f0 = f1 = f2 = f3 = f4 = f5 = 0;
17612855Sgabeblack@google.com
17712855Sgabeblack@google.com  }
17812855Sgabeblack@google.com
17912855Sgabeblack@google.com  int f0, f1, f2, f3, f4, f5;
18012855Sgabeblack@google.com
18112855Sgabeblack@google.com  void T1()
18212855Sgabeblack@google.com  {
18312855Sgabeblack@google.com    resolved = SC_LOGIC_0;
18412855Sgabeblack@google.com    rv = sc_lv<2>("01");
18512855Sgabeblack@google.com
18612855Sgabeblack@google.com    // Attempt to write SC_ONE_WRITER signal from >1 process should fail
18712855Sgabeblack@google.com    try {
18812855Sgabeblack@google.com      one_sig_1 = 1;
18912855Sgabeblack@google.com    }
19012855Sgabeblack@google.com    catch (const std::exception& e) {
19112855Sgabeblack@google.com      f3 = 1;
19212855Sgabeblack@google.com    }
19312855Sgabeblack@google.com
19412855Sgabeblack@google.com    try {
19512855Sgabeblack@google.com      one_sig_2 = 1;
19612855Sgabeblack@google.com    }
19712855Sgabeblack@google.com    catch (const std::exception& e) {
19812855Sgabeblack@google.com      f4 = 1;
19912855Sgabeblack@google.com    }
20012855Sgabeblack@google.com    wait(1, SC_PS);
20112855Sgabeblack@google.com
20212855Sgabeblack@google.com    // Attempt to write SC_MANY_WRITER signal from >1 process IN SAME DELTA should fail
20312855Sgabeblack@google.com    try {
20412855Sgabeblack@google.com      many_sig_2.write(3);
20512855Sgabeblack@google.com    }
20612855Sgabeblack@google.com    catch (const std::exception& e) {
20712855Sgabeblack@google.com      f5 = 1;
20812855Sgabeblack@google.com    }
20912855Sgabeblack@google.com    wait(3, SC_PS);
21012855Sgabeblack@google.com
21112855Sgabeblack@google.com    many_sig_2.write(6);
21212855Sgabeblack@google.com    buffy = SC_LOGIC_0;
21312855Sgabeblack@google.com
21412855Sgabeblack@google.com    wait(many_sig_2.default_event());
21512855Sgabeblack@google.com    f0 = 1;
21612855Sgabeblack@google.com  }
21712855Sgabeblack@google.com
21812855Sgabeblack@google.com  void T2()
21912855Sgabeblack@google.com  {
22012855Sgabeblack@google.com    resolved = SC_LOGIC_1;
22112855Sgabeblack@google.com    rv = sc_lv<2>("10");
22212855Sgabeblack@google.com
22312855Sgabeblack@google.com    try {
22412855Sgabeblack@google.com      one_sig_1 = 2;
22512855Sgabeblack@google.com    }
22612855Sgabeblack@google.com    catch (const std::exception& e) {
22712855Sgabeblack@google.com      f3 = 1;
22812855Sgabeblack@google.com    }
22912855Sgabeblack@google.com
23012855Sgabeblack@google.com    try {
23112855Sgabeblack@google.com      one_sig_2 = 2;
23212855Sgabeblack@google.com    }
23312855Sgabeblack@google.com    catch (const std::exception& e) {
23412855Sgabeblack@google.com      f4 = 1;
23512855Sgabeblack@google.com    }
23612855Sgabeblack@google.com    wait(1, SC_PS);
23712855Sgabeblack@google.com
23812855Sgabeblack@google.com    try {
23912855Sgabeblack@google.com      many_sig_2.write(4);
24012855Sgabeblack@google.com    }
24112855Sgabeblack@google.com    catch (const std::exception& e) {
24212855Sgabeblack@google.com      f5 = 1;
24312855Sgabeblack@google.com    }
24412855Sgabeblack@google.com    wait(4, SC_PS);
24512855Sgabeblack@google.com
24612855Sgabeblack@google.com    many_sig_2.write(7);
24712855Sgabeblack@google.com    buffy = SC_LOGIC_1;
24812855Sgabeblack@google.com
24912855Sgabeblack@google.com    wait(many_sig_2.default_event());
25012855Sgabeblack@google.com    f1 = 1;
25112855Sgabeblack@google.com  }
25212855Sgabeblack@google.com
25312855Sgabeblack@google.com  void T3()
25412855Sgabeblack@google.com  {
25512855Sgabeblack@google.com    resolved = SC_LOGIC_Z;
25612855Sgabeblack@google.com    rv = sc_lv<2>("ZZ");
25712855Sgabeblack@google.com
25812855Sgabeblack@google.com    try {
25912855Sgabeblack@google.com      one_sig_1 = 3;
26012855Sgabeblack@google.com    }
26112855Sgabeblack@google.com    catch (const std::exception& e) {
26212855Sgabeblack@google.com      f3 = 1;
26312855Sgabeblack@google.com    }
26412855Sgabeblack@google.com
26512855Sgabeblack@google.com    try {
26612855Sgabeblack@google.com      one_sig_2 = 3;
26712855Sgabeblack@google.com    }
26812855Sgabeblack@google.com    catch (const std::exception& e) {
26912855Sgabeblack@google.com      f4 = 1;
27012855Sgabeblack@google.com    }
27112855Sgabeblack@google.com    wait(1, SC_PS);
27212855Sgabeblack@google.com
27312855Sgabeblack@google.com    try {
27412855Sgabeblack@google.com      many_sig_2.write(5);
27512855Sgabeblack@google.com    }
27612855Sgabeblack@google.com    catch (const std::exception& e) {
27712855Sgabeblack@google.com      f5 = 1;
27812855Sgabeblack@google.com    }
27912855Sgabeblack@google.com    wait(5, SC_PS);
28012855Sgabeblack@google.com
28112855Sgabeblack@google.com    many_sig_2.write(8);
28212855Sgabeblack@google.com    buffy = SC_LOGIC_0;
28312855Sgabeblack@google.com
28412855Sgabeblack@google.com    wait(many_sig_2.default_event());
28512855Sgabeblack@google.com    f2 = 1;
28612855Sgabeblack@google.com
28712855Sgabeblack@google.com    sc_assert( resolved.read() == SC_LOGIC_X );
28812855Sgabeblack@google.com    sc_assert( rv.read() == sc_lv<2>("XX") );
28912855Sgabeblack@google.com    sc_assert( many_sig_2.read() == 8 );
29012855Sgabeblack@google.com    sc_assert( buffy.read() == SC_LOGIC_0 );
29112855Sgabeblack@google.com  }
29212855Sgabeblack@google.com
29312855Sgabeblack@google.com  SC_HAS_PROCESS(Top);
29412855Sgabeblack@google.com};
29512855Sgabeblack@google.com
29612855Sgabeblack@google.com
29712855Sgabeblack@google.comint sc_main(int argc, char* argv[])
29812855Sgabeblack@google.com{
29912855Sgabeblack@google.com  Top top("top");
30012855Sgabeblack@google.com  sc_start();
30112855Sgabeblack@google.com
30212855Sgabeblack@google.com  sc_assert( top.f0 );
30312855Sgabeblack@google.com  sc_assert( top.f1 );
30412855Sgabeblack@google.com  sc_assert( top.f2 );
30512855Sgabeblack@google.com  sc_assert( top.f3 );
30612855Sgabeblack@google.com  sc_assert( top.f4 );
30712855Sgabeblack@google.com  sc_assert( top.f5 );
30812855Sgabeblack@google.com
30912855Sgabeblack@google.com  sc_assert( top.m1->g0 );
31012855Sgabeblack@google.com  sc_assert( top.m2->g0 );
31112855Sgabeblack@google.com  sc_assert( top.m1->g1 );
31212855Sgabeblack@google.com  sc_assert( top.m2->g1 );
31312855Sgabeblack@google.com  sc_assert( top.m1->g2 );
31412855Sgabeblack@google.com  sc_assert( top.m2->g2 );
31512855Sgabeblack@google.com  sc_assert( top.m1->g3 );
31612855Sgabeblack@google.com  sc_assert( top.m2->g3 );
31712855Sgabeblack@google.com
31812855Sgabeblack@google.com  cout << endl << "Success" << endl;
31912855Sgabeblack@google.com  return 0;
32012855Sgabeblack@google.com}
32112855Sgabeblack@google.com
322