Show simpleAddressMap.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 __simpleAddressMap_h__
#define __simpleAddressMap_h__
#include "systemc.h"
#include "protocol/generic.h"
#include "gstlm/tlm.h"
#include "gstlm/tlm_slave_if.h"
#include <map>
using namespace tlm;
//--------------------------------------------------------------------------
/**
* Simple address map implementation.
*/
//--------------------------------------------------------------------------
template<typename ADD, class INITPORT, class TRANSACTION, class PHASE>
class SimpleAddressMap
{
typedef sc_export<payload_event_queue_if<tlm::unevenpair<boost::shared_ptr<TRANSACTION>,PHASE > > > * destinationPort;
typedef typename std::map<ADD, unsigned int>::iterator addressMapIterator;
public:
SimpleAddressMap() {}
//--------------------------------------------------------------------------
/**
* Generate an address map from the connected slaves
*/
//--------------------------------------------------------------------------
void generateMap(INITPORT* port)
{
if(port == NULL)
{
SC_REPORT_ERROR("Address Map", "Null pointer passed to GenerateMap().");
}
MAddr b,h;
const char* target_name;
GS_TRACE("SimpleAddressMap", "Generating address map:");
GS_TRACE("SimpleAddressMap", "Number of connected slaves: %d", ( *port ).connected_in_ports.size());
for (unsigned int i=0; i<( *port ).connected_in_ports.size(); i++)
{
destinationPort destination= ( *port ).connected_in_ports[i];
// check whether slave is itself sc_module (then we need a second getParent) or not (a UserAPI might only extend from tlm_port)
bool doubleParent = true;
if (dynamic_cast< tlm_slave_if<ADD>* >((*destination).get_parent()->get_parent()) == 0)
{
if (dynamic_cast< tlm_slave_if<ADD>* >((*destination).get_parent()) != 0)
{
GS_TRACE("SimpleAddressMap", "target.get_parent() is a tlm_slave_if");
doubleParent = false;
}
else
{
SC_REPORT_ERROR("SimpleAddressMap", "Slaves must implement the tlm_slave_if!");
}
}
else
{
GS_TRACE("SimpleAddressMap", "target.get_parent()->get_parent() is a tlm_slave_if");
}
if (doubleParent)
{
(dynamic_cast< tlm_slave_if<ADD>* >((*destination).get_parent()->get_parent()))->getAddress(b,h);
target_name=(dynamic_cast<sc_object*>((*destination).get_parent()->get_parent()))->name();
}
else
{
(dynamic_cast< tlm_slave_if<ADD>* >((*destination).get_parent()))->getAddress(b,h);
target_name=(dynamic_cast<sc_object*>((*destination).get_parent()))->name();
}
char str[256];
GS_TRACE("SimpleAddressMap", "Target=%s is connected to port number %d, Baseaddress=0x%x, Highaddress=0x%x",
target_name, i, (unsigned int)b, (unsigned int)h);
insert(b,h,i);
}
}
//--------------------------------------------------------------------------
/**
* Check for overlapping address ranges
*/
//--------------------------------------------------------------------------
void checkSanity()
{
addressMapIterator pos;
for (pos=m_addressMap.begin();pos!=m_addressMap.end();++pos){
if(pos->second!=255)
SC_REPORT_ERROR("SimpleAddressMap","Overlapping Address Regions.");
else
++pos;
if(pos->second==255)
SC_REPORT_ERROR("SimpleAddressMap","Overlapping Address Regions.");
}
GS_TRACE("SimpleAddressMap", "Address sanity check successfull.");
}
//--------------------------------------------------------------------------
/**
* Print map
*/
//--------------------------------------------------------------------------
void dumpMap()
{
cout<<"SimpleAddressMap: printing the sorted MAP:"<<endl<<flush;
addressMapIterator pos;
for (pos=m_addressMap.begin();pos!=m_addressMap.end();++pos){
if(pos->second==255)
printf("key: %x value: %i \n", (unsigned int) ((pos->first+1)>>1)-1, pos->second);
else
printf("key: %x value: %i \n", (unsigned int) (pos->first>>1)-1, pos->second);
}
}
//--------------------------------------------------------------------------
/**
* Decode slave address.
* @param address_ A slave address.
* @return The decoded slave port number. On error, the value 255 is returned.
*/
//--------------------------------------------------------------------------
unsigned int decode(MAddr address_)
{
addressMapIterator lbound;
if(address_>0xffffffff)
SC_REPORT_ERROR("SimpleAddressMap", "Address must not exceed 32 bits in width.");
lbound=m_addressMap.lower_bound(((ADD) address_+1)<<1);
if(lbound->second == 255 | lbound==m_addressMap.end()){
GS_TRACE("SimpleAddressMap", "Decode attempt for address 0x%x failed:\n", (unsigned int)address_);
SC_REPORT_ERROR("SimpleAddressMap", "Address does not match any registered address range.");
}
else{
return lbound->second;
}
return 255;
}
private:
typedef std::map< ADD, unsigned int> mapType;
//--------------------------------------------------------------------------
/**
* Insert a slave into the address map
*/
//--------------------------------------------------------------------------
void insert(MAddr baseAddress_, MAddr highAddress_, unsigned int portNumber_)
{
if(baseAddress_>highAddress_)
SC_REPORT_ERROR("Address Map", "Base address must be lower than high address.");
if(baseAddress_>0xffffffff | highAddress_>0xffffffff)
SC_REPORT_ERROR("Address Map", "Addresses must not exceed 32 bits in width.");
if(portNumber_>=255)
SC_REPORT_ERROR("Address Map", "Only ;-) 255 targets can be handled.");
m_addressMap.insert(typename mapType::value_type(((baseAddress_+1)<<1)-1, 255 ));
m_addressMap.insert(typename mapType::value_type( (highAddress_+1)<<1 ,portNumber_));
}
/// the address map
mapType m_addressMap;
};
#endif
See more files for this project here