Show genericRouter.h syntax highlighted
/*
Copyright (c) 2006 : Technical University of Braunschweig, Germany
All rights reserved.
Authors: Robert Guenzel, Wolfgang Klingauf, TU Braunschweig, E.I.S.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer. Redistributions
in binary form must reproduce the above copyright notice, this list of
conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution. Neither the name of
the Technical University of Braunschweig, Germany nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __genericRouter_h__
#define __genericRouter_h__
#include <systemc.h>
#include "gstlm/tlm.h"
#include "protocol/generic.h"
#include "userAPI/basicPorts.h"
#include "router/genericRouter_if.h"
#include "router/genericProtocol_if.h"
#include "router/protocol/simpleAddressMap.h"
using namespace tlm;
//--------------------------------------------------------------------------
/**
* The GenericRouter. It owns a multi-initiator port
* and a multi-target port for connecting arbitrary numbers
* of master and slave modules. All specific router implementations
* inherit from this class.
*/
//--------------------------------------------------------------------------
template <class TRANSACTION, /* the transaction */
class PHASE, /* the phases that are supported by the protocol */
class ROUTERACCESS, /* the quarks that the router may access */
class TRANSACTION_P = boost::shared_ptr<TRANSACTION>,
class PHASE_P = PHASE,
class TRANSACTION_PHASE = unevenpair<TRANSACTION_P, PHASE_P>,
class INITPORT = initiator_multi_port<TRANSACTION,ROUTERACCESS,PHASE>,
class TARGETPORT = target_multi_port<TRANSACTION,ROUTERACCESS,PHASE>,
class ADDRESSMAP = SimpleAddressMap<MAddr,INITPORT, TRANSACTION,PHASE>
>
class GenericRouter : public sc_module,
public GenericRouter_if<INITPORT, TARGETPORT>,
public tlm_b_if<TRANSACTION_P>
{
public:
/// target multiport
TARGETPORT target_port;
/// slave multiport
INITPORT init_port;
/// port to the protocol
sc_port<GenericProtocol_if<TRANSACTION, PHASE> > protocol_port;
/// slave address map
ADDRESSMAP m_addressMap;
SC_HAS_PROCESS(GenericRouter);
//--------------------------------------------------------------------------
/**
* Constructor; bind ports and register SC_METHODs with the kernel.
*/
//--------------------------------------------------------------------------
GenericRouter(sc_module_name name_)
: sc_module(name_),
target_port("tport"),
init_port("iport"),
protocol_port("protocol_port")
{
GS_TRACE(name(), "I am a generic router.");
// DUST structure analysis
#ifdef DUST_ENABLE
DUST_BUS("GenericRouter");
#endif
// we implement the tlm_b_if for PV bypassing
target_port.bind_b_if(*this);
SC_METHOD( MasterAccessMonitor );
sensitive << target_port.default_event();
dont_initialize();
SC_METHOD( SlaveAccessMonitor );
sensitive << init_port.default_event();
dont_initialize();
SC_METHOD( ProcessMasterAccess );
p_PMAMethod = sc_get_last_created_process_handle();
dont_initialize();
SC_METHOD( ProcessSlaveAccess );
p_PSAMethod = sc_get_last_created_process_handle();
dont_initialize();
}
//--------------------------------------------------------------------------
/**
* This method starts whenever a master triggers a payload-event.
*/
//--------------------------------------------------------------------------
void MasterAccessMonitor()
{
// get payload (transaction)
TRANSACTION_PHASE t_p = target_port.get_payload();
// forward payload to protocol (there it can be queued for later arbitration or whatever)
protocol_port->registerMasterAccess(t_p);
}
//--------------------------------------------------------------------------
/**
* This method can be made sensitive by the bus protocol to control
* the processing of transfers from master to slave by triggering an event.
*/
//--------------------------------------------------------------------------
void ProcessMasterAccess()
{
// tell protocol that it's time to process the master accesses
// this could include arbitrate between accesses that were enqueued earlier with registerMasterAccess...
protocol_port->processMasterAccess();
}
//--------------------------------------------------------------------------
/**
* This method starts whenever a slave triggers a payload-event.
*/
//--------------------------------------------------------------------------
void SlaveAccessMonitor()
{
// get payload
TRANSACTION_PHASE t_p = init_port.get_payload();
// forward payload to protocol class (there it can be queued or parsed or whatever)
protocol_port->registerSlaveAccess(t_p);
}
//--------------------------------------------------------------------------
/**
* This method can be made sensitive by the protocol to control
* the processing of transfers from slave to master by triggering an event.
*/
//--------------------------------------------------------------------------
void ProcessSlaveAccess()
{
// tell bus protocol that it's time to process the slave accesses
// this could include arbitrate between accesses that were enqueued earlier with registerSlaveAccess...
protocol_port->processSlaveAccess();
}
//--------------------------------------------------------------------------
/**
* Provide access to the initiator port (used by bus protocol).
*/
//--------------------------------------------------------------------------
virtual INITPORT* getInitPort(){ return &init_port;}
//--------------------------------------------------------------------------
/**
* Provide access to the target port (used by bus protocol).
*/
//--------------------------------------------------------------------------
virtual TARGETPORT* getTargetPort(){ return &target_port;}
//--------------------------------------------------------------------------
/**
* End of elab simulation kernel callback
*/
//--------------------------------------------------------------------------
virtual void end_of_elaboration()
{
GS_TRACE(name(), "end_of_elaboration called.");
// tell the protocol to assign sensitivies to the "process" methods
protocol_port->assignProcessMasterAccessSensitivity(p_PMAMethod);
protocol_port->assignProcessSlaveAccessSensitivity(p_PSAMethod);
// create the slave address map
GS_TRACE(name(), "Creating address map...");
m_addressMap.generateMap(getInitPort());
//m_addressMap.dumpMap();
GS_TRACE(name(), "Checking address map sanity (overlapping address regions)...");
m_addressMap.checkSanity();
}
//--------------------------------------------------------------------------
/**
* This is the PV TLM blocking if implementation
*/
//--------------------------------------------------------------------------
void b_transact(TRANSACTION_P t)
{
// TODO: catch decodeAddress exceptions
GS_TRACE(name(), "forwarding PV transaction from master id=0x%x directly to slave at address=0x%x",
(unsigned int)t->GenericTransaction::get_mID(), (unsigned)t->GenericTransaction::get_mAddr());
(*(init_port.connected_b_in_ports[decodeAddress(t->GenericTransaction::get_mAddr())]))->b_transact(t);
}
//--------------------------------------------------------------------------
/**
* GenericRouter_if's decodeAddress function.
*/
//--------------------------------------------------------------------------
virtual unsigned int decodeAddress(MAddr addr)
{
return m_addressMap.decode(addr);
}
private:
//--------------------------------------------------------------------------
/**
* Process handle to SC_METHOD processMasterAccess
* that will be triggered by the bus protocol class.
*/
//--------------------------------------------------------------------------
sc_process_b* p_PMAMethod;
//--------------------------------------------------------------------------
/**
* Process handle to SC_METHOD processSlaveAccess
* that will be triggered by the bus protocol class.
*/
//--------------------------------------------------------------------------
sc_process_b* p_PSAMethod;
};
#endif
See more files for this project here