diff --git a/src/main/scala/jtag/JtagStateMachine.scala b/src/main/scala/jtag/JtagStateMachine.scala index bf191d79..8fdb9e7f 100644 --- a/src/main/scala/jtag/JtagStateMachine.scala +++ b/src/main/scala/jtag/JtagStateMachine.scala @@ -4,6 +4,8 @@ package freechips.rocketchip.jtag import Chisel._ import chisel3.{Input, Output} +import chisel3.experimental.withReset + import freechips.rocketchip.config.{Parameters} import freechips.rocketchip.util.{AsyncResetRegVec} 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 { val tms = Input(Bool()) - val currState = Output(JtagState.State.chiselType()) - - val jtag_reset = Input(Bool()) + val currState = Output(JtagState.State.chiselType) } val io = IO(new StateMachineIO) - // val nextState = WireInit(JtagState.State.chiselType(), DontCare) val nextState = Wire(JtagState.State.chiselType()) - val currStateReg = Module (new AsyncResetRegVec(w = JtagState.State.width, init = JtagState.State.toInt(JtagState.TestLogicReset))) - - currStateReg.clock := clock - currStateReg.reset := io.jtag_reset currStateReg.io.en := true.B currStateReg.io.d := nextState - val currState = currStateReg.io.q switch (currState) { @@ -148,7 +142,8 @@ 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 && 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") + } } diff --git a/src/main/scala/jtag/JtagTap.scala b/src/main/scala/jtag/JtagTap.scala index 733b4802..6506ad75 100644 --- a/src/main/scala/jtag/JtagTap.scala +++ b/src/main/scala/jtag/JtagTap.scala @@ -9,6 +9,8 @@ import scala.collection.SortedMap import Chisel._ import chisel3.core.{Input, Output} import chisel3.util._ +import chisel3.experimental.withReset + import freechips.rocketchip.config.Parameters /** 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_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.driven := NegativeEdgeLatch(clock, tdo_driven, name = Some("tdoeReg")) + 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 := NegEdgeReg(clock, tdo_driven, name = Some("tdoeReg")) // // JTAG state machine // - val stateMachine = Module(new JtagStateMachine) - stateMachine.io.tms := io.jtag.TMS - val currState = stateMachine.io.currState - io.output.state := stateMachine.io.currState + + val currState = Wire(JtagState.State.chiselType) // At this point, the TRSTn should already have been // combined with any POR, and it should also be // synchronized to TCK. 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 @@ -105,7 +111,7 @@ class JtagTapController(irLength: Int, initialInstruction: BigInt)(implicit val val updateInstruction = Wire(Bool()) 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) { nextActiveInstruction := initialInstruction.U(irLength.W) diff --git a/src/main/scala/jtag/Utils.scala b/src/main/scala/jtag/Utils.scala index b6ae8128..542f1a7c 100644 --- a/src/main/scala/jtag/Utils.scala +++ b/src/main/scala/jtag/Utils.scala @@ -2,9 +2,9 @@ package freechips.rocketchip.jtag -//import chisel3._ import Chisel._ import chisel3.core.{Input, Output} +import chisel3.experimental.withClock /** 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 } -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. */ -object NegativeEdgeLatch { +object NegEdgeReg { 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 - val latch_module = Module(new NegativeEdgeLatch((!clock.asUInt).asClock, next.cloneType)) - name.foreach(latch_module.suggestName(_)) - latch_module.io.next := next - latch_module.io.enable := enable - latch_module.io.output + // TODO pass in initial value as well + withClock((!clock.asUInt).asClock) { + val reg = RegEnable(next = next, enable = enable) + name.foreach{reg.suggestName(_)} + reg + } } } /** A module that counts transitions on the input clock line, used as a basic sanity check and * debug indicator clock-crossing designs. */ -class ClockedCounter(modClock: Clock, counts: BigInt, init: Option[BigInt]) - extends Module(override_clock=Some(modClock)) { +class ClockedCounter(counts: BigInt, init: Option[BigInt]) extends Module { require(counts > 0, "really?") val width = log2Ceil(counts) @@ -65,19 +48,23 @@ class ClockedCounter(modClock: Clock, counts: BigInt, init: Option[BigInt]) } .otherwise { 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. */ object ClockedCounter { def apply (data: Bool, counts: BigInt, init: BigInt): UInt = { - val counter = Module(new ClockedCounter(data.asClock, counts, Some(init))) - counter.io.count + withClock(data.asClock) { + val counter = Module(new ClockedCounter(counts, Some(init))) + counter.io.count + } } + def apply (data: Bool, counts: BigInt): UInt = { - val counter = Module(new ClockedCounter(data.asClock, counts, None)) - counter.io.count + withClock(data.asClock) { + val counter = Module(new ClockedCounter(counts, None)) + counter.io.count + } } }