我在编译此 Scala 2 代码时遇到问题:
import chisel3._
import circt.stage.ChiselStage.emitCHIRRTL
class Box[X](val content: X)
abstract class Combination[I <: Bits, O <: Bits] {
def fn1: I => O
def fn2: Box[I] => I
}
object Comb1 extends Combination[SInt, SInt] {
def fn1 = (x: SInt) => x
def fn2 = (x: Box[SInt]) => x.content
}
object Comb2 extends Combination[UInt, UInt] {
def fn1 = (x: UInt) => x
def fn2 = (x: Box[UInt]) => x.content
}
val rand = new scala.util.Random
val temp = rand.nextInt(2) + 1
val comb = temp match {
case 1 => Comb1
case 2 => Comb2
}
class TopModule[I <: Bits, O <: Bits](comb: Combination[I, O]) extends Module
println(emitCHIRRTL(new TopModule(comb)))
但是,我得到的错误如下:
type mismatch;
found : Playground.Combination[_ >: chisel3.SInt with chisel3.UInt <: chisel3.Bits with chisel3.Num[_ >: chisel3.SInt with chisel3.UInt <: chisel3.Bits], _ >: chisel3.SInt with chisel3.UInt <: chisel3.Bits with chisel3.Num[_ >: chisel3.SInt with chisel3.UInt <: chisel3.Bits]]{def fn2: Playground.Box[chisel3.SInt] with Playground.Box[chisel3.UInt] => chisel3.Bits}
required: Playground.Combination[chisel3.Bits with chisel3.Num[_ >: chisel3.SInt with chisel3.UInt <: chisel3.Bits],chisel3.Bits with chisel3.Num[_ >: chisel3.SInt with chisel3.UInt <: chisel3.Bits]]
此示例可在 Scastie 上使用:https://scastie.scala-lang.org/JersAqMWRAC3Zgykbewr5A
任何人都可以帮助我理解为什么会发生这种情况吗?我意识到这在某种程度上是包含
fn2
的效果,它使用了 Boxed 参数。因此,如果我删除 fn2
实例,此代码可以正常编译。
我的目标是使用
Combination
来参数化 TopModule
和其他类似的类。
虽然
SInt
和 UInt
都是 Bits
的子类型,但它们彼此不兼容。当您在 Comb1
和 Comb2
之间进行模式匹配时,必须为结果分配一个类型,但 Scala 无法确定满足两者的通用超类型,因为 fn2
需要 Box[SInt]
或 Box[UInt]
。这种不匹配导致了错误。
为了解决这个问题,我在
Combination
类中使用了路径相关类型,并且效果很好 here。
import chisel3._
import circt.stage.ChiselStage.emitCHIRRTL
import chisel3.util._
import chisel3.experimental.VecLiterals._
class Box[X](val content: X)
abstract class Combination{
type I <: Bits
type O <: Bits
def fn1: I => O
def fn2: Box[I] => I
}
object Comb1 extends Combination {
type I = SInt
type O = SInt
def fn1 = (x: I) => x
def fn2 = (x: Box[I]) => x.content
}
object Comb2 extends Combination {
type I = UInt
type O = UInt
def fn1 = (x: I) => x
def fn2 = (x: Box[I]) => x.content
}
val rand = new scala.util.Random
val temp = rand.nextInt(2) + 1
val comb: Combination = temp match {
case 1 => Comb1
case 2 => Comb2
}
class TopModule(val comb: Combination) extends Module
println(emitCHIRRTL(new TopModule(comb)))