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