sc_module.hh revision 13091
18745Sgblack@eecs.umich.edu/*
28745Sgblack@eecs.umich.edu * Copyright 2018 Google, Inc.
38745Sgblack@eecs.umich.edu *
48745Sgblack@eecs.umich.edu * Redistribution and use in source and binary forms, with or without
58745Sgblack@eecs.umich.edu * modification, are permitted provided that the following conditions are
68745Sgblack@eecs.umich.edu * met: redistributions of source code must retain the above copyright
78745Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer;
88745Sgblack@eecs.umich.edu * redistributions in binary form must reproduce the above copyright
98745Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer in the
108745Sgblack@eecs.umich.edu * documentation and/or other materials provided with the distribution;
118745Sgblack@eecs.umich.edu * neither the name of the copyright holders nor the names of its
128745Sgblack@eecs.umich.edu * contributors may be used to endorse or promote products derived from
138745Sgblack@eecs.umich.edu * this software without specific prior written permission.
148745Sgblack@eecs.umich.edu *
158745Sgblack@eecs.umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
168745Sgblack@eecs.umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
178745Sgblack@eecs.umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
188745Sgblack@eecs.umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
198745Sgblack@eecs.umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
208745Sgblack@eecs.umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
218745Sgblack@eecs.umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
228745Sgblack@eecs.umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
238745Sgblack@eecs.umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
248745Sgblack@eecs.umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
258745Sgblack@eecs.umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
268745Sgblack@eecs.umich.edu *
278745Sgblack@eecs.umich.edu * Authors: Gabe Black
288745Sgblack@eecs.umich.edu */
298745Sgblack@eecs.umich.edu
308745Sgblack@eecs.umich.edu#ifndef __SYSTEMC_CORE_EXT_SC_MODULE_HH__
318745Sgblack@eecs.umich.edu#define __SYSTEMC_CORE_EXT_SC_MODULE_HH__
328745Sgblack@eecs.umich.edu
338745Sgblack@eecs.umich.edu#include <vector>
3412334Sgabeblack@google.com
358745Sgblack@eecs.umich.edu#include "sc_object.hh"
368745Sgblack@eecs.umich.edu#include "sc_process_handle.hh"
378745Sgblack@eecs.umich.edu#include "sc_sensitive.hh"
3811800Sbrandon.potter@amd.com#include "sc_time.hh"
398745Sgblack@eecs.umich.edu
408745Sgblack@eecs.umich.edunamespace sc_dt
418745Sgblack@eecs.umich.edu{
428745Sgblack@eecs.umich.edu
438745Sgblack@eecs.umich.educlass sc_logic;
448745Sgblack@eecs.umich.edu
458745Sgblack@eecs.umich.edu} // namespace sc_dt
468745Sgblack@eecs.umich.edu
478745Sgblack@eecs.umich.edunamespace sc_gem5
488745Sgblack@eecs.umich.edu{
498745Sgblack@eecs.umich.edu
508745Sgblack@eecs.umich.educlass Kernel;
518745Sgblack@eecs.umich.educlass Module;
528745Sgblack@eecs.umich.educlass Process;
538745Sgblack@eecs.umich.edustruct ProcessFuncWrapper;
548745Sgblack@eecs.umich.edu
558745Sgblack@eecs.umich.eduProcess *newMethodProcess(const char *name, ProcessFuncWrapper *func);
568745Sgblack@eecs.umich.eduProcess *newThreadProcess(const char *name, ProcessFuncWrapper *func);
578745Sgblack@eecs.umich.eduProcess *newCThreadProcess(const char *name, ProcessFuncWrapper *func);
588745Sgblack@eecs.umich.edu
598745Sgblack@eecs.umich.edu} // namespace sc_gem5
608745Sgblack@eecs.umich.edu
618745Sgblack@eecs.umich.edunamespace sc_core
628745Sgblack@eecs.umich.edu{
638745Sgblack@eecs.umich.edu
648745Sgblack@eecs.umich.edutemplate <class T>
658745Sgblack@eecs.umich.educlass sc_in;
668745Sgblack@eecs.umich.edutemplate <class T>
678745Sgblack@eecs.umich.educlass sc_out;
688745Sgblack@eecs.umich.edutemplate <class T>
698745Sgblack@eecs.umich.educlass sc_inout;
708745Sgblack@eecs.umich.edutemplate <class T>
718745Sgblack@eecs.umich.educlass sc_signal_in_if;
728745Sgblack@eecs.umich.edu
738745Sgblack@eecs.umich.educlass sc_event;
748745Sgblack@eecs.umich.educlass sc_event_and_list;
758745Sgblack@eecs.umich.educlass sc_event_or_list;
768745Sgblack@eecs.umich.educlass sc_module_name;
778745Sgblack@eecs.umich.edu
788745Sgblack@eecs.umich.educlass sc_bind_proxy
798745Sgblack@eecs.umich.edu{
808745Sgblack@eecs.umich.edu  private:
818745Sgblack@eecs.umich.edu    sc_interface *_interface;
828745Sgblack@eecs.umich.edu    sc_port_base *_port;
838745Sgblack@eecs.umich.edu
848745Sgblack@eecs.umich.edu  public:
858745Sgblack@eecs.umich.edu    sc_bind_proxy(sc_interface &_interface);
868745Sgblack@eecs.umich.edu    sc_bind_proxy(sc_port_base &_port);
878745Sgblack@eecs.umich.edu
888745Sgblack@eecs.umich.edu    sc_interface *interface() const { return _interface; }
898745Sgblack@eecs.umich.edu    sc_port_base *port() const { return _port; }
908745Sgblack@eecs.umich.edu};
918745Sgblack@eecs.umich.edu
928745Sgblack@eecs.umich.eduextern const sc_bind_proxy SC_BIND_PROXY_NIL;
9311566Smitch.hayenga@arm.com
948745Sgblack@eecs.umich.educlass sc_module : public sc_object
958745Sgblack@eecs.umich.edu{
968745Sgblack@eecs.umich.edu  public:
978745Sgblack@eecs.umich.edu    friend class ::sc_gem5::Kernel;
988745Sgblack@eecs.umich.edu
998745Sgblack@eecs.umich.edu    virtual ~sc_module();
1008745Sgblack@eecs.umich.edu
1018745Sgblack@eecs.umich.edu    virtual const char *kind() const { return "sc_module"; }
1028745Sgblack@eecs.umich.edu
1038745Sgblack@eecs.umich.edu    void operator () (const sc_bind_proxy &p001,
1048745Sgblack@eecs.umich.edu                      const sc_bind_proxy &p002 = SC_BIND_PROXY_NIL,
1058745Sgblack@eecs.umich.edu                      const sc_bind_proxy &p003 = SC_BIND_PROXY_NIL,
1068745Sgblack@eecs.umich.edu                      const sc_bind_proxy &p004 = SC_BIND_PROXY_NIL,
1078745Sgblack@eecs.umich.edu                      const sc_bind_proxy &p005 = SC_BIND_PROXY_NIL,
108                      const sc_bind_proxy &p006 = SC_BIND_PROXY_NIL,
109                      const sc_bind_proxy &p007 = SC_BIND_PROXY_NIL,
110                      const sc_bind_proxy &p008 = SC_BIND_PROXY_NIL,
111                      const sc_bind_proxy &p009 = SC_BIND_PROXY_NIL,
112                      const sc_bind_proxy &p010 = SC_BIND_PROXY_NIL,
113                      const sc_bind_proxy &p011 = SC_BIND_PROXY_NIL,
114                      const sc_bind_proxy &p012 = SC_BIND_PROXY_NIL,
115                      const sc_bind_proxy &p013 = SC_BIND_PROXY_NIL,
116                      const sc_bind_proxy &p014 = SC_BIND_PROXY_NIL,
117                      const sc_bind_proxy &p015 = SC_BIND_PROXY_NIL,
118                      const sc_bind_proxy &p016 = SC_BIND_PROXY_NIL,
119                      const sc_bind_proxy &p017 = SC_BIND_PROXY_NIL,
120                      const sc_bind_proxy &p018 = SC_BIND_PROXY_NIL,
121                      const sc_bind_proxy &p019 = SC_BIND_PROXY_NIL,
122                      const sc_bind_proxy &p020 = SC_BIND_PROXY_NIL,
123                      const sc_bind_proxy &p021 = SC_BIND_PROXY_NIL,
124                      const sc_bind_proxy &p022 = SC_BIND_PROXY_NIL,
125                      const sc_bind_proxy &p023 = SC_BIND_PROXY_NIL,
126                      const sc_bind_proxy &p024 = SC_BIND_PROXY_NIL,
127                      const sc_bind_proxy &p025 = SC_BIND_PROXY_NIL,
128                      const sc_bind_proxy &p026 = SC_BIND_PROXY_NIL,
129                      const sc_bind_proxy &p027 = SC_BIND_PROXY_NIL,
130                      const sc_bind_proxy &p028 = SC_BIND_PROXY_NIL,
131                      const sc_bind_proxy &p029 = SC_BIND_PROXY_NIL,
132                      const sc_bind_proxy &p030 = SC_BIND_PROXY_NIL,
133                      const sc_bind_proxy &p031 = SC_BIND_PROXY_NIL,
134                      const sc_bind_proxy &p032 = SC_BIND_PROXY_NIL,
135                      const sc_bind_proxy &p033 = SC_BIND_PROXY_NIL,
136                      const sc_bind_proxy &p034 = SC_BIND_PROXY_NIL,
137                      const sc_bind_proxy &p035 = SC_BIND_PROXY_NIL,
138                      const sc_bind_proxy &p036 = SC_BIND_PROXY_NIL,
139                      const sc_bind_proxy &p037 = SC_BIND_PROXY_NIL,
140                      const sc_bind_proxy &p038 = SC_BIND_PROXY_NIL,
141                      const sc_bind_proxy &p039 = SC_BIND_PROXY_NIL,
142                      const sc_bind_proxy &p040 = SC_BIND_PROXY_NIL,
143                      const sc_bind_proxy &p041 = SC_BIND_PROXY_NIL,
144                      const sc_bind_proxy &p042 = SC_BIND_PROXY_NIL,
145                      const sc_bind_proxy &p043 = SC_BIND_PROXY_NIL,
146                      const sc_bind_proxy &p044 = SC_BIND_PROXY_NIL,
147                      const sc_bind_proxy &p045 = SC_BIND_PROXY_NIL,
148                      const sc_bind_proxy &p046 = SC_BIND_PROXY_NIL,
149                      const sc_bind_proxy &p047 = SC_BIND_PROXY_NIL,
150                      const sc_bind_proxy &p048 = SC_BIND_PROXY_NIL,
151                      const sc_bind_proxy &p049 = SC_BIND_PROXY_NIL,
152                      const sc_bind_proxy &p050 = SC_BIND_PROXY_NIL,
153                      const sc_bind_proxy &p051 = SC_BIND_PROXY_NIL,
154                      const sc_bind_proxy &p052 = SC_BIND_PROXY_NIL,
155                      const sc_bind_proxy &p053 = SC_BIND_PROXY_NIL,
156                      const sc_bind_proxy &p054 = SC_BIND_PROXY_NIL,
157                      const sc_bind_proxy &p055 = SC_BIND_PROXY_NIL,
158                      const sc_bind_proxy &p056 = SC_BIND_PROXY_NIL,
159                      const sc_bind_proxy &p057 = SC_BIND_PROXY_NIL,
160                      const sc_bind_proxy &p058 = SC_BIND_PROXY_NIL,
161                      const sc_bind_proxy &p059 = SC_BIND_PROXY_NIL,
162                      const sc_bind_proxy &p060 = SC_BIND_PROXY_NIL,
163                      const sc_bind_proxy &p061 = SC_BIND_PROXY_NIL,
164                      const sc_bind_proxy &p062 = SC_BIND_PROXY_NIL,
165                      const sc_bind_proxy &p063 = SC_BIND_PROXY_NIL,
166                      const sc_bind_proxy &p064 = SC_BIND_PROXY_NIL);
167
168    virtual const std::vector<sc_object *> &get_child_objects() const;
169    virtual const std::vector<sc_event *> &get_child_events() const;
170
171  protected:
172    sc_module(const sc_module_name &);
173    sc_module();
174
175    // Deprecated
176    sc_module(const char *);
177    sc_module(const std::string &);
178
179    /* Deprecated, but used in the regression tests. */
180    void end_module() {}
181
182    void reset_signal_is(const sc_in<bool> &, bool);
183    void reset_signal_is(const sc_inout<bool> &, bool);
184    void reset_signal_is(const sc_out<bool> &, bool);
185    void reset_signal_is(const sc_signal_in_if<bool> &, bool);
186
187    void async_reset_signal_is(const sc_in<bool> &, bool);
188    void async_reset_signal_is(const sc_inout<bool> &, bool);
189    void async_reset_signal_is(const sc_out<bool> &, bool);
190    void async_reset_signal_is(const sc_signal_in_if<bool> &, bool);
191
192    sc_sensitive sensitive;
193
194    void dont_initialize();
195    void set_stack_size(size_t);
196
197    void next_trigger();
198    void next_trigger(const sc_event &);
199    void next_trigger(const sc_event_or_list &);
200    void next_trigger(const sc_event_and_list &);
201    void next_trigger(const sc_time &);
202    void next_trigger(double, sc_time_unit);
203    void next_trigger(const sc_time &, const sc_event &);
204    void next_trigger(double, sc_time_unit, const sc_event &);
205    void next_trigger(const sc_time &, const sc_event_or_list &);
206    void next_trigger(double, sc_time_unit, const sc_event_or_list &);
207    void next_trigger(const sc_time &, const sc_event_and_list &);
208    void next_trigger(double, sc_time_unit, const sc_event_and_list &);
209
210    // Nonstandard
211    bool timed_out();
212
213    void wait();
214    void wait(int);
215    void wait(const sc_event &);
216    void wait(const sc_event_or_list &);
217    void wait(const sc_event_and_list &);
218    void wait(const sc_time &);
219    void wait(double, sc_time_unit);
220    void wait(const sc_time &, const sc_event &);
221    void wait(double, sc_time_unit, const sc_event &);
222    void wait(const sc_time &, const sc_event_or_list &);
223    void wait(double, sc_time_unit, const sc_event_or_list &);
224    void wait(const sc_time &, const sc_event_and_list &);
225    void wait(double, sc_time_unit, const sc_event_and_list &);
226
227    // Nonstandard
228    void halt();
229    void at_posedge(const sc_signal_in_if<bool> &);
230    void at_posedge(const sc_signal_in_if<sc_dt::sc_logic> &);
231    void at_negedge(const sc_signal_in_if<bool> &);
232    void at_negedge(const sc_signal_in_if<sc_dt::sc_logic> &);
233
234    virtual void before_end_of_elaboration() {}
235    virtual void end_of_elaboration() {}
236    virtual void start_of_simulation() {}
237    virtual void end_of_simulation() {}
238
239  private:
240    sc_gem5::Module *_gem5_module;
241
242    // Disabled
243    sc_module(const sc_module &) : sc_object() {};
244    sc_module &operator = (const sc_module &) { return *this; }
245};
246
247void next_trigger();
248void next_trigger(const sc_event &);
249void next_trigger(const sc_event_or_list &);
250void next_trigger(const sc_event_and_list &);
251void next_trigger(const sc_time &);
252void next_trigger(double, sc_time_unit);
253void next_trigger(const sc_time &, const sc_event &);
254void next_trigger(double, sc_time_unit, const sc_event &);
255void next_trigger(const sc_time &, const sc_event_or_list &);
256void next_trigger(double, sc_time_unit, const sc_event_or_list &);
257void next_trigger(const sc_time &, const sc_event_and_list &);
258void next_trigger(double, sc_time_unit, const sc_event_and_list &);
259
260void wait();
261void wait(int);
262void wait(const sc_event &);
263void wait(const sc_event_or_list &);
264void wait(const sc_event_and_list &);
265void wait(const sc_time &);
266void wait(double, sc_time_unit);
267void wait(const sc_time &, const sc_event &);
268void wait(double, sc_time_unit, const sc_event &);
269void wait(const sc_time &, const sc_event_or_list &);
270void wait(double, sc_time_unit, const sc_event_or_list &);
271void wait(const sc_time &, const sc_event_and_list &);
272void wait(double, sc_time_unit, const sc_event_and_list &);
273
274// Nonstandard
275bool timed_out();
276
277#define SC_MODULE(name) struct name : ::sc_core::sc_module
278
279#define SC_CTOR(name) \
280    typedef name SC_CURRENT_USER_MODULE; \
281    name(::sc_core::sc_module_name)
282
283#define SC_HAS_PROCESS(name) typedef name SC_CURRENT_USER_MODULE
284
285#define SC_METHOD(name) \
286    { \
287        ::sc_gem5::Process *p = \
288            ::sc_gem5::newMethodProcess( \
289                #name, new ::sc_gem5::ProcessMemberFuncWrapper< \
290                    SC_CURRENT_USER_MODULE>(this, \
291                        &SC_CURRENT_USER_MODULE::name)); \
292        this->sensitive << p; \
293    }
294#define SC_THREAD(name) \
295    { \
296        ::sc_gem5::Process *p = \
297            ::sc_gem5::newThreadProcess( \
298                #name, new ::sc_gem5::ProcessMemberFuncWrapper< \
299                    SC_CURRENT_USER_MODULE>(this, \
300                        &SC_CURRENT_USER_MODULE::name)); \
301        this->sensitive << p; \
302    }
303#define SC_CTHREAD(name, clk) \
304    { \
305        ::sc_gem5::Process *p = \
306            ::sc_gem5::newCThreadProcess( \
307                #name, new ::sc_gem5::ProcessMemberFuncWrapper< \
308                    SC_CURRENT_USER_MODULE>(this, \
309                        &SC_CURRENT_USER_MODULE::name)); \
310        this->sensitive << p; \
311        this->sensitive << clk; \
312    }
313
314// Nonstandard
315// Documentation for this is very scarce, but it looks like it's supposed to
316// stop the currently executing cthread, or if a cthread isn't running report
317// an error.
318void halt();
319void at_posedge(const sc_signal_in_if<bool> &);
320void at_posedge(const sc_signal_in_if<sc_dt::sc_logic> &);
321void at_negedge(const sc_signal_in_if<bool> &);
322void at_negedge(const sc_signal_in_if<sc_dt::sc_logic> &);
323
324const char *sc_gen_unique_name(const char *);
325
326// Nonstandard
327bool sc_hierarchical_name_exists(const char *name);
328
329typedef sc_module sc_behavior;
330typedef sc_module sc_channel;
331
332bool sc_start_of_simulation_invoked();
333bool sc_end_of_simulation_invoked();
334
335// Nonstandard
336// Allocates a module of type x and records a pointer to it so that it gets
337// destructed automatically at the end of the simulation.
338sc_module *sc_module_sc_new(sc_module *);
339#define SC_NEW(x) ::sc_core::sc_module_sc_new(new x);
340
341// Nonstandard
342#define SC_WAIT() \
343    ::sc_core::sc_set_location(__FILE__, __LINE__); \
344    ::sc_core::wait(); \
345    ::sc_core::sc_set_location(NULL, 0)
346
347// Nonstandard
348#define SC_WAITN(n) \
349    ::sc_core::sc_set_location(__FILE__, __LINE__); \
350    ::sc_core::wait(n); \
351    ::sc_core::sc_set_location(NULL, 0)
352
353// Nonstandard
354#define SC_WAIT_UNTIL(expr) \
355    do { SC_WAIT(); } while (!(expr))
356
357} // namespace sc_core
358
359#endif  //__SYSTEMC_EXT_CORE_SC_MODULE_HH__
360