如何理解这一行凿子代码

我正在学习凿子和斯卡拉语言,并尝试分析一些火箭芯片代码行,有人可以尝试向我解释这一行吗? https://github.com/chipsalliance/rocket-chip/blob/54237b5602a273378e3b35307bb47eb1e58cb9fb/src/main/scala/rocket/RocketCore.scala#L957

我了解log2Up函数在做什么,但不了解为什么将log2Up(n)-1和0像“参数”一样传递给类型为UInt的val的addr!?

xkdtj 回答:如何理解这一行凿子代码

我找不到UInt的定义位置,但是如果我不得不猜测,UInt是具有class方法的apply。这是一种特殊的方法,它使我们可以在类的实例上使用括号运算符。

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

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

这使您可以在该类的任何实例上调用运算符()。例如:

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

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

如果我们以此方式成为RegFile类的对象

val reg = RegFile(31,10)

首先,创建内存rf。该内存的大小是UInt宽度为10的31个数据,从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)。

本文链接:https://www.f2er.com/3122255.html

大家都在问