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