From 70f421bfc4a852eb0ef91b1d6bc09adb7825ec4e Mon Sep 17 00:00:00 2001 From: Asherah Connor Date: Wed, 22 May 2024 18:13:05 +0300 Subject: [PATCH] refactor connectors. --- .../hrzn/chryse/platform/ecp5/ECP5Top.scala | 4 +-- .../hrzn/chryse/platform/ice40/ICE40Top.scala | 10 ------- .../platform/ice40/IceBreakerPlatform.scala | 25 +++++++++++------- .../hrzn/chryse/platform/resource/Base.scala | 2 +- .../chryse/platform/resource/Connector.scala | 26 +++++++++++++++++++ .../hrzn/chryse/platform/resource/InOut.scala | 2 +- .../chryse/platform/resource/Resource.scala | 2 ++ .../platform/resource/SinglePinResource.scala | 5 ++++ .../chryse/platform/BoardResourcesSpec.scala | 4 +-- 9 files changed, 53 insertions(+), 27 deletions(-) create mode 100644 src/main/scala/ee/hrzn/chryse/platform/resource/Connector.scala create mode 100644 src/main/scala/ee/hrzn/chryse/platform/resource/SinglePinResource.scala diff --git a/src/main/scala/ee/hrzn/chryse/platform/ecp5/ECP5Top.scala b/src/main/scala/ee/hrzn/chryse/platform/ecp5/ECP5Top.scala index 7f5c13c..dfdd55f 100644 --- a/src/main/scala/ee/hrzn/chryse/platform/ecp5/ECP5Top.scala +++ b/src/main/scala/ee/hrzn/chryse/platform/ecp5/ECP5Top.scala @@ -30,8 +30,6 @@ object ECP5Top { def apply[Top <: Module]( platform: BoardPlatform[_ <: BoardResources], genTop: => Top, - ) = { - platform.resources.setNames() // XXX: refactor setNames call + ) = new ECP5Top(platform, genTop) - } } diff --git a/src/main/scala/ee/hrzn/chryse/platform/ice40/ICE40Top.scala b/src/main/scala/ee/hrzn/chryse/platform/ice40/ICE40Top.scala index e510891..8e3d6ae 100644 --- a/src/main/scala/ee/hrzn/chryse/platform/ice40/ICE40Top.scala +++ b/src/main/scala/ee/hrzn/chryse/platform/ice40/ICE40Top.scala @@ -89,13 +89,3 @@ class ICE40Top[Top <: Module]( lastPCF = Some(PCF(ios.to(Map), freqs.to(Map))) } - -object ICE40Top { - def apply[Top <: Module]( - platform: BoardPlatform[_ <: BoardResources], - genTop: => Top, - ) = { - platform.resources.setNames() // XXX refactor setNames call - new ICE40Top(platform, genTop) - } -} diff --git a/src/main/scala/ee/hrzn/chryse/platform/ice40/IceBreakerPlatform.scala b/src/main/scala/ee/hrzn/chryse/platform/ice40/IceBreakerPlatform.scala index 1011d97..471c10e 100644 --- a/src/main/scala/ee/hrzn/chryse/platform/ice40/IceBreakerPlatform.scala +++ b/src/main/scala/ee/hrzn/chryse/platform/ice40/IceBreakerPlatform.scala @@ -19,8 +19,10 @@ final case class IceBreakerPlatform(ubtnReset: Boolean = false) val resources = new IceBreakerResources - override def apply[Top <: Module](genTop: Platform => Top) = - ICE40Top(this, genTop(this)) + override def apply[Top <: Module](genTop: Platform => Top) = { + resources.setNames() + new ICE40Top(this, genTop(this)) + } } class IceBreakerResources extends BoardResources { @@ -33,14 +35,17 @@ class IceBreakerResources extends BoardResources { val ledg = resource.LED().inverted.onPin(37) val ledr = resource.LED().inverted.onPin(11) - val pmod1a1 = resource.InOut().onPin(4) - val pmod1a2 = resource.InOut().onPin(2) - val pmod1a3 = resource.InOut().onPin(47) - val pmod1a4 = resource.InOut().onPin(45) - val pmod1a7 = resource.InOut().onPin(3) - val pmod1a8 = resource.InOut().onPin(48) - val pmod1a9 = resource.InOut().onPin(46) - val pmod1a10 = resource.InOut().onPin(44) + val pmod1a = resource.Connector( + resource.InOut(), + 1 -> 4, + 2 -> 2, + 3 -> 47, + 4 -> 45, + 7 -> 3, + 8 -> 48, + 9 -> 46, + 10 -> 44, + ) val pmod1b1 = resource.InOut().onPin(43) val pmod1b2 = resource.InOut().onPin(38) diff --git a/src/main/scala/ee/hrzn/chryse/platform/resource/Base.scala b/src/main/scala/ee/hrzn/chryse/platform/resource/Base.scala index bf96328..b6d5053 100644 --- a/src/main/scala/ee/hrzn/chryse/platform/resource/Base.scala +++ b/src/main/scala/ee/hrzn/chryse/platform/resource/Base.scala @@ -2,7 +2,7 @@ package ee.hrzn.chryse.platform.resource import chisel3._ -abstract class Base[HW <: Data](gen: => HW) extends Resource { +abstract class Base[HW <: Data](gen: => HW) extends SinglePinResource { final private[chryse] var pinId: Option[Pin] = None final var name: Option[String] = None diff --git a/src/main/scala/ee/hrzn/chryse/platform/resource/Connector.scala b/src/main/scala/ee/hrzn/chryse/platform/resource/Connector.scala new file mode 100644 index 0000000..f6ffd61 --- /dev/null +++ b/src/main/scala/ee/hrzn/chryse/platform/resource/Connector.scala @@ -0,0 +1,26 @@ +package ee.hrzn.chryse.platform.resource + +import chisel3._ + +class Connector[E <: SinglePinResource]( + gen: => E, + private val ixToPin: (Int, Pin)*, +) extends Resource { + private val mappings: Map[Int, E] = ixToPin + .map { case (i, p) => + i -> gen.onPin(p) + } + .to(Map) + + def apply(ix: Int): E = mappings(ix) + + def setName(name: String): Unit = + mappings.foreach { case (i, e) => e.setName(s"$name$i") } + + def bases(): Seq[Base[_ <: Data]] = mappings.flatMap(_._2.bases()).toSeq +} + +object Connector { + def apply[E <: SinglePinResource](gen: => E, ixToPin: (Int, Pin)*) = + new Connector(gen, ixToPin: _*) +} diff --git a/src/main/scala/ee/hrzn/chryse/platform/resource/InOut.scala b/src/main/scala/ee/hrzn/chryse/platform/resource/InOut.scala index 3f868f2..fe9223c 100644 --- a/src/main/scala/ee/hrzn/chryse/platform/resource/InOut.scala +++ b/src/main/scala/ee/hrzn/chryse/platform/resource/InOut.scala @@ -2,7 +2,7 @@ package ee.hrzn.chryse.platform.resource import chisel3._ -class InOut extends Resource { +class InOut extends Resource with SinglePinResource { val i = new Base[Bool](Input(Bool())) {} val o = new Base[Bool](Output(Bool())) {} diff --git a/src/main/scala/ee/hrzn/chryse/platform/resource/Resource.scala b/src/main/scala/ee/hrzn/chryse/platform/resource/Resource.scala index c4c8111..4c98444 100644 --- a/src/main/scala/ee/hrzn/chryse/platform/resource/Resource.scala +++ b/src/main/scala/ee/hrzn/chryse/platform/resource/Resource.scala @@ -5,6 +5,8 @@ import ee.hrzn.chryse.platform.BoardResources import scala.collection.mutable.ArrayBuffer +// XXX: This is more of a resource holder/container. +// It's one or possibly many (or no?) resources. Hrm. trait Resource { def setName(name: String): Unit def bases(): Seq[Base[_ <: Data]] diff --git a/src/main/scala/ee/hrzn/chryse/platform/resource/SinglePinResource.scala b/src/main/scala/ee/hrzn/chryse/platform/resource/SinglePinResource.scala new file mode 100644 index 0000000..0b24c4f --- /dev/null +++ b/src/main/scala/ee/hrzn/chryse/platform/resource/SinglePinResource.scala @@ -0,0 +1,5 @@ +package ee.hrzn.chryse.platform.resource + +trait SinglePinResource extends Resource { + def onPin(id: Pin): this.type +} diff --git a/src/test/scala/ee/hrzn/chryse/platform/BoardResourcesSpec.scala b/src/test/scala/ee/hrzn/chryse/platform/BoardResourcesSpec.scala index 843030b..869f8d8 100644 --- a/src/test/scala/ee/hrzn/chryse/platform/BoardResourcesSpec.scala +++ b/src/test/scala/ee/hrzn/chryse/platform/BoardResourcesSpec.scala @@ -130,8 +130,8 @@ class InversionTop(platform: Platform) extends Module { class InOutTop(platform: Platform) extends Module { val plat = platform.asInstanceOf[IceBreakerPlatform] // Treat pmod1a1 as output, 1a2 as input. - plat.resources.pmod1a1.o := plat.resources.uart.rx - plat.resources.uart.tx := plat.resources.pmod1a2.i + plat.resources.pmod1a(1).o := plat.resources.uart.rx + plat.resources.uart.tx := plat.resources.pmod1a(2).i // Do the same with 1b1 and 1b2, but use inverted inputs/outputs. plat.resources.pmod1b1.o := plat.resources.ubtn