A SystemC productivity library for virtual platform development utilizing SCV and TLM2.0 https://www.minres.com/#opensource

sparse_array.h 2.7KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. /*******************************************************************************
  2. * Copyright 2017 MINRES Technologies GmbH
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. *******************************************************************************/
  16. #ifndef _SPARSE_ARRAY_H_
  17. #define _SPARSE_ARRAY_H_
  18. #include <array>
  19. #include <cassert>
  20. namespace util {
  21. /**
  22. * a simple array which allocates memory in configurable chunks (size of 2^lower_width), used for
  23. * large sparse arrays. Memory is allocated on demand
  24. */
  25. template <typename T, uint64_t SIZE, int lower_width = 24> class sparse_array {
  26. public:
  27. const uint64_t page_addr_mask = (1 << lower_width) - 1;
  28. const uint64_t page_size = (1 << lower_width);
  29. const unsigned page_count = 1 + SIZE / page_size;
  30. const uint64_t page_addr_width = lower_width;
  31. using page_type = std::array<T, 1 << lower_width>;
  32. /**
  33. * the default constructor
  34. */
  35. sparse_array() { arr.fill(nullptr); }
  36. /**
  37. * the destructor
  38. */
  39. ~sparse_array() {
  40. for (auto i : arr) delete i;
  41. }
  42. /**
  43. * element access operator
  44. *
  45. * @param addr address to access
  46. * @return the data type reference
  47. */
  48. T &operator[](uint32_t addr) {
  49. assert(addr < SIZE);
  50. T nr = addr >> lower_width;
  51. if (arr[nr] == nullptr) arr[nr] = new page_type();
  52. return arr[nr]->at(addr & page_addr_mask);
  53. }
  54. /**
  55. * page fetch operator
  56. *
  57. * @param page_nr the page number ot fetch
  58. * @return reference to page
  59. */
  60. page_type &operator()(uint32_t page_nr) {
  61. assert(page_nr < page_count);
  62. if (arr[page_nr] == nullptr) arr[page_nr] = new page_type();
  63. return *(arr[page_nr]);
  64. }
  65. /**
  66. * check if page for address is allocated
  67. *
  68. * @param addr the address to check
  69. * @return true if the page is allocated
  70. */
  71. bool is_allocated(uint32_t addr) {
  72. assert(addr < SIZE);
  73. T nr = addr >> lower_width;
  74. return arr[nr] != nullptr;
  75. }
  76. /**
  77. * get the size of the array
  78. *
  79. * @return the size
  80. */
  81. uint64_t size() { return SIZE; }
  82. protected:
  83. std::array<page_type *, SIZE / (1 << lower_width) + 1> arr;
  84. };
  85. }
  86. #endif /* _SPARSE_ARRAY_H_ */