Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add PortAPI between IO and Harness blocks #1610

Merged
merged 13 commits into from
Oct 15, 2023
2 changes: 1 addition & 1 deletion docs/Customization/IOBinders.rst
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ The ``IOBinder`` functions are responsible for instantiating IO cells and IOPort
For example, the ``WithUARTIOCells`` IOBinder will, for any ``System`` that might have UART ports (``HasPeripheryUARTModuleImp``, generate ports within the ``ChipTop`` (``ports``) as well as IOCells with the appropriate type and direction (``cells2d``). This function returns a the list of generated ports, and the list of generated IOCells. The list of generated ports is passed to the ``HarnessBinders`` such that they can be connected to ``TestHarness`` devices.


.. literalinclude:: ../../generators/chipyard/src/main/scala/IOBinders.scala
.. literalinclude:: ../../generators/chipyard/src/main/scala/iobinders/IOBinders.scala
:language: scala
:start-after: DOC include start: WithUARTIOCells
:end-before: DOC include end: WithUARTIOCells
Expand Down
3 changes: 2 additions & 1 deletion fpga/src/main/scala/arty/Configs.scala
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ import chipyard.{BuildSystem}

// DOC include start: AbstractArty and Rocket
class WithArtyTweaks extends Config(
new WithArtyResetHarnessBinder ++
new WithArtyDebugResetHarnessBinder ++
new WithArtyJTAGResetHarnessBinder ++
new WithArtyJTAGHarnessBinder ++
new WithArtyUARTHarnessBinder ++
new WithDebugResetPassthrough ++
Expand Down
83 changes: 38 additions & 45 deletions fpga/src/main/scala/arty/HarnessBinders.scala
Original file line number Diff line number Diff line change
Expand Up @@ -11,68 +11,61 @@ import sifive.blocks.devices.pinctrl.{BasePin}

import sifive.fpgashells.ip.xilinx.{IBUFG, IOBUF, PULLUP, PowerOnResetFPGAOnly}

import chipyard.harness.{ComposeHarnessBinder, OverrideHarnessBinder}
import chipyard.iobinders.JTAGChipIO
import chipyard.harness.{HarnessBinder}
import chipyard.iobinders._

class WithArtyResetHarnessBinder extends ComposeHarnessBinder({
(system: HasPeripheryDebug, th: ArtyFPGATestHarness, ports: Seq[Data]) => {
val resetPorts = ports.collect { case b: Bool => b }
require(resetPorts.size == 2)
withClockAndReset(th.clock_32MHz, th.ck_rst) {
// Debug module reset
th.dut_ndreset := resetPorts(0)
class WithArtyDebugResetHarnessBinder extends HarnessBinder({
case (th: ArtyFPGATestHarness, port: DebugResetPort) => {
th.dut_ndreset := port.io // Debug module reset
}
})

// JTAG reset
resetPorts(1) := PowerOnResetFPGAOnly(th.clock_32MHz)
}
class WithArtyJTAGResetHarnessBinder extends HarnessBinder({
case (th: ArtyFPGATestHarness, port: JTAGResetPort) => {
port.io := PowerOnResetFPGAOnly(th.clock_32MHz) // JTAG module reset
}
})

class WithArtyJTAGHarnessBinder extends OverrideHarnessBinder({
(system: HasPeripheryDebug, th: ArtyFPGATestHarness, ports: Seq[Data]) => {
ports.map {
case j: JTAGChipIO => {
val jtag_wire = Wire(new JTAGIO)
jtag_wire.TDO.data := j.TDO
jtag_wire.TDO.driven := true.B
j.TCK := jtag_wire.TCK
j.TMS := jtag_wire.TMS
j.TDI := jtag_wire.TDI
class WithArtyJTAGHarnessBinder extends HarnessBinder({
case (th: ArtyFPGATestHarness, port: JTAGPort) => {
val jtag_wire = Wire(new JTAGIO)
jtag_wire.TDO.data := port.io.TDO
jtag_wire.TDO.driven := true.B
port.io.TCK := jtag_wire.TCK
port.io.TMS := jtag_wire.TMS
port.io.TDI := jtag_wire.TDI

val io_jtag = Wire(new JTAGPins(() => new BasePin(), false)).suggestName("jtag")
val io_jtag = Wire(new JTAGPins(() => new BasePin(), false)).suggestName("jtag")

JTAGPinsFromPort(io_jtag, jtag_wire)
JTAGPinsFromPort(io_jtag, jtag_wire)

io_jtag.TCK.i.ival := IBUFG(IOBUF(th.jd_2).asClock).asBool
io_jtag.TCK.i.ival := IBUFG(IOBUF(th.jd_2).asClock).asBool

IOBUF(th.jd_5, io_jtag.TMS)
PULLUP(th.jd_5)
IOBUF(th.jd_5, io_jtag.TMS)
PULLUP(th.jd_5)

IOBUF(th.jd_4, io_jtag.TDI)
PULLUP(th.jd_4)
IOBUF(th.jd_4, io_jtag.TDI)
PULLUP(th.jd_4)

IOBUF(th.jd_0, io_jtag.TDO)
IOBUF(th.jd_0, io_jtag.TDO)

// mimic putting a pullup on this line (part of reset vote)
th.SRST_n := IOBUF(th.jd_6)
PULLUP(th.jd_6)
// mimic putting a pullup on this line (part of reset vote)
th.SRST_n := IOBUF(th.jd_6)
PULLUP(th.jd_6)

// ignore the po input
io_jtag.TCK.i.po.map(_ := DontCare)
io_jtag.TDI.i.po.map(_ := DontCare)
io_jtag.TMS.i.po.map(_ := DontCare)
io_jtag.TDO.i.po.map(_ := DontCare)
}
case b: Bool =>
}
// ignore the po input
io_jtag.TCK.i.po.map(_ := DontCare)
io_jtag.TDI.i.po.map(_ := DontCare)
io_jtag.TMS.i.po.map(_ := DontCare)
io_jtag.TDO.i.po.map(_ := DontCare)
}
})

class WithArtyUARTHarnessBinder extends OverrideHarnessBinder({
(system: HasPeripheryUARTModuleImp, th: ArtyFPGATestHarness, ports: Seq[UARTPortIO]) => {
class WithArtyUARTHarnessBinder extends HarnessBinder({
case (th: ArtyFPGATestHarness, port: UARTPort) => {
withClockAndReset(th.clock_32MHz, th.ck_rst) {
IOBUF(th.uart_rxd_out, ports.head.txd)
ports.head.rxd := IOBUF(th.uart_txd_in)
IOBUF(th.uart_rxd_out, port.io.txd)
port.io.rxd := IOBUF(th.uart_txd_in)
}
}
})
4 changes: 2 additions & 2 deletions fpga/src/main/scala/arty/IOBinders.scala
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import chisel3.experimental.{IO}

import freechips.rocketchip.devices.debug.{HasPeripheryDebug}

import chipyard.iobinders.{ComposeIOBinder}
import chipyard.iobinders.{ComposeIOBinder, DebugResetPort, JTAGResetPort}

class WithDebugResetPassthrough extends ComposeIOBinder({
(system: HasPeripheryDebug) => {
Expand All @@ -18,6 +18,6 @@ class WithDebugResetPassthrough extends ComposeIOBinder({
val io_sjtag_reset: Bool = IO(Input(Bool())).suggestName("sjtag_reset")
sjtag.reset := io_sjtag_reset

(Seq(io_ndreset, io_sjtag_reset), Nil)
(Seq(DebugResetPort(io_ndreset), JTAGResetPort(io_sjtag_reset)), Nil)
}
})
29 changes: 12 additions & 17 deletions fpga/src/main/scala/arty100t/HarnessBinders.scala
Original file line number Diff line number Diff line change
Expand Up @@ -16,33 +16,28 @@ import sifive.fpgashells.ip.xilinx.{IBUFG, IOBUF, PULLUP, PowerOnResetFPGAOnly}

import chipyard._
import chipyard.harness._
import chipyard.iobinders.JTAGChipIO
import chipyard.iobinders._

import testchipip._

class WithArty100TUARTTSI(uartBaudRate: BigInt = 115200) extends OverrideHarnessBinder({
(system: CanHavePeripheryUARTTSI, th: HasHarnessInstantiators, ports: Seq[UARTTSIIO]) => {
implicit val p = chipyard.iobinders.GetSystemParameters(system)
require(ports.size <= 1)
class WithArty100TUARTTSI(uartBaudRate: BigInt = 115200) extends HarnessBinder({
case (th: HasHarnessInstantiators, port: UARTTSIPort) => {
val ath = th.asInstanceOf[LazyRawModuleImp].wrapper.asInstanceOf[Arty100THarness]
ports.map({ port =>
ath.io_uart_bb.bundle <> port.uart
ath.other_leds(1) := port.dropped
ath.other_leds(9) := port.tsi2tl_state(0)
ath.other_leds(10) := port.tsi2tl_state(1)
ath.other_leds(11) := port.tsi2tl_state(2)
ath.other_leds(12) := port.tsi2tl_state(3)
})
ath.io_uart_bb.bundle <> port.io.uart
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)
ath.other_leds(11) := port.io.tsi2tl_state(2)
ath.other_leds(12) := port.io.tsi2tl_state(3)
}
})

class WithArty100TDDRTL extends OverrideHarnessBinder({
(system: CanHaveMasterTLMemPort, th: HasHarnessInstantiators, ports: Seq[HeterogeneousBag[TLBundle]]) => {
require(ports.size == 1)
class WithArty100TDDRTL extends HarnessBinder({
case (th: HasHarnessInstantiators, port: TLMemPort) => {
val artyTh = th.asInstanceOf[LazyRawModuleImp].wrapper.asInstanceOf[Arty100THarness]
val bundles = artyTh.ddrClient.out.map(_._1)
val ddrClientBundle = Wire(new HeterogeneousBag(bundles.map(_.cloneType)))
bundles.zip(ddrClientBundle).foreach { case (bundle, io) => bundle <> io }
ddrClientBundle <> ports.head
ddrClientBundle <> port.io
}
})
28 changes: 12 additions & 16 deletions fpga/src/main/scala/nexysvideo/HarnessBinders.scala
Original file line number Diff line number Diff line change
Expand Up @@ -14,30 +14,26 @@ import chipyard._
import chipyard.harness._

import testchipip._
import chipyard.iobinders._

class WithNexysVideoUARTTSI(uartBaudRate: BigInt = 115200) extends OverrideHarnessBinder({
(system: CanHavePeripheryUARTTSI, th: HasHarnessInstantiators, ports: Seq[UARTTSIIO]) => {
implicit val p = chipyard.iobinders.GetSystemParameters(system)
require(ports.size <= 1)
class WithNexysVideoUARTTSI(uartBaudRate: BigInt = 115200) extends HarnessBinder({
case (th: HasHarnessInstantiators, port: UARTTSIPort) => {
val nexysvideoth = th.asInstanceOf[LazyRawModuleImp].wrapper.asInstanceOf[NexysVideoHarness]
ports.map({ port =>
nexysvideoth.io_uart_bb.bundle <> port.uart
nexysvideoth.other_leds(1) := port.dropped
nexysvideoth.other_leds(2) := port.tsi2tl_state(0)
nexysvideoth.other_leds(3) := port.tsi2tl_state(1)
nexysvideoth.other_leds(4) := port.tsi2tl_state(2)
nexysvideoth.other_leds(5) := port.tsi2tl_state(3)
})
nexysvideoth.io_uart_bb.bundle <> port.io.uart
nexysvideoth.other_leds(1) := port.io.dropped
nexysvideoth.other_leds(2) := port.io.tsi2tl_state(0)
nexysvideoth.other_leds(3) := port.io.tsi2tl_state(1)
nexysvideoth.other_leds(4) := port.io.tsi2tl_state(2)
nexysvideoth.other_leds(5) := port.io.tsi2tl_state(3)
}
})

class WithNexysVideoDDRTL extends OverrideHarnessBinder({
(system: CanHaveMasterTLMemPort, th: HasHarnessInstantiators, ports: Seq[HeterogeneousBag[TLBundle]]) => {
require(ports.size == 1)
class WithNexysVideoDDRTL extends HarnessBinder({
case (th: HasHarnessInstantiators, port: TLMemPort) => {
val nexysTh = th.asInstanceOf[LazyRawModuleImp].wrapper.asInstanceOf[NexysVideoHarness]
val bundles = nexysTh.ddrClient.get.out.map(_._1)
val ddrClientBundle = Wire(new HeterogeneousBag(bundles.map(_.cloneType)))
bundles.zip(ddrClientBundle).foreach { case (bundle, io) => bundle <> io }
ddrClientBundle <> ports.head
ddrClientBundle <> port.io
}
})
4 changes: 0 additions & 4 deletions fpga/src/main/scala/vc707/Configs.scala
Original file line number Diff line number Diff line change
Expand Up @@ -53,10 +53,6 @@ class WithVC707Tweaks extends Config (
new WithVC707UARTHarnessBinder ++
new WithVC707SPISDCardHarnessBinder ++
new WithVC707DDRMemHarnessBinder ++
// io binders
new WithUARTIOPassthrough ++
new WithSPIIOPassthrough ++
new WithTLIOPassthrough ++
// other configuration
new WithDefaultPeripherals ++
new chipyard.config.WithTLBackingMemory ++ // use TL backing memory
Expand Down
35 changes: 14 additions & 21 deletions fpga/src/main/scala/vc707/HarnessBinders.scala
Original file line number Diff line number Diff line change
Expand Up @@ -11,36 +11,29 @@ import sifive.blocks.devices.spi.{HasPeripherySPI, SPIPortIO}
import sifive.fpgashells.devices.xilinx.xilinxvc707pciex1.{HasSystemXilinxVC707PCIeX1ModuleImp, XilinxVC707PCIeX1IO}

import chipyard.{CanHaveMasterTLMemPort}
import chipyard.harness.{OverrideHarnessBinder}
import chipyard.harness.{HarnessBinder}
import chipyard.iobinders._

/*** UART ***/
class WithVC707UARTHarnessBinder extends OverrideHarnessBinder({
(system: HasPeripheryUARTModuleImp, th: BaseModule, ports: Seq[UARTPortIO]) => {
th match { case vc707th: VC707FPGATestHarnessImp => {
vc707th.vc707Outer.io_uart_bb.bundle <> ports.head
}}
class WithVC707UARTHarnessBinder extends HarnessBinder({
case (th: VC707FPGATestHarnessImp, port: UARTPort) => {
th.vc707Outer.io_uart_bb.bundle <> port.io
}
})

/*** SPI ***/
class WithVC707SPISDCardHarnessBinder extends OverrideHarnessBinder({
(system: HasPeripherySPI, th: BaseModule, ports: Seq[SPIPortIO]) => {
th match { case vc707th: VC707FPGATestHarnessImp => {
vc707th.vc707Outer.io_spi_bb.bundle <> ports.head
}}
class WithVC707SPISDCardHarnessBinder extends HarnessBinder({
case (th: VC707FPGATestHarnessImp, port: SPIPort) => {
th.vc707Outer.io_spi_bb.bundle <> port.io
}
})

/*** Experimental DDR ***/
class WithVC707DDRMemHarnessBinder extends OverrideHarnessBinder({
(system: CanHaveMasterTLMemPort, th: BaseModule, ports: Seq[HeterogeneousBag[TLBundle]]) => {
th match { case vc707th: VC707FPGATestHarnessImp => {
require(ports.size == 1)

val bundles = vc707th.vc707Outer.ddrClient.out.map(_._1)
val ddrClientBundle = Wire(new HeterogeneousBag(bundles.map(_.cloneType)))
bundles.zip(ddrClientBundle).foreach { case (bundle, io) => bundle <> io }
ddrClientBundle <> ports.head
}}
class WithVC707DDRMemHarnessBinder extends HarnessBinder({
case (th: VC707FPGATestHarnessImp, port: TLMemPort) => {
val bundles = th.vc707Outer.ddrClient.out.map(_._1)
val ddrClientBundle = Wire(new HeterogeneousBag(bundles.map(_.cloneType)))
bundles.zip(ddrClientBundle).foreach { case (bundle, io) => bundle <> io }
ddrClientBundle <> port.io
}
})
53 changes: 0 additions & 53 deletions fpga/src/main/scala/vc707/IOBinders.scala

This file was deleted.

3 changes: 0 additions & 3 deletions fpga/src/main/scala/vcu118/Configs.scala
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,6 @@ class WithVCU118Tweaks extends Config(
new WithUART ++
new WithSPISDCard ++
new WithDDRMem ++
// io binders
new WithUARTIOPassthrough ++
new WithSPIIOPassthrough ++
// other configuration
new WithDefaultPeripherals ++
new chipyard.config.WithTLBackingMemory ++ // use TL backing memory
Expand Down
Loading