| /***************************************************************************** |
| |
| Licensed to Accellera Systems Initiative Inc. (Accellera) under one or |
| more contributor license agreements. See the NOTICE file distributed |
| with this work for additional information regarding copyright ownership. |
| Accellera licenses this file to you under the Apache License, Version 2.0 |
| (the "License"); you may not use this file except in compliance with the |
| License. You may obtain a copy of the License at |
| |
| http://www.apache.org/licenses/LICENSE-2.0 |
| |
| Unless required by applicable law or agreed to in writing, software |
| distributed under the License is distributed on an "AS IS" BASIS, |
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or |
| implied. See the License for the specific language governing |
| permissions and limitations under the License. |
| |
| *****************************************************************************/ |
| |
| #ifndef __simpleAddressMap_h__ |
| #define __simpleAddressMap_h__ |
| |
| #include <systemc> |
| #include <map> |
| |
| |
| //-------------------------------------------------------------------------- |
| /** |
| * Simple address map implementation for the generic protocol. |
| */ |
| //-------------------------------------------------------------------------- |
| class SimpleAddressMap |
| { |
| typedef std::map<sc_dt::uint64, unsigned int> mapType; |
| typedef std::map<sc_dt::uint64, unsigned int>::iterator addressMapIterator; |
| |
| public: |
| SimpleAddressMap() {} |
| |
| //-------------------------------------------------------------------------- |
| /** |
| * 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."); |
| } |
| std::cout<<"Address check successful."<<std::endl; |
| } |
| |
| |
| //-------------------------------------------------------------------------- |
| /** |
| * Print map |
| */ |
| //-------------------------------------------------------------------------- |
| void dumpMap() |
| { |
| std::cout<<"SimpleAddressMap: printing the sorted MAP:"<<std::endl; |
| 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(sc_dt::uint64 address_) |
| { |
| addressMapIterator lbound; |
| |
| lbound=m_addressMap.lower_bound((address_+1)<<1); |
| if((lbound->second == 255) | (lbound==m_addressMap.end())){ |
| SC_REPORT_ERROR("SimpleAddressMap", "Address does not match any registered address range."); |
| } |
| else{ |
| return lbound->second; |
| } |
| return 255; |
| } |
| |
| const sc_dt::uint64& get_max(){ |
| if (m_addressMap.size()){ |
| addressMapIterator i=(m_addressMap.end()); |
| i--; |
| retval=(i->first>>1)-1; |
| return retval; |
| } |
| else { |
| SC_REPORT_ERROR("SimpleAddressMap", "get_max() called on empty address map."); |
| return retval; |
| } |
| } |
| |
| const sc_dt::uint64& get_min(){ |
| if (m_addressMap.size()){ |
| addressMapIterator i=(m_addressMap.begin()); |
| retval=((i->first+1)>>1)-1; |
| return retval; |
| } |
| else { |
| SC_REPORT_ERROR("SimpleAddressMap", "get_min() called on empty address map."); |
| return retval; |
| } |
| } |
| |
| //-------------------------------------------------------------------------- |
| /** |
| * Insert a slave into the address map |
| */ |
| //-------------------------------------------------------------------------- |
| void insert(sc_dt::uint64 baseAddress_, sc_dt::uint64 highAddress_, unsigned int portNumber_) |
| { |
| if(baseAddress_>highAddress_) |
| SC_REPORT_ERROR("SimpleAddressMap", "Base address must be lower than high address."); |
| if(portNumber_>=255) |
| SC_REPORT_ERROR("SimpleAddressMap", "Only ;-) 255 targets can be handled."); |
| m_addressMap.insert(mapType::value_type(((baseAddress_+1)<<1)-1, 255 )); |
| m_addressMap.insert(mapType::value_type( (highAddress_+1)<<1 ,portNumber_)); |
| } |
| |
| private: |
| sc_dt::uint64 retval; |
| /// the address map |
| mapType m_addressMap; |
| }; |
| |
| |
| |
| |
| #endif |