Skip to content
This repository has been archived by the owner on Jun 16, 2024. It is now read-only.

Commit

Permalink
WIP: interposing platform-specific IO buffer/"port".
Browse files Browse the repository at this point in the history
  • Loading branch information
kivikakk committed May 25, 2024
1 parent 8db5073 commit efe997d
Show file tree
Hide file tree
Showing 12 changed files with 90 additions and 37 deletions.
38 changes: 28 additions & 10 deletions src/main/scala/ee/hrzn/chryse/platform/ChryseTop.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package ee.hrzn.chryse.platform

import chisel3._
import chisel3.experimental.noPrefix
import ee.hrzn.chryse.chisel.DirectionOf

import scala.collection.mutable
import scala.language.implicitConversions
Expand All @@ -16,6 +17,11 @@ trait ChryseTop extends RawModule {
ConnectedResource(pin, None)
}

protected def platformConnect(
name: String,
res: resource.ResourceData[_ <: Data],
): Option[Data] = None

protected def connectResources(
platform: PlatformBoard[_ <: PlatformBoardResources],
clock: Option[Clock],
Expand All @@ -41,20 +47,32 @@ trait ChryseTop extends RawModule {
clock.get := noPrefix(IO(Input(Clock())).suggestName(name))

case _ =>
if (platformConnect(name, res)) {
connected += name -> res.pinId.get
} else if (res.ioInst.isDefined) {
res.makeIoConnection()
connected += name -> res.pinId.get
val topIo: Option[Data] = platformConnect(name, res) match {
case Some(t) =>
connected += name -> res.pinId.get
Some(t)
case None =>
if (res.ioInst.isDefined) {
connected += name -> res.pinId.get
Some(res.makeIoConnection())
} else None
}
topIo match {
case None =>
case Some(t) =>
val port = IO(res.makeIo()).suggestName(name)
DirectionOf(port) match {
case SpecifiedDirection.Input =>
t := port
case SpecifiedDirection.Output =>
port := t
case dir =>
throw new Exception(s"unhandled direction: $dir")
}
}
}
}

connected.to(Map)
}

protected def platformConnect(
name: String,
res: resource.ResourceData[_ <: Data],
): Boolean = false
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
package ee.hrzn.chryse.platform

import chisel3._
import chisel3.experimental.Param
import ee.hrzn.chryse.platform.resource.ResourceBase
import ee.hrzn.chryse.platform.resource.ResourceData

import scala.collection.mutable.ArrayBuffer

