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