sc_writer_policy.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// sc_writer_policy.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: sc_writer_policy.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// sc_writer_policy template argument of class sc_signal
32
33#define SC_INCLUDE_DYNAMIC_PROCESSES
34#include <systemc>
35
36using namespace sc_core;
37using namespace sc_dt;
38using std::cout;
39using std::endl;
40using std::string;
41
42
43struct M: sc_module
44{
45  sc_inout<bool> port;
46
47  sc_time delay;
48  sc_signal<int>                  one_sig;
49  sc_signal<int, SC_MANY_WRITERS> many_sig;
50
51  bool first_run;
52  int g0, g1, g2, g3;
53
54  M(sc_module_name _name, sc_time _delay)
55  : port("port")
56  , delay(_delay)
57  , first_run(true)
58  {
59    sc_assert( one_sig.get_writer_policy() == SC_ONE_WRITER );
60    sc_assert( many_sig.get_writer_policy() == SC_MANY_WRITERS );
61
62    SC_THREAD(T);
63    SC_METHOD(method_process_1);
64    SC_METHOD(method_process_2);
65
66    one_sig.write(-1);
67    many_sig.write(-1);
68
69    g0 = g1 = g2 = g3 = 0;
70  }
71
72  void end_of_elaboration()
73  {
74    sc_assert( port->get_writer_policy() == SC_MANY_WRITERS );
75    one_sig.write(1);
76    many_sig.write(1);
77    g0 = 1;
78  }
79
80  void start_of_simulation()
81  {
82    one_sig.write(2);
83    many_sig.write(2);
84    g1 = 1;
85  }
86
87  void T()
88  {
89    wait(delay);
90    port.write(true);
91    g2 = 1;
92  }
93
94  void method_process_1()
95  {
96    one_sig.write(3);
97    many_sig.write(3);
98  }
99
100  void method_process_2()
101  {
102    if (first_run)
103    {
104      first_run = false;
105      next_trigger(SC_ZERO_TIME);
106    }
107    else
108    {
109      try {
110        one_sig = 4;
111      }
112      catch (const std::exception& e) {
113        g3 = 1;
114      }
115      many_sig.write(4);
116    }
117  }
118
119  SC_HAS_PROCESS(M);
120};
121
122struct Top: sc_module
123{
124  M *m1;
125  M *m2;
126
127  sc_signal<bool,SC_MANY_WRITERS> many_sig_1;
128  sc_signal<int,SC_MANY_WRITERS>  many_sig_2;
129  sc_signal<int,SC_ONE_WRITER>    one_sig_1;
130  sc_signal<int>                  one_sig_2;
131
132  sc_buffer<sc_logic, SC_MANY_WRITERS> buffy;
133
134  sc_signal_resolved              resolved;
135  sc_signal_rv<2>                 rv;
136
137  Top(sc_module_name _name)
138  : many_sig_1("many_sig_1")
139  , many_sig_2("many_sig_2")
140  , one_sig_1("one_sig_1")
141  , buffy("buffy")
142  , resolved("resolved")
143  , rv("rv")
144  {
145    m1 = new M("m1", sc_time(1, SC_PS));
146    m2 = new M("m2", sc_time(2, SC_PS));
147
148    m1->port.bind(many_sig_1);
149    m2->port.bind(many_sig_1);
150
151    SC_THREAD(T1);
152    SC_THREAD(T2);
153    sc_spawn(sc_bind(&Top::T3, this));
154
155    sc_assert( many_sig_1.get_writer_policy() == SC_MANY_WRITERS );
156    sc_assert( many_sig_2.get_writer_policy() == SC_MANY_WRITERS );
157    sc_assert( one_sig_1 .get_writer_policy() == SC_ONE_WRITER );
158    sc_assert( one_sig_2 .get_writer_policy() == SC_ONE_WRITER );
159    sc_assert( buffy     .get_writer_policy() == SC_MANY_WRITERS );
160    sc_assert( resolved  .get_writer_policy() == SC_MANY_WRITERS );
161    sc_assert( rv        .get_writer_policy() == SC_MANY_WRITERS );
162
163    one_sig_1 = 0;
164    buffy = SC_LOGIC_X;
165    resolved = SC_LOGIC_Z;
166    rv = sc_lv<2>("ZZ");
167
168    // Writes outside of a process should not count as manyple writers
169    many_sig_1.write(true);
170    many_sig_2.write(0);
171    one_sig_1.write(0);
172    one_sig_2.write(0);
173    buffy.write(SC_LOGIC_0);
174
175    f0 = f1 = f2 = f3 = f4 = f5 = 0;
176
177  }
178
179  int f0, f1, f2, f3, f4, f5;
180
181  void T1()
182  {
183    resolved = SC_LOGIC_0;
184    rv = sc_lv<2>("01");
185
186    // Attempt to write SC_ONE_WRITER signal from >1 process should fail
187    try {
188      one_sig_1 = 1;
189    }
190    catch (const std::exception& e) {
191      f3 = 1;
192    }
193
194    try {
195      one_sig_2 = 1;
196    }
197    catch (const std::exception& e) {
198      f4 = 1;
199    }
200    wait(1, SC_PS);
201
202    // Attempt to write SC_MANY_WRITER signal from >1 process IN SAME DELTA should fail
203    try {
204      many_sig_2.write(3);
205    }
206    catch (const std::exception& e) {
207      f5 = 1;
208    }
209    wait(3, SC_PS);
210
211    many_sig_2.write(6);
212    buffy = SC_LOGIC_0;
213
214    wait(many_sig_2.default_event());
215    f0 = 1;
216  }
217
218  void T2()
219  {
220    resolved = SC_LOGIC_1;
221    rv = sc_lv<2>("10");
222
223    try {
224      one_sig_1 = 2;
225    }
226    catch (const std::exception& e) {
227      f3 = 1;
228    }
229
230    try {
231      one_sig_2 = 2;
232    }
233    catch (const std::exception& e) {
234      f4 = 1;
235    }
236    wait(1, SC_PS);
237
238    try {
239      many_sig_2.write(4);
240    }
241    catch (const std::exception& e) {
242      f5 = 1;
243    }
244    wait(4, SC_PS);
245
246    many_sig_2.write(7);
247    buffy = SC_LOGIC_1;
248
249    wait(many_sig_2.default_event());
250    f1 = 1;
251  }
252
253  void T3()
254  {
255    resolved = SC_LOGIC_Z;
256    rv = sc_lv<2>("ZZ");
257
258    try {
259      one_sig_1 = 3;
260    }
261    catch (const std::exception& e) {
262      f3 = 1;
263    }
264
265    try {
266      one_sig_2 = 3;
267    }
268    catch (const std::exception& e) {
269      f4 = 1;
270    }
271    wait(1, SC_PS);
272
273    try {
274      many_sig_2.write(5);
275    }
276    catch (const std::exception& e) {
277      f5 = 1;
278    }
279    wait(5, SC_PS);
280
281    many_sig_2.write(8);
282    buffy = SC_LOGIC_0;
283
284    wait(many_sig_2.default_event());
285    f2 = 1;
286
287    sc_assert( resolved.read() == SC_LOGIC_X );
288    sc_assert( rv.read() == sc_lv<2>("XX") );
289    sc_assert( many_sig_2.read() == 8 );
290    sc_assert( buffy.read() == SC_LOGIC_0 );
291  }
292
293  SC_HAS_PROCESS(Top);
294};
295
296
297int sc_main(int argc, char* argv[])
298{
299  Top top("top");
300  sc_start();
301
302  sc_assert( top.f0 );
303  sc_assert( top.f1 );
304  sc_assert( top.f2 );
305  sc_assert( top.f3 );
306  sc_assert( top.f4 );
307  sc_assert( top.f5 );
308
309  sc_assert( top.m1->g0 );
310  sc_assert( top.m2->g0 );
311  sc_assert( top.m1->g1 );
312  sc_assert( top.m2->g1 );
313  sc_assert( top.m1->g2 );
314  sc_assert( top.m2->g2 );
315  sc_assert( top.m1->g3 );
316  sc_assert( top.m2->g3 );
317
318  cout << endl << "Success" << endl;
319  return 0;
320}
321
322