Skip to content

Commit

Permalink
Support externally-driven separate JTAG reset pin
Browse files Browse the repository at this point in the history
  • Loading branch information
jerryz123 committed Aug 4, 2024
1 parent 30bbaf8 commit c55224f
Show file tree
Hide file tree
Showing 6 changed files with 25 additions and 13 deletions.
1 change: 1 addition & 0 deletions fpga/src/main/scala/arty/HarnessBinders.scala
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ class WithArtyJTAGHarnessBinder extends HarnessBinder({
port.io.TCK := jtag_wire.TCK
port.io.TMS := jtag_wire.TMS
port.io.TDI := jtag_wire.TDI
port.io.reset.foreach(_ := th.referenceReset)

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

Expand Down
9 changes: 7 additions & 2 deletions fpga/src/main/scala/arty100t/HarnessBinders.scala
Original file line number Diff line number Diff line change
Expand Up @@ -126,8 +126,12 @@ class WithArty100TPMODUART extends WithArty100TUART("G2", "F3")
class WithArty100TJTAG extends HarnessBinder({
case (th: HasHarnessInstantiators, port: JTAGPort, chipId: Int) => {
val ath = th.asInstanceOf[LazyRawModuleImp].wrapper.asInstanceOf[Arty100THarness]
val harnessIO = IO(chiselTypeOf(port.io)).suggestName("jtag")
harnessIO <> port.io
val harnessIO = IO(new JTAGChipIO(false)).suggestName("jtag")
harnessIO.TDO := port.io.TDO
port.io.TCK := harnessIO.TCK
port.io.TDI := harnessIO.TDI
port.io.TMS := harnessIO.TMS
port.io.reset.foreach(_ := th.referenceReset)

ath.sdc.addClock("JTCK", IOPin(harnessIO.TCK), 10)
ath.sdc.addGroup(clocks = Seq("JTCK"))
Expand All @@ -138,6 +142,7 @@ class WithArty100TJTAG extends HarnessBinder({
("E2", IOPin(harnessIO.TDI)),
("D4", IOPin(harnessIO.TDO))
)

packagePinsWithPackageIOs foreach { case (pin, io) => {
ath.xdc.addPackagePin(io, pin)
ath.xdc.addIOStandard(io, "LVCMOS33")
Expand Down
1 change: 1 addition & 0 deletions fpga/src/main/scala/vcu118/HarnessBinders.scala
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ class WithJTAG extends HarnessBinder({
port.io.TCK := jtag_io.TCK
port.io.TMS := jtag_io.TMS
port.io.TDI := jtag_io.TDI
port.io.reset.foreach(_ := referenceReset)
jtag_io.TDO.data := port.io.TDO
jtag_io.TDO.driven := true.B
// ignore srst_n
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ class FlatChipTop(implicit p: Parameters) extends LazyModule with HasChipyardPor
require(!debug.clockeddmi.isDefined)
require(!debug.apb.isDefined)
val (jtag_pad, jtagIOCells) = debug.systemjtag.map { j =>
val jtag_wire = Wire(new JTAGChipIO)
val jtag_wire = Wire(new JTAGChipIO(false))
j.jtag.TCK := jtag_wire.TCK
j.jtag.TMS := jtag_wire.TMS
j.jtag.TDI := jtag_wire.TDI
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,7 @@ class WithSimJTAGDebug extends HarnessBinder({
port.io.TCK := jtag_wire.TCK
port.io.TMS := jtag_wire.TMS
port.io.TDI := jtag_wire.TDI
port.io.reset.foreach(_ := th.harnessBinderReset.asBool)
val jtag = Module(new SimJTAG(tickDelay=3))
jtag.connect(jtag_wire, th.harnessBinderClock, th.harnessBinderReset.asBool, ~(th.harnessBinderReset.asBool), dtm_success)
}
Expand All @@ -199,6 +200,7 @@ class WithTiedOffJTAG extends HarnessBinder({
port.io.TCK := true.B.asClock
port.io.TMS := true.B
port.io.TDI := true.B
port.io.reset.foreach(_ := true.B)
}
})

Expand Down
23 changes: 13 additions & 10 deletions generators/chipyard/src/main/scala/iobinders/IOBinders.scala
Original file line number Diff line number Diff line change
Expand Up @@ -288,16 +288,18 @@ class WithExtInterruptIOCells extends OverrideIOBinder({
})

// Rocketchip's JTAGIO exposes the oe signal, which doesn't go off-chip
class JTAGChipIO extends Bundle {
class JTAGChipIO(hasReset: Boolean) extends Bundle {
val TCK = Input(Clock())
val TMS = Input(Bool())
val TDI = Input(Bool())
val TDO = Output(Bool())
val reset = Option.when(hasReset)(Input(Bool()))
}

// WARNING: Don't disable syncReset unless you are trying to
// get around bugs in RTL simulators
class WithDebugIOCells(syncReset: Boolean = true) extends OverrideLazyIOBinder({
// If externalReset, exposes a reset in through JTAGChipIO, which is sync'd to TCK
class WithDebugIOCells(syncReset: Boolean = true, externalReset: Boolean = true) extends OverrideLazyIOBinder({
(system: HasPeripheryDebug) => {
implicit val p = GetSystemParameters(system)
val tlbus = system.asInstanceOf[BaseSubsystem].locateTLBusWrapper(p(ExportDebug).slaveWhere)
Expand All @@ -319,13 +321,6 @@ class WithDebugIOCells(syncReset: Boolean = true) extends OverrideLazyIOBinder({
}
// Tie off disableDebug
d.disableDebug.foreach { d => d := false.B }
// Drive JTAG on-chip IOs
d.systemjtag.map { j =>
j.reset := (if (syncReset) ResetCatchAndSync(j.jtag.TCK, clockBundle.reset.asBool) else clockBundle.reset.asBool)
j.mfr_id := p(JtagDTMKey).idcodeManufId.U(11.W)
j.part_number := p(JtagDTMKey).idcodePartNum.U(16.W)
j.version := p(JtagDTMKey).idcodeVersion.U(4.W)
}
}
Debug.connectDebugClockAndReset(Some(debug), clockBundle.clock)

Expand All @@ -336,7 +331,15 @@ class WithDebugIOCells(syncReset: Boolean = true) extends OverrideLazyIOBinder({
}

val jtagTuple = debug.systemjtag.map { j =>
val jtag_wire = Wire(new JTAGChipIO)
val jtag_wire = Wire(new JTAGChipIO(externalReset))

// Drive JTAG on-chip IOs
val jReset = if (externalReset) jtag_wire.reset.get else clockBundle.reset.asBool
j.reset := (if (syncReset) ResetCatchAndSync(j.jtag.TCK, jReset) else jReset)
j.mfr_id := p(JtagDTMKey).idcodeManufId.U(11.W)
j.part_number := p(JtagDTMKey).idcodePartNum.U(16.W)
j.version := p(JtagDTMKey).idcodeVersion.U(4.W)

j.jtag.TCK := jtag_wire.TCK
j.jtag.TMS := jtag_wire.TMS
j.jtag.TDI := jtag_wire.TDI
Expand Down

0 comments on commit c55224f

Please sign in to comment.