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 utility._ 26import xiangshan.cache._ 27import difftest._ 28 29class DatamoduleResultBufferIO[T <: Data](gen: T)(implicit p: Parameters) extends XSBundle 30{ 31 // val flush = Input(Bool()) 32 val enq = Vec(EnsbufferWidth, Flipped(DecoupledIO(gen))) 33 val deq = Vec(EnsbufferWidth, DecoupledIO(gen)) 34 35} 36 37class DatamoduleResultBuffer[T <: Data] 38( 39 gen: T, 40)(implicit p: Parameters) extends XSModule { 41 42 val genType = if (compileOptions.declaredTypeMustBeUnbound) { 43 requireIsChiselType(gen) 44 gen 45 } else { 46 if (DataMirror.internal.isSynthesizable(gen)) { 47 chiselTypeOf(gen) 48 } else { 49 gen 50 } 51 } 52 53 val io = IO(new DatamoduleResultBufferIO[T](gen)) 54 55 val data = Reg(Vec(EnsbufferWidth, genType)) 56 val valids = RegInit(VecInit(Seq.fill(EnsbufferWidth)(false.B))) 57 val enq_flag = RegInit(0.U(log2Up(EnsbufferWidth).W)) // head is entry 0 58 val deq_flag = RegInit(0.U(log2Up(EnsbufferWidth).W)) // tail is entry 0 59 60 val entry_allowin = Wire(Vec(EnsbufferWidth, Bool())) 61 62 (0 until EnsbufferWidth).foreach(index => { 63 io.deq(index).valid := valids(deq_flag + index.U) && (if (index == 0) 1.B else io.deq(index - 1).valid) 64 io.deq(index).bits := data(deq_flag + index.U) 65 }) 66 67 (1 until EnsbufferWidth).foreach(i => { 68 assert(!(io.deq(i).valid && !io.deq(i - 1).valid)) 69 assert(!(io.deq(i).ready && !io.deq(i - 1).ready)) 70 }) 71 72 (0 until EnsbufferWidth).foreach( 73 index => entry_allowin(index) := !valids(index) || (0 until EnsbufferWidth).map(i => io.deq(i).fire && deq_flag + i.U === index.U).reduce(_ || _) 74 ) 75 76 (0 until EnsbufferWidth).foreach( 77 index => io.enq(index).ready := entry_allowin(enq_flag + index.U) && (if (index == 0) 1.B else io.enq(index - 1).ready) 78 ) 79 80 (1 until EnsbufferWidth).foreach(i => { 81 assert(!(io.enq(i).ready && !io.enq(i - 1).ready)) 82 assert(!(io.enq(i).valid && !io.enq(i - 1).valid)) 83 }) 84 85 (0 until EnsbufferWidth).foreach(index => 86 when(io.deq(index).fire) { 87 valids(deq_flag + index.U) := 0.B 88 if (EnsbufferWidth > 1) deq_flag := deq_flag + index.U + 1.U 89 } 90 ) 91 92 (0 until EnsbufferWidth).foreach(index => 93 when(io.enq(index).fire) { 94 valids(enq_flag + index.U) := 1.B 95 data(enq_flag + index.U) := io.enq(index).bits 96 if (EnsbufferWidth > 1) enq_flag := enq_flag + index.U + 1.U 97 } 98 ) 99} 100