⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sc_link_mp.h

📁 system c 是在C环境下的硬件描述语言,比VHDL 等语言具有更强的抽象能力,内有system C的开发支持库和一些VC下的开发例程
💻 H
字号:
/*****************************************************************************  The following code is derived, directly or indirectly, from the SystemC  source code Copyright (c) 1996-2002 by all Contributors.  All Rights reserved.  The contents of this file are subject to the restrictions and limitations  set forth in the SystemC Open Source License Version 2.2 (the "License");  You may not use this file except in compliance with such restrictions and  limitations. You may obtain instructions on how to receive a copy of the  License at http://www.systemc.org/. Software distributed by Contributors  under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF  ANY KIND, either express or implied. See the License for the specific  language governing rights and limitations under the License. *****************************************************************************//*****************************************************************************  sc_link_mp.h -- implementation of multi-point link  Original Author: Dirk Vermeersch, Coware, Inc.                   Vijay Kumar, Coware, Inc. *****************************************************************************//*****************************************************************************  MODIFICATION LOG - modifiers, enter your name, affiliation, date and  changes you are making here.      Name, Affiliation, Date:  Description of Modification: *****************************************************************************/#ifndef SC_LINK_MP_H#define SC_LINK_MP_H#include "systemc/utils/sc_report.h"#include "systemc/utils/sc_string.h"#include "sc_ms/sc_abstract_if.h"#include "sc_ms/sc_indexed_if.h"#include "sc_ms/sc_refined_if.h"class sc_link_mp_b : public virtual sc_link_mp_if {public:};//----------------------------------------------------------------template<class T = int>class sc_link_mp :  public virtual sc_link_mp_b,  public virtual sc_abstract_master_if<T>,  public virtual sc_abstract_inmaster_if<T>,  public virtual sc_abstract_outmaster_if<T>,  public virtual sc_abstract_inoutmaster_if<T>,  public virtual sc_abstract_slave_if<T>,  public virtual sc_abstract_inslave_if<T>,  public virtual sc_abstract_outslave_if<T>,  public virtual sc_abstract_inoutslave_if<T>,  public virtual sc_indexed_master_if<T>,  public virtual sc_indexed_inmaster_if<T>,  public virtual sc_indexed_outmaster_if<T>,  public virtual sc_indexed_inoutmaster_if<T>,  public virtual sc_indexed_slave_if<T>,  public virtual sc_indexed_inslave_if<T>,  public virtual sc_indexed_outslave_if<T>,  public virtual sc_indexed_inoutslave_if<T>,  public virtual sc_refined_if<T>,  public virtual sc_prim_channel{public:  sc_link_mp( const char* nm = 0 ) :     sc_prim_channel( sc_gen_unique_name( nm ? nm : "link" ) ),    validated_( false )  {     set_input( false );  }    void		run( sc_slave_proc_list& list) {    int size = list.size( );    sc_slave_handle* l_slaves_static = list.raw_data( );    sc_slave_handle h;    for(int i = 0; i < size ; i++) {      h = l_slaves_static[i];      execute_slave_process( h );    }  }public:  // abstract interface implementation  void		run_slaves( ) 		{  run( slave_procs ); }  void		run_inslaves( ) 	{  run( inslave_procs ); }  void		run_outslaves( )        {  run( outslave_procs ); }  void		run_inoutslaves( )      {  run( inoutslave_procs ); }  virtual void register_port( sc_port_base& port, const char* port_name);    bool is_validated( ) 	{ return validated_; }  void validate( );  void add_port( sc_master_slave_b* port ); // { port_list_.push_back( port ); }  void	add_slave_proc( sc_slave_proc_list& l );  void	add_inslave_proc( sc_slave_proc_list& l );  void	add_outslave_proc( sc_slave_proc_list& l );  void	add_inoutslave_proc( sc_slave_proc_list& l );  virtual void end_of_elaboration( ) {      validate( );  }private:  const T& 	read( ) { return value; }  void		write( const T& data ) {    if ( write_count > 0 ) {        char msg[BUFSIZ];        const char* link_name = sc_object::name( );        sprintf( msg, ": %s", link_name );        SC_REPORT_ERROR(SC_ID_MS_MULTIPLE_WRITE_TO_LINK_, msg );    }    write_count++;    value = data;  }  void		free_write( const T& data ) { value = data; } private:  void	add_to_list( sc_slave_proc_list& , sc_slave_proc_list& );  bool	can_bind( sc_master_slave_b*, sc_master_slave_b *);private:  bool		get_input( )		{ return is_input; }  void 		set_input( bool b )	{ is_input = b; }private:  T 	value;  int	write_count;	// for error checking, only one slave can write  bool	is_input;	// are we currently reading or writing			// inout slaves can use this information to			// respond in the read or write mode.// indexed port implementation  virtual void		set_address( uint64 i )	{ last_address = i; }  virtual uint64	get_address( ) const	{ return last_address; }protected:  uint64	last_address;private:  // implementation of abstract M/S read write functions  virtual void operator ( ) ( ) {  run_slaves( ); }    virtual const T& read_inmaster( )   {    set_input( false );    reset_write_count( );    run_outslaves( );    run_inoutslaves( );    return read( );  }    virtual void write_outmaster(const T& data )  {    set_input( true );    free_write( data );    run_inslaves( );    run_inoutslaves( );  }   virtual void write_inoutmaster(const T& data )   {    set_input( true );    free_write( data );    run_inslaves( );    run_inoutslaves( );  }      virtual const T& read_inoutmaster( )    {    reset_write_count( );    set_input( false );    run_outslaves( );    run_inoutslaves( );    return read( );  }    void		reset_write_count( )	{ write_count = 0; }public:  virtual bool	input( ) { return get_input( ); }private:  sc_master_slave_list  port_list_;  bool			validated_;  // the list of all slave processess attached to this link.  sc_slave_proc_list	slave_procs;  sc_slave_proc_list	inslave_procs;  sc_slave_proc_list	outslave_procs;  sc_slave_proc_list	inoutslave_procs;  sc_master_slave_list	master_list;  sc_master_slave_list	inmaster_list;  sc_master_slave_list	outmaster_list;  sc_master_slave_list	inoutmaster_list;  sc_master_slave_list	slave_list;  sc_master_slave_list	inslave_list;  sc_master_slave_list	outslave_list;  sc_master_slave_list	inoutslave_list;  // implementation for refined protocolprivate:  typedef sc_phash<int, sc_interface* > refined_signals;  typedef sc_phash<int, void* >		attribute_data;  refined_signals	data_signals;  refined_signals	address_signals;  refined_signals	control_signals;  attribute_data	attribute_data_list;  public:  virtual sc_interface* get_signal(int id, sc_terminal_type ttype );  virtual void add_signal( sc_interface* intf, sc_terminal_type ttype, int id );  virtual void add_attribute_data( void * data, int id );  virtual void * get_attribute_data( int id );};  // sc_link_mp//////////////////////////////////////////////////////////////////////////----------------------------------------------------------------------//----------------------------------------------------------------------template<class T>void sc_link_mp<T>::register_port( sc_port_base& port,                                    const char* port_name) {  sc_master_slave_b* ms_port     =  dynamic_cast< sc_master_slave_b* >( &port );    if ( !ms_port ) {    cout << "sc_link_mp.h::register_port : Error "       << port_name << " is not an master/slave port " << endl;  }  add_port( ms_port );  // validate( );} // register_port//----------------------------------------------------------------------template<class T>void sc_link_mp<T>::validate( ) {  if ( is_validated( ) ) {      return;    }  assert( port_list_.size( ) );  sc_master_slave_list::iterator it	= port_list_.begin( );  sc_master_slave_list::iterator last	= port_list_.end( );  sc_master_slave_b *port = *it; // save the first one  bool valid = true;   for ( it++ ; ( it != last) && valid ; it++ ) {    valid = can_bind( port, *it );  }  validated_ = true;} // validate//----------------------------------------------------------------------// can_bind is called to check if two ports connected to the same link// are compatible.  ** This is not used for checking compatiblity between// port-to-port binding**template<class T>bool sc_link_mp<T>::can_bind( sc_master_slave_b* port1,                          sc_master_slave_b* port2 ){  const char * this_name 	= port1->port_typename( );  const char * other_name 	= port2->port_typename( );  bool match = strcmp( this_name, other_name)==0;  if ( ! match ) {    char msg[BUFSIZ];    const char* link_name = sc_object::name( );    const char* port_name = port1->get_name( );     sprintf( msg,  	     "`%s\' and `%s\'  : Cannot bind port `%s\' to link `%s\'",	     port1->port_typename( ), 	     port2->port_typename( ), 	     port_name, 	     link_name );    SC_REPORT_ERROR( SC_ID_MS_INCOMPATIBLE_PORT_PROTOCOL_ON_LINKMP_, msg );  }  return true;}////////////////////////////////////////////////////////////////////// add slave procs to the appropriate listtemplate<class T> void sc_link_mp<T>::add_slave_proc( sc_slave_proc_list& l ) {  add_to_list( slave_procs, l );}template<class T> void sc_link_mp<T>::add_inslave_proc( sc_slave_proc_list& l )  {  add_to_list( inslave_procs, l );}template<class T> void sc_link_mp<T>::add_outslave_proc( sc_slave_proc_list& l ) {  add_to_list( outslave_procs, l );}template<class T> void sc_link_mp<T>::add_inoutslave_proc( sc_slave_proc_list& l )  {  add_to_list( inoutslave_procs, l );}////////////////////////////////////////////////////////////////////template<class T> void sc_link_mp<T>::add_to_list( sc_slave_proc_list& list1, 			   sc_slave_proc_list& list2 ) {  for ( sc_slave_proc_list::iterator 	it 	= list2.begin( ),	last 	= list2.end( );       last != it;       it++ ) {    list1.push_back( *it );  }}////////////////////////////////////////////////////////////////////template<class T> sc_interface* sc_link_mp<T>::get_signal(int id, sc_terminal_type ttype ) {  sc_interface* sig = 0;  switch( ttype ) {  case TT_DATA:    data_signals.lookup( id, &sig );    break;    case TT_ADDRESS:    address_signals.lookup( id, &sig );    break;    case TT_CONTROL:    control_signals.lookup( id, &sig );    break;  } // switch  return sig;}template<class T> void sc_link_mp<T>::add_signal( sc_interface* intf, sc_terminal_type ttype, int id ) {  switch( ttype ) {  case TT_DATA:    data_signals.insert( id, intf );    break;    case TT_ADDRESS:    address_signals.insert( id, intf );    break;    case TT_CONTROL:    control_signals.insert( id, intf );    break;  } // switch}template<class T> void sc_link_mp<T>::add_attribute_data( void * data, int id ) {  attribute_data_list.insert( id, data );}template<class T> void* sc_link_mp<T>::get_attribute_data( int id ) {  void *d;  attribute_data_list.lookup( id, &d );  return d;}template<class T>void sc_link_mp<T>::add_port( sc_master_slave_b* port  ) {    // add port to the general list    port_list_.push_back( port );     // add the master port to the correct list    if ( dynamic_cast< sc_port< sc_abstract_master_if<T> > * > ( port ) ) {        master_list.push_back( port );     } else if ( dynamic_cast< sc_port< sc_abstract_inmaster_if<T> > * > ( port ) ) {        inmaster_list.push_back( port );    } else if ( dynamic_cast< sc_port< sc_abstract_outmaster_if<T> > * > ( port ) ) {        outmaster_list.push_back( port );    } else if ( dynamic_cast< sc_port< sc_abstract_inoutmaster_if<T> > * > ( port ) ) {        inoutmaster_list.push_back( port );    } else if ( dynamic_cast< sc_port< sc_abstract_slave_if<T> > * > ( port ) ) {        slave_list.push_back( port );     } else if ( dynamic_cast< sc_port< sc_abstract_inslave_if<T> > * > ( port ) ) {        inslave_list.push_back( port );    } else if ( dynamic_cast< sc_port< sc_abstract_outslave_if<T> > * > ( port ) ) {        outslave_list.push_back( port );    } else if ( dynamic_cast< sc_port< sc_abstract_inoutslave_if<T> > * > ( port ) ) {        inoutslave_list.push_back( port );    }}#endif  // SC_LINK_MP_H

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -