diff --git a/README.md b/README.md index 804bdb1..9718fda 100644 --- a/README.md +++ b/README.md @@ -1404,6 +1404,62 @@ halt A full example can be found in GenFullWithOfficialRiscvDebug.scala +##### Tunneled JTAG + +The EmbeddedRiscvJtag plugin can also be used with tunneled JTAG. This allows debugging with the same cable used to configure an FPGA. + +This uses an FPGA-specific primitive for JTAG access (e.g. Xilinx BSCANE2): +```scala +val xilJtag = BSCANE2(userId = 4) // must be userId = 4 +val jtagClockDomain = ClockDomain( + clock = xilJtag.TCK +) +``` + +Then, the EmbeddedRiscvJtag plugin must be configured for tunneling without a TAP. Note, the debug clock domain must have a separate reset from the CPU clock domain. + +```scala +// in plugins +new EmbeddedRiscvJtag( + p = DebugTransportModuleParameter( + addressWidth = 7, + version = 1, + idle = 7 + ), + withTunneling = true, + withTap = false, + debugCd = debugClockDomain, + jtagCd = jtagClockDomain +) +``` + +Then connect the EmbeddedRiscvJtag to the FPGA-specific JTAG primitive: + +```scala +for (plugin <- cpuConfig.plugins) plugin match { + case plugin: EmbeddedRiscvJtag => { + plugin.jtagInstruction <> xilJtag.toJtagTapInstructionCtrl() + } + case _ => +} +``` + +Here is an example OpenOCD TCL script to connect on a Xilinx 7-Series FPGA: + +```tcl +# ADD HERE YOUR JTAG ADAPTER SETTINGS + +source [find cpld/xilinx-xc7.cfg] +set TAP_NAME xc7.tap + +set _TARGETNAME cpu +target create $_TARGETNAME.0 riscv -chain-position $TAP_NAME +riscv use_bscan_tunnel 6 1 + +init +halt +``` + #### YamlPlugin This plugin offers a service to other plugins to generate a useful Yaml file describing the CPU configuration. It contains, for instance, the sequence of instructions required diff --git a/src/main/scala/vexriscv/plugin/EmbeddedRiscvJtag.scala b/src/main/scala/vexriscv/plugin/EmbeddedRiscvJtag.scala index 8a1c668..1e625b2 100644 --- a/src/main/scala/vexriscv/plugin/EmbeddedRiscvJtag.scala +++ b/src/main/scala/vexriscv/plugin/EmbeddedRiscvJtag.scala @@ -14,6 +14,7 @@ import vexriscv._ class EmbeddedRiscvJtag(var p : DebugTransportModuleParameter, var debugCd : ClockDomain = null, + var jtagCd : ClockDomain = null, var withTap : Boolean = true, var withTunneling : Boolean = false ) extends Plugin[VexRiscv] with VexRiscvRegressionArg{ @@ -61,7 +62,7 @@ class EmbeddedRiscvJtag(var p : DebugTransportModuleParameter, dm.io.ctrl <> logic.io.bus logic.io.jtag <> jtag } - val dmiTunneled = if(withTap && withTunneling) new Area { + val dmiTunneledWithTap = if(withTap && withTunneling) new Area { val logic = DebugTransportModuleJtagTapWithTunnel( p.copy(addressWidth = 7), debugCd = ClockDomain.current @@ -69,6 +70,15 @@ class EmbeddedRiscvJtag(var p : DebugTransportModuleParameter, dm.io.ctrl <> logic.io.bus logic.io.jtag <> jtag } + val dmiTunneledNoTap = if (!withTap && withTunneling) new Area { + val logic = DebugTransportModuleTunneled( + p.copy(addressWidth = 7), + debugCd = ClockDomain.current, + jtagCd = jtagCd + ) + logic.io.instruction <> jtagInstruction + dm.io.ctrl <> logic.io.bus + } val privBus = pipeline.service(classOf[CsrPlugin]).debugBus.setAsDirectionLess() privBus <> dm.io.harts(0)