Slice: refactor task arbiter to avoid dead lock

This commit is contained in:
LinJiawei 2021-09-05 19:50:07 +08:00
parent 3c5afef886
commit 562a806784
1 changed files with 33 additions and 11 deletions

View File

@ -267,14 +267,20 @@ class Slice()(implicit p: Parameters) extends HuanCunModule {
arbTasks(sourceE.io.task, ms.map(_.io.tasks.source_e), Some("sourceE"))
arbTasks(sinkA.io.task, ms.map(_.io.tasks.sink_a), Some("sinkA"))
arbTasks(sinkC.io.task, ms.map(_.io.tasks.sink_c), Some("sinkC"))
arbTasks(directory.io.tagWReq, ms.map(_.io.tasks.tag_write), Some("tagWrite"))
arbTasks(
directory.io.tagWReq, ms.map(_.io.tasks.tag_write),
Some("tagWrite"), strict = true
)
(directory, ms) match {
case (dir: noninclusive.Directory, ms: Seq[noninclusive.MSHR]) =>
for ((dirW, idx) <- dir.io.clientDirWReqs.zipWithIndex) {
block_decoupled(dirW, ms.map(_.io.tasks.client_dir_write(idx)))
}
for ((tagW, idx) <- dir.io.clientTagWreq.zipWithIndex) {
arbTasks(tagW, ms.map(_.io.tasks.client_tag_write(idx)), Some(s"client_${idx}_tagWrite"))
arbTasks(
tagW, ms.map(_.io.tasks.client_tag_write(idx)),
Some(s"client_${idx}_tagWrite"), strict = true
)
}
case (_: inclusive.Directory, _: Seq[inclusive.MSHR]) =>
// skip
@ -282,8 +288,15 @@ class Slice()(implicit p: Parameters) extends HuanCunModule {
assert(false)
}
def arbTasks[T <: Bundle](out: DecoupledIO[T], in: Seq[DecoupledIO[T]], name: Option[String] = None) = {
if (in.size == mshrsAll) {
def arbTasks[T <: Bundle]
(
out: DecoupledIO[T],
in: Seq[DecoupledIO[T]],
name: Option[String] = None,
strict: Boolean = false
) = {
require(!strict || in.size == mshrsAll)
if(in.size == mshrsAll){
val abc = in.init.init
val bc = in.init.last
val c = in.last
@ -292,15 +305,24 @@ class Slice()(implicit p: Parameters) extends HuanCunModule {
for ((arb, req) <- arbiter.io.in.zip(abc)) {
arb <> req
}
out.valid := c.valid ||
!block_bc && bc.valid ||
!block_abc && arbiter.io.out.valid
out.bits := Mux(c.valid, c.bits, Mux(bc.valid, bc.bits, arbiter.io.out.bits))
c.ready := out.ready
bc.ready := out.ready && !block_bc
arbiter.io.out.ready := out.ready && !block_abc
if(strict){
out.valid := c.valid ||
!block_bc && bc.valid ||
!block_abc && arbiter.io.out.valid
out.bits := Mux(c.valid, c.bits, Mux(bc.valid, bc.bits, arbiter.io.out.bits))
c.ready := out.ready
bc.ready := out.ready && !block_bc
arbiter.io.out.ready := out.ready && !block_abc
} else {
out.valid := c.valid || bc.valid || arbiter.io.out.valid
out.bits := Mux(c.valid, c.bits, Mux(bc.valid, bc.bits, arbiter.io.out.bits))
c.ready := out.ready
bc.ready := out.ready && !c.valid
arbiter.io.out.ready := out.ready && !c.valid && !bc.valid
}
} else {
val arbiter = Module(new RRArbiter[T](chiselTypeOf(out.bits), in.size))
if (name.nonEmpty) arbiter.suggestName(s"${name.get}_task_arb")
for ((arb, req) <- arbiter.io.in.zip(in)) {
arb <> req
}