xref: /XiangShan/src/main/scala/utils/ArbiterHelper.scala (revision b8b991d636e3eae0d6cc2e36846166652699f0c2)
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