simpleAddressMap.h revision 12855:588919e0e4aa
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#ifndef __simpleAddressMap_h__
21#define __simpleAddressMap_h__
22
23#include <systemc>
24#include <map>
25
26
27//--------------------------------------------------------------------------
28/**
29 * Simple address map implementation for the generic protocol.
30 */
31//--------------------------------------------------------------------------
32class SimpleAddressMap
33{
34  typedef std::map<sc_dt::uint64, unsigned int> mapType;
35  typedef std::map<sc_dt::uint64, unsigned int>::iterator addressMapIterator;
36
37public:
38  SimpleAddressMap() {}
39
40  //--------------------------------------------------------------------------
41  /**
42   * Check for overlapping address ranges
43   */
44  //--------------------------------------------------------------------------
45  void checkSanity()
46  {
47    addressMapIterator pos;
48    for (pos=m_addressMap.begin();pos!=m_addressMap.end();++pos){
49      if(pos->second!=255)
50        SC_REPORT_ERROR("SimpleAddressMap","Overlapping Address Regions.");
51      else
52        ++pos;
53      if(pos->second==255)
54        SC_REPORT_ERROR("SimpleAddressMap","Overlapping Address Regions.");
55    }
56    std::cout<<"Address check successful."<<std::endl;
57  }
58
59
60  //--------------------------------------------------------------------------
61  /**
62   * Print map
63   */
64  //--------------------------------------------------------------------------
65  void dumpMap()
66  {
67    std::cout<<"SimpleAddressMap: printing the sorted MAP:"<<std::endl;
68    addressMapIterator pos;
69    for (pos=m_addressMap.begin();pos!=m_addressMap.end();++pos){
70      if(pos->second==255)
71        printf("key: %x    value: %i \n", (unsigned int) ((pos->first+1)>>1)-1, pos->second);
72      else
73        printf("key: %x    value: %i \n", (unsigned int) (pos->first>>1)-1, pos->second);
74    }
75  }
76
77
78  //--------------------------------------------------------------------------
79  /**
80   * Decode slave address.
81   * @param address_ A slave address.
82   * @return The decoded slave port number. On error, the value 255 is returned.
83   */
84  //--------------------------------------------------------------------------
85  unsigned int decode(sc_dt::uint64 address_)
86  {
87    addressMapIterator lbound;
88
89    lbound=m_addressMap.lower_bound((address_+1)<<1);
90    if((lbound->second == 255) | (lbound==m_addressMap.end())){
91      SC_REPORT_ERROR("SimpleAddressMap", "Address does not match any registered address range.");
92    }
93    else{
94      return lbound->second;
95    }
96    return 255;
97  }
98
99  const sc_dt::uint64& get_max(){
100    if (m_addressMap.size()){
101      addressMapIterator i=(m_addressMap.end());
102      i--;
103      retval=(i->first>>1)-1;
104      return retval;
105    }
106    else {
107      SC_REPORT_ERROR("SimpleAddressMap", "get_max() called on empty address map.");
108      return retval;
109    }
110  }
111
112  const sc_dt::uint64& get_min(){
113    if (m_addressMap.size()){
114      addressMapIterator i=(m_addressMap.begin());
115      retval=((i->first+1)>>1)-1;
116      return retval;
117    }
118    else {
119      SC_REPORT_ERROR("SimpleAddressMap", "get_min() called on empty address map.");
120      return retval;
121    }
122  }
123
124  //--------------------------------------------------------------------------
125  /**
126   * Insert a slave into the address map
127   */
128  //--------------------------------------------------------------------------
129  void insert(sc_dt::uint64 baseAddress_, sc_dt::uint64 highAddress_, unsigned int portNumber_)
130  {
131    if(baseAddress_>highAddress_)
132      SC_REPORT_ERROR("SimpleAddressMap", "Base address must be lower than high address.");
133    if(portNumber_>=255)
134      SC_REPORT_ERROR("SimpleAddressMap", "Only ;-) 255 targets can be handled.");
135    m_addressMap.insert(mapType::value_type(((baseAddress_+1)<<1)-1,    255    ));
136    m_addressMap.insert(mapType::value_type( (highAddress_+1)<<1   ,portNumber_));
137  }
138
139private:
140  sc_dt::uint64 retval;
141  /// the address map
142  mapType m_addressMap;
143};
144
145
146
147
148#endif
149