41#ifndef __BASE_ADDR_RANGE_HH__
42#define __BASE_ADDR_RANGE_HH__
107 template <
class Iterator>
111 if (begin_it != end_it) {
113 _start = begin_it->_start;
114 _end = begin_it->_end;
115 masks = begin_it->masks;
119 auto count = std::distance(begin_it, end_it);
124 "Got %d ranges spanning %d interleaving bits.",
128 for (
auto it = begin_it; it != end_it; it++) {
130 "Can only merge ranges with the same start, end "
131 "and interleaving bits, %s %s.",
to_string(),
135 "Expected interleave match %d but got %d when "
136 "merging.", match, it->intlvMatch);
184 uint8_t _intlv_match)
190 "Match value %d does not fit in %d interleaving bits\n",
191 _intlv_match,
masks.size());
221 uint8_t _xor_high_bit, uint8_t _intlv_bits,
222 uint8_t _intlv_match)
227 fatal_if(_intlv_bits && _intlv_match >= 1ULL << _intlv_bits,
228 "Match value %d does not fit in %d interleaving bits\n",
229 _intlv_match, _intlv_bits);
232 if (_intlv_bits && _xor_high_bit) {
233 if (_xor_high_bit == _intlv_high_bit) {
234 fatal(
"XOR and interleave high bit must be different\n");
235 }
else if (_xor_high_bit > _intlv_high_bit) {
236 if ((_xor_high_bit - _intlv_high_bit) < _intlv_bits)
237 fatal(
"XOR and interleave high bit must be at least "
238 "%d bits apart\n", _intlv_bits);
240 if ((_intlv_high_bit - _xor_high_bit) < _intlv_bits) {
241 fatal(
"Interleave and XOR high bit must be at least "
242 "%d bits apart\n", _intlv_bits);
247 for (
auto i = 0;
i < _intlv_bits;
i++) {
248 uint8_t bit1 = _intlv_high_bit -
i;
251 uint8_t bit2 = _xor_high_bit -
i;
252 mask |= (1ULL << bit2);
297 auto combined_mask = 0;
299 combined_mask |=
mask;
301 const uint8_t lowest_bit =
ctz64(combined_mask);
302 return 1ULL << lowest_bit;
364 for (
unsigned int i = 0;
i <
masks.size();
i++) {
369 mask &= ~(1ULL << bit);
429 panic(
"Cannot test intersection of %s and %s\n",
448 panic(
"Cannot test subset of interleaved range %s\n",
to_string());
454 if (
r.interleaved()) {
456 size() <=
r.granularity();
464 return _start >=
r._start &&
r._end == 0;
465 }
else if (
r._end <=
r._start){
497 for (
unsigned int i = 0;
i <
masks.size();
i++) {
544 int masks_lsb[
masks.size()];
545 for (
unsigned int i = 0;
i <
masks.size();
i++) {
551 std::sort(masks_lsb, masks_lsb +
masks.size());
553 for (
unsigned int i = 0;
i <
masks.size();
i++) {
554 const int intlv_bit = masks_lsb[
i];
583 int masks_lsb[
masks.size()];
584 for (
unsigned int i = 0;
i <
masks.size();
i++) {
589 std::sort(masks_lsb, masks_lsb +
masks.size());
590 for (
unsigned int i = 0;
i <
masks.size();
i++) {
591 const int intlv_bit = masks_lsb[
i];
603 for (
unsigned int i = 0;
i <
masks.size();
i++) {
661 auto sorted_ranges = exclude_ranges;
662 sorted_ranges.sort();
667 for (
const auto &
e : sorted_ranges) {
668 assert(!
e.interleaved());
673 if (
e.start() <= next_start) {
674 if (
e.end() <
end()) {
675 if (next_start <
e.end()) {
676 next_start =
e.end();
682 ranges.push_back(
AddrRange(next_start,
e.start()));
683 if (
e.end() <
end()) {
684 next_start =
e.end();
691 if (next_start <
end()) {
737 if (
_start !=
r._start)
return false;
738 if (
_end !=
r._end)
return false;
739 if (
masks !=
r.masks)
return false;
751 return !(*
this ==
r);
761 "Cannot calculate intersection of interleaved ranges.");
762 Addr start = std::max(this->_start,
r._start);
763 Addr end = std::min(this->_end,
r._end);
774 return range.
exclude(to_exclude);
780 return range.
exclude(to_exclude);
789 for (
const auto &range:
base)
790 ret.splice(ret.end(), range.exclude(to_exclude));
Defines global host-dependent types: Counter, Tick, and (indirectly) {int,uint}{8,...
The AddrRange class encapsulates an address range, and supports a number of tests to check if two ran...
uint8_t intlvMatch
The value to compare sel with.
AddrRange(Addr _start, Addr _end)
AddrRange(std::list< AddrRange > ranges)
AddrRangeList exclude(const AddrRange &excluded_range) const
AddrRange(Dummy, Iterator begin_it, Iterator end_it)
std::vector< Addr > masks
Each mask determines the bits we need to xor to get one bit of sel.
Addr _start
Private fields for the start and end of the range _start is the beginning of the range (inclusive).
bool interleaved() const
Determine if the range is interleaved or not.
AddrRange operator&(const AddrRange &r) const
bool operator!=(const AddrRange &r) const
bool isSubset(const AddrRange &r) const
Determine if this range is a subset of another range, i.e.
AddrRange RangeEx(Addr start, Addr end)
AddrRange RangeSize(Addr start, Addr size)
Addr removeIntlvBits(Addr a) const
Remove the interleaving bits from an input address.
AddrRange(Addr _start, Addr _end, const std::vector< Addr > &_masks, uint8_t _intlv_match)
Construct an address range.
uint64_t granularity() const
Determing the interleaving granularity of the range.
AddrRange(std::vector< AddrRange > ranges)
Create an address range by merging a collection of interleaved ranges.
AddrRange RangeIn(Addr start, Addr end)
std::list< AddrRange > AddrRangeList
Convenience typedef for a collection of address ranges.
AddrRangeList exclude(const AddrRangeList &exclude_ranges) const
Subtract a list of intervals from the range and return the resulting collection of ranges,...
uint32_t stripes() const
Determine the number of interleaved address stripes this range is part of.
bool valid() const
Determine if the range is valid.
bool contains(const Addr &a) const
Determine if the range contains an address.
Addr getOffset(const Addr &a) const
Determine the offset of an address within the range.
bool intersects(const AddrRange &r) const
Determine if another range intersects this one, i.e.
Addr end() const
Get the end address of the range.
bool mergesWith(const AddrRange &r) const
Determine if another range merges with the current one, i.e.
Addr start() const
Get the start address of the range.
Addr size() const
Get the size of the address range.
bool operator<(const AddrRange &r) const
Less-than operator used to turn an STL map into a binary search tree of non-overlapping address range...
AddrRange(Addr _start, Addr _end, uint8_t _intlv_high_bit, uint8_t _xor_high_bit, uint8_t _intlv_bits, uint8_t _intlv_match)
Legacy constructor of AddrRange.
std::string to_string() const
Get a string representation of the range.
Addr addIntlvBits(Addr a) const
This method adds the interleaving bits removed by removeIntlvBits.
bool operator==(const AddrRange &r) const
constexpr T bits(T val, unsigned first, unsigned last)
Extract the bitfield from position 'first' to 'last' (inclusive) from 'val' and right justify it.
constexpr int popCount(uint64_t val)
Returns the number of set ones in the provided value.
constexpr T insertBits(T val, unsigned first, unsigned last, B bit_val)
Returns val with bits first to last set to the LSBs of bit_val.
constexpr int ctz64(uint64_t value)
Count trailing zeros in a 64-bit value.
#define panic(...)
This implements a cprintf based panic() function.
#define fatal_if(cond,...)
Conditional fatal macro that checks the supplied condition and only causes a fatal error if the condi...
#define fatal(...)
This implements a cprintf based fatal() function.
#define panic_if(cond,...)
Conditional panic macro that checks the supplied condition and only panics if the condition is true a...
Copyright (c) 2024 - Pranith Kumar Copyright (c) 2020 Inria All rights reserved.
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
static AddrRangeList exclude(const AddrRangeList &base, AddrRangeList to_exclude)
std::string csprintf(const char *format, const Args &...args)
static AddrRangeList operator-=(AddrRangeList &base, const AddrRangeList &to_exclude)
static AddrRangeList operator-(const AddrRange &range, const AddrRangeList &to_exclude)