summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMegan Wachs2022-01-11 10:10:20 -0800
committerGitHub2022-01-11 18:10:20 +0000
commit747d16311bdf185d2e98e452b14cb5d8ccca004c (patch)
tree4f73b2e875107153d324b9062ec0bf955c2ddb18
parent2b48fd15a7711dcd44334fbbc538667a102a581a (diff)
Lookupable: add Either version (#2335)
* Add Lookupable for Either * Lookupable: enhance the @public/@instantiable error message to include traits and Eithers Co-authored-by: Jack Koenig <koenig@sifive.com>
-rw-r--r--core/src/main/scala/chisel3/experimental/hierarchy/Lookupable.scala25
-rw-r--r--src/test/scala/chiselTests/experimental/hierarchy/DefinitionSpec.scala10
-rw-r--r--src/test/scala/chiselTests/experimental/hierarchy/Examples.scala5
-rw-r--r--src/test/scala/chiselTests/experimental/hierarchy/InstanceSpec.scala10
4 files changed, 48 insertions, 2 deletions
diff --git a/core/src/main/scala/chisel3/experimental/hierarchy/Lookupable.scala b/core/src/main/scala/chisel3/experimental/hierarchy/Lookupable.scala
index 1223d6ce..8552267a 100644
--- a/core/src/main/scala/chisel3/experimental/hierarchy/Lookupable.scala
+++ b/core/src/main/scala/chisel3/experimental/hierarchy/Lookupable.scala
@@ -18,8 +18,8 @@ import chisel3.internal.{throwException, AggregateViewBinding, Builder, ChildBin
* Sealed.
*/
@implicitNotFound(
- "@public is only legal within a class marked @instantiable and only on vals of type" +
- " Data, BaseModule, IsInstantiable, IsLookupable, or Instance[_], or in an Iterable or Option"
+ "@public is only legal within a class or trait marked @instantiable, and only on vals of type" +
+ " Data, BaseModule, IsInstantiable, IsLookupable, or Instance[_], or in an Iterable, Option, or Either"
)
trait Lookupable[-B] {
type C // Return type of the lookup
@@ -381,6 +381,27 @@ object Lookupable {
ret.map { x: B => lookupable.instanceLookup[A](_ => x, instance) }
}
}
+ implicit def lookupEither[L, R](
+ implicit sourceInfo: SourceInfo,
+ compileOptions: CompileOptions,
+ lookupableL: Lookupable[L],
+ lookupableR: Lookupable[R]
+ ) = new Lookupable[Either[L, R]] {
+ type C = Either[lookupableL.C, lookupableR.C]
+ def definitionLookup[A](that: A => Either[L, R], definition: Definition[A]): C = {
+ val ret = that(definition.proto)
+ ret.map { x: R => lookupableR.definitionLookup[A](_ => x, definition) }.left.map { x: L =>
+ lookupableL.definitionLookup[A](_ => x, definition)
+ }
+ }
+ def instanceLookup[A](that: A => Either[L, R], instance: Instance[A]): C = {
+ import instance._
+ val ret = that(proto)
+ ret.map { x: R => lookupableR.instanceLookup[A](_ => x, instance) }.left.map { x: L =>
+ lookupableL.instanceLookup[A](_ => x, instance)
+ }
+ }
+ }
implicit def lookupIsInstantiable[B <: IsInstantiable](
implicit sourceInfo: SourceInfo,
compileOptions: CompileOptions
diff --git a/src/test/scala/chiselTests/experimental/hierarchy/DefinitionSpec.scala b/src/test/scala/chiselTests/experimental/hierarchy/DefinitionSpec.scala
index efc81f94..63beb394 100644
--- a/src/test/scala/chiselTests/experimental/hierarchy/DefinitionSpec.scala
+++ b/src/test/scala/chiselTests/experimental/hierarchy/DefinitionSpec.scala
@@ -319,6 +319,16 @@ class DefinitionSpec extends ChiselFunSpec with Utils {
val (_, annos) = getFirrtlAndAnnos(new Top)
annos should contain(MarkAnnotation("~Top|ConcreteHasBlah".mt, "10"))
}
+ it("3.11: should work on eithers") {
+ class Top() extends Module {
+ val i = Definition(new HasEither())
+ i.x.map(x => mark(x, "xright")).left.map(x => mark(x, "xleft"))
+ i.y.map(x => mark(x, "yright")).left.map(x => mark(x, "yleft"))
+ }
+ val (_, annos) = getFirrtlAndAnnos(new Top)
+ annos should contain(MarkAnnotation("~Top|HasEither>x".rt, "xright"))
+ annos should contain(MarkAnnotation("~Top|HasEither>y".rt, "yleft"))
+ }
}
describe("4: toDefinition") {
it("4.0: should work on modules") {
diff --git a/src/test/scala/chiselTests/experimental/hierarchy/Examples.scala b/src/test/scala/chiselTests/experimental/hierarchy/Examples.scala
index de03b74b..5b78b7cc 100644
--- a/src/test/scala/chiselTests/experimental/hierarchy/Examples.scala
+++ b/src/test/scala/chiselTests/experimental/hierarchy/Examples.scala
@@ -195,6 +195,11 @@ object Examples {
@public val x: Option[UInt] = Some(Wire(UInt(3.W)))
}
@instantiable
+ class HasEither() extends Module {
+ @public val x: Either[Bool, UInt] = Right(Wire(UInt(3.W)).suggestName("x"))
+ @public val y: Either[Bool, UInt] = Left(Wire(Bool()).suggestName("y"))
+ }
+ @instantiable
class HasVec() extends Module {
@public val x = VecInit(1.U, 2.U, 3.U)
}
diff --git a/src/test/scala/chiselTests/experimental/hierarchy/InstanceSpec.scala b/src/test/scala/chiselTests/experimental/hierarchy/InstanceSpec.scala
index e6bf04c1..f62d1e49 100644
--- a/src/test/scala/chiselTests/experimental/hierarchy/InstanceSpec.scala
+++ b/src/test/scala/chiselTests/experimental/hierarchy/InstanceSpec.scala
@@ -288,6 +288,16 @@ class InstanceSpec extends ChiselFunSpec with Utils {
val (_, annos) = getFirrtlAndAnnos(new Top)
annos should contain(MarkAnnotation("~Top|Top/i:HasPublicConstructorArgs>x".rt, "10"))
}
+ it("3.11: should work on eithers") {
+ class Top() extends Module {
+ val i = Instance(Definition(new HasEither()))
+ i.x.map(x => mark(x, "xright")).left.map(x => mark(x, "xleft"))
+ i.y.map(x => mark(x, "yright")).left.map(x => mark(x, "yleft"))
+ }
+ val (_, annos) = getFirrtlAndAnnos(new Top)
+ annos should contain(MarkAnnotation("~Top|Top/i:HasEither>x".rt, "xright"))
+ annos should contain(MarkAnnotation("~Top|Top/i:HasEither>y".rt, "yleft"))
+ }
}
describe("4: toInstance") {
it("4.0: should work on modules") {