我正在研究一个 Z-Scale RISCV 处理器,我已经在数据路径中实现了新的功能和逻辑。我想知道是否存在一种简单的方法来“关闭”代码的某些部分而不使用一堆 if 循环?我想让 Z 级处理器的常规实现和扩展实现之间的切换变得容易。
我实现的新逻辑并没有取代数据路径的主要组件,而是扩展了功能。
我正在研究一个 Z-Scale RISCV 处理器,我已经在数据路径中实现了新的功能和逻辑。我想知道是否存在一种简单的方法来“关闭”代码的某些部分而不使用一堆 if 循环?我想让 Z 级处理器的常规实现和扩展实现之间的切换变得容易。
我实现的新逻辑并没有取代数据路径的主要组件,而是扩展了功能。
这个问题真正触及了 Chisel 强大的核心。作为嵌入在 Scala 中的 DSL,您可以使用面向对象和函数式编程语言的全部功能。
虽然我不确定你在做什么,但这似乎是一个使用继承的好地方。您可以创建一个扩展数据路径模块并添加附加功能的新模块类。
一个玩具例子:
import Chisel._
class ParentIO extends Bundle {
val foo = UInt(width = 32).asInput
val bar = UInt(width = 32).asOutput
}
class Parent extends Module {
// Note the use of lazy val
// Due to Scala initialization order (http://docs.scala-lang.org/tutorials/FAQ/initialization-order.html)
// this cannot be a val
// Due to quirks of Chisel, this cannot be a def
lazy val io = new ParentIO
io.bar := io.foo
}
class ChildIO extends ParentIO {
val isOdd = Bool().asOutput
}
class Child extends Parent {
override lazy val io = new ChildIO
io.isOdd := io.foo(0)
}
// Note use of call-by-name for passing gen
// Chisel Modules must be constructed within a call to the Module(...) function
class Top(gen: => Parent) extends Module {
val dut = Module(gen)
val io = dut.io.cloneType
io <> dut.io
}
Module Top 由它实例化的 Module 的类型参数化:Parent 或 Child。因此,您可以有条件地实例化 Parent 或 Child 而不是区分它们的所有逻辑。如果您希望子项覆盖父项的某些功能,Chisel 的最后一个连接语义允许子项中的任何连接覆盖父项中的连接。
听起来您的代码如下所示:
val a = Wire(UInt())
if (extension)
a := 1.U
else
a := 2.U
您可以做的是创建一个 Z-scale 类和一个 Z-scale-extended 类,该类实现包含两种设计之间差异的特征。
trait RISC_V_Processor {
def do_a : UInt
}
class Z_Scale with RISC_V_Processor {
def do_a : UInt = 2.U
}
class Z_Scale_extended with RISC_V_Processor {
def do_a : UInt = 1.U
}
val processor = new Z_Scale_extended()
val a = processor.do_a()
这实质上是用多态性代替条件。 https://sourcemaking.com/refactoring/replace-conditional-with-polymorphism