[Feature Request] expose outer class of `ChiselEnum#Type`
Anillc opened this issue · comments
Type of issue: Feature Request
Is your feature request related to a problem? Please describe.
I'm extending ChiselEnum
for some features.
An inner class in the ChiselEnum
is bad for extending. It's not possible to override an inner class. Expose the outer class might not be a good solution, but it's effective for me.
Describe the solution you'd like
Maybe change to class Type(val factor: ChiselEnum) extends EnumType(this)
Additional context
It's possible to use implict class
to extend ChiselEnum#Type
, but we can't apply implict conversion automatically at runtime.
For example:
trait Default {
def default: Data
}
abstract class ChiselEnumDefault extends ChiselEnum {
def default: Type
implicit class TypeExtension(ty: Type) extends Default {
override def default = ChiselEnumDefault.this.default
}
}
object E extends ChiselEnumDefault {
val a, b, c = Value
override def default = a
}
val e1 = E()
val foo = e1.default
// ^ E.a
val e2 = E().asInstanceOf[Data]
val bar = e2.asInstanceOf[Default].default
// ^ runtime exception class chisel3.ChiselEnum$Type cannot be cast to class Default
What is the use case for implementing this feature?
Here are some examples:
object Extension {
implicit class ChiselEnumExtension[T <: ChiselEnum](value: T#Type) {
def is(select: T => Data) = {
val field = value.getClass.getField("$outer")
select(field.get(value).asInstanceOf[T]) === value
}
}
}
So we can use foo.is(Foo.bar)
instead of foo === Foo.bar
. It's shorter.
abstract class EnumDefault extends ChiselEnum {
def default: Type
}
object Extension {
implicit class TypeExtension(ty: EnumDefault#Type) {
def default = {
val field = ty.getClass.getField("$outer")
field.get(ty).asInstanceOf[EnumDefault].default
}
}
}
object AluOp extends EnumDefault {
val n, add, sub = Value
def default = n
}
So we can use AluOp().default
to get a literal value.