abstract class PlatformBoardResources {
val defaultAttributes = Map[String, Param]()

private[chryse] def setNames() =
for { f <- this.getClass().getDeclaredFields() } {
f.setAccessible(true)
Expand Down
36 changes: 18 additions & 18 deletions src/main/scala/ee/hrzn/chryse/platform/ice40/ICE40Top.scala
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,24 @@ class ICE40Top[Top <: Module](
genTop: => Top,
) extends RawModule
with ChryseTop {
var lastPCF: Option[PCF] = None
override protected def platformConnect(
name: String,
res: resource.ResourceData[_ <: Data],
): Option[Data] = {
if (name == "ubtn" && ubtn_reset.isDefined) {
if (res.ioInst.isDefined)
throw new Exception("ubtnReset requested but ubtn used in design")

// TODO (iCE40): SB_GBs between a lot more things.
// ubtn_reset.get := IO(res.makeIo()).suggestName("ubtn")
val topIo = Wire(res.makeIo())
ubtn_reset.get := topIo
return Some(topIo)
}

None
}

// TODO (iCE40): actually create IO buffers.

private val clki = Wire(Clock())

Expand Down Expand Up @@ -58,22 +73,7 @@ class ICE40Top[Top <: Module](
private val connectedResources =
connectResources(platform, Some(clki))

override protected def platformConnect(
name: String,
res: resource.ResourceData[_ <: Data],
): Boolean = {
if (name == "ubtn" && ubtn_reset.isDefined) {
if (res.ioInst.isDefined)
throw new Exception("ubtnReset requested but ubtn used in design")

ubtn_reset.get := IO(res.makeIo()).suggestName("ubtn")
return true
}

false
}

lastPCF = Some(
val lastPCF = Some(
PCF(
connectedResources
.map { case (name, cr) => (name, cr.pin) }
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package ee.hrzn.chryse.platform.ice40

object IOStandard {
val LV_CMOS = "SB_LVCMOS"
val LVCMOS = "SB_LVCMOS"
val LVTTL = "SB_LVTTL"
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package ee.hrzn.chryse.platform.ice40

import chisel3._
import chisel3.experimental.Param
import ee.hrzn.chryse.platform.PlatformBoard
import ee.hrzn.chryse.platform.PlatformBoardResources
import ee.hrzn.chryse.platform.resource
Expand All @@ -24,12 +25,16 @@ final case class IceBreakerPlatform(ubtnReset: Boolean = false)
}

class IceBreakerPlatformResources extends PlatformBoardResources {
// TODO: IO_STANDARD=SB_LVCMOS needs to be set on most SB_IOs.
override val defaultAttributes = Map("IO_STANDARD" -> IOStandard.LVCMOS)

val clock = resource.ClockSource(12_000_000).onPin(35)

val ubtn = resource.Button().inverted.onPin(10)

val uart = resource.UART().onPins(rx = 6, tx = 9)
val uart = resource
.UART()
.onPins(rx = 6, tx = 9)
.withAttributes("IO_STANDARD" -> IOStandard.LVTTL, "PULLUP" -> 1)

val ledg = resource.LED().inverted.onPin(37)
val ledr = resource.LED().inverted.onPin(11)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import chisel3.experimental.ExtModule
class SB_GB_IO(pinType: Int = (PinType.PIN_INPUT | PinType.PIN_NO_OUTPUT))
extends ExtModule(
Map(
"IO_STANDARD" -> IOStandard.LV_CMOS,
"IO_STANDARD" -> IOStandard.LVCMOS,
"PIN_TYPE" -> pinType,
),
) {
Expand Down
2 changes: 1 addition & 1 deletion src/main/scala/ee/hrzn/chryse/platform/ice40/SB_IO.scala
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import chisel3.experimental.ExtModule

class SB_IO(
pinType: Int,
ioStandard: String = IOStandard.LV_CMOS,
ioStandard: String = IOStandard.LVCMOS,
pullup: Boolean = false,
) extends ExtModule(
Map(
Expand Down
7 changes: 7 additions & 0 deletions src/main/scala/ee/hrzn/chryse/platform/resource/InOut.scala
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package ee.hrzn.chryse.platform.resource

import chisel3._
import chisel3.experimental.Param

// TODO: it's an error to use both "i" and "o" (tristate is a different kettle
// of fish entirely) — this'll currently throw an obscure Chisel error (since
Expand All @@ -20,6 +21,12 @@ class InOut extends ResourceBase with ResourceSinglePin {
this
}

def withAttributes(attribs: (String, Param)*): this.type = {
i.withAttributes(attribs: _*)
o.withAttributes(attribs: _*)
this
}

def data: Seq[ResourceData[_ <: Data]] = Seq(i, o)
}

Expand Down
13 changes: 11 additions & 2 deletions src/main/scala/ee/hrzn/chryse/platform/resource/ResourceData.scala
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package ee.hrzn.chryse.platform.resource

import chisel3._
import chisel3.experimental.Param
import chisel3.experimental.dataview._
import ee.hrzn.chryse.chisel.DirectionOf

Expand All @@ -18,6 +19,7 @@ abstract class ResourceData[HW <: Data](gen: => HW, invert: Boolean = false)
final private[chryse] var pinId: Option[Pin] = None
final var name: Option[String] = None
final protected var _invert = invert
final protected var _attribs = Map[String, Param]()

// Should return Chisel datatype with Input/Output attached.
def makeIo(): HW = gen
Expand All @@ -38,12 +40,14 @@ abstract class ResourceData[HW <: Data](gen: => HW, invert: Boolean = false)
}
}

final def makeIoConnection(): Unit = {
final def makeIoConnection(): HW = {
if (topIoInst.isDefined)
throw new IllegalStateException("topIoInst already defined")
val topIo = IO(makeIo()).suggestName(name.get)
// val topIo = IO(makeIo()).suggestName(name.get)
val topIo = Wire(makeIo()) // .suggestName(name.get)
topIoInst = Some(topIo)
connectIo(ioInst.get, topIo)
topIo
}

protected def connectIo(user: HW, top: HW): Unit = {
Expand All @@ -64,6 +68,11 @@ abstract class ResourceData[HW <: Data](gen: => HW, invert: Boolean = false)
this
}

def withAttributes(attribs: (String, Param)*): this.type = {
_attribs = attribs.to(Map)
this
}

def data: Seq[ResourceData[_ <: Data]] = Seq(this)
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
package ee.hrzn.chryse.platform.resource

import chisel3.experimental.Param

trait ResourceSinglePin extends ResourceBase {
def onPin(id: Pin): this.type
def withAttributes(attribs: (String, Param)*): this.type
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ package ee.hrzn.chryse.platform.resource
import chisel3._

class SPIFlash extends ResourceBase {
// TODO: DSPI, QSPI

val cs = ResourceData(Output(Bool()), invert = true)
val clock = ResourceData(Output(Clock()))
val copi = ResourceData(Output(Bool()))
Expand Down
9 changes: 7 additions & 2 deletions src/main/scala/ee/hrzn/chryse/platform/resource/UART.scala
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
package ee.hrzn.chryse.platform.resource

import chisel3._
import chisel3.experimental.Param

class UART extends ResourceBase {
// TODO (iCE40): lower IO_STANDARD=SB_LVTTL and PULLUP=1.
// TODO: these will differ per-platform so need to come in from outside.
val rx = ResourceData(Input(Bool()))
val tx = ResourceData(Output(Bool()))

Expand All @@ -19,6 +18,12 @@ class UART extends ResourceBase {
this
}

def withAttributes(attribs: (String, Param)*): this.type = {
rx.withAttributes(attribs: _*)
tx.withAttributes(attribs: _*)
this
}

def data: Seq[ResourceData[_ <: Data]] = Seq(rx, tx)
}

Expand Down

0 comments on commit efe997d

Please sign in to comment.