xref: /XiangShan/src/main/scala/utils/ArbiterHelper.scala (revision 8891a219bbc84f568e1d134854d8d5ed86d6d560)
16008d57dShappy-lx/***************************************************************************************
26008d57dShappy-lx* Copyright (c) 2020-2021 Institute of Computing Technology, Chinese Academy of Sciences
36008d57dShappy-lx* Copyright (c) 2020-2021 Peng Cheng Laboratory
46008d57dShappy-lx*
56008d57dShappy-lx* XiangShan is licensed under Mulan PSL v2.
66008d57dShappy-lx* You can use this software according to the terms and conditions of the Mulan PSL v2.
76008d57dShappy-lx* You may obtain a copy of Mulan PSL v2 at:
86008d57dShappy-lx*          http://license.coscl.org.cn/MulanPSL2
96008d57dShappy-lx*
106008d57dShappy-lx* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
116008d57dShappy-lx* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
126008d57dShappy-lx* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
136008d57dShappy-lx*
146008d57dShappy-lx* See the Mulan PSL v2 for more details.
156008d57dShappy-lx***************************************************************************************/
166008d57dShappy-lx
176008d57dShappy-lxpackage utils
186008d57dShappy-lx
19*8891a219SYinan Xuimport org.chipsalliance.cde.config.Parameters
206008d57dShappy-lximport chisel3._
216008d57dShappy-lximport chisel3.util._
226008d57dShappy-lximport xiangshan.cache._
236008d57dShappy-lx
246008d57dShappy-lxobject ArbiterCtrl {
256008d57dShappy-lx  def apply(request: Seq[Bool]): Seq[Bool] = request.length match {
266008d57dShappy-lx    case 0 => Seq()
276008d57dShappy-lx    case 1 => Seq(true.B)
286008d57dShappy-lx    case _ => true.B +: request.tail.init.scanLeft(request.head)(_ || _).map(!_)
296008d57dShappy-lx  }
306008d57dShappy-lx}
316008d57dShappy-lx
326008d57dShappy-lx/** Hardware module that is used to sequence n producers into 1 consumer.
336008d57dShappy-lx  * Priority is given to lower producer.
346008d57dShappy-lx  * if any producer's cache block addr matches the one of chosen producer, the producer will be served
356008d57dShappy-lx  *
366008d57dShappy-lx  * @param gen data type, must have addr which indicates physical address
376008d57dShappy-lx  * @param n number of inputs
386008d57dShappy-lx  * @param offset_width cache line offset width
396008d57dShappy-lx  * @param paddr_bits how many bits in paddr
406008d57dShappy-lx  *
416008d57dShappy-lx  * @example {{{
426008d57dShappy-lx  * val arb = Module(new Arbiter(UInt(), 2))
436008d57dShappy-lx  * arb.io.in(0) <> producer0.io.out
446008d57dShappy-lx  * arb.io.in(1) <> producer1.io.out
456008d57dShappy-lx  * consumer.io.in <> arb.io.out
466008d57dShappy-lx  * }}}
476008d57dShappy-lx  */
486008d57dShappy-lxclass ArbiterFilterByCacheLineAddr[T <: MissReqWoStoreData](val gen: T, val n: Int, val offset_width: Int, val paddr_bits: Int) extends Module{
496008d57dShappy-lx  val io = IO(new ArbiterIO(gen, n))
506008d57dShappy-lx
516008d57dShappy-lx  io.chosen := (n - 1).asUInt
526008d57dShappy-lx  io.out.bits := io.in(n - 1).bits
536008d57dShappy-lx  for (i <- n - 2 to 0 by -1) {
546008d57dShappy-lx    when(io.in(i).valid) {
556008d57dShappy-lx      io.chosen := i.asUInt
566008d57dShappy-lx      io.out.bits := io.in(i).bits
576008d57dShappy-lx    }
586008d57dShappy-lx  }
596008d57dShappy-lx
606008d57dShappy-lx  val grant = ArbiterCtrl(io.in.map(_.valid))
616008d57dShappy-lx  for ((in, g) <- io.in.zip(grant))
626008d57dShappy-lx    in.ready := (g || (in.bits.addr(paddr_bits - 1, offset_width) === io.out.bits.addr(paddr_bits - 1, offset_width))) && io.out.ready
636008d57dShappy-lx  io.out.valid := !grant.last || io.in.last.valid
646008d57dShappy-lx}
65