1
0
Fork 0

JTAG: Use new withClock way of overriding clocks (#1072)

* JTAG: Use new withClock way of overriding clocks

the override clock way is deprecated

* JTAG: use withClock instead of override clock

* JTAG:  extend Module for ClockedCounter

* JTAG: Don't use deprecated clock constructs

* JTAG: Remove another override_clock

* Rename "NegativeEdgeLatch"

because it's not a latch, it's just a register on the negative edge of the clock.

* Use the appropriately named NegEdgeReg

* JTAG: Rename another NegativeEdgeLatch
This commit is contained in:
Megan Wachs 2018-01-17 13:59:05 -08:00 committed by GitHub
parent 80ca018e3a
commit 338e453a91
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 39 additions and 51 deletions

View File

@ -4,6 +4,8 @@ package freechips.rocketchip.jtag
import Chisel._ import Chisel._
import chisel3.{Input, Output} import chisel3.{Input, Output}
import chisel3.experimental.withReset
import freechips.rocketchip.config.{Parameters} import freechips.rocketchip.config.{Parameters}
import freechips.rocketchip.util.{AsyncResetRegVec} import freechips.rocketchip.util.{AsyncResetRegVec}
import freechips.rocketchip.util.property._ import freechips.rocketchip.util.property._
@ -69,26 +71,18 @@ object JtagState {
* *
* *
*/ */
class JtagStateMachine(implicit val p: Parameters) extends Module(override_reset=Some(false.B)) { class JtagStateMachine(implicit val p: Parameters) extends Module() {
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)
val jtag_reset = Input(Bool())
} }
val io = IO(new StateMachineIO) val io = IO(new StateMachineIO)
// val nextState = WireInit(JtagState.State.chiselType(), DontCare)
val nextState = Wire(JtagState.State.chiselType()) val nextState = Wire(JtagState.State.chiselType())
val currStateReg = Module (new AsyncResetRegVec(w = JtagState.State.width, val currStateReg = Module (new AsyncResetRegVec(w = JtagState.State.width,
init = JtagState.State.toInt(JtagState.TestLogicReset))) init = JtagState.State.toInt(JtagState.TestLogicReset)))
currStateReg.clock := clock
currStateReg.reset := io.jtag_reset
currStateReg.io.en := true.B currStateReg.io.en := true.B
currStateReg.io.d := nextState currStateReg.io.d := nextState
val currState = currStateReg.io.q val currState = currStateReg.io.q
switch (currState) { switch (currState) {
@ -148,7 +142,8 @@ class JtagStateMachine(implicit val p: Parameters) extends Module(override_reset
JtagState.State.all.foreach { s => 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 === 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.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") cover (currState === s.U && reset.toBool === true.B, s"${s.toString}_reset", "JTAG; ${s.toString} with reset; JTAG Reset asserted during ${s.toString")
} }
} }

View File

@ -9,6 +9,8 @@ import scala.collection.SortedMap
import Chisel._ import Chisel._
import chisel3.core.{Input, Output} import chisel3.core.{Input, Output}
import chisel3.util._ import chisel3.util._
import chisel3.experimental.withReset
import freechips.rocketchip.config.Parameters import freechips.rocketchip.config.Parameters
/** JTAG signals, viewed from the master side /** JTAG signals, viewed from the master side
@ -71,22 +73,26 @@ class JtagTapController(irLength: Int, initialInstruction: BigInt)(implicit val
val tdo = Wire(Bool()) // 4.4.1c TDI should appear here uninverted after shifting val tdo = Wire(Bool()) // 4.4.1c TDI should appear here uninverted after shifting
val tdo_driven = Wire(Bool()) val tdo_driven = Wire(Bool())
io.jtag.TDO.data := NegativeEdgeLatch(clock, tdo, name = Some("tdoReg")) // 4.5.1a TDO changes on falling edge of TCK, 6.1.2.1d driver active on first TCK falling edge in ShiftIR and ShiftDR states io.jtag.TDO.data := NegEdgeReg(clock, tdo, name = Some("tdoReg")) // 4.5.1a TDO changes on falling edge of TCK, 6.1.2.1d driver active on first TCK falling edge in ShiftIR and ShiftDR states
io.jtag.TDO.driven := NegativeEdgeLatch(clock, tdo_driven, name = Some("tdoeReg")) io.jtag.TDO.driven := NegEdgeReg(clock, tdo_driven, name = Some("tdoeReg"))
// //
// JTAG state machine // JTAG state machine
// //
val stateMachine = Module(new JtagStateMachine)
stateMachine.io.tms := io.jtag.TMS val currState = Wire(JtagState.State.chiselType)
val currState = stateMachine.io.currState
io.output.state := stateMachine.io.currState
// At this point, the TRSTn should already have been // At this point, the TRSTn should already have been
// combined with any POR, and it should also be // combined with any POR, and it should also be
// synchronized to TCK. // synchronized to TCK.
require(!io.jtag.TRSTn.isDefined, "TRSTn should be absorbed into jtckPOReset outside of JtagTapController.") require(!io.jtag.TRSTn.isDefined, "TRSTn should be absorbed into jtckPOReset outside of JtagTapController.")
stateMachine.io.jtag_reset := io.control.jtag_reset withReset(io.control.jtag_reset) {
val stateMachine = Module(new JtagStateMachine)
stateMachine.suggestName("stateMachine")
stateMachine.io.tms := io.jtag.TMS
currState := stateMachine.io.currState
io.output.state := stateMachine.io.currState
}
// //
// Instruction Register // Instruction Register
@ -105,7 +111,7 @@ class JtagTapController(irLength: Int, initialInstruction: BigInt)(implicit val
val updateInstruction = Wire(Bool()) val updateInstruction = Wire(Bool())
val nextActiveInstruction = Wire(UInt(irLength.W)) val nextActiveInstruction = Wire(UInt(irLength.W))
val activeInstruction = NegativeEdgeLatch(clock, nextActiveInstruction, updateInstruction, name = Some("irReg")) // 7.2.1d active instruction output latches on TCK falling edge val activeInstruction = NegEdgeReg(clock, nextActiveInstruction, updateInstruction, name = Some("irReg")) // 7.2.1d active instruction output latches on TCK falling edge
when (reset.toBool) { when (reset.toBool) {
nextActiveInstruction := initialInstruction.U(irLength.W) nextActiveInstruction := initialInstruction.U(irLength.W)

View File

@ -2,9 +2,9 @@
package freechips.rocketchip.jtag package freechips.rocketchip.jtag
//import chisel3._
import Chisel._ import Chisel._
import chisel3.core.{Input, Output} import chisel3.core.{Input, Output}
import chisel3.experimental.withClock
/** Bundle representing a tristate pin. /** Bundle representing a tristate pin.
*/ */
@ -13,40 +13,23 @@ class Tristate extends Bundle {
val driven = Bool() // active high, pin is hi-Z when driven is low val driven = Bool() // active high, pin is hi-Z when driven is low
} }
class NegativeEdgeLatch[T <: Data](clock: Clock, dataType: T)
extends Module(override_clock=Some(clock)) {
class IoClass extends Bundle {
val next = Input(dataType)
val enable = Input(Bool())
val output = Output(dataType)
}
val io = IO(new IoClass)
val reg = Reg(dataType)
when (io.enable) {
reg := io.next
}
io.output := reg
}
/** Generates a register that updates on the falling edge of the input clock signal. /** Generates a register that updates on the falling edge of the input clock signal.
*/ */
object NegativeEdgeLatch { object NegEdgeReg {
def apply[T <: Data](clock: Clock, next: T, enable: Bool=true.B, name: Option[String] = None): T = { def apply[T <: Data](clock: Clock, next: T, enable: Bool=true.B, name: Option[String] = None): T = {
// TODO better init passing once in-module multiclock support improves // TODO pass in initial value as well
val latch_module = Module(new NegativeEdgeLatch((!clock.asUInt).asClock, next.cloneType)) withClock((!clock.asUInt).asClock) {
name.foreach(latch_module.suggestName(_)) val reg = RegEnable(next = next, enable = enable)
latch_module.io.next := next name.foreach{reg.suggestName(_)}
latch_module.io.enable := enable reg
latch_module.io.output }
} }
} }
/** A module that counts transitions on the input clock line, used as a basic sanity check and /** A module that counts transitions on the input clock line, used as a basic sanity check and
* debug indicator clock-crossing designs. * debug indicator clock-crossing designs.
*/ */
class ClockedCounter(modClock: Clock, counts: BigInt, init: Option[BigInt]) class ClockedCounter(counts: BigInt, init: Option[BigInt]) extends Module {
extends Module(override_clock=Some(modClock)) {
require(counts > 0, "really?") require(counts > 0, "really?")
val width = log2Ceil(counts) val width = log2Ceil(counts)
@ -65,19 +48,23 @@ class ClockedCounter(modClock: Clock, counts: BigInt, init: Option[BigInt])
} .otherwise { } .otherwise {
count := count + 1.U count := count + 1.U
} }
io.count := count
io.count := count
} }
/** Count transitions on the input bit by specifying it as a clock to a counter. /** Count transitions on the input bit by specifying it as a clock to a counter.
*/ */
object ClockedCounter { object ClockedCounter {
def apply (data: Bool, counts: BigInt, init: BigInt): UInt = { def apply (data: Bool, counts: BigInt, init: BigInt): UInt = {
val counter = Module(new ClockedCounter(data.asClock, counts, Some(init))) withClock(data.asClock) {
counter.io.count val counter = Module(new ClockedCounter(counts, Some(init)))
counter.io.count
}
} }
def apply (data: Bool, counts: BigInt): UInt = { def apply (data: Bool, counts: BigInt): UInt = {
val counter = Module(new ClockedCounter(data.asClock, counts, None)) withClock(data.asClock) {
counter.io.count val counter = Module(new ClockedCounter(counts, None))
counter.io.count
}
} }
} }