All Downloads are FREE. Search and download functionalities are using the official Maven repository.

chisel.lib.dclib.DCArbiter.scala Maven / Gradle / Ivy

The newest version!
package chisel.lib.dclib

import chisel3._
import chisel3.util._

/**
  * Round-robin arbiter
  *
  * Accepts number of inputs and arbitrates between them on a per-cycle basis.
  *
  * @param data    Data type of item to be arbitrated
  * @param inputs  Number of inputs to arbiter
  * @param locking Creates a locking arbiter with a rearb input
  */
class DCArbiter[D <: Data](data: D, inputs: Int, locking: Boolean) extends Module {
  val io = IO(new Bundle {
    val c = Vec(inputs, Flipped(Decoupled(data.cloneType)))
    val p = Decoupled(data.cloneType)
    val grant = Output(UInt(inputs.W))
    val rearb = if (locking) Some(Input(UInt(inputs.W))) else None
  })

  override def desiredName: String = "DCArbiter_" + data.toString

  val justGranted = RegInit(1.asUInt(inputs.W))
  val toBeGranted = Wire(UInt(inputs.W))
  val nxtRRLocked = Wire(Bool())
  val ioCValid = Wire(UInt(inputs.W))

  for (i <- 0 until inputs) {
    io.c(i).ready := toBeGranted(i) && io.p.ready
  }
  io.grant := toBeGranted

  def nxt_grant(cur_grant: UInt, cur_req: UInt, cur_accept: Bool): UInt = {
    val mskReq = Wire(UInt(inputs.W))
    val tmpGrant = Wire(UInt(inputs.W))
    val tmpGrant2 = Wire(UInt(inputs.W))
    val rv = Wire(UInt(inputs.W))

    mskReq := cur_req & ~((cur_grant - 1.U) | cur_grant)
    tmpGrant := mskReq & (~mskReq + 1.U)
    tmpGrant2 := cur_req & (~cur_req + 1.U)

    when(cur_accept) {
      when(mskReq =/= 0.U) {
        rv := tmpGrant
      }.otherwise {
        rv := tmpGrant2
      }
    }.elsewhen(cur_req =/= 0.U) {
      when(mskReq =/= 0.U) {
        rv := Cat(tmpGrant(0), tmpGrant(inputs - 1, 1))
      }.otherwise {
        rv := Cat(tmpGrant2(0), tmpGrant2(inputs - 1, 1))
      }
    }.otherwise {
      rv := cur_grant
    }
    rv
  }

  ioCValid := Cat(io.c.map(_.valid).reverse)

  io.p.valid := ioCValid.orR()
  toBeGranted := justGranted

  if (locking) {
    val rr_locked = RegInit(false.B)

    when((ioCValid & justGranted).orR() && !rr_locked) {
      nxtRRLocked := true.B
    }.elsewhen((ioCValid & justGranted & io.rearb.get).orR()) {
      nxtRRLocked := false.B
    }.otherwise {
      nxtRRLocked := rr_locked
    }

    when(nxtRRLocked && (ioCValid & justGranted).orR()) {
      toBeGranted := justGranted
    }.otherwise {
      when(io.p.ready) {
        toBeGranted := Cat(justGranted(0), justGranted(inputs - 1, 1))
      }.otherwise {
        toBeGranted := justGranted
      }
    }
  } else {
    nxtRRLocked := false.B
    toBeGranted := nxt_grant(justGranted, ioCValid, io.p.ready)
  }

  when(toBeGranted =/= 0.U) {
    justGranted := toBeGranted
  }

  io.p.bits := io.c(0).bits
  for (i <- 0 until inputs) {
    when(toBeGranted(i)) {
      io.p.bits := io.c(i).bits
    }
  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy