在 Scala/Chisel 中使用类型参数覆盖/重载运算符
Posted
技术标签:
【中文标题】在 Scala/Chisel 中使用类型参数覆盖/重载运算符【英文标题】:Override/Overload operator with type parameter in Scala/Chisel 【发布时间】:2017-02-28 11:41:43 【问题描述】:我正在使用 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)
它通过了编译器,但 > 运算符始终是 Record 中的那个,而不是 RecordIndexed 中的那个。
我有点理解为什么,因为 > 是重载而不是覆盖。根据 Comparator 中的 T 类型,编译器会静态选择 Record 中的 >。
如何解决这个问题并让 Scala 选择重载?我认为 typed trait 是一种方法,但完全没有弄清楚如何。
【问题讨论】:
听起来你想使用类型类。你试过了吗? @dveim 没有。但是类型类看起来很有前途。今晚我会试一试。我在 Scala 方面并没有真正的经验。任何更多的提示或示例都会非常有帮助。 @dveim Typeclass 工作!非常感谢。你想提出一个简单的答案然后我可以接受。 很高兴能为您提供帮助。不要在意声誉:) 如果您有问题的解决方案,那么您可以将其发布为答案而不是编辑您的问题吗? 【参考方案1】:从@wei-song 对问题的编辑中复制:
根据@dveim 的建议,我尝试了type class,终于成功了:
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)
【讨论】:
以上是关于在 Scala/Chisel 中使用类型参数覆盖/重载运算符的主要内容,如果未能解决你的问题,请参考以下文章