In 2.6 chiseltest of chisel-bootcamp tutorials, there is a example about create a Queue using Decoupled interface:
case class QueueModule[T <: Data](ioType: T, entries: Int) extends MultiIOModule {
val in = IO(Flipped(Decoupled(ioType)))
val out = IO(Decoupled(ioType))
out <> Queue(in, entries)
}
the <> operator's direction in the last line out <> Queue(in, entries) is really confusing to me as I check <> operator of class DecoupledIO in chisel-api and got the definition is "Connect this data to that data bi-directionally and element-wise." which means out and Queue(in, entries)'s return must be bi-directionally. However, I found the Queue source code:
object Queue
{
/** Create a queue and supply a DecoupledIO containing the product. */
@chiselName
def apply[T <: Data](
enq: ReadyValidIO[T],
entries: Int = 2,
pipe: Boolean = false,
flow: Boolean = false): DecoupledIO[T] = {
if (entries == 0) {
val deq = Wire(new DecoupledIO(chiselTypeOf(enq.bits)))
deq.valid := enq.valid
deq.bits := enq.bits
enq.ready := deq.ready
deq
} else {
val q = Module(new Queue(chiselTypeOf(enq.bits), entries, pipe, flow))
q.io.enq.valid := enq.valid // not using <> so that override is allowed
q.io.enq.bits := enq.bits
enq.ready := q.io.enq.ready
TransitName(q.io.deq, q)
}
}
which return q.io.deq by TransitName method, and q.io.deq are defined as follows:
object DeqIO {
def apply[T<:Data](gen: T): DecoupledIO[T] = Flipped(Decoupled(gen))
}
/** An I/O Bundle for Queues
* @param gen The type of data to queue
* @param entries The max number of entries in the queue.
*/
class QueueIO[T <: Data](private val gen: T, val entries: Int) extends Bundle
{ // See github.com/freechipsproject/chisel3/issues/765 for why gen is a private val and proposed replacement APIs.
/* These may look inverted, because the names (enq/deq) are from the perspective of the client,
* but internally, the queue implementation itself sits on the other side
* of the interface so uses the flipped instance.
*/
/** I/O to enqueue data (client is producer, and Queue object is consumer), is [[Chisel.DecoupledIO]] flipped. */
val enq = Flipped(EnqIO(gen))
/** I/O to dequeue data (client is consumer and Queue object is producer), is [[Chisel.DecoupledIO]]*/
val deq = Flipped(DeqIO(gen))
/** The current amount of data in the queue */
val count = Output(UInt(log2Ceil(entries + 1).W))
}
that means q.io.deq is No-Flipped DecoupledIO and has the same interface direction of out. So I really want to know that how <> works in out <> Queue(in, entries) ?