https://mp.weixin.qq.com/s/qqL2XWqAhVcnGSxs6kxhLg
。
1. 基本定义
A non-empty half-open range; [start, end)
非空,半闭合区间。
限定条件如下:
a. start >= 0;
b. start <= end;
2. compare
比较方法。用于排序。
3. overlaps
判断是否重叠。
4. contains
this contains x,x的区间完全处在this的区间范围内。
电路生成器:
a. 如果this.size == 0,那么this不可能包含x;
b. 如果this.size == 1,那么只需要判断x是否等于start即可;
c. 把this分成两部分进行比较:高位一直不变的部分和低位变化的部分。
首先,this的有效部分即从start到end-1的过程中,高位始终保持不变的位,与x相应的高位进行比较;
其次,低位变化的位数进行比较,即:LowPartOf(start) <= LowPartOf(x) <= LowPartOf(end-1);
其中:
LowPartOf(start) = start & uncommonMask;
LowPartOf(end-1) = (end-1) & uncommonMask;
LowPartOf(x) = uncommonBits,其计算使用位截取;
(x >> smallestCommonBit) === UInt(start >> smallestCommonBit)
因为x和start的类型不同,所以这里的两个移位符号并不是同一个方法。
虽然在构建时,第一个移位和第二个移位都会执行,但第一个移位方法只是添加一个针对x的移位命令,用于构建一个移位逻辑,真正的移位动作发生在硬件中。而第二个针对start的移位方法,是切切实实直接执行的移位动作,当时就发生了移位(在软件中)。
5. shift
区间平移。
6. size
区间包含整数的个数。
7. isEmpty
区间是否为空。
8. range
返回一个Range对象。
9. 伴生对象
检查IdRange序列s中的区间是否存在重叠。
10. 附录
IdRange:
// A non-empty half-open range; [start, end)
[IdRange]
{
)
)
compare(x: IdRange) = {
.start - x.start).signum
.end).signum
secondary
}
overlaps(x: IdRange) = start < x.end && x.start < end
contains(x: IdRange) = start <= x.start && x.end <= end
contains(x: Int) = start <= x && x < end
) =
) {
)
// simple comparison
x === UInt(start)
{
// find index of largest different bit
))
// may not exist in x
1
)
// the prefix must match exactly (note: may shift ALL bits away)
(x >> smallestCommonBit) === UInt(start >> smallestCommonBit) &&
// firrtl constant prop range analysis can eliminate these two:
UInt(start & uncommonMask) <= uncommonBits &&
) & uncommonMask)
}
shift(x: Int) = IdRange(start+x, end+x)
size = end - start
isEmpty = end == start
range = start until end
}
IdRange
{
{
ranges = s.sorted
(a, b) => a overlaps b }
}
}