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