syncregs: Use common primitives for AsyncQueue grey code synchronizers
This commit is contained in:
parent
3461cb47cc
commit
8b462d1595
@ -13,27 +13,12 @@ object GrayCounter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
object UIntSyncChain {
|
|
||||||
def apply(in: UInt, sync: Int, name: String = "gray"): UInt = {
|
|
||||||
val syncv = List.tabulate(sync) { i =>
|
|
||||||
Module (new AsyncResetRegVec(w = in.getWidth, 0)).suggestName(s"${name}_sync_${i}")
|
|
||||||
}
|
|
||||||
syncv.last.io.d := in
|
|
||||||
syncv.last.io.en := Bool(true)
|
|
||||||
(syncv.init zip syncv.tail).foreach { case (sink, source) =>
|
|
||||||
sink.io.d := source.io.q
|
|
||||||
sink.io.en := Bool(true)
|
|
||||||
}
|
|
||||||
syncv.head.io.q
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class AsyncValidSync(sync: Int, desc: String) extends Module {
|
class AsyncValidSync(sync: Int, desc: String) extends Module {
|
||||||
val io = new Bundle {
|
val io = new Bundle {
|
||||||
val in = Bool(INPUT)
|
val in = Bool(INPUT)
|
||||||
val out = Bool(OUTPUT)
|
val out = Bool(OUTPUT)
|
||||||
}
|
}
|
||||||
io.out := UIntSyncChain(io.in.asUInt, sync, desc)(0)
|
io.out := AsyncResetSynchronizerShiftReg(io.in, sync, Some(desc))
|
||||||
}
|
}
|
||||||
|
|
||||||
class AsyncQueueSource[T <: Data](gen: T, depth: Int, sync: Int, safe: Boolean = true, narrowData: Boolean = false) extends Module {
|
class AsyncQueueSource[T <: Data](gen: T, depth: Int, sync: Int, safe: Boolean = true, narrowData: Boolean = false) extends Module {
|
||||||
@ -55,7 +40,7 @@ class AsyncQueueSource[T <: Data](gen: T, depth: Int, sync: Int, safe: Boolean =
|
|||||||
val sink_ready = Wire(init = Bool(true))
|
val sink_ready = Wire(init = Bool(true))
|
||||||
val mem = Reg(Vec(depth, gen)) // This does NOT need to be reset at all.
|
val mem = Reg(Vec(depth, gen)) // This does NOT need to be reset at all.
|
||||||
val widx = GrayCounter(bits+1, io.enq.fire(), !sink_ready, "widx_bin")
|
val widx = GrayCounter(bits+1, io.enq.fire(), !sink_ready, "widx_bin")
|
||||||
val ridx = UIntSyncChain(io.ridx, sync, "ridx_gray")
|
val ridx = AsyncResetSynchronizerShiftReg(io.ridx, sync, Some("ridx_gray"))
|
||||||
val ready = sink_ready && widx =/= (ridx ^ UInt(depth | depth >> 1))
|
val ready = sink_ready && widx =/= (ridx ^ UInt(depth | depth >> 1))
|
||||||
|
|
||||||
val index = if (depth == 1) UInt(0) else io.widx(bits-1, 0) ^ (io.widx(bits, bits) << (bits-1))
|
val index = if (depth == 1) UInt(0) else io.widx(bits-1, 0) ^ (io.widx(bits, bits) << (bits-1))
|
||||||
@ -112,7 +97,7 @@ class AsyncQueueSink[T <: Data](gen: T, depth: Int, sync: Int, safe: Boolean = t
|
|||||||
|
|
||||||
val source_ready = Wire(init = Bool(true))
|
val source_ready = Wire(init = Bool(true))
|
||||||
val ridx = GrayCounter(bits+1, io.deq.fire(), !source_ready, "ridx_bin")
|
val ridx = GrayCounter(bits+1, io.deq.fire(), !source_ready, "ridx_bin")
|
||||||
val widx = UIntSyncChain(io.widx, sync, "widx_gray")
|
val widx = AsyncResetSynchronizerShiftReg(io.widx, sync, Some("widx_gray"))
|
||||||
val valid = source_ready && ridx =/= widx
|
val valid = source_ready && ridx =/= widx
|
||||||
|
|
||||||
// The mux is safe because timing analysis ensures ridx has reached the register
|
// The mux is safe because timing analysis ensures ridx has reached the register
|
||||||
|
@ -32,9 +32,10 @@ object AbstractSynchronizerReg {
|
|||||||
|
|
||||||
def apply [T <: Chisel.Data](gen: (Int, Int) => AbstractSynchronizerReg, in: T, sync: Int = 3, name: Option[String] = None): T = {
|
def apply [T <: Chisel.Data](gen: (Int, Int) => AbstractSynchronizerReg, in: T, sync: Int = 3, name: Option[String] = None): T = {
|
||||||
val sync_chain = Module(gen(in.getWidth, sync))
|
val sync_chain = Module(gen(in.getWidth, sync))
|
||||||
name.foreach{ sync_reg.suggestName(_) }
|
name.foreach{ sync_chain.suggestName(_) }
|
||||||
sync_reg.io.d := in.asUInt
|
sync_chain.io.d := in.asUInt
|
||||||
(in.chiselCloneType).fromBits(sync_reg.io.q)
|
|
||||||
|
(in.chiselCloneType).fromBits(sync_chain.io.q)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user