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:
		| @@ -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") | ||||
|   | ||||
|   } | ||||
|  | ||||
| } | ||||
|   | ||||
| @@ -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) | ||||
|   | ||||
| @@ -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 | ||||
|     } | ||||
|   } | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user