diff --git a/fpga/src/main/scala/arty100t/Configs.scala b/fpga/src/main/scala/arty100t/Configs.scala index c9892aa8..140df42b 100644 --- a/fpga/src/main/scala/arty100t/Configs.scala +++ b/fpga/src/main/scala/arty100t/Configs.scala @@ -21,9 +21,13 @@ class WithNoDesignKey extends Config((site, here, up) => { case DesignKey => (p: Parameters) => new SimpleLazyModule()(p) }) +// By default, this uses the on-board USB-UART for the TSI-over-UART link +// The PMODUART HarnessBinder maps the actual UART device to JD pin class WithArty100TTweaks(freqMHz: Double = 50) extends Config( + new WithArty100TPMODUART ++ new WithArty100TUARTTSI ++ new WithArty100TDDRTL ++ + new WithArty100TJTAG ++ new WithNoDesignKey ++ new testchipip.tsi.WithUARTTSIClient ++ new chipyard.harness.WithSerialTLTiedOff ++ @@ -36,14 +40,13 @@ class WithArty100TTweaks(freqMHz: Double = 50) extends Config( new chipyard.config.WithOffchipBusFrequency(freqMHz) ++ new chipyard.harness.WithAllClocksFromHarnessClockInstantiator ++ new chipyard.clocking.WithPassthroughClockGenerator ++ - new chipyard.config.WithNoDebug ++ // no jtag - new chipyard.config.WithNoUART ++ // use UART for the UART-TSI thing instad new chipyard.config.WithTLBackingMemory ++ // FPGA-shells converts the AXI to TL for us new freechips.rocketchip.subsystem.WithExtMemSize(BigInt(256) << 20) ++ // 256mb on ARTY new freechips.rocketchip.subsystem.WithoutTLMonitors) class RocketArty100TConfig extends Config( new WithArty100TTweaks ++ + new testchipip.soc.WithMbusScratchpad(base = 0x08000000, size = 128 * 1024) ++ // add on-chip scratchpad for small programs new chipyard.config.WithBroadcastManager ++ // no l2 new chipyard.RocketConfig) diff --git a/fpga/src/main/scala/arty100t/Harness.scala b/fpga/src/main/scala/arty100t/Harness.scala index a535e65f..577bd1b2 100644 --- a/fpga/src/main/scala/arty100t/Harness.scala +++ b/fpga/src/main/scala/arty100t/Harness.scala @@ -33,9 +33,6 @@ class Arty100THarness(override implicit val p: Parameters) extends Arty100TShell harnessSysPLLNode := clockOverlay.overlayOutput.node - val io_uart_bb = BundleBridgeSource(() => new UARTPortIO(dp(PeripheryUARTKey).headOption.getOrElse(UARTParams(0)))) - val uartOverlay = dp(UARTOverlayKey).head.place(UARTDesignInput(io_uart_bb)) - val ddrOverlay = dp(DDROverlayKey).head.place(DDRDesignInput(dp(ExtTLMem).get.master.base, dutWrangler.node, harnessSysPLLNode)).asInstanceOf[DDRArtyPlacedOverlay] val ddrClient = TLClientNode(Seq(TLMasterPortParameters.v1(Seq(TLMasterParameters.v1( name = "chip_ddr", diff --git a/fpga/src/main/scala/arty100t/HarnessBinders.scala b/fpga/src/main/scala/arty100t/HarnessBinders.scala index dd7c1a35..072b900e 100644 --- a/fpga/src/main/scala/arty100t/HarnessBinders.scala +++ b/fpga/src/main/scala/arty100t/HarnessBinders.scala @@ -23,7 +23,17 @@ import chipyard.iobinders._ class WithArty100TUARTTSI extends HarnessBinder({ case (th: HasHarnessInstantiators, port: UARTTSIPort) => { val ath = th.asInstanceOf[LazyRawModuleImp].wrapper.asInstanceOf[Arty100THarness] - ath.io_uart_bb.bundle <> port.io.uart + val harnessIO = IO(new UARTPortIO(port.io.uartParams)).suggestName("uart_tsi") + harnessIO <> port.io.uart + val packagePinsWithPackageIOs = Seq( + ("A9" , IOPin(harnessIO.rxd)), + ("D10", IOPin(harnessIO.txd))) + packagePinsWithPackageIOs foreach { case (pin, io) => { + ath.xdc.addPackagePin(io, pin) + ath.xdc.addIOStandard(io, "LVCMOS33") + ath.xdc.addIOB(io) + } } + ath.other_leds(1) := port.io.dropped ath.other_leds(9) := port.io.tsi2tl_state(0) ath.other_leds(10) := port.io.tsi2tl_state(1) @@ -32,6 +42,7 @@ class WithArty100TUARTTSI extends HarnessBinder({ } }) + class WithArty100TDDRTL extends HarnessBinder({ case (th: HasHarnessInstantiators, port: TLMemPort) => { val artyTh = th.asInstanceOf[LazyRawModuleImp].wrapper.asInstanceOf[Arty100THarness] @@ -81,3 +92,46 @@ class WithArty100TSerialTLToGPIO extends HarnessBinder({ artyTh.xdc.clockDedicatedRouteFalse(clkIO) } }) + +// Maps the UART device to the on-board USB-UART +class WithArty100TUART(rxdPin: String = "A9", txdPin: String = "D10") extends HarnessBinder({ + case (th: HasHarnessInstantiators, port: UARTPort) => { + val ath = th.asInstanceOf[LazyRawModuleImp].wrapper.asInstanceOf[Arty100THarness] + val harnessIO = IO(chiselTypeOf(port.io)).suggestName("uart") + harnessIO <> port.io + val packagePinsWithPackageIOs = Seq( + (rxdPin, IOPin(harnessIO.rxd)), + (txdPin, IOPin(harnessIO.txd))) + packagePinsWithPackageIOs foreach { case (pin, io) => { + ath.xdc.addPackagePin(io, pin) + ath.xdc.addIOStandard(io, "LVCMOS33") + ath.xdc.addIOB(io) + } } + } +}) + +// Maps the UART device to PMOD JD pins 3/7 +class WithArty100TPMODUART extends WithArty100TUART("G2", "F3") + +class WithArty100TJTAG extends HarnessBinder({ + case (th: HasHarnessInstantiators, port: JTAGPort) => { + val ath = th.asInstanceOf[LazyRawModuleImp].wrapper.asInstanceOf[Arty100THarness] + val harnessIO = IO(chiselTypeOf(port.io)).suggestName("jtag") + harnessIO <> port.io + + ath.sdc.addClock("JTCK", IOPin(harnessIO.TCK), 10) + ath.sdc.addGroup(clocks = Seq("JTCK")) + ath.xdc.clockDedicatedRouteFalse(IOPin(harnessIO.TCK)) + val packagePinsWithPackageIOs = Seq( + ("F4", IOPin(harnessIO.TCK)), + ("D2", IOPin(harnessIO.TMS)), + ("E2", IOPin(harnessIO.TDI)), + ("D4", IOPin(harnessIO.TDO)) + ) + packagePinsWithPackageIOs foreach { case (pin, io) => { + ath.xdc.addPackagePin(io, pin) + ath.xdc.addIOStandard(io, "LVCMOS33") + ath.xdc.addPullup(io) + } } + } +})