diff --git a/src/main/scala/uncore/tilelink2/Bundles.scala b/src/main/scala/uncore/tilelink2/Bundles.scala index c32e3f4c..27071966 100644 --- a/src/main/scala/uncore/tilelink2/Bundles.scala +++ b/src/main/scala/uncore/tilelink2/Bundles.scala @@ -3,7 +3,8 @@ package uncore.tilelink2 import Chisel._ -import chisel3.util.{Irrevocable, IrrevocableIO} +import chisel3.util.{Irrevocable, IrrevocableIO, ReadyValidIO} +import util.{AsyncQueueSource, AsyncQueueSink} abstract class GenericParameterizedBundle[T <: Object](val params: T) extends Bundle { @@ -233,7 +234,7 @@ object TLBundleSnoop } } -final class AsyncBundle[T <: Data](depth: Int, gen: T) extends Bundle +final class AsyncBundle[T <: Data](val depth: Int, gen: T) extends Bundle { require (isPow2(depth)) val ridx = UInt(width = log2Up(depth)+1).flip @@ -242,6 +243,36 @@ final class AsyncBundle[T <: Data](depth: Int, gen: T) extends Bundle override def cloneType: this.type = new AsyncBundle(depth, gen).asInstanceOf[this.type] } +object FromAsyncBundle +{ + def apply[T <: Data](x: AsyncBundle[T], sync: Int = 3): IrrevocableIO[T] = { + val sink = Module(new AsyncQueueSink(x.mem(0), x.depth, sync)) + x.ridx := sink.io.ridx + sink.io.widx := x.widx + sink.io.mem := x.mem + val out = Wire(Irrevocable(x.mem(0))) + out.valid := sink.io.deq.valid + out.bits := sink.io.deq.bits + sink.io.deq.ready := out.ready + out + } +} + +object ToAsyncBundle +{ + def apply[T <: Data](x: ReadyValidIO[T], depth: Int = 8, sync: Int = 3): AsyncBundle[T] = { + val source = Module(new AsyncQueueSource(x.bits, depth, sync)) + source.io.enq.valid := x.valid + source.io.enq.bits := x.bits + x.ready := source.io.enq.ready + val out = Wire(new AsyncBundle(depth, x.bits)) + source.io.ridx := out.ridx + out.mem := source.io.mem + out.widx := source.io.widx + out + } +} + class TLAsyncBundleBase(params: TLAsyncBundleParameters) extends GenericParameterizedBundle(params) class TLAsyncBundle(params: TLAsyncBundleParameters) extends TLAsyncBundleBase(params) diff --git a/src/main/scala/util/AsyncQueue.scala b/src/main/scala/util/AsyncQueue.scala index 81049414..9c8732d7 100644 --- a/src/main/scala/util/AsyncQueue.scala +++ b/src/main/scala/util/AsyncQueue.scala @@ -25,8 +25,7 @@ object AsyncGrayCounter { } } -class AsyncQueueSource[T <: Data](gen: T, depth: Int, sync: Int, clockIn: Clock, resetIn: Bool) - extends Module(_clock = clockIn, _reset = resetIn) { +class AsyncQueueSource[T <: Data](gen: T, depth: Int, sync: Int) extends Module { val bits = log2Ceil(depth) val io = new Bundle { // These come from the source domain @@ -53,8 +52,7 @@ class AsyncQueueSource[T <: Data](gen: T, depth: Int, sync: Int, clockIn: Clock, io.mem := mem } -class AsyncQueueSink[T <: Data](gen: T, depth: Int, sync: Int, clockIn: Clock, resetIn: Bool) - extends Module(_clock = clockIn, _reset = resetIn) { +class AsyncQueueSink[T <: Data](gen: T, depth: Int, sync: Int) extends Module { val bits = log2Ceil(depth) val io = new Bundle { // These come from the sink domain @@ -88,8 +86,13 @@ class AsyncQueue[T <: Data](gen: T, depth: Int = 8, sync: Int = 3) extends Cross require (depth > 0 && isPow2(depth)) val io = new CrossingIO(gen) - val source = Module(new AsyncQueueSource(gen, depth, sync, io.enq_clock, io.enq_reset)) - val sink = Module(new AsyncQueueSink (gen, depth, sync, io.deq_clock, io.deq_reset)) + val source = Module(new AsyncQueueSource(gen, depth, sync)) + val sink = Module(new AsyncQueueSink (gen, depth, sync)) + + source.clock := io.enq_clock + source.reset := io.enq_reset + sink.clock := io.deq_clock + sink.reset := io.deq_reset source.io.enq <> io.enq io.deq <> sink.io.deq