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