event_triggered.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  event_triggered.cpp -- test sc_event::triggered
23
24  Original Author: Philipp A. Hartmann, Intel Corporation - 2017-08-06
25
26 *****************************************************************************/
27
28/*****************************************************************************
29
30  MODIFICATION LOG - modifiers, enter your name, affiliation, date and
31  changes you are making here.
32
33      Name, Affiliation, Date:
34  Description of Modification:
35
36 *****************************************************************************/
37
38#define SC_INCLUDE_DYNAMIC_PROCESSES
39#include <systemc>
40#include <iomanip>
41
42#ifdef BENCHMARK
43  static const sc_dt::uint64 num_events     = 128;
44  static const sc_dt::uint64 num_triggers   = 4;
45  static const sc_dt::uint64 num_iterations = 10000000;
46# define CHECK(expr) ((void)0)
47#else
48  static const sc_dt::uint64 num_events     = 16;
49  static const sc_dt::uint64 num_triggers   = 4;
50  static const sc_dt::uint64 num_iterations = 4;
51# define CHECK(expr) sc_assert(expr)
52#endif
53
54#ifndef UINT64_C
55#if defined(_WIN32) && !defined(__MINGW32__)
56# define UINT64_C(v) v ## ui64
57#else
58# define UINT64_C(v) v ## ULL
59#endif
60#endif // UINT64_C
61
62using namespace sc_core;
63
64SC_MODULE( module )
65{
66  sc_vector<sc_event> events;
67  sc_event            event_return;
68
69  SC_CTOR( module )
70    : events("ev", num_events)
71    , m_rng_state()
72  {
73    SC_THREAD(driver);
74
75    SC_THREAD(consumer_dynamic);
76    SC_THREAD(consumer_static); // odd events only
77      for(unsigned i = 1; i<events.size(); i+=2)
78        sensitive << events[i];
79  }
80private:
81
82  void driver()
83  {
84    CHECK( !event_return.triggered() );
85    wait(1, SC_NS);
86    CHECK( !event_return.triggered() );
87
88    random_notify();
89    random_notify();
90    wait(event_return);
91
92    random_notify(SC_ZERO_TIME);
93    random_notify(SC_ZERO_TIME);
94    wait(event_return);
95
96    random_notify(sc_time(1, SC_NS));
97    random_notify(sc_time(1, SC_NS));
98    wait(event_return);
99    wait(2, SC_NS);
100    CHECK( !event_return.triggered() );
101
102    for(unsigned i = 0; i < num_triggers; ++i)
103      random_notify();
104    wait(event_return);
105    CHECK( event_return.triggered() );
106
107    for(unsigned i = 0; i < num_triggers; ++i)
108      random_notify(SC_ZERO_TIME);
109    wait(event_return);
110    CHECK( event_return.triggered() );
111
112    for(unsigned iter = 0; iter < num_iterations; ++iter) {
113      for(unsigned i = 0; i < num_triggers; ++i) {
114        random_notify(sc_time(1, SC_NS));
115      }
116      wait(event_return);
117    }
118    CHECK( event_return.triggered() );
119  }
120
121  void consumer_dynamic()
122  {
123    sc_event_or_list events_or; // even events only
124    for(unsigned i = 0; i < events.size(); i+=2)
125      events_or |= events[i];
126
127    while(true) {
128      wait(events_or);
129      print_triggered();
130      event_return.notify();
131    }
132  }
133
134  void consumer_static()
135  {
136    while(true) {
137      wait();
138      print_triggered();
139      event_return.notify();
140    }
141  }
142
143  void print_triggered()
144  {
145#ifndef BENCHMARK
146    using namespace std;
147    cout
148      << setw(6) << sc_time_stamp()
149      << " (" << sc_delta_count() << "): "
150      << sc_get_current_process_handle().name() << ": ";
151    for(unsigned i =0; i< events.size(); ++i)
152      if (events[i].triggered())
153        std::cout << events[i].basename() << " ";
154    cout << endl;
155#endif
156  }
157
158  void random_notify()
159    { random_notify(SC_ZERO_TIME, true); }
160
161  void random_notify(const sc_time& t, bool immediate = false)
162  {
163    sc_event& ev = events[ lcg_rng() % num_events ];
164#ifndef BENCHMARK
165    using namespace std;
166    cout
167      << setw(6) << sc_time_stamp()
168      << " (" << sc_delta_count() << "): "
169      << sc_get_current_process_handle().name() << ": "
170      << ev.basename();
171    if (immediate) {
172      cout << ".notify()";
173    } else {
174      cout << ".notify(" << t << ")";
175    }
176    cout << endl;
177#endif
178    if (immediate) {
179      ev.notify();
180    } else {
181      ev.notify(t);
182    }
183  }
184
185  unsigned lcg_rng()
186  {
187    m_rng_state = UINT64_C(2862933555777941757) * m_rng_state
188                + UINT64_C(3037000493);
189    return ( m_rng_state >> 48 );
190  }
191
192  sc_dt::uint64 m_rng_state;
193};
194
195
196int
197sc_main( int, char*[] )
198{
199    module m("m");
200    sc_start();
201    sc_stop();
202    return 0;
203}
204