xref: /XiangShan/src/main/scala/xiangshan/frontend/icache/FIFO.scala (revision 211d620b07edb797ba35b635d24fef4e7294bae2)
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 freechips.rocketchip.diplomacy.IdRange
23import freechips.rocketchip.diplomacy.LazyModule
24import freechips.rocketchip.diplomacy.LazyModuleImp
25import freechips.rocketchip.tilelink._
26import freechips.rocketchip.util.BundleFieldBase
27import huancun.AliasField
28import huancun.PrefetchField
29import org.chipsalliance.cde.config.Parameters
30import utility._
31import utils._
32import xiangshan._
33import xiangshan.cache._
34import xiangshan.cache.mmu.TlbRequestIO
35import xiangshan.frontend._
36
37class FIFOReg[T <: Data](
38    val gen:      T,
39    val entries:  Int,
40    val pipe:     Boolean = false,
41    val hasFlush: Boolean = false
42) extends Module() {
43  require(entries > 0, "Queue must have non-negative number of entries")
44
45  val io = IO(new Bundle {
46    val enq   = Flipped(DecoupledIO(gen))
47    val deq   = DecoupledIO(gen)
48    val flush = if (hasFlush) Some(Input(Bool())) else None
49  })
50  val flush = io.flush.getOrElse(false.B)
51
52  class FIFOPtr() extends CircularQueuePtr[FIFOPtr](entries)
53
54  object FIFOPtr {
55    def apply(f: Bool, v: UInt): FIFOPtr = {
56      val ptr = Wire(new FIFOPtr)
57      ptr.flag  := f
58      ptr.value := v
59      ptr
60    }
61  }
62
63  val regFiles = RegInit(VecInit(Seq.fill(entries)(0.U.asTypeOf(gen.cloneType))))
64  val enq_ptr  = RegInit(FIFOPtr(false.B, 0.U))
65  val deq_ptr  = RegInit(FIFOPtr(false.B, 0.U))
66
67  val empty = enq_ptr === deq_ptr
68  val full  = (enq_ptr.value === deq_ptr.value) && (enq_ptr.flag ^ deq_ptr.flag)
69
70  when(io.enq.fire) {
71    enq_ptr := enq_ptr + 1.U
72  }
73  when(io.deq.fire) {
74    deq_ptr := deq_ptr + 1.U
75  }
76  when(flush) {
77    enq_ptr.value := 0.U
78    enq_ptr.flag  := false.B
79    deq_ptr.value := 0.U
80    deq_ptr.flag  := false.B
81  }
82
83  when(io.enq.fire) {
84    regFiles(enq_ptr.value) := io.enq.bits
85  }
86  io.deq.bits := regFiles(deq_ptr.value)
87
88  io.deq.valid := !empty
89  io.enq.ready := !full
90  if (pipe) {
91    when(io.deq.ready)(io.enq.ready := true.B)
92  }
93}
94