1
0
Fork 0

jtag: make it easier to assign MFR ID externally

This commit is contained in:
Megan Wachs 2017-04-13 16:12:22 -07:00 committed by Andrew Waterman
parent 34d45b4fb0
commit fd7f4a4c0f
5 changed files with 46 additions and 20 deletions

View File

@ -32,17 +32,19 @@ class JtagControl extends Bundle {
/** Aggregate JTAG block IO.
*/
class JtagBlockIO(irLength: Int) extends Bundle {
class JtagBlockIO(irLength: Int, hasIdcode:Boolean = true) extends Bundle {
val jtag = Flipped(new JTAGIO())
val control = new JtagControl
val output = new JtagOutput(irLength)
val idcode = if (hasIdcode) Some(Input(new JTAGIdcodeBundle())) else None
override def cloneType = new JtagBlockIO(irLength).asInstanceOf[this.type]
override def cloneType = new JtagBlockIO(irLength, hasIdcode).asInstanceOf[this.type]
}
/** Internal controller block IO with data shift outputs.
*/
class JtagControllerIO(irLength: Int) extends JtagBlockIO(irLength) {
class JtagControllerIO(irLength: Int) extends JtagBlockIO(irLength, false) {
val dataChainOut = Output(new ShifterIO)
val dataChainIn = Input(new ShifterIO)
@ -140,7 +142,7 @@ object JtagTapGenerator {
* @param irLength length, in bits, of instruction register, must be at least 2
* @param instructions map of instruction codes to data register chains that select that data
* register; multiple instructions may map to the same data chain
* @param idcode optional idcode, tuple of (instruction code, idcode)
* @param idcode optional idcode instruction. idcode UInt will come from outside this core.
*
* @note all other instruction codes (not part of instructions or idcode) map to BYPASS
* @note initial instruction is idcode (if supported), otherwise all ones BYPASS
@ -158,25 +160,30 @@ object JtagTapGenerator {
* TODO:
* - support concatenated scan chains
*/
def apply(irLength: Int, instructions: Map[BigInt, Chain], idcode:Option[(BigInt, BigInt)]=None): JtagBlockIO = {
def apply(irLength: Int, instructions: Map[BigInt, Chain], icode: Option[BigInt] = None): JtagBlockIO = {
val internalIo = Wire(new JtagBlockIO(irLength, icode.isDefined))
// Create IDCODE chain if needed
val allInstructions = idcode match {
case Some((icode, idcode)) => {
val idcodeChain = Module(CaptureChain(UInt(32.W)))
idcodeChain.suggestName("idcodeChain")
require(idcode % 2 == 1, "LSB must be set in IDCODE, see 12.1.1d")
require(((idcode >> 1) & ((1 << 11) - 1)) != JtagIdcode.dummyMfrId, "IDCODE must not have 0b00001111111 as manufacturer identity, see 12.2.1b")
val allInstructions = icode match {
case (Some(icode)) => {
require(!(instructions contains icode), "instructions may not contain IDCODE")
idcodeChain.io.capture.bits := idcode.U(32.W)
val idcodeChain = Module(CaptureChain(new JTAGIdcodeBundle()))
idcodeChain.suggestName("idcodeChain")
val i = internalIo.idcode.get.asUInt()
assert(i % 2.U === 1.U, "LSB must be set in IDCODE, see 12.1.1d")
assert(((i >> 1) & ((1.U << 11) - 1.U)) =/= JtagIdcode.dummyMfrId.U,
"IDCODE must not have 0b00001111111 as manufacturer identity, see 12.2.1b")
idcodeChain.io.capture.bits := internalIo.idcode.get
instructions + (icode -> idcodeChain)
} case None => instructions
}
case None => instructions
}
val bypassIcode = (BigInt(1) << irLength) - 1 // required BYPASS instruction
val initialInstruction = idcode match { // 7.2.1e load IDCODE or BYPASS instruction after entry into TestLogicReset
case Some((icode, _)) => icode
case None => bypassIcode
}
val initialInstruction = icode.getOrElse(bypassIcode) // 7.2.1e load IDCODE or BYPASS instruction after entry into TestLogicReset
require(!(allInstructions contains bypassIcode), "instructions may not contain BYPASS code")
@ -230,12 +237,11 @@ object JtagTapGenerator {
chainToSelect.map(mapInSelect)
val internalIo = Wire(new JtagBlockIO(irLength))
controllerInternal.io.jtag <> internalIo.jtag
controllerInternal.io.control <> internalIo.control
controllerInternal.io.output <> internalIo.output
internalIo
}
}

View File

@ -5,6 +5,13 @@ package jtag
import chisel3._
import chisel3.util._
class JTAGIdcodeBundle extends Bundle {
val version = UInt(4.W)
val partNumber = UInt(16.W)
val mfrId = UInt(11.W)
val always1 = UInt(1.W)
}
object JtagIdcode {
/** Generates a JTAG IDCODE as a 32-bit integer, using the format in 12.1.1d.
*/

View File

@ -64,6 +64,7 @@ class DebugTransportModuleJTAG(debugAddrBits: Int, c: JtagDTMConfig)
val dmi = new DMIIO()(p)
val jtag = Flipped(new JTAGIO(hasTRSTn = false))
val jtag_reset = Bool(INPUT)
val jtag_mfr_id = UInt(INPUT, 11)
val fsmReset = Bool(OUTPUT)
}
@ -210,12 +211,19 @@ class DebugTransportModuleJTAG(debugAddrBits: Int, c: JtagDTMConfig)
//--------------------------------------------------------
// Actual JTAG TAP
val idcode = Wire(init = new JTAGIdcodeBundle().fromBits(0.U))
idcode.always1 := 1.U
idcode.version := c.idcodeVersion.U
idcode.partNumber := c.idcodePartNum.U
idcode.mfrId := io.jtag_mfr_id
val tapIO = JtagTapGenerator(irLength = 5,
instructions = Map(dtmJTAGAddrs.DMI_ACCESS -> dmiAccessChain,
dtmJTAGAddrs.DTM_INFO -> dtmInfoChain),
idcode = Some((dtmJTAGAddrs.IDCODE, JtagIdcode(c.idcodeVersion, c.idcodePartNum, c.idcodeManufId))))
icode = Some(dtmJTAGAddrs.IDCODE)
)
tapIO.idcode.get := idcode
tapIO.jtag <> io.jtag
tapIO.control.jtag_reset := io.jtag_reset

View File

@ -24,6 +24,7 @@ trait PeripheryJTAGDTMBundle extends HasTopLevelNetworksBundle {
val jtag = new JTAGIO(hasTRSTn = false).flip
val jtag_reset = Bool(INPUT)
val jtag_mfr_id = UInt(INPUT, 11)
}
@ -36,6 +37,7 @@ trait PeripheryJTAGDTMModule extends HasTopLevelNetworksModule {
dtm.clock := io.jtag.TCK
dtm.io.jtag_reset := io.jtag_reset
dtm.io.jtag_mfr_id := io.jtag_mfr_id
dtm.reset := dtm.io.fsmReset
outer.coreplex.module.io.debug.dmi <> dtm.io.dmi
@ -79,6 +81,7 @@ trait PeripheryDebugBundle extends HasTopLevelNetworksBundle {
val jtag = (p(IncludeJtagDTM)).option(new JTAGIO(hasTRSTn = false).flip)
val jtag_reset = (p(IncludeJtagDTM)).option(Bool(INPUT))
val jtag_mfr_id = (p(IncludeJtagDTM)).option(UInt(INPUT, 11))
val ndreset = Bool(OUTPUT)
val dmactive = Bool(OUTPUT)
@ -96,6 +99,7 @@ trait PeripheryDebugModule extends HasTopLevelNetworksModule {
dtm.clock := io.jtag.get.TCK
dtm.io.jtag_reset := io.jtag_reset.get
dtm.io.jtag_mfr_id := io.jtag_mfr_id.get
dtm.reset := dtm.io.fsmReset
outer.coreplex.module.io.debug.dmi <> dtm.io.dmi

View File

@ -28,6 +28,7 @@ class TestHarness()(implicit p: Parameters) extends Module {
val dtm = Module(new SimDTM).connect(clock, reset, dut.io.debug.get, io.success)
} else {
val jtag = Module(new JTAGVPI).connect(dut.io.jtag.get, dut.io.jtag_reset.get, reset, io.success)
dut.io.jtag_mfr_id.get := p(JtagDTMKey).idcodeManufId.U(11.W)
}
val mmio_sim = Module(LazyModule(new SimAXIMem(1, 4096)).module)