【问题标题】:Use generic type to turn off logic in datapath (Chisel)使用泛型类型关闭数据路径中的逻辑(凿子)
【发布时间】:2016-11-17 09:00:47
【问题描述】:

我正在开发一个 Z-Scale RISCV 处理器,我已经在数据路径中实现了新的功能和逻辑。我想知道是否存在一种简单的方法来“关闭”代码的某些部分而不使用一堆 if 循环?我想让 Z 规模处理器的常规实现和扩展实现之间的切换变得容易。

我实现的新逻辑并没有取代数据路径的主要组件,而是扩展了功能。

【问题讨论】:

    标签: scala generic-programming hdl riscv chisel


    【解决方案1】:

    这个问题真正触及了 Chisel 强大的核心。作为嵌入在 Scala 中的 DSL,您可以使用面向对象和函数式编程语言的全部功能。

    虽然我不确定您在做什么,但这似乎是使用继承的好地方。您可以创建一个新的 Module 类来扩展数据路径 Module 并添加其他功能。

    一个玩具例子:

    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 而不是区分它们的所有逻辑。如果您希望 Child 覆盖父级的某些功能,Chisel 的最后一个连接语义允许 Child 中的任何连接覆盖 Parent 中的连接。

    【讨论】:

    • 感谢您的回复!我想知道是否有可能有一个可以控制Module Top参数的变量,所以如果变量设置为1,它将实例化Child,否则实例化Parent?我尝试了不同的想法,但没有得到我想要的。
    • @JackKoenig 嗨,我试过你的方法,但出现以下错误,Error:(210, 21) overriding lazy value io in class SPadCommonModule of type SPadCommonModuleIO; lazy value io has incompatible type override lazy val io = new SPadModuleIO (dataWidth = DataWidth, padSize = PadSize),想知道在这种情况下如何覆盖 IO。
    • 我认为这是说您正在使用不是子类型的类型覆盖 lazy val io。例如,如果lazy val io = IO(new Animal),用override lazy val io = IO(new Cat) 覆盖是合法的,但用override lazy val io = IO(new Apple) 覆盖是合法的,请确保您在覆盖中实例化的 Bundle 类扩展了您正在扩展的父级使用的 Bundle。
    【解决方案2】:

    听起来你的代码是这样的:

    val a = Wire(UInt())
    if (extension)
        a := 1.U
    else
        a := 2.U
    

    你可以做的是创建一个 Z 比例的类 和一个实现 Z 尺度扩展的类 包含之间差异的特征 两种设计。

    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

    【讨论】:

    • 我只是想指出第一个示例由于重新分配给a而不是连接而无法编译,它应该是a := 1.Ua := 2.U
    • 是的,这是为了说明一个观点而快速绘制的,不过会修复它。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-09
    • 1970-01-01
    相关资源
    最近更新 更多