xref: /XiangShan/src/main/scala/xiangshan/mem/sbuffer/DatamoduleResultBuffer.scala (revision 46f74b57fbbf4201e712073b1780aa947b6e1198)
1300ded30SWilliam Wang/***************************************************************************************
2300ded30SWilliam Wang* Copyright (c) 2020-2021 Institute of Computing Technology, Chinese Academy of Sciences
3300ded30SWilliam Wang* Copyright (c) 2020-2021 Peng Cheng Laboratory
4300ded30SWilliam Wang*
5300ded30SWilliam Wang* XiangShan is licensed under Mulan PSL v2.
6300ded30SWilliam Wang* You can use this software according to the terms and conditions of the Mulan PSL v2.
7300ded30SWilliam Wang* You may obtain a copy of Mulan PSL v2 at:
8300ded30SWilliam Wang*          http://license.coscl.org.cn/MulanPSL2
9300ded30SWilliam Wang*
10300ded30SWilliam Wang* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
11300ded30SWilliam Wang* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
12300ded30SWilliam Wang* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
13300ded30SWilliam Wang*
14300ded30SWilliam Wang* See the Mulan PSL v2 for more details.
15300ded30SWilliam Wang***************************************************************************************/
16300ded30SWilliam Wang
17300ded30SWilliam Wangpackage xiangshan.mem
18300ded30SWilliam Wang
19300ded30SWilliam Wangimport chipsalliance.rocketchip.config.Parameters
20300ded30SWilliam Wangimport chisel3.experimental.{DataMirror, requireIsChiselType}
21300ded30SWilliam Wangimport chisel3._
22300ded30SWilliam Wangimport chisel3.util._
23300ded30SWilliam Wangimport xiangshan._
24300ded30SWilliam Wangimport utils._
25300ded30SWilliam Wangimport xiangshan.cache._
26300ded30SWilliam Wangimport difftest._
27300ded30SWilliam Wang
28*46f74b57SHaojin Tangclass DatamoduleResultBufferIO[T <: Data](gen: T)(implicit p: Parameters) extends XSBundle
29300ded30SWilliam Wang{
30300ded30SWilliam Wang  // val flush = Input(Bool())
31*46f74b57SHaojin Tang  val enq = Vec(EnsbufferWidth, Flipped(DecoupledIO(gen)))
32*46f74b57SHaojin Tang  val deq = Vec(EnsbufferWidth, DecoupledIO(gen))
33300ded30SWilliam Wang
34300ded30SWilliam Wang}
35300ded30SWilliam Wang
36300ded30SWilliam Wangclass DatamoduleResultBuffer[T <: Data]
37300ded30SWilliam Wang(
38300ded30SWilliam Wang  gen: T,
39*46f74b57SHaojin Tang)(implicit p: Parameters) extends XSModule {
40300ded30SWilliam Wang
41300ded30SWilliam Wang  val genType = if (compileOptions.declaredTypeMustBeUnbound) {
42300ded30SWilliam Wang    requireIsChiselType(gen)
43300ded30SWilliam Wang    gen
44300ded30SWilliam Wang  } else {
45300ded30SWilliam Wang    if (DataMirror.internal.isSynthesizable(gen)) {
46300ded30SWilliam Wang      chiselTypeOf(gen)
47300ded30SWilliam Wang    } else {
48300ded30SWilliam Wang      gen
49300ded30SWilliam Wang    }
50300ded30SWilliam Wang  }
51300ded30SWilliam Wang
52300ded30SWilliam Wang  val io = IO(new DatamoduleResultBufferIO[T](gen))
53300ded30SWilliam Wang
54*46f74b57SHaojin Tang  val data = Reg(Vec(EnsbufferWidth, genType))
55*46f74b57SHaojin Tang  val valids = RegInit(VecInit(Seq.fill(EnsbufferWidth)(false.B)))
56*46f74b57SHaojin Tang  val enq_flag = RegInit(0.U(log2Up(EnsbufferWidth).W)) // head is entry 0
57*46f74b57SHaojin Tang  val deq_flag = RegInit(0.U(log2Up(EnsbufferWidth).W)) // tail is entry 0
58300ded30SWilliam Wang
59*46f74b57SHaojin Tang  val entry_allowin = Wire(Vec(EnsbufferWidth, Bool()))
60300ded30SWilliam Wang
61*46f74b57SHaojin Tang  (0 until EnsbufferWidth).foreach(index => {
62*46f74b57SHaojin Tang    io.deq(index).valid := valids(deq_flag + index.U) && (if (index == 0) 1.B else io.deq(index - 1).valid)
63*46f74b57SHaojin Tang    io.deq(index).bits := data(deq_flag + index.U)
64*46f74b57SHaojin Tang  })
65300ded30SWilliam Wang
66*46f74b57SHaojin Tang  (1 until EnsbufferWidth).foreach(i => {
67*46f74b57SHaojin Tang    assert(!(io.deq(i).valid && !io.deq(i - 1).valid))
68*46f74b57SHaojin Tang    assert(!(io.deq(i).ready && !io.deq(i - 1).ready))
69*46f74b57SHaojin Tang  })
70*46f74b57SHaojin Tang
71*46f74b57SHaojin Tang  (0 until EnsbufferWidth).foreach(
72*46f74b57SHaojin Tang    index => entry_allowin(index) := !valids(index) || (0 until EnsbufferWidth).map(i => io.deq(i).fire && deq_flag + i.U === index.U).reduce(_ || _)
73300ded30SWilliam Wang  )
74300ded30SWilliam Wang
75*46f74b57SHaojin Tang  (0 until EnsbufferWidth).foreach(
76*46f74b57SHaojin Tang    index => io.enq(index).ready := entry_allowin(enq_flag + index.U) && (if (index == 0) 1.B else io.enq(index - 1).ready)
77300ded30SWilliam Wang  )
78300ded30SWilliam Wang
79*46f74b57SHaojin Tang  (1 until EnsbufferWidth).foreach(i => {
80*46f74b57SHaojin Tang    assert(!(io.enq(i).ready && !io.enq(i - 1).ready))
81*46f74b57SHaojin Tang    assert(!(io.enq(i).valid && !io.enq(i - 1).valid))
82*46f74b57SHaojin Tang  })
83300ded30SWilliam Wang
84*46f74b57SHaojin Tang  (0 until EnsbufferWidth).foreach(index =>
85*46f74b57SHaojin Tang    when(io.deq(index).fire) {
86*46f74b57SHaojin Tang      valids(deq_flag + index.U) := 0.B
87*46f74b57SHaojin Tang      if (EnsbufferWidth > 1) deq_flag := deq_flag + index.U + 1.U
88300ded30SWilliam Wang    }
89*46f74b57SHaojin Tang  )
90300ded30SWilliam Wang
91*46f74b57SHaojin Tang  (0 until EnsbufferWidth).foreach(index =>
92*46f74b57SHaojin Tang    when(io.enq(index).fire) {
93*46f74b57SHaojin Tang      valids(enq_flag + index.U) := 1.B
94*46f74b57SHaojin Tang      data(enq_flag + index.U) := io.enq(index).bits
95*46f74b57SHaojin Tang      if (EnsbufferWidth > 1) enq_flag := enq_flag + index.U + 1.U
96300ded30SWilliam Wang    }
97*46f74b57SHaojin Tang  )
98300ded30SWilliam Wang}
99