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