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