1*6008d57dShappy-lx/*************************************************************************************** 2*6008d57dShappy-lx* Copyright (c) 2020-2021 Institute of Computing Technology, Chinese Academy of Sciences 3*6008d57dShappy-lx* Copyright (c) 2020-2021 Peng Cheng Laboratory 4*6008d57dShappy-lx* 5*6008d57dShappy-lx* XiangShan is licensed under Mulan PSL v2. 6*6008d57dShappy-lx* You can use this software according to the terms and conditions of the Mulan PSL v2. 7*6008d57dShappy-lx* You may obtain a copy of Mulan PSL v2 at: 8*6008d57dShappy-lx* http://license.coscl.org.cn/MulanPSL2 9*6008d57dShappy-lx* 10*6008d57dShappy-lx* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, 11*6008d57dShappy-lx* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, 12*6008d57dShappy-lx* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. 13*6008d57dShappy-lx* 14*6008d57dShappy-lx* See the Mulan PSL v2 for more details. 15*6008d57dShappy-lx***************************************************************************************/ 16*6008d57dShappy-lx 17*6008d57dShappy-lxpackage utils 18*6008d57dShappy-lx 19*6008d57dShappy-lximport chipsalliance.rocketchip.config.Parameters 20*6008d57dShappy-lximport chisel3._ 21*6008d57dShappy-lximport chisel3.util._ 22*6008d57dShappy-lximport chisel3.internal.naming.chiselName 23*6008d57dShappy-lximport xiangshan.cache._ 24*6008d57dShappy-lx 25*6008d57dShappy-lxobject ArbiterCtrl { 26*6008d57dShappy-lx def apply(request: Seq[Bool]): Seq[Bool] = request.length match { 27*6008d57dShappy-lx case 0 => Seq() 28*6008d57dShappy-lx case 1 => Seq(true.B) 29*6008d57dShappy-lx case _ => true.B +: request.tail.init.scanLeft(request.head)(_ || _).map(!_) 30*6008d57dShappy-lx } 31*6008d57dShappy-lx} 32*6008d57dShappy-lx 33*6008d57dShappy-lx/** Hardware module that is used to sequence n producers into 1 consumer. 34*6008d57dShappy-lx * Priority is given to lower producer. 35*6008d57dShappy-lx * if any producer's cache block addr matches the one of chosen producer, the producer will be served 36*6008d57dShappy-lx * 37*6008d57dShappy-lx * @param gen data type, must have addr which indicates physical address 38*6008d57dShappy-lx * @param n number of inputs 39*6008d57dShappy-lx * @param offset_width cache line offset width 40*6008d57dShappy-lx * @param paddr_bits how many bits in paddr 41*6008d57dShappy-lx * 42*6008d57dShappy-lx * @example {{{ 43*6008d57dShappy-lx * val arb = Module(new Arbiter(UInt(), 2)) 44*6008d57dShappy-lx * arb.io.in(0) <> producer0.io.out 45*6008d57dShappy-lx * arb.io.in(1) <> producer1.io.out 46*6008d57dShappy-lx * consumer.io.in <> arb.io.out 47*6008d57dShappy-lx * }}} 48*6008d57dShappy-lx */ 49*6008d57dShappy-lx@chiselName 50*6008d57dShappy-lxclass ArbiterFilterByCacheLineAddr[T <: MissReqWoStoreData](val gen: T, val n: Int, val offset_width: Int, val paddr_bits: Int) extends Module{ 51*6008d57dShappy-lx val io = IO(new ArbiterIO(gen, n)) 52*6008d57dShappy-lx 53*6008d57dShappy-lx io.chosen := (n - 1).asUInt 54*6008d57dShappy-lx io.out.bits := io.in(n - 1).bits 55*6008d57dShappy-lx for (i <- n - 2 to 0 by -1) { 56*6008d57dShappy-lx when(io.in(i).valid) { 57*6008d57dShappy-lx io.chosen := i.asUInt 58*6008d57dShappy-lx io.out.bits := io.in(i).bits 59*6008d57dShappy-lx } 60*6008d57dShappy-lx } 61*6008d57dShappy-lx 62*6008d57dShappy-lx val grant = ArbiterCtrl(io.in.map(_.valid)) 63*6008d57dShappy-lx for ((in, g) <- io.in.zip(grant)) 64*6008d57dShappy-lx in.ready := (g || (in.bits.addr(paddr_bits - 1, offset_width) === io.out.bits.addr(paddr_bits - 1, offset_width))) && io.out.ready 65*6008d57dShappy-lx io.out.valid := !grant.last || io.in.last.valid 66*6008d57dShappy-lx} 67