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 utils 18 19import org.chipsalliance.cde.config.Parameters 20import chisel3._ 21import chisel3.util._ 22import xiangshan.cache._ 23 24object ArbiterCtrl { 25 def apply(request: Seq[Bool]): Seq[Bool] = request.length match { 26 case 0 => Seq() 27 case 1 => Seq(true.B) 28 case _ => true.B +: request.tail.init.scanLeft(request.head)(_ || _).map(!_) 29 } 30} 31 32/** Hardware module that is used to sequence n producers into 1 consumer. 33 * Priority is given to lower producer. 34 * if any producer's cache block addr matches the one of chosen producer, the producer will be served 35 * 36 * @param gen data type, must have addr which indicates physical address 37 * @param n number of inputs 38 * @param offset_width cache line offset width 39 * @param paddr_bits how many bits in paddr 40 * 41 * @example {{{ 42 * val arb = Module(new Arbiter(UInt(), 2)) 43 * arb.io.in(0) <> producer0.io.out 44 * arb.io.in(1) <> producer1.io.out 45 * consumer.io.in <> arb.io.out 46 * }}} 47 */ 48class ArbiterFilterByCacheLineAddr[T <: MissReqWoStoreData](val gen: T, val n: Int, val offset_width: Int, val paddr_bits: Int) extends Module{ 49 val io = IO(new ArbiterIO(gen, n)) 50 51 io.chosen := (n - 1).asUInt 52 io.out.bits := io.in(n - 1).bits 53 for (i <- n - 2 to 0 by -1) { 54 when(io.in(i).valid) { 55 io.chosen := i.asUInt 56 io.out.bits := io.in(i).bits 57 } 58 } 59 60 val grant = ArbiterCtrl(io.in.map(_.valid)) 61 for ((in, g) <- io.in.zip(grant)) 62 in.ready := (g || (in.bits.addr(paddr_bits - 1, offset_width) === io.out.bits.addr(paddr_bits - 1, offset_width))) && io.out.ready 63 io.out.valid := !grant.last || io.in.last.valid 64} 65