2017-03-27 03:03:21 +02:00
|
|
|
// See LICENSE.jtag for license details.
|
|
|
|
|
2017-07-07 19:48:16 +02:00
|
|
|
package freechips.rocketchip.jtag
|
2017-03-27 03:03:21 +02:00
|
|
|
|
2017-12-19 06:02:31 +01:00
|
|
|
//import chisel3._
|
|
|
|
import Chisel._
|
|
|
|
import chisel3.core.{Input, Output}
|
2017-03-27 03:03:21 +02:00
|
|
|
|
|
|
|
/** Bundle representing a tristate pin.
|
|
|
|
*/
|
|
|
|
class Tristate extends Bundle {
|
|
|
|
val data = Bool()
|
|
|
|
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 {
|
|
|
|
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
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/** 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)) {
|
|
|
|
require(counts > 0, "really?")
|
|
|
|
|
2017-04-07 20:48:54 +02:00
|
|
|
val width = log2Ceil(counts)
|
2017-03-27 03:03:21 +02:00
|
|
|
class CountIO extends Bundle {
|
|
|
|
val count = Output(UInt(width.W))
|
|
|
|
}
|
|
|
|
val io = IO(new CountIO)
|
|
|
|
|
|
|
|
val count = init match {
|
2017-04-07 20:48:54 +02:00
|
|
|
case Some(init) => RegInit(init.U(width.W))
|
2017-03-27 03:03:21 +02:00
|
|
|
case None => Reg(UInt(width.W))
|
|
|
|
}
|
|
|
|
|
|
|
|
when (count === (counts - 1).asUInt) {
|
|
|
|
count := 0.U
|
|
|
|
} .otherwise {
|
|
|
|
count := count + 1.U
|
|
|
|
}
|
|
|
|
|
|
|
|
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
|
|
|
|
}
|
|
|
|
def apply (data: Bool, counts: BigInt): UInt = {
|
|
|
|
val counter = Module(new ClockedCounter(data.asClock, counts, None))
|
|
|
|
counter.io.count
|
|
|
|
}
|
|
|
|
}
|