我得出的结论是,我们使用 addr(log2Up(n)-1, 0) 来获取从零开始到 log2Up(n)-1 位的地址位。让我们举个例子。
如果我们以这种方式创建类 RegFile 的对象
val reg = RegFile(31, 10)
首先,创建内存 rf。该内存的大小是 31 个 UInt 宽度为 10 的数据,从 0 到 30。当我们计算 log2Up(n)-1 时,我们得到 4,我们有这样的东西:addr(4,0)。这给了我们最后五位 addr。就像@Jack Koenig 在上面的评论中所说的那样:“Rocket 的寄存器文件使用了一个小技巧,与 RISC-V 相比,它在物理上颠倒了寄存器的顺序”,这就是我们使用 ~addr 的原因。并且至少 rf(~addr) 让我们返回了那个内存位置的内容。
这是以这种方式实现的,以提供足够的内存访问。看看如果我们尝试从我们的内存中没有的内存位置获取数据会发生什么。如果以这种方式调用方法访问
access(42)
我们尝试访问第 41 个位置的内存位置,但我们只有 31 个内存位置(30 是顶部)。42二进制是101010。使用我上面所说的
~addr(log2Up(n)-1,0)
将以十进制返回 10101 或 21。因为寄存器的顺序是颠倒的,所以这是第 10 个内存位置(我们尝试访问第 41 个但只有 31 个,41 减去 31 是 10)。