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