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