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_signal_ports.cpp -- The sc_signal<T> port classes.
23
24  Original Author: Martin Janssen, Synopsys, Inc., 2001-08-20
25
26  CHANGE LOG IS AT THE END OF THE FILE
27 *****************************************************************************/
28
29#include "sysc/communication/sc_signal_ports.h"
30#include "sysc/datatypes/int/sc_signed.h"
31#include "sysc/datatypes/int/sc_unsigned.h"
32#include "sysc/datatypes/bit/sc_lv_base.h"
33#include "sysc/utils/sc_utils_ids.h"
34
35namespace sc_core {
36
37// ----------------------------------------------------------------------------
38//  CLASS : sc_in<bool>
39//
40//  Specialization of sc_in<T> for type bool.
41// ----------------------------------------------------------------------------
42
43// called when elaboration is done
44
45void
46sc_in<bool>::end_of_elaboration()
47{
48    if( m_traces != 0 ) {
49	for( int i = 0; i < (int)m_traces->size(); ++ i ) {
50	    sc_trace_params* p = (*m_traces)[i];
51	    in_if_type* iface = DCAST<in_if_type*>( get_interface() );
52	    sc_trace( p->tf, iface->read(), p->name );
53	}
54	remove_traces();
55    }
56}
57
58// called by sc_trace
59
60void
61sc_in<bool>::add_trace_internal(sc_trace_file* tf_,
62	const std::string& name_) const
63{
64    if( tf_ != 0 ) {
65	if( m_traces == 0 ) {
66	    m_traces = new sc_trace_params_vec;
67	}
68	m_traces->push_back( new sc_trace_params( tf_, name_ ) );
69    }
70}
71
72void
73sc_in<bool>::add_trace(sc_trace_file* tf_,
74	const std::string& name_) const
75{
76    sc_deprecated_add_trace();
77	add_trace_internal(tf_, name_);
78}
79
80void
81sc_in<bool>::remove_traces() const
82{
83    if( m_traces != 0 ) {
84	for( int i = m_traces->size() - 1; i >= 0; -- i ) {
85	    delete (*m_traces)[i];
86	}
87	delete m_traces;
88	m_traces = 0;
89    }
90}
91
92
93// called by pbind (for internal use only)
94
95int
96sc_in<bool>::vbind( sc_interface& interface_ )
97{
98    return sc_port_b<if_type>::vbind( interface_ );
99}
100
101int
102sc_in<bool>::vbind( sc_port_base& parent_ )
103{
104    in_port_type* in_parent = DCAST<in_port_type*>( &parent_ );
105    if( in_parent != 0 ) {
106	sc_port_base::bind( *in_parent );
107	return 0;
108    }
109    inout_port_type* inout_parent = DCAST<inout_port_type*>( &parent_ );
110    if( inout_parent != 0 ) {
111	sc_port_base::bind( *inout_parent );
112	return 0;
113    }
114    // type mismatch
115    return 2;
116}
117
118
119// ----------------------------------------------------------------------------
120//  CLASS : sc_in<sc_logic>
121//
122//  Specialization of sc_in<T> for type sc_logic.
123// ----------------------------------------------------------------------------
124
125// called when elaboration is done
126
127void
128sc_in<sc_dt::sc_logic>::end_of_elaboration()
129{
130    if( m_traces != 0 ) {
131	for( int i = 0; i < (int)m_traces->size(); ++ i ) {
132	    sc_trace_params* p = (*m_traces)[i];
133	    in_if_type* iface = DCAST<in_if_type*>( get_interface() );
134	    sc_trace( p->tf, iface->read(), p->name );
135	}
136	remove_traces();
137    }
138}
139
140
141// called by sc_trace
142
143void
144sc_in<sc_dt::sc_logic>::add_trace_internal( sc_trace_file* tf_,
145    const std::string& name_ ) const
146{
147    if( tf_ != 0 ) {
148	if( m_traces == 0 ) {
149	    m_traces = new sc_trace_params_vec;
150	}
151	m_traces->push_back( new sc_trace_params( tf_, name_ ) );
152    }
153}
154
155void
156sc_in<sc_dt::sc_logic>::add_trace( sc_trace_file* tf_,
157    const std::string& name_ ) const
158{
159    sc_deprecated_add_trace();
160    add_trace_internal(tf_, name_);
161}
162
163void
164sc_in<sc_dt::sc_logic>::remove_traces() const
165{
166    if( m_traces != 0 ) {
167	for( int i = m_traces->size() - 1; i >= 0; -- i ) {
168	    delete (*m_traces)[i];
169	}
170	delete m_traces;
171	m_traces = 0;
172    }
173}
174
175
176// called by pbind (for internal use only)
177
178int
179sc_in<sc_dt::sc_logic>::vbind( sc_interface& interface_ )
180{
181    return sc_port_b<if_type>::vbind( interface_ );
182}
183
184int
185sc_in<sc_dt::sc_logic>::vbind( sc_port_base& parent_ )
186{
187    in_port_type* in_parent = DCAST<in_port_type*>( &parent_ );
188    if( in_parent != 0 ) {
189	sc_port_base::bind( *in_parent );
190	return 0;
191    }
192    inout_port_type* inout_parent = DCAST<inout_port_type*>( &parent_ );
193    if( inout_parent != 0 ) {
194	sc_port_base::bind( *inout_parent );
195	return 0;
196    }
197    // type mismatch
198    return 2;
199}
200
201
202// ----------------------------------------------------------------------------
203//  CLASS : sc_inout<bool>
204//
205//  Specialization of sc_inout<T> for type bool.
206// ----------------------------------------------------------------------------
207
208// destructor
209
210sc_inout<bool>::~sc_inout()
211{
212    delete m_change_finder_p;
213    delete m_neg_finder_p;
214    delete m_pos_finder_p;
215    delete m_init_val;
216    remove_traces();
217}
218
219
220// set initial value (can also be called when port is not bound yet)
221
222void
223sc_inout<bool>::initialize( const data_type& value_ )
224{
225    inout_if_type* iface = DCAST<inout_if_type*>( get_interface() );
226    if( iface != 0 ) {
227	iface->write( value_ );
228    } else {
229	if( m_init_val == 0 ) {
230	    m_init_val = new data_type;
231	}
232	*m_init_val = value_;
233    }
234}
235
236
237// called when elaboration is done
238
239void
240sc_inout<bool>::end_of_elaboration()
241{
242    if( m_init_val != 0 ) {
243	write( *m_init_val );
244	delete m_init_val;
245	m_init_val = 0;
246    }
247    if( m_traces != 0 ) {
248	for( int i = 0; i < (int)m_traces->size(); ++ i ) {
249	    sc_trace_params* p = (*m_traces)[i];
250	    in_if_type* iface = DCAST<in_if_type*>( get_interface() );
251	    sc_trace( p->tf, iface->read(), p->name );
252	}
253	remove_traces();
254    }
255}
256
257
258// called by sc_trace
259
260void
261sc_inout<bool>::add_trace_internal( sc_trace_file* tf_,
262    const std::string& name_ ) const
263{
264    if( tf_ != 0 ) {
265	if( m_traces == 0 ) {
266	    m_traces = new sc_trace_params_vec;
267	}
268	m_traces->push_back( new sc_trace_params( tf_, name_ ) );
269    }
270}
271
272void
273sc_inout<bool>::add_trace( sc_trace_file* tf_,
274    const std::string& name_ ) const
275{
276    sc_deprecated_add_trace();
277    add_trace_internal(tf_, name_);
278}
279
280void
281sc_inout<bool>::remove_traces() const
282{
283    if( m_traces != 0 ) {
284	for( int i = m_traces->size() - 1; i >= 0; -- i ) {
285	    delete (*m_traces)[i];
286	}
287	delete m_traces;
288	m_traces = 0;
289    }
290}
291
292
293// ----------------------------------------------------------------------------
294//  CLASS : sc_inout<sc_dt::sc_logic>
295//
296//  Specialization of sc_inout<T> for type sc_dt::sc_logic.
297// ----------------------------------------------------------------------------
298
299// destructor
300
301sc_inout<sc_dt::sc_logic>::~sc_inout()
302{
303    delete m_change_finder_p;
304    delete m_neg_finder_p;
305    delete m_pos_finder_p;
306    delete m_init_val;
307    remove_traces();
308}
309
310
311// set initial value (can also be called when port is not bound yet)
312
313void
314sc_inout<sc_dt::sc_logic>::initialize( const data_type& value_ )
315{
316    inout_if_type* iface = DCAST<inout_if_type*>( get_interface() );
317    if( iface != 0 ) {
318	iface->write( value_ );
319    } else {
320	if( m_init_val == 0 ) {
321	    m_init_val = new data_type;
322	}
323	*m_init_val = value_;
324    }
325}
326
327
328// called when elaboration is done
329
330void
331sc_inout<sc_dt::sc_logic>::end_of_elaboration()
332{
333    if( m_init_val != 0 ) {
334	write( *m_init_val );
335	delete m_init_val;
336	m_init_val = 0;
337    }
338    if( m_traces != 0 ) {
339	for( int i = 0; i < (int)m_traces->size(); ++ i ) {
340	    sc_trace_params* p = (*m_traces)[i];
341	    in_if_type* iface = DCAST<in_if_type*>( get_interface() );
342	    sc_trace( p->tf, iface->read(), p->name );
343	}
344	remove_traces();
345    }
346}
347
348
349// called by sc_trace
350
351void
352sc_inout<sc_dt::sc_logic>::add_trace_internal( sc_trace_file* tf_,
353			       const std::string& name_ ) const
354{
355    if( tf_ != 0 ) {
356	if( m_traces == 0 ) {
357	    m_traces = new sc_trace_params_vec;
358	}
359	m_traces->push_back( new sc_trace_params( tf_, name_ ) );
360    }
361}
362
363
364void
365sc_inout<sc_dt::sc_logic>::add_trace( sc_trace_file* tf_,
366			       const std::string& name_ ) const
367{
368    sc_deprecated_add_trace();
369    add_trace_internal(tf_, name_);
370}
371
372void
373sc_inout<sc_dt::sc_logic>::remove_traces() const
374{
375    if( m_traces != 0 ) {
376	for( int i = m_traces->size() - 1; i >= 0; -- i ) {
377	    delete (*m_traces)[i];
378	}
379	delete m_traces;
380	m_traces = 0;
381    }
382}
383
384void sc_deprecated_add_trace()
385{
386    static bool warn_add_trace_deprecated=true;
387    if ( warn_add_trace_deprecated )
388    {
389        warn_add_trace_deprecated=false;
390	SC_REPORT_INFO(SC_ID_IEEE_1666_DEPRECATION_,
391	    "sc_signal<T>::addtrace() is deprecated");
392    }
393}
394} // namespace sc_core
395
396// $Log: sc_signal_ports.cpp,v $
397// Revision 1.3  2011/08/26 20:45:43  acg
398//  Andy Goodrich: moved the modification log to the end of the file to
399//  eliminate source line number skew when check-ins are done.
400//
401// Revision 1.2  2011/02/18 20:23:45  acg
402//  Andy Goodrich: Copyright update.
403//
404// Revision 1.1.1.1  2006/12/15 20:20:04  acg
405// SystemC 2.3
406//
407// Revision 1.8  2006/05/08 17:52:47  acg
408//  Andy Goodrich:
409//    (1) added David Long's forward declarations for friend functions,
410//        methods, and operators to keep the Microsoft compiler happy.
411//    (2) Added delta_count() method to sc_prim_channel for use by
412//        sc_signal so that the friend declaration in sc_simcontext.h
413// 	   can be for a non-templated class (i.e., sc_prim_channel.)
414//
415// Revision 1.7  2006/04/18 18:01:26  acg
416//  Andy Goodrich: added an add_trace_internal() method to the various port
417//  classes so that sc_trace has something to call that won't emit an
418//  IEEE 1666 deprecation message.
419//
420// Revision 1.6  2006/02/02 23:42:37  acg
421//  Andy Goodrich: implemented a much better fix to the sc_event_finder
422//  proliferation problem. This new version allocates only a single event
423//  finder for each port for each type of event, e.g., pos(), neg(), and
424//  value_change(). The event finder persists as long as the port does,
425//  which is what the LRM dictates. Because only a single instance is
426//  allocated for each event type per port there is not a potential
427//  explosion of storage as was true in the 2.0.1/2.1 versions.
428//
429// Revision 1.5  2006/01/25 00:31:11  acg
430//  Andy Goodrich: Changed over to use a standard message id of
431//  SC_ID_IEEE_1666_DEPRECATION for all deprecation messages.
432//
433// Revision 1.4  2006/01/24 20:46:32  acg
434// Andy Goodrich: changes to eliminate use of deprecated features. For instance,
435// using notify(SC_ZERO_TIME) in place of notify_delayed().
436//
437// Revision 1.3  2006/01/13 18:47:42  acg
438// Added $Log command so that CVS comments are reproduced in the source.
439//
440
441// Taf!
442