如何理解这行凿子代码

How to understand this line of chisel code

我正在学习 chisel 和 scala 语言并尝试分析 rocket-chip 的一些行 code.Could 谁能解释一下这一行? https://github.com/chipsalliance/rocket-chip/blob/54237b5602a273378e3b35307bb47eb1e58cb9fb/src/main/scala/rocket/RocketCore.scala#L957

我明白 log2Up 函数在做什么,但不明白为什么 log2Up(n)-1 和 0 像 "arguments" 一样传递给 addr,它是 UInt 类型的 val!?

我找不到 UInt 的定义位置,但如果我不得不猜测,UInt 是一个具有 apply 方法的 class。这是一个特殊的方法,允许我们在 class.

的实例上使用括号运算符

例如,假设我们有一个名为 Multiply 的 class,它定义了一个 apply 方法。

class Multiply {
  def apply(a: Int, b: Int): Int = a * b
}

这允许您在 class 的任何实例上调用运算符 ()。例如:

val mul = new Multiply()
println(mul(5, 6)) // prints 30

我得出的结论是,我们使用 addr(log2Up(n)-1, 0) 来获取从零开始到 log2Up(n)-1 位的地址位。举个例子吧。

如果我们以这种方式创建 class RegFile 的对象

val reg = RegFile(31, 10)

首先,创建内存rf。该内存的大小是 31 个 UInt 类型的数据,宽度为 10,从 0 开始到 30。 当我们计算 log2Up(n)-1 时,我们得到 4,我们有这样的东西:addr(4,0)。这给了我们地址的最后五位。正如@Jack Koenig 在上面的评论之一中所说:"Rocket's register file uses a little trick where it reverses the order of the registers physically compared to the RISC-V",这就是我们使用 ~addr 的原因。至少 rf(~addr) 返回了那个内存位置的内容。

以这种方式实现以提供足够的内存访问。 看看如果我们尝试从内存中没有的内存位置获取数据会怎样。如果以这种方式调用方法访问

access(42)

我们尝试访问第 41 个位置的内存位置,但我们只有 31 个内存位置(30 是顶部)。 42二进制是101010。用我上面说的

~addr(log2Up(n)-1,0)

会 return 我们 10101 或十进制的 21。因为寄存器的顺序颠倒了这是 第 10 个内存位置(我们尝试访问第 41 个但只有 31 个,41 减去 31 是 10)。