Merge pull request #1024 from freechipsproject/jtag_coverage
Add Coverage points for JTAG TAP
This commit is contained in:
commit
0e6aa7ae9d
@ -7,6 +7,9 @@ import chisel3.core.DataMirror
|
|||||||
import chisel3.internal.firrtl.KnownWidth
|
import chisel3.internal.firrtl.KnownWidth
|
||||||
import chisel3.util._
|
import chisel3.util._
|
||||||
|
|
||||||
|
import freechips.rocketchip.config.Parameters
|
||||||
|
import freechips.rocketchip.util.property._
|
||||||
|
|
||||||
/** Base JTAG shifter IO, viewed from input to shift register chain.
|
/** Base JTAG shifter IO, viewed from input to shift register chain.
|
||||||
* Can be chained together.
|
* Can be chained together.
|
||||||
*/
|
*/
|
||||||
@ -51,7 +54,7 @@ trait Chain extends Module {
|
|||||||
*
|
*
|
||||||
* Implements Clause 10.
|
* Implements Clause 10.
|
||||||
*/
|
*/
|
||||||
class JtagBypassChain extends Chain {
|
class JtagBypassChain(implicit val p: Parameters) extends Chain {
|
||||||
class ModIO extends ChainIO
|
class ModIO extends ChainIO
|
||||||
val io = IO(new ModIO)
|
val io = IO(new ModIO)
|
||||||
io.chainOut chainControlFrom io.chainIn
|
io.chainOut chainControlFrom io.chainIn
|
||||||
@ -60,6 +63,8 @@ class JtagBypassChain extends Chain {
|
|||||||
|
|
||||||
io.chainOut.data := reg
|
io.chainOut.data := reg
|
||||||
|
|
||||||
|
cover(io.chainIn.capture, "bypass_chain_capture", "JTAG; bypass_chain_capture; This Bypass Chain captured data")
|
||||||
|
|
||||||
when (io.chainIn.capture) {
|
when (io.chainIn.capture) {
|
||||||
reg := false.B // 10.1.1b capture logic 0 on TCK rising
|
reg := false.B // 10.1.1b capture logic 0 on TCK rising
|
||||||
} .elsewhen (io.chainIn.shift) {
|
} .elsewhen (io.chainIn.shift) {
|
||||||
@ -71,7 +76,7 @@ class JtagBypassChain extends Chain {
|
|||||||
}
|
}
|
||||||
|
|
||||||
object JtagBypassChain {
|
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.
|
/** 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
|
* 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
|
* 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 {
|
class ModIO extends ChainIO {
|
||||||
val capture = Capture(gen)
|
val capture = Capture(gen)
|
||||||
}
|
}
|
||||||
@ -98,6 +103,8 @@ class CaptureChain[+T <: Data](gen: T) extends Chain {
|
|||||||
|
|
||||||
io.chainOut.data := regs(0)
|
io.chainOut.data := regs(0)
|
||||||
|
|
||||||
|
cover(io.chainIn.capture, "chain_capture", "JTAG; chain_capture; This Chain captured data")
|
||||||
|
|
||||||
when (io.chainIn.capture) {
|
when (io.chainIn.capture) {
|
||||||
(0 until n) map (x => regs(x) := io.capture.bits.asUInt()(x))
|
(0 until n) map (x => regs(x) := io.capture.bits.asUInt()(x))
|
||||||
io.capture.capture := true.B
|
io.capture.capture := true.B
|
||||||
@ -114,7 +121,7 @@ class CaptureChain[+T <: Data](gen: T) extends Chain {
|
|||||||
}
|
}
|
||||||
|
|
||||||
object CaptureChain {
|
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
|
/** 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
|
* 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
|
* 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 {
|
class ModIO extends ChainIO {
|
||||||
val capture = Capture(genCapture)
|
val capture = Capture(genCapture)
|
||||||
val update = Valid(genUpdate) // valid high when in update state (single cycle), contents may change any time after
|
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()
|
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) {
|
when (io.chainIn.capture) {
|
||||||
(0 until math.min(n, captureWidth)) map (x => regs(x) := captureBits(x))
|
(0 until math.min(n, captureWidth)) map (x => regs(x) := captureBits(x))
|
||||||
(captureWidth until n) map (x => regs(x) := 0.U)
|
(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 {
|
object CaptureUpdateChain {
|
||||||
/** Capture-update chain with matching capture and update types.
|
/** Capture-update chain with matching capture and update types.
|
||||||
*/
|
*/
|
||||||
def apply[T <: Data](gen: T) = new CaptureUpdateChain(gen, gen)
|
def apply[T <: Data](gen: T)(implicit p: Parameters) = new CaptureUpdateChain(gen, gen)
|
||||||
def apply[T <: Data, V <: Data](genCapture: T, genUpdate: V) =
|
def apply[T <: Data, V <: Data](genCapture: T, genUpdate: V)(implicit p: Parameters) =
|
||||||
new CaptureUpdateChain(genCapture, genUpdate)
|
new CaptureUpdateChain(genCapture, genUpdate)
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,9 @@ package freechips.rocketchip.jtag
|
|||||||
|
|
||||||
import chisel3._
|
import chisel3._
|
||||||
import chisel3.util._
|
import chisel3.util._
|
||||||
|
import freechips.rocketchip.config.{Parameters}
|
||||||
import freechips.rocketchip.util.{AsyncResetRegVec}
|
import freechips.rocketchip.util.{AsyncResetRegVec}
|
||||||
|
import freechips.rocketchip.util.property._
|
||||||
|
|
||||||
object JtagState {
|
object JtagState {
|
||||||
sealed abstract class State(val id: Int) {
|
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 {
|
class StateMachineIO extends Bundle {
|
||||||
val tms = Input(Bool())
|
val tms = Input(Bool())
|
||||||
val currState = Output(JtagState.State.chiselType())
|
val currState = Output(JtagState.State.chiselType())
|
||||||
@ -140,4 +142,12 @@ class JtagStateMachine extends Module(override_reset=Some(false.B)) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
io.currState := currState
|
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")
|
||||||
|
cover (currState === s.U && io.jtag_reset === true.B, s"${s.toString}_reset", "JTAG; ${s.toString} with reset; JTAG Reset asserted during ${s.toString")
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,8 @@ package freechips.rocketchip.jtag
|
|||||||
|
|
||||||
import chisel3._
|
import chisel3._
|
||||||
import chisel3.util._
|
import chisel3.util._
|
||||||
|
import freechips.rocketchip.config.Parameters
|
||||||
|
|
||||||
/** JTAG signals, viewed from the master side
|
/** JTAG signals, viewed from the master side
|
||||||
*/
|
*/
|
||||||
class JTAGIO(hasTRSTn: Boolean = false) extends Bundle {
|
class JTAGIO(hasTRSTn: Boolean = false) extends Bundle {
|
||||||
@ -57,7 +59,7 @@ class JtagControllerIO(irLength: Int) extends JtagBlockIO(irLength, false) {
|
|||||||
* Misc notes:
|
* Misc notes:
|
||||||
* - Figure 6-3 and 6-4 provides examples with timing behavior
|
* - 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
|
require(irLength >= 2) // 7.1.1a
|
||||||
|
|
||||||
val io = IO(new JtagControllerIO(irLength))
|
val io = IO(new JtagControllerIO(irLength))
|
||||||
@ -160,7 +162,7 @@ object JtagTapGenerator {
|
|||||||
* TODO:
|
* TODO:
|
||||||
* - support concatenated scan chains
|
* - 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))
|
val internalIo = Wire(new JtagBlockIO(irLength, icode.isDefined))
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user