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  sc_clock.h -- The clock channel.
23
24  Original Author: Martin Janssen, Synopsys, Inc., 2001-05-21
25
26  CHANGE LOG IS AT THE END OF THE FILE
27 *****************************************************************************/
28
29#ifndef SC_CLOCK_H
30#define SC_CLOCK_H
31
32
33#include "sysc/kernel/sc_module.h"
34#include "sysc/communication/sc_signal.h"
35#include "sysc/tracing/sc_trace.h"
36
37namespace sc_core {
38
39// ----------------------------------------------------------------------------
40//  CLASS : sc_clock
41//
42//  The clock channel.
43// ----------------------------------------------------------------------------
44
45class sc_clock
46  : public sc_signal<bool,SC_ONE_WRITER>
47{
48  typedef sc_signal<bool,SC_ONE_WRITER> base_type;
49public:
50
51    friend class sc_clock_posedge_callback;
52    friend class sc_clock_negedge_callback;
53
54    // constructors
55
56    sc_clock();
57
58    explicit sc_clock( const char* name_ );
59
60    sc_clock( const char* name_,
61	      const sc_time& period_,
62	      double         duty_cycle_ = 0.5,
63	      const sc_time& start_time_ = SC_ZERO_TIME,
64	      bool           posedge_first_ = true );
65
66    sc_clock( const char* name_,
67	      double         period_v_,
68	      sc_time_unit   period_tu_,
69	      double         duty_cycle_ = 0.5 );
70
71    sc_clock( const char* name_,
72	      double         period_v_,
73	      sc_time_unit   period_tu_,
74	      double         duty_cycle_,
75	      double         start_time_v_,
76	      sc_time_unit   start_time_tu_,
77	      bool           posedge_first_ = true );
78
79    // for backward compatibility with 1.0
80    sc_clock( const char* name_,
81	      double         period_,            // in default time units
82	      double         duty_cycle_ = 0.5,
83	      double         start_time_ = 0.0,  // in default time units
84	      bool           posedge_first_ = true );
85
86    // destructor (does nothing)
87    virtual ~sc_clock();
88
89    virtual void register_port( sc_port_base&, const char* if_type );
90    virtual void write( const bool& );
91
92    // get the period
93    const sc_time& period() const
94	{ return m_period; }
95
96    // get the duty cycle
97    double duty_cycle() const
98	{ return m_duty_cycle; }
99
100
101    // get the current time / clock characteristics
102
103    bool posedge_first() const
104        { return m_posedge_first; }
105
106    sc_time start_time() const
107        { return m_start_time; }
108
109    static const sc_time& time_stamp();
110
111    virtual const char* kind() const
112        { return "sc_clock"; }
113
114
115#if 0 // @@@@#### REMOVE
116    // for backward compatibility with 1.0
117
118    sc_signal_in_if<bool>& signal()
119	{ return *this; }
120
121    const sc_signal_in_if<bool>& signal() const
122	{ return *this; }
123
124    static void start( const sc_time& duration )
125	{ sc_start( duration ); }
126
127    static void start( double v, sc_time_unit tu )
128	{ sc_start( sc_time(v, tu) ); }
129
130    static void start( double duration = -1 )
131	{ sc_start( duration ); }
132
133    static void stop()
134	{ sc_stop(); }
135#endif
136
137protected:
138
139    void before_end_of_elaboration();
140
141    // processes
142    void posedge_action();
143    void negedge_action();
144
145
146    // error reporting
147    void report_error( const char* id, const char* add_msg = 0 ) const;
148
149
150    void init( const sc_time&, double, const sc_time&, bool );
151
152    bool is_clock() const { return true; }
153
154protected:
155
156    sc_time  m_period;		// the period of this clock
157    double   m_duty_cycle;	// the duty cycle (fraction of period)
158    sc_time  m_start_time;	// the start time of the first edge
159    bool     m_posedge_first;   // true if first edge is positive
160    sc_time  m_posedge_time;	// time till next positive edge
161    sc_time  m_negedge_time;	// time till next negative edge
162
163    sc_event m_next_posedge_event;
164    sc_event m_next_negedge_event;
165
166private:
167
168    // disabled
169    sc_clock( const sc_clock& );
170    sc_clock& operator = ( const sc_clock& );
171};
172
173
174// IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
175
176// processes
177
178inline
179void
180sc_clock::posedge_action()
181{
182    m_next_negedge_event.notify_internal( m_negedge_time );
183	m_new_val = true;
184	request_update();
185}
186
187inline
188void
189sc_clock::negedge_action()
190{
191    m_next_posedge_event.notify_internal( m_posedge_time );
192	m_new_val = false;
193	request_update();
194}
195
196
197// ----------------------------------------------------------------------------
198
199class sc_clock_posedge_callback {
200public:
201    sc_clock_posedge_callback(sc_clock* target_p) : m_target_p(target_p) {}
202    inline void operator () () { m_target_p->posedge_action(); }
203  protected:
204    sc_clock* m_target_p;
205};
206
207class sc_clock_negedge_callback {
208  public:
209    sc_clock_negedge_callback(sc_clock* target_p) : m_target_p(target_p) {}
210    inline void operator () () { m_target_p->negedge_action(); }
211  protected:
212    sc_clock* m_target_p;
213};
214
215
216} // namespace sc_core
217
218/*****************************************************************************
219
220  MODIFICATION LOG - modifiers, enter your name, affiliation, date and
221  changes you are making here.
222
223      Name, Affiliation, Date: Bishnupriya Bhattacharya, Cadence Design Systems,
224                               3 October, 2003
225  Description of Modification: sc_clock inherits from sc_signal<bool> only
226                               instead of sc_signal_in_if<bool> and sc_module.
227
228      Name, Affiliation, Date:
229  Description of Modification:
230
231 *****************************************************************************/
232//$Log: sc_clock.h,v $
233//Revision 1.5  2011/08/26 20:45:39  acg
234// Andy Goodrich: moved the modification log to the end of the file to
235// eliminate source line number skew when check-ins are done.
236//
237//Revision 1.4  2011/08/24 22:05:35  acg
238// Torsten Maehne: initialization changes to remove warnings.
239//
240//Revision 1.3  2011/02/18 20:23:45  acg
241// Andy Goodrich: Copyright update.
242//
243//Revision 1.2  2011/01/20 16:52:15  acg
244// Andy Goodrich: changes for IEEE 1666 2011.
245//
246//Revision 1.1.1.1  2006/12/15 20:20:04  acg
247//SystemC 2.3
248//
249//Revision 1.5  2006/01/25 00:31:11  acg
250// Andy Goodrich: Changed over to use a standard message id of
251// SC_ID_IEEE_1666_DEPRECATION for all deprecation messages.
252//
253//Revision 1.4  2006/01/24 20:43:25  acg
254// Andy Goodrich: convert notify_delayed() calls into notify_internal() calls.
255// notify_internal() is an implementation dependent version of notify_delayed()
256// that is simpler, and does not trigger the deprecation warning one would get
257// using notify_delayed().
258//
259//Revision 1.3  2006/01/18 21:42:26  acg
260//Andy Goodrich: Changes for check writer support, and tightening up sc_clock
261//port usage.
262//
263//Revision 1.2  2006/01/03 23:18:26  acg
264//Changed copyright to include 2006.
265//
266//Revision 1.1.1.1  2005/12/19 23:16:43  acg
267//First check in of SystemC 2.1 into its own archive.
268//
269//Revision 1.14  2005/06/10 22:43:55  acg
270//Added CVS change log annotation.
271//
272
273#endif
274
275// Taf!
276