|
Queue和ready-valid接口的DecoupledIO都在一个文件Decoupled.scala中,通过这就可以说明Queue其实也是
具有ready-valid接口功能的。Queue其实就是一个具有ready-valid的FIFO。
要想使用Queue,需要先了解QueueIO,EnqIO和DeqIO:
object EnqIO {
def apply[T <: Data](gen:T)ecoupledIO[T] = Decoupled(gen)
}
object DeqIO {
def apply[T <: Data](gen:T)ecoupledIO[T] = Flipped(Decoupled(gen))
}
class QueueIO[T <: Data](private val gen:T,val entries:Int) extends Bundle {
//entries是最大深度
val enq = Flipped(EnqIO(gen)) //用户是producer,Queue是consumer
val deq = Flipped(DeqIO(gen)) //用户是consumer,Queue是producer
//上面enq和deq的意义其实和FIFO中的是一样的,enq的对面就是Master,deq的对面就是Slave
val count = Output(UInt(log2Ceil(entries+1).W)) //log2Ceil(x)表示x-1数值需要多少bit位,当然log2Ceil(x+1)就表示x需要多少bit位
}
要想使用Queue,可以有二种方法产生Queue对象,一种是chisel中常用的apply方法,
这个apply方法需要一个enq:ReadyValidIO[T]接口类型的参数,这种apply方法返回的是DecoupledIO[T]类型对象,
另一种是new Queue[T](gen:T,entries:Int)。当然,通过apply方法返回的DecoupledIO[T]类型对象只能访问它的
ready,valid,bits,通过new Queue[T]产生的对象则可以访问它的io.enq/deq/count。关于这二种形式如何使用,参考如下:
class MyQueue extends Module {
val io = IO(new Bundle {
val in = Flipped(Decoupled(UInt(8.W)))
val out = Decoupled(UInt(8.W))
val cnt = Output(UInt(4.W))
})
val q = Module(new Queue(UInt(8.W),entries = 16))
q.io.enq <> io.in
io.out <> q.io.deq
io.cnt <> q.io.count
}
class MyQueue extends Module {
val io = IO(new Bundle {
val in = Flipped(Decoupled(UInt(8.W)))
val out = Decoupled(UInt(8.W))
val cnt = Output(UInt(4.W))
})
val q = Queue(io.in,16)//这种Queue返回的类型其实是DecoupledIO,里面有ready,valid,bits
io.out <> q //q即使要使用里面的成员,也只能用ready,valid,bits,没有enq和deq
}
|
|