From a8ab06d57219d7bf9ace2a6433b935ddc1ab34f2 Mon Sep 17 00:00:00 2001 From: Megan Wachs Date: Mon, 2 Oct 2017 11:05:45 -0700 Subject: [PATCH 1/3] JTAG: Add coverage points to the JTAG Tap --- src/main/scala/jtag/JtagShifter.scala | 24 +++++++++++++++------- src/main/scala/jtag/JtagStateMachine.scala | 11 +++++++++- src/main/scala/jtag/JtagTap.scala | 6 ++++-- 3 files changed, 31 insertions(+), 10 deletions(-) diff --git a/src/main/scala/jtag/JtagShifter.scala b/src/main/scala/jtag/JtagShifter.scala index a218fd70..869d45b4 100644 --- a/src/main/scala/jtag/JtagShifter.scala +++ b/src/main/scala/jtag/JtagShifter.scala @@ -7,6 +7,9 @@ import chisel3.core.DataMirror import chisel3.internal.firrtl.KnownWidth import chisel3.util._ +import freechips.rocketchip.config.Parameters +import freechips.rocketchip.util.property._ + /** Base JTAG shifter IO, viewed from input to shift register chain. * Can be chained together. */ @@ -51,7 +54,7 @@ trait Chain extends Module { * * Implements Clause 10. */ -class JtagBypassChain extends Chain { +class JtagBypassChain(implicit val p: Parameters) extends Chain { class ModIO extends ChainIO val io = IO(new ModIO) io.chainOut chainControlFrom io.chainIn @@ -60,6 +63,8 @@ class JtagBypassChain extends Chain { io.chainOut.data := reg + cover(io.chainIn.capture, "bypass_chain_capture", "JTAG; bypass_chain_capture; This Bypass Chain captured data") + when (io.chainIn.capture) { reg := false.B // 10.1.1b capture logic 0 on TCK rising } .elsewhen (io.chainIn.shift) { @@ -71,7 +76,7 @@ class JtagBypassChain extends Chain { } object JtagBypassChain { - def apply() = new JtagBypassChain + def apply()(implicit p: Parameters) = new JtagBypassChain } /** Simple shift register with parallel capture only, for read-only data registers. @@ -82,7 +87,7 @@ object JtagBypassChain { * 7.2.1c shifter shifts on TCK rising edge * 4.3.2a TDI captured on TCK rising edge, 6.1.2.1b assumed changes on TCK falling edge */ -class CaptureChain[+T <: Data](gen: T) extends Chain { +class CaptureChain[+T <: Data](gen: T)(implicit val p: Parameters) extends Chain { class ModIO extends ChainIO { val capture = Capture(gen) } @@ -98,6 +103,8 @@ class CaptureChain[+T <: Data](gen: T) extends Chain { io.chainOut.data := regs(0) + cover(io.chainIn.capture, "chain_capture", "JTAG; chain_capture; This Chain captured data") + when (io.chainIn.capture) { (0 until n) map (x => regs(x) := io.capture.bits.asUInt()(x)) io.capture.capture := true.B @@ -114,7 +121,7 @@ class CaptureChain[+T <: Data](gen: T) extends Chain { } object CaptureChain { - def apply[T <: Data](gen: T) = new CaptureChain(gen) + def apply[T <: Data](gen: T)(implicit p: Parameters) = new CaptureChain(gen) } /** Simple shift register with parallel capture and update. Useful for general instruction and data @@ -127,7 +134,7 @@ object CaptureChain { * 7.2.1c shifter shifts on TCK rising edge * 4.3.2a TDI captured on TCK rising edge, 6.1.2.1b assumed changes on TCK falling edge */ -class CaptureUpdateChain[+T <: Data, +V <: Data](genCapture: T, genUpdate: V) extends Chain { +class CaptureUpdateChain[+T <: Data, +V <: Data](genCapture: T, genUpdate: V)(implicit val p: Parameters) extends Chain { class ModIO extends ChainIO { val capture = Capture(genCapture) val update = Valid(genUpdate) // valid high when in update state (single cycle), contents may change any time after @@ -154,6 +161,9 @@ class CaptureUpdateChain[+T <: Data, +V <: Data](genCapture: T, genUpdate: V) ex val captureBits = io.capture.bits.asUInt() + cover(io.chainIn.capture, "chain_capture", "JTAG;chain_capture; This Chain captured data") + cover(io.chainIn.capture, "chain_update", "JTAG;chain_update; This Chain updated data") + when (io.chainIn.capture) { (0 until math.min(n, captureWidth)) map (x => regs(x) := captureBits(x)) (captureWidth until n) map (x => regs(x) := 0.U) @@ -179,7 +189,7 @@ class CaptureUpdateChain[+T <: Data, +V <: Data](genCapture: T, genUpdate: V) ex object CaptureUpdateChain { /** Capture-update chain with matching capture and update types. */ - def apply[T <: Data](gen: T) = new CaptureUpdateChain(gen, gen) - def apply[T <: Data, V <: Data](genCapture: T, genUpdate: V) = + def apply[T <: Data](gen: T)(implicit p: Parameters) = new CaptureUpdateChain(gen, gen) + def apply[T <: Data, V <: Data](genCapture: T, genUpdate: V)(implicit p: Parameters) = new CaptureUpdateChain(genCapture, genUpdate) } diff --git a/src/main/scala/jtag/JtagStateMachine.scala b/src/main/scala/jtag/JtagStateMachine.scala index 240a946a..34311e95 100644 --- a/src/main/scala/jtag/JtagStateMachine.scala +++ b/src/main/scala/jtag/JtagStateMachine.scala @@ -4,7 +4,9 @@ package freechips.rocketchip.jtag import chisel3._ import chisel3.util._ +import freechips.rocketchip.config.{Parameters} import freechips.rocketchip.util.{AsyncResetRegVec} +import freechips.rocketchip.util.property._ object JtagState { sealed abstract class State(val id: Int) { @@ -67,7 +69,7 @@ object JtagState { * * */ -class JtagStateMachine extends Module(override_reset=Some(false.B)) { +class JtagStateMachine(implicit val p: Parameters) extends Module(override_reset=Some(false.B)) { class StateMachineIO extends Bundle { val tms = Input(Bool()) val currState = Output(JtagState.State.chiselType()) @@ -140,4 +142,11 @@ class JtagStateMachine extends Module(override_reset=Some(false.B)) { } io.currState := currState + + // Generate Coverate Points + JtagState.State.all.foreach { s => + cover (currState === s.U && io.tms === true.B, s"${s.toString}_tms_1", "JTAG; ${s.toString} with TMS = 1; State Transition from ${s.toString} with TMS = 1") + cover (currState === s.U && io.tms === false.B, s"${s.toString}_tms_0", "JTAG; ${s.toString} with TMS = 0; State Transition from ${s.toString} with TMS = 0") + } + } diff --git a/src/main/scala/jtag/JtagTap.scala b/src/main/scala/jtag/JtagTap.scala index 78468582..44a55ef1 100644 --- a/src/main/scala/jtag/JtagTap.scala +++ b/src/main/scala/jtag/JtagTap.scala @@ -4,6 +4,8 @@ package freechips.rocketchip.jtag import chisel3._ import chisel3.util._ +import freechips.rocketchip.config.Parameters + /** JTAG signals, viewed from the master side */ class JTAGIO(hasTRSTn: Boolean = false) extends Bundle { @@ -57,7 +59,7 @@ class JtagControllerIO(irLength: Int) extends JtagBlockIO(irLength, false) { * Misc notes: * - Figure 6-3 and 6-4 provides examples with timing behavior */ -class JtagTapController(irLength: Int, initialInstruction: BigInt) extends Module { +class JtagTapController(irLength: Int, initialInstruction: BigInt)(implicit val p: Parameters) extends Module { require(irLength >= 2) // 7.1.1a val io = IO(new JtagControllerIO(irLength)) @@ -160,7 +162,7 @@ object JtagTapGenerator { * TODO: * - support concatenated scan chains */ - def apply(irLength: Int, instructions: Map[BigInt, Chain], icode: Option[BigInt] = None): JtagBlockIO = { + def apply(irLength: Int, instructions: Map[BigInt, Chain], icode: Option[BigInt] = None)(implicit p: Parameters): JtagBlockIO = { val internalIo = Wire(new JtagBlockIO(irLength, icode.isDefined)) From 9c9cb68462525fe124689484131a0be0c56f2d64 Mon Sep 17 00:00:00 2001 From: Megan Wachs Date: Mon, 2 Oct 2017 11:07:55 -0700 Subject: [PATCH 2/3] JTAG Coverage: Add reset coverage points --- src/main/scala/jtag/JtagStateMachine.scala | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/scala/jtag/JtagStateMachine.scala b/src/main/scala/jtag/JtagStateMachine.scala index 34311e95..fd149d2b 100644 --- a/src/main/scala/jtag/JtagStateMachine.scala +++ b/src/main/scala/jtag/JtagStateMachine.scala @@ -147,6 +147,7 @@ class JtagStateMachine(implicit val p: Parameters) extends Module(override_reset JtagState.State.all.foreach { s => cover (currState === s.U && io.tms === true.B, s"${s.toString}_tms_1", "JTAG; ${s.toString} with TMS = 1; State Transition from ${s.toString} with TMS = 1") cover (currState === s.U && io.tms === false.B, s"${s.toString}_tms_0", "JTAG; ${s.toString} with TMS = 0; State Transition from ${s.toString} with TMS = 0") + cover (currState === s.U && jtag_reset === true.B, s"${s.toString}_reset", "JTAG; ${s.toString} with reset; JTAG Reset asserted during ${s.toString") } } From 0916cf1bdd01afac15f16ba9a6e56537994084d9 Mon Sep 17 00:00:00 2001 From: Megan Wachs Date: Mon, 9 Oct 2017 09:54:15 -0700 Subject: [PATCH 3/3] JTAG Coverage: Correct jtag_reset case --- src/main/scala/jtag/JtagStateMachine.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/scala/jtag/JtagStateMachine.scala b/src/main/scala/jtag/JtagStateMachine.scala index fd149d2b..91228d02 100644 --- a/src/main/scala/jtag/JtagStateMachine.scala +++ b/src/main/scala/jtag/JtagStateMachine.scala @@ -147,7 +147,7 @@ class JtagStateMachine(implicit val p: Parameters) extends Module(override_reset JtagState.State.all.foreach { s => cover (currState === s.U && io.tms === true.B, s"${s.toString}_tms_1", "JTAG; ${s.toString} with TMS = 1; State Transition from ${s.toString} with TMS = 1") cover (currState === s.U && io.tms === false.B, s"${s.toString}_tms_0", "JTAG; ${s.toString} with TMS = 0; State Transition from ${s.toString} with TMS = 0") - cover (currState === s.U && jtag_reset === true.B, s"${s.toString}_reset", "JTAG; ${s.toString} with reset; JTAG Reset asserted during ${s.toString") + cover (currState === s.U && io.jtag_reset === true.B, s"${s.toString}_reset", "JTAG; ${s.toString} with reset; JTAG Reset asserted during ${s.toString") } }