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// named_events.cpp -- test for
21//
22//  Original Author: John Aynsley, Doulos, Inc.
23//
24// MODIFICATION LOG - modifiers, enter your name, affiliation, date and
25//
26// $Log: named_events.cpp,v $
27// Revision 1.2  2011/05/08 19:18:46  acg
28//  Andy Goodrich: remove extraneous + prefixes from git diff.
29//
30
31// Hierarchically named events
32
33#define SC_INCLUDE_DYNAMIC_PROCESSES
34
35#include <systemc>
36
37using namespace sc_core;
38using std::cout;
39using std::endl;
40
41struct Object: sc_object
42{
43  Object(const char* n)
44  : sc_object(n)
45  , ev((std::string(n) + "_ev").c_str()) {}
46
47  sc_event ev; // Parent of event is containing module or process instance
48};
49
50struct Top: sc_module
51{
52  sc_event ev1, ev2;
53  Object *obj;
54  sc_signal<int> sig; // Kernel events should not be hierarchically named
55  sc_fifo<int> fifo;  // Kernel events should not be hierarchically named
56  sc_semaphore sema;  // Kernel events should not be hierarchically named
57  sc_mutex mut;       // Kernel events should not be hierarchically named
58
59  bool T_done;
60
61  Top(sc_module_name _name)
62  : ev2("ev2")
63  , sig("sig")
64  , sema(1)
65  , T_done(false)
66  {
67
68    sc_assert( ev1.in_hierarchy() );
69    sc_assert( ev1.get_parent_object() == this );
70    sc_assert( std::string(ev1.name()).substr(0,9) == "top.event" );
71    sc_assert( std::string(ev1.basename()).substr(0,5) == "event" );
72
73    sc_assert( ev2.in_hierarchy() );
74    sc_assert( ev2.get_parent_object() == this );
75    sc_assert( std::string(ev2.name()) == "top.ev2" );
76    sc_assert( std::string(ev2.basename()) == "ev2" );
77
78    sc_assert( sc_find_event("top.ev2") == &ev2 );
79
80    std::vector<sc_event*> vec = this->get_child_events();
81    sc_assert( vec.size() == 2 );
82
83    sc_process_handle dummy_handle;
84    sc_assert( dummy_handle.get_child_events().size() == 0 );
85    sc_assert( std::string(dummy_handle.name()) == "");
86
87    obj = new Object("obj");
88    vec = obj->get_child_events(); // Should return empty vector
89    sc_assert( vec.size() == 0 );
90
91    vec = this->get_child_events();
92    sc_assert( vec.size() == 3 );
93
94    sc_assert( sc_find_event("top.obj_ev") == &obj->ev );
95
96    Object obj2("ev2");  // Name clash
97
98    vec = this->get_child_events();
99    sc_assert( vec.size() == 4 );
100
101    SC_THREAD(T);
102  }
103
104  void T()
105  {
106    sc_event ev1("local1");
107    sc_event ev2("local2");
108
109    sc_process_handle handle = sc_get_current_process_handle();
110    std::string proc_name = handle.name();
111
112    sc_assert( ev1.in_hierarchy() );
113    sc_assert( ev1.get_parent_object() == handle.get_process_object() );
114    sc_assert( std::string(ev1.name()) == proc_name + ".local1" );
115    sc_assert( std::string(ev1.basename()) == "local1" );
116    sc_assert( sc_hierarchical_name_exists(ev1.name()) );
117
118    sc_assert( ev2.in_hierarchy() );
119    sc_assert( ev2.get_parent_object() == handle.get_process_object() );
120    sc_assert( std::string(ev2.name()) == proc_name + ".local2" );
121    sc_assert( std::string(ev2.basename()) == "local2" );
122    sc_assert( sc_hierarchical_name_exists(ev2.name()) );
123
124    std::vector<sc_event*> vec = handle.get_child_events();
125    sc_assert( vec.size() == 2 );
126    sc_assert( vec[0] == &ev1 );
127    sc_assert( vec[1] == &ev2 );
128
129    sc_assert( sc_find_event(ev1.name()) == &ev1 );
130    sc_assert( sc_find_event(ev2.name()) == &ev2 );
131
132    T_done = true;
133  }
134
135  SC_HAS_PROCESS(Top);
136};
137
138int sc_main(int argc, char* argv[])
139{
140  std::vector<sc_object*> vec_o;
141  vec_o = sc_get_top_level_objects();
142  sc_assert( vec_o.size() == 0 );
143
144  std::vector<sc_event*> vec_e;
145  vec_e = sc_get_top_level_events();
146  sc_assert( vec_e.size() == 0 );
147
148  sc_event ev("foo");
149
150  sc_assert( ev.in_hierarchy() );
151  sc_assert( ev.get_parent_object() == 0 );
152  sc_assert( std::string(ev.name()) == "foo" );
153  sc_assert( std::string(ev.basename()) == "foo" );
154  sc_assert( sc_hierarchical_name_exists("foo") );
155
156  vec_o = sc_get_top_level_objects();
157  sc_assert( vec_o.size() == 0 );
158  vec_e = sc_get_top_level_events();
159  sc_assert( vec_e.size() == 1 );
160  sc_assert( vec_e[0] == &ev );
161  sc_assert( std::string(vec_e[0]->name()) == "foo" );
162
163  sc_assert( sc_find_event("foo") == &ev );
164
165  Top top("top");
166  sc_assert( sc_hierarchical_name_exists("top") );
167  sc_assert( sc_hierarchical_name_exists("top.ev2") );
168  sc_assert( sc_hierarchical_name_exists("top.sig") );
169  sc_assert( sc_hierarchical_name_exists("top.obj") );
170  sc_assert( sc_hierarchical_name_exists("top.obj_ev") );
171  sc_assert( !sc_hierarchical_name_exists("woowoo") );
172  sc_assert( !sc_hierarchical_name_exists("top.woowoo") );
173
174  sc_event ev2;
175
176  sc_assert( ev2.in_hierarchy() );
177  sc_assert( ev2.get_parent_object() == 0 );
178  sc_assert( std::string(ev2.name()).substr(0,5) == "event" );
179  sc_assert( std::string(ev2.basename()).substr(0,5) == "event" );
180  sc_assert( sc_hierarchical_name_exists(ev2.name()) );
181
182  vec_e = sc_get_top_level_events();
183  sc_assert( vec_e.size() == 2);
184
185  sc_event ev3("top"); // Name clash
186  vec_e = sc_get_top_level_events();
187  sc_assert( vec_e.size() == 3);
188  vec_o = sc_get_top_level_objects();
189  sc_assert( vec_o.size() == 1 );
190
191  sc_assert( sc_find_event(ev3.name()) == &ev3 );
192
193  sc_signal<bool> sig; // Kernel events should not be hierarchically named
194  vec_e = sc_get_top_level_events();
195  sc_assert( vec_e.size() == 3 );
196  vec_o = sc_get_top_level_objects();
197  sc_assert( vec_o.size() == 2 );
198
199  sc_start();
200
201  sc_assert( top.T_done );
202
203  cout << endl << "There should be two name clashes reported above" << endl;
204  cout << endl << "Success" << endl;
205  return 0;
206}
207
208