|
import chisel3._
import chisel3.util._
class FifoIO[T <: Data](private val gen:T) extends Bundle {
val enq = Flipped(new DecoupledIO[T](gen)) //DecoupledIO-->>ReadyValidIO-->>Bundle 是带有valid和ready的复杂信号 Flipped则将bits,ready和valid信号切换方向
val deq = new DecoupledIO[T](gen) //deq是正常的bits,ready,valid方向
}
abstract class Fifo[T <: Data](gen:T,depth:Int) extends Module { //带有valid和ready的FIFO,并且有二个“group”,一个是enq,一个是deq
val io = IO(new FifoIO[T](gen))
assert(depth > 0,"Number of buffer elements needs to be larger than 0")
}
import chisel3._
import chisel3.util._
class RegFifo[T <: Data](gen:T,depth:Int) extends Fifo(gen,depth) {
def counter(depth:Int,incr:Bool): (UInt,UInt) = {
val cntReg = RegInit(0.U(log2Ceil(depth).W)) //log2Ceil(n:BigInt)求log2的值且向上取整 log2Ceil(1)->0,log2Ceil(2)->1,log2Ceil(3)->2,log2Ceil(4)->2,log2Ceil(5)->3
//要想获取n值所对应的bit数量则log2Ceil(n+1) 4-->0100->3bit log2Ceil(4+1)=3
//cntReg表示深度depth-1值所需要的bit位数
val nextVal = Mux(cntReg === (depth - 1).U,0.U,cntReg + 1.U) //达到最大深度则复位,否则下次值为cntReg加1
when (incr) {
cntReg := nextVal //只要没有达到最大深度,每次加1
}
(cntReg,nextVal) //以元组类型返回计数器值以下一次值
}
val memReg = Reg(Vec(depth,gen)) //深度为depth的向量
val incrRead = WireInit(false.B)
val incrWrite = WireInit(false.B)
val (readPtr,nextRead) = counter(depth,incrRead) //返回的元组中的readPtr和nextRead都是Reg硬件类型???
val (writePtr,nextWrite) = counter(depth,incrWrite)
val emptyReg = RegInit(true.B) //FIFO空标志
val fullReg = RegInit(false.B) //FIFO满标志
when(io.enq.valid && !fullReg) { //收到MASTER发来的valid,且FIFO不满
memReg(writePtr) := io.enq.bits //writePtr指针所指的FIFO缓冲区的数据被设置为MASTER发来的数据
emptyReg := false.B //需要清空 空标志位
fullReg := nextWrite === readPtr //写指针和读指针相同时则置 满标志
incrWrite := true.B //启动写计数
}
when(io.deq.ready && !emptyReg) { //返回数据给MASTER的控制相关逻辑
fullReg := false.B //清满标志位
emptyReg := nextRead === writePtr //读写指针相等时则为空
incrRead := true.B //启动读计数
}
io.deq.bits := memReg(readPtr) //根据读指针将缓冲区对应位置的数据返回
io.enq.ready := !fullReg //output出准备好信号 只要不满
io.deq.valid := !emptyReg //只要不空 output类型的deq.valid就发出指标
}
|
|