xref: /XiangShan/src/main/scala/xiangshan/mem/sbuffer/DatamoduleResultBuffer.scala (revision 300ded30f9a12af9b1869345910a1a6168b0188a)
1*300ded30SWilliam Wang/***************************************************************************************
2*300ded30SWilliam Wang* Copyright (c) 2020-2021 Institute of Computing Technology, Chinese Academy of Sciences
3*300ded30SWilliam Wang* Copyright (c) 2020-2021 Peng Cheng Laboratory
4*300ded30SWilliam Wang*
5*300ded30SWilliam Wang* XiangShan is licensed under Mulan PSL v2.
6*300ded30SWilliam Wang* You can use this software according to the terms and conditions of the Mulan PSL v2.
7*300ded30SWilliam Wang* You may obtain a copy of Mulan PSL v2 at:
8*300ded30SWilliam Wang*          http://license.coscl.org.cn/MulanPSL2
9*300ded30SWilliam Wang*
10*300ded30SWilliam Wang* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
11*300ded30SWilliam Wang* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
12*300ded30SWilliam Wang* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
13*300ded30SWilliam Wang*
14*300ded30SWilliam Wang* See the Mulan PSL v2 for more details.
15*300ded30SWilliam Wang***************************************************************************************/
16*300ded30SWilliam Wang
17*300ded30SWilliam Wangpackage xiangshan.mem
18*300ded30SWilliam Wang
19*300ded30SWilliam Wangimport chipsalliance.rocketchip.config.Parameters
20*300ded30SWilliam Wangimport chisel3.experimental.{DataMirror, requireIsChiselType}
21*300ded30SWilliam Wangimport chisel3._
22*300ded30SWilliam Wangimport chisel3.util._
23*300ded30SWilliam Wangimport xiangshan._
24*300ded30SWilliam Wangimport utils._
25*300ded30SWilliam Wangimport xiangshan.cache._
26*300ded30SWilliam Wangimport difftest._
27*300ded30SWilliam Wang
28*300ded30SWilliam Wangclass DatamoduleResultBufferIO[T <: Data](gen: T) extends Bundle
29*300ded30SWilliam Wang{
30*300ded30SWilliam Wang  // val flush = Input(Bool())
31*300ded30SWilliam Wang  val enq = Vec(2, Flipped(DecoupledIO(gen)))
32*300ded30SWilliam Wang  val deq = Vec(2, DecoupledIO(gen))
33*300ded30SWilliam Wang
34*300ded30SWilliam Wang  override def cloneType: DatamoduleResultBufferIO.this.type =
35*300ded30SWilliam Wang    new DatamoduleResultBufferIO[T](gen).asInstanceOf[this.type]
36*300ded30SWilliam Wang}
37*300ded30SWilliam Wang
38*300ded30SWilliam Wangclass DatamoduleResultBuffer[T <: Data]
39*300ded30SWilliam Wang(
40*300ded30SWilliam Wang  gen: T,
41*300ded30SWilliam Wang) extends Module {
42*300ded30SWilliam Wang
43*300ded30SWilliam Wang  val genType = if (compileOptions.declaredTypeMustBeUnbound) {
44*300ded30SWilliam Wang    requireIsChiselType(gen)
45*300ded30SWilliam Wang    gen
46*300ded30SWilliam Wang  } else {
47*300ded30SWilliam Wang    if (DataMirror.internal.isSynthesizable(gen)) {
48*300ded30SWilliam Wang      chiselTypeOf(gen)
49*300ded30SWilliam Wang    } else {
50*300ded30SWilliam Wang      gen
51*300ded30SWilliam Wang    }
52*300ded30SWilliam Wang  }
53*300ded30SWilliam Wang
54*300ded30SWilliam Wang  val io = IO(new DatamoduleResultBufferIO[T](gen))
55*300ded30SWilliam Wang
56*300ded30SWilliam Wang  val data = Reg(Vec(2, genType))
57*300ded30SWilliam Wang  val valids = RegInit(VecInit(Seq.fill(2)(false.B)))
58*300ded30SWilliam Wang  val enq_flag = RegInit(false.B) // head is entry 0
59*300ded30SWilliam Wang  val deq_flag = RegInit(false.B) // tail is entry 0
60*300ded30SWilliam Wang
61*300ded30SWilliam Wang  val entry_allowin = Wire(Vec(2, Bool()))
62*300ded30SWilliam Wang
63*300ded30SWilliam Wang  io.deq(0).valid := Mux(deq_flag,
64*300ded30SWilliam Wang    valids(1),
65*300ded30SWilliam Wang    valids(0)
66*300ded30SWilliam Wang  )
67*300ded30SWilliam Wang  io.deq(1).valid := Mux(deq_flag,
68*300ded30SWilliam Wang    valids(0),
69*300ded30SWilliam Wang    valids(1)
70*300ded30SWilliam Wang  ) && io.deq(0).valid
71*300ded30SWilliam Wang
72*300ded30SWilliam Wang  io.deq(0).bits := Mux(deq_flag,
73*300ded30SWilliam Wang    data(1),
74*300ded30SWilliam Wang    data(0)
75*300ded30SWilliam Wang  )
76*300ded30SWilliam Wang  io.deq(1).bits := Mux(deq_flag,
77*300ded30SWilliam Wang    data(0),
78*300ded30SWilliam Wang    data(1)
79*300ded30SWilliam Wang  )
80*300ded30SWilliam Wang
81*300ded30SWilliam Wang  assert(!(io.deq(1).valid && !io.deq(0).valid))
82*300ded30SWilliam Wang  assert(!(io.deq(1).ready && !io.deq(0).ready))
83*300ded30SWilliam Wang
84*300ded30SWilliam Wang  entry_allowin(0) := !valids(0) ||
85*300ded30SWilliam Wang    io.deq(0).fire() && !deq_flag ||
86*300ded30SWilliam Wang    io.deq(1).fire() && deq_flag
87*300ded30SWilliam Wang  entry_allowin(1) := !valids(1) ||
88*300ded30SWilliam Wang    io.deq(0).fire() && deq_flag ||
89*300ded30SWilliam Wang    io.deq(1).fire() && !deq_flag
90*300ded30SWilliam Wang
91*300ded30SWilliam Wang  io.enq(0).ready := Mux(enq_flag,
92*300ded30SWilliam Wang    entry_allowin(1),
93*300ded30SWilliam Wang    entry_allowin(0)
94*300ded30SWilliam Wang  )
95*300ded30SWilliam Wang  io.enq(1).ready := Mux(enq_flag,
96*300ded30SWilliam Wang    entry_allowin(0),
97*300ded30SWilliam Wang    entry_allowin(1)
98*300ded30SWilliam Wang  ) && io.enq(0).ready
99*300ded30SWilliam Wang
100*300ded30SWilliam Wang  assert(!(io.enq(1).ready && !io.enq(0).ready))
101*300ded30SWilliam Wang  assert(!(io.enq(1).valid && !io.enq(0).valid))
102*300ded30SWilliam Wang
103*300ded30SWilliam Wang  when(io.deq(0).fire()){
104*300ded30SWilliam Wang    when(deq_flag){
105*300ded30SWilliam Wang      valids(1) := false.B
106*300ded30SWilliam Wang    }.otherwise{
107*300ded30SWilliam Wang      valids(0) := false.B
108*300ded30SWilliam Wang    }
109*300ded30SWilliam Wang    deq_flag := ~deq_flag
110*300ded30SWilliam Wang  }
111*300ded30SWilliam Wang  when(io.deq(1).fire()){
112*300ded30SWilliam Wang    when(deq_flag){
113*300ded30SWilliam Wang      valids(0) := false.B
114*300ded30SWilliam Wang    }.otherwise{
115*300ded30SWilliam Wang      valids(1) := false.B
116*300ded30SWilliam Wang    }
117*300ded30SWilliam Wang    deq_flag := deq_flag
118*300ded30SWilliam Wang  }
119*300ded30SWilliam Wang
120*300ded30SWilliam Wang  when(io.enq(0).fire()){
121*300ded30SWilliam Wang    when(enq_flag){
122*300ded30SWilliam Wang      valids(1) := true.B
123*300ded30SWilliam Wang      data(1) := io.enq(0).bits
124*300ded30SWilliam Wang    }.otherwise{
125*300ded30SWilliam Wang      valids(0) := true.B
126*300ded30SWilliam Wang      data(0) := io.enq(0).bits
127*300ded30SWilliam Wang    }
128*300ded30SWilliam Wang    enq_flag := ~enq_flag
129*300ded30SWilliam Wang  }
130*300ded30SWilliam Wang  when(io.enq(1).fire()){
131*300ded30SWilliam Wang    when(enq_flag){
132*300ded30SWilliam Wang      valids(0) := true.B
133*300ded30SWilliam Wang      data(0) := io.enq(1).bits
134*300ded30SWilliam Wang    }.otherwise{
135*300ded30SWilliam Wang      valids(1) := true.B
136*300ded30SWilliam Wang      data(1) := io.enq(1).bits
137*300ded30SWilliam Wang    }
138*300ded30SWilliam Wang    enq_flag := enq_flag
139*300ded30SWilliam Wang  }
140*300ded30SWilliam Wang}
141