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