【问题标题】:Override/Overload operator with type parameter in Scala/Chisel在 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 工作!非常感谢。你想提出一个简单的答案然后我可以接受。
  • 很高兴能为您提供帮助。不要在意声誉:)
  • 如果您有问题的解决方案,那么您可以将其发布为答案而不是编辑您的问题吗?

标签: scala chisel


【解决方案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) 
}

【讨论】:

    猜你喜欢
    • 2018-10-19
    • 2011-07-27
    • 2017-04-07
    • 2017-11-30
    • 1970-01-01
    • 2018-04-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多