Skip to content

Commit

Permalink
Merge pull request #1610 from ucb-bar/port_api
Browse files Browse the repository at this point in the history
Add PortAPI between IO and Harness blocks
  • Loading branch information
jerryz123 authored Oct 15, 2023
2 parents 73efea0 + 6bd2e9d commit 2b16b9b
Show file tree
Hide file tree
Showing 33 changed files with 700 additions and 809 deletions.
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

0 comments on commit 2b16b9b

Please sign in to comment.