我正在使用Chisel,但实际上这是一个Scala问题。 我想要做的是覆盖>派生对象的运算符。 考虑以下类别:
class Record extends Bundle {
val key = UInt(32.W)
val data = UInt(8.W)
def > (rhs:Record) = key > rhs.key
}
class RecordIndexed extends Record {
val index = UInt(8.W)
def > (rhs:RecordIndexed) = key > rhs.key || (key === rhs.key && index > rhs.index)
}
然后我想为从Record:
派生的任何记录类型构建一个通用比较器class Comparator[T <: Record](gen: T) extends Module {
val io = IO(new bundle {
val a = Flipped(Valid(gen))
val b = Flipped(Valid(gen))
val o = Output(Bool())
}
io.o := io.a.valid && io.b.valid && io.a.bits > io.b.bits
}
我可以使用
Comparator(new Record)
但是当我尝试
时它失败了Comparator(new RecordIndexed)
它传递编译器但是&gt; operator始终是Record中的一个,而不是RecordIndexed中的一个。
我有点理解为什么,因为&gt;是过载而不是覆盖。根据比较器中的类型T,编译器将静态选择&gt;来自记录。
我如何解决这个问题并让Scala选择重载?我认为打字特质是一种方法,但完全没有弄清楚如何。
答案 0 :(得分:0)
@ wei-song从编辑到问题复制:
根据@dveim的建议,我尝试了类型,最后它起作用了:
class Record extends Bundle {
val key = UInt(32.W)
val data = UInt(8.W)
}
class RecordIndexed extends Record {
val index = UInt(8.W)
}
object record_operation {
trait RecordLike[t] {
def isLarger(l: T, r: T): Bool
}
object RecordLike {
implicit object RecordLikeRecord extends RecordLike[Record] {
def isLarger(l: Record, r: Record): Bool =
l.key > r.key
}
implicit object RecordLikeRecordIndexed extends RecordLike[RecordIndexed] {
def isLarger(l: RecordIndexed, r: RecordIndexed): Bool =
l.key > r.key || (l.key === r.key && l.index > r.index)
}
}
def larger[T](l: T, r: T)(implicit op: RecordLike[T]): Bool = op.isLarger(l, r)
}
class Comparator[T <: Record : RecordLike](gen: T) extends Module {
val io = IO(new bundle {
val a = Flipped(Valid(gen))
val b = Flipped(Valid(gen))
val o = Output(Bool())
}
import record_operation._
io.o := io.a.valid && io.b.valid && larger(io.a.bits, io.b.bits)
}