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