xref: /XiangShan/src/main/scala/xiangshan/mem/sbuffer/DatamoduleResultBuffer.scala (revision 9658ce50e75af9566868a3e788b4888e8be1859f)
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.mem
18
19import chipsalliance.rocketchip.config.Parameters
20import chisel3.experimental.{DataMirror, requireIsChiselType}
21import chisel3._
22import chisel3.util._
23import xiangshan._
24import utils._
25import xiangshan.cache._
26import difftest._
27
28class DatamoduleResultBufferIO[T <: Data](gen: T) extends Bundle
29{
30  // val flush = Input(Bool())
31  val enq = Vec(2, Flipped(DecoupledIO(gen)))
32  val deq = Vec(2, DecoupledIO(gen))
33
34}
35
36class DatamoduleResultBuffer[T <: Data]
37(
38  gen: T,
39) extends Module {
40
41  val genType = if (compileOptions.declaredTypeMustBeUnbound) {
42    requireIsChiselType(gen)
43    gen
44  } else {
45    if (DataMirror.internal.isSynthesizable(gen)) {
46      chiselTypeOf(gen)
47    } else {
48      gen
49    }
50  }
51
52  val io = IO(new DatamoduleResultBufferIO[T](gen))
53
54  val data = Reg(Vec(2, genType))
55  val valids = RegInit(VecInit(Seq.fill(2)(false.B)))
56  val enq_flag = RegInit(false.B) // head is entry 0
57  val deq_flag = RegInit(false.B) // tail is entry 0
58
59  val entry_allowin = Wire(Vec(2, Bool()))
60
61  io.deq(0).valid := Mux(deq_flag,
62    valids(1),
63    valids(0)
64  )
65  io.deq(1).valid := Mux(deq_flag,
66    valids(0),
67    valids(1)
68  ) && io.deq(0).valid
69
70  io.deq(0).bits := Mux(deq_flag,
71    data(1),
72    data(0)
73  )
74  io.deq(1).bits := Mux(deq_flag,
75    data(0),
76    data(1)
77  )
78
79  assert(!(io.deq(1).valid && !io.deq(0).valid))
80  assert(!(io.deq(1).ready && !io.deq(0).ready))
81
82  entry_allowin(0) := !valids(0) ||
83    io.deq(0).fire() && !deq_flag ||
84    io.deq(1).fire() && deq_flag
85  entry_allowin(1) := !valids(1) ||
86    io.deq(0).fire() && deq_flag ||
87    io.deq(1).fire() && !deq_flag
88
89  io.enq(0).ready := Mux(enq_flag,
90    entry_allowin(1),
91    entry_allowin(0)
92  )
93  io.enq(1).ready := Mux(enq_flag,
94    entry_allowin(0),
95    entry_allowin(1)
96  ) && io.enq(0).ready
97
98  assert(!(io.enq(1).ready && !io.enq(0).ready))
99  assert(!(io.enq(1).valid && !io.enq(0).valid))
100
101  when(io.deq(0).fire()){
102    when(deq_flag){
103      valids(1) := false.B
104    }.otherwise{
105      valids(0) := false.B
106    }
107    deq_flag := ~deq_flag
108  }
109  when(io.deq(1).fire()){
110    when(deq_flag){
111      valids(0) := false.B
112    }.otherwise{
113      valids(1) := false.B
114    }
115    deq_flag := deq_flag
116  }
117
118  when(io.enq(0).fire()){
119    when(enq_flag){
120      valids(1) := true.B
121      data(1) := io.enq(0).bits
122    }.otherwise{
123      valids(0) := true.B
124      data(0) := io.enq(0).bits
125    }
126    enq_flag := ~enq_flag
127  }
128  when(io.enq(1).fire()){
129    when(enq_flag){
130      valids(0) := true.B
131      data(0) := io.enq(1).bits
132    }.otherwise{
133      valids(1) := true.B
134      data(1) := io.enq(1).bits
135    }
136    enq_flag := enq_flag
137  }
138}
139