diff --git a/src/main/scala/ee/hrzn/chryse/platform/ecp5/ECP5Platform.scala b/src/main/scala/ee/hrzn/chryse/platform/ecp5/ECP5Platform.scala index 3b05a2f..e470661 100644 --- a/src/main/scala/ee/hrzn/chryse/platform/ecp5/ECP5Platform.scala +++ b/src/main/scala/ee/hrzn/chryse/platform/ecp5/ECP5Platform.scala @@ -13,6 +13,7 @@ trait ECP5Platform { this: PlatformBoard[_ <: PlatformBoardResources] => val ecp5Variant: ECP5Variant val ecp5Package: String val ecp5Speed: Int + val ecp5PackOpts: Seq[String] = Seq() override def apply[Top <: Module](genTop: => Top) = { resources.setNames() @@ -72,18 +73,11 @@ trait ECP5Platform { this: PlatformBoard[_ <: PlatformBoardResources] => Seq(), bitPath, Seq("ecppack", "--input", textcfgPath, "--bit", bitPath, "--svf", - svfPath), + svfPath) ++ ecp5PackOpts, ) runCu(CmdStepPack, bitCu) BuildResult(bitPath, svfPath) } } - - def program(bitAndSvf: BuildResult): Unit = - programImpl(bitAndSvf) - - private object programImpl extends BaseTask { - def apply(bitAndSvf: BuildResult): Unit = ??? - } } 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 2bf34a3..dba236d 100644 --- a/src/main/scala/ee/hrzn/chryse/platform/ecp5/ECP5Top.scala +++ b/src/main/scala/ee/hrzn/chryse/platform/ecp5/ECP5Top.scala @@ -5,6 +5,7 @@ import ee.hrzn.chryse.platform.ChryseTop import ee.hrzn.chryse.platform.Platform import ee.hrzn.chryse.platform.PlatformBoard import ee.hrzn.chryse.platform.PlatformBoardResources +import ee.hrzn.chryse.platform.resource.PinPlatform import ee.hrzn.chryse.platform.resource.PinString import ee.hrzn.chryse.platform.resource.ResourceData @@ -17,8 +18,13 @@ class ECP5Top[Top <: Module]( name: String, res: ResourceData[_ <: Data], ): PlatformConnectResult = { - println(s"evaluating: $name / $res") - // TODO (ECP5): USRMCLK + if (res.pinId == Some(PinPlatform(USRMCLKPin)) && res.ioInst.isDefined) { + val inst = Module(new USRMCLK) + inst.USRMCLKI := res.ioInst.get + inst.USRMCLKTS := 0.U + return PlatformConnectResultNoop + } + PlatformConnectResultFallthrough } diff --git a/src/main/scala/ee/hrzn/chryse/platform/ecp5/OrangeCrabPlatform.scala b/src/main/scala/ee/hrzn/chryse/platform/ecp5/OrangeCrabPlatform.scala index bc98bc1..ec35cc2 100644 --- a/src/main/scala/ee/hrzn/chryse/platform/ecp5/OrangeCrabPlatform.scala +++ b/src/main/scala/ee/hrzn/chryse/platform/ecp5/OrangeCrabPlatform.scala @@ -15,6 +15,8 @@ case class OrangeCrabPlatform(ecp5Variant: ECP5Variant) val ecp5Package = "csfBGA285" val ecp5Speed = 8 + def program(binPath: BuildResult): Unit = ??? + val resources = new OrangeCrabPlatformResources } diff --git a/src/main/scala/ee/hrzn/chryse/platform/ecp5/ULX3SPlatform.scala b/src/main/scala/ee/hrzn/chryse/platform/ecp5/ULX3SPlatform.scala index 03bd9b5..06dbaa2 100644 --- a/src/main/scala/ee/hrzn/chryse/platform/ecp5/ULX3SPlatform.scala +++ b/src/main/scala/ee/hrzn/chryse/platform/ecp5/ULX3SPlatform.scala @@ -6,9 +6,11 @@ import ee.hrzn.chryse.platform.PlatformBoard import ee.hrzn.chryse.platform.PlatformBoardResources import ee.hrzn.chryse.platform.resource.Button import ee.hrzn.chryse.platform.resource.ClockSource +import ee.hrzn.chryse.platform.resource.LED import ee.hrzn.chryse.platform.resource.ResourceData import ee.hrzn.chryse.platform.resource.SPIFlash import ee.hrzn.chryse.platform.resource.UART +import ee.hrzn.chryse.tasks.BaseTask // TODO: restrict the variants to those the ULX3S was delivered with. // TODO: try one of these: https://github.com/emard/ulx3s/blob/master/doc/MANUAL.md#programming-over-wifi-esp32-micropython @@ -18,8 +20,20 @@ case class ULX3SPlatform(ecp5Variant: ECP5Variant) val id = s"ulx3s-${ecp5Variant.id}" val clockHz = 25_000_000 - val ecp5Package = "CABGA381" - val ecp5Speed = 6 + val ecp5Package = "CABGA381" + val ecp5Speed = 6 + override val ecp5PackOpts = Seq("--compress") + + def program(bitAndSvf: BuildResult): Unit = + programImpl(bitAndSvf) + + private object programImpl extends BaseTask { + def apply(bitAndSvf: BuildResult): Unit = + runCmd( + CmdStepProgram, + Seq("openFPGALoader", "-b", "ulx3s", "-m", bitAndSvf.bitPath), + ) + } val resources = new ULX3SPlatformResources } @@ -30,13 +44,21 @@ class ULX3SPlatformResources extends PlatformBoardResources { val clock = ClockSource(25_000_000).onPin("G2") val program = - Button().inverted.onPin("M4").withAttributes("PULLMODE" -> "UP") + LED().inverted.onPin("M4").withAttributes("PULLMODE" -> "UP") // TODO: also expose RTS, DTR. var uart = UART() .onPins(rx = "M1", tx = "L4") var uartTxEnable = ResourceData(Output(Bool())).onPin("L3") + val led0 = LED().inverted.onPin("B2").withAttributes("DRIVE" -> 4) + val led1 = LED().inverted.onPin("C2").withAttributes("DRIVE" -> 4) + val led2 = LED().inverted.onPin("C1").withAttributes("DRIVE" -> 4) + val led3 = LED().inverted.onPin("D2").withAttributes("DRIVE" -> 4) + val led4 = LED().inverted.onPin("D1").withAttributes("DRIVE" -> 4) + val led5 = LED().inverted.onPin("E2").withAttributes("DRIVE" -> 4) + val led6 = LED().inverted.onPin("E1").withAttributes("DRIVE" -> 4) + val led7 = LED().inverted.onPin("H3").withAttributes("DRIVE" -> 4) // val leds = // resource // .LEDs() @@ -45,7 +67,7 @@ class ULX3SPlatformResources extends PlatformBoardResources { val spiFlash = SPIFlash() .onPins( - csN = "R2", clock = USRMCLK, copi = "W2", cipo = "V2", wpN = "Y2", + csN = "R2", clock = USRMCLKPin, copi = "W2", cipo = "V2", wpN = "Y2", holdN = "W1", ) .withAttributes("PULLMODE" -> "NONE", "DRIVE" -> "4") diff --git a/src/main/scala/ee/hrzn/chryse/platform/ecp5/USRMCLK.scala b/src/main/scala/ee/hrzn/chryse/platform/ecp5/USRMCLK.scala index e1dbea2..c8b1842 100644 --- a/src/main/scala/ee/hrzn/chryse/platform/ecp5/USRMCLK.scala +++ b/src/main/scala/ee/hrzn/chryse/platform/ecp5/USRMCLK.scala @@ -1,11 +1,9 @@ package ee.hrzn.chryse.platform.ecp5 -import ee.hrzn.chryse.platform.resource.Pin -import ee.hrzn.chryse.platform.resource.PinPlatform +import chisel3._ +import chisel3.experimental.ExtModule -import scala.language.implicitConversions - -object USRMCLK { - implicit def usrmclk2Pin(usrmclk: this.type): Pin = - PinPlatform(this) +class USRMCLK extends ExtModule { + val USRMCLKI = IO(Input(Clock())) + val USRMCLKTS = IO(Input(Bool())) } diff --git a/src/main/scala/ee/hrzn/chryse/platform/ecp5/USRMCLKPin.scala b/src/main/scala/ee/hrzn/chryse/platform/ecp5/USRMCLKPin.scala new file mode 100644 index 0000000..59c768f --- /dev/null +++ b/src/main/scala/ee/hrzn/chryse/platform/ecp5/USRMCLKPin.scala @@ -0,0 +1,11 @@ +package ee.hrzn.chryse.platform.ecp5 + +import ee.hrzn.chryse.platform.resource.Pin +import ee.hrzn.chryse.platform.resource.PinPlatform + +import scala.language.implicitConversions + +object USRMCLKPin { + implicit def usrmclk2Pin(usrmclk: this.type): Pin = + PinPlatform(this) +} diff --git a/src/test/scala/ee/hrzn/chryse/platform/SimPlatform.scala b/src/test/scala/ee/hrzn/chryse/platform/SimPlatform.scala index d3b500b..126610f 100644 --- a/src/test/scala/ee/hrzn/chryse/platform/SimPlatform.scala +++ b/src/test/scala/ee/hrzn/chryse/platform/SimPlatform.scala @@ -4,12 +4,12 @@ import chisel3._ import ee.hrzn.chryse.ChryseApp import ee.hrzn.chryse.platform.PlatformBoard import ee.hrzn.chryse.platform.PlatformBoardResources -import ee.hrzn.chryse.platform.ecp5.USRMCLK +import ee.hrzn.chryse.platform.ecp5.USRMCLKPin +import ee.hrzn.chryse.platform.resource.Button import ee.hrzn.chryse.platform.resource.Connector +import ee.hrzn.chryse.platform.resource.InOut import ee.hrzn.chryse.platform.resource.LED import ee.hrzn.chryse.platform.resource.UART -import ee.hrzn.chryse.platform.resource.Button -import ee.hrzn.chryse.platform.resource.InOut final case class SimPlatform() extends PlatformBoard[SimPlatformResources] { type TopPlatform[Top <: Module] = SimTop[Top] @@ -61,7 +61,7 @@ class SimPlatformResources extends PlatformBoardResources { val spiFlash = resource .SPIFlash() .onPins( - csN = "R2", clock = USRMCLK, copi = "W2", cipo = "V2", wpN = "Y2", + csN = "R2", clock = USRMCLKPin, copi = "W2", cipo = "V2", wpN = "Y2", holdN = "W1", ) }