1/*************************************************************************************** 2* Copyright (c) 2024 Beijing Institute of Open Source Chip (BOSC) 3* Copyright (c) 2020-2024 Institute of Computing Technology, Chinese Academy of Sciences 4* Copyright (c) 2020-2021 Peng Cheng Laboratory 5* 6* XiangShan is licensed under Mulan PSL v2. 7* You can use this software according to the terms and conditions of the Mulan PSL v2. 8* You may obtain a copy of Mulan PSL v2 at: 9* http://license.coscl.org.cn/MulanPSL2 10* 11* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, 12* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, 13* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. 14* 15* See the Mulan PSL v2 for more details. 16***************************************************************************************/ 17 18package xiangshan.frontend.icache 19 20import chisel3._ 21import chisel3.util._ 22import utility._ 23 24class FIFORegIO[T <: Data](gen: T, hasFlush: Boolean = false) extends Bundle { 25 val enq: DecoupledIO[T] = Flipped(DecoupledIO(gen)) 26 val deq: DecoupledIO[T] = DecoupledIO(gen) 27 val flush: Option[Bool] = Option.when(hasFlush)(Input(Bool())) 28} 29 30class FIFOReg[T <: Data]( 31 val gen: T, 32 val entries: Int, 33 val pipe: Boolean = false, 34 val hasFlush: Boolean = false 35) extends Module() { 36 require(entries > 0, "Queue must have non-negative number of entries") 37 38 val io: FIFORegIO[T] = IO(new FIFORegIO(gen, hasFlush)) 39 private val flush = io.flush.getOrElse(false.B) 40 41 private class FIFOPtr extends CircularQueuePtr[FIFOPtr](entries) 42 private object FIFOPtr { 43 def apply(f: Bool, v: UInt): FIFOPtr = { 44 val ptr = Wire(new FIFOPtr) 45 ptr.flag := f 46 ptr.value := v 47 ptr 48 } 49 } 50 51 private val regFiles = RegInit(VecInit(Seq.fill(entries)(0.U.asTypeOf(gen.cloneType)))) 52 private val enq_ptr = RegInit(FIFOPtr(false.B, 0.U)) 53 private val deq_ptr = RegInit(FIFOPtr(false.B, 0.U)) 54 55 private val empty = enq_ptr === deq_ptr 56 private val full = (enq_ptr.value === deq_ptr.value) && (enq_ptr.flag ^ deq_ptr.flag) 57 58 when(io.enq.fire) { 59 enq_ptr := enq_ptr + 1.U 60 } 61 when(io.deq.fire) { 62 deq_ptr := deq_ptr + 1.U 63 } 64 when(flush) { 65 enq_ptr.value := 0.U 66 enq_ptr.flag := false.B 67 deq_ptr.value := 0.U 68 deq_ptr.flag := false.B 69 } 70 71 when(io.enq.fire) { 72 regFiles(enq_ptr.value) := io.enq.bits 73 } 74 io.deq.bits := regFiles(deq_ptr.value) 75 76 io.deq.valid := !empty 77 io.enq.ready := !full 78 if (pipe) { 79 when(io.deq.ready)(io.enq.ready := true.B) 80 } 81} 82