2017-02-28 79 views
1

我正在使用凿子,但实际上这是一个Scala问题。 我想要做的是重写导出对象的>操作符。 考虑以下类:Scala/Chisel中带有类型参数的Override/Overload运算符

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) 
} 

然后我想建立从记录派生的任何记录类型的通用比较:

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 
} 

这是OK,我使用

Comparator(new Record) 

但我尝试时失败

Comparator(new RecordIndexed) 

它通过编译器,但>运算符始终是Record中的一个,而不是RecordIndexed中的一个。

我有点理解为什么,因为>是过载而不是覆盖。根据Comparator中的类型T,编译器会静态地从Record中选择>。

我该如何解决这个问题,并让Scala选择超载>。我认为一种打字特质是要走的路,但完全没有弄清楚如何。

+0

听起来像你想使用类型类。你尝试过吗? – dveim

+0

@dveim号但类型类看起来很有前途。我今晚会试一试。我在Scala中并不是很有经验。任何更多的提示或例子都会非常有帮助。 –

+0

@dveim Typeclass工作!非常感谢。你想提出一个简单的答案,然后我可以接受它。 –

回答

0

通过@唯歌从一个编辑的问题复制:

据@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) 
} 
相关问题