diff --git a/src/main/scala/coupledL2/CustomL1Hint.scala b/src/main/scala/coupledL2/CustomL1Hint.scala index 3cd350f31..bf9a47eba 100644 --- a/src/main/scala/coupledL2/CustomL1Hint.scala +++ b/src/main/scala/coupledL2/CustomL1Hint.scala @@ -60,14 +60,16 @@ class CustomL1Hint(implicit p: Parameters) extends L2Module { def isRelease(t: TaskBundle): Bool = t.fromC && (t.opcode === Release || t.opcode === ReleaseData) def isMergeGrantData(t: TaskBundle): Bool = t.fromA && t.mergeA && t.aMergeTask.opcode === GrantData def isMergeGrant(t: TaskBundle): Bool = t.fromA && t.mergeA && t.aMergeTask.opcode === Grant + def isAccessAckData(t: TaskBundle): Bool = t.fromA && t.opcode === AccessAckData // ==================== Hint Generation ==================== // Hint for "MSHRTask and ReleaseAck" will fire@s1 val mshr_GrantData_s1 = task_s1.valid && mshrReq_s1 && (isGrantData(task_s1.bits) || isMergeGrantData(task_s1.bits)) val mshr_Grant_s1 = task_s1.valid && mshrReq_s1 && (isGrant(task_s1.bits) || isMergeGrant(task_s1.bits)) + val mshr_AccessAckData_s1 = task_s1.valid && mshrReq_s1 && isAccessAckData(task_s1.bits) val chn_Release_s1 = task_s1.valid && !mshrReq_s1 && isRelease(task_s1.bits) - val enqValid_s1 = mshr_GrantData_s1 || mshr_Grant_s1 || chn_Release_s1 + val enqValid_s1 = mshr_GrantData_s1 || mshr_Grant_s1 || mshr_AccessAckData_s1 || chn_Release_s1 val enqSource_s1 = Mux(task_s1.bits.mergeA, task_s1.bits.aMergeTask.sourceId, task_s1.bits.sourceId) val enqKeyWord_s1 = Mux(task_s1.bits.mergeA, task_s1.bits.aMergeTask.isKeyword.getOrElse(false.B), @@ -77,20 +79,23 @@ class CustomL1Hint(implicit p: Parameters) extends L2Module { Seq( mshr_Grant_s1 -> Grant, mshr_GrantData_s1 -> GrantData, - chn_Release_s1 -> ReleaseAck + chn_Release_s1 -> ReleaseAck, + mshr_AccessAckData_s1 -> AccessAckData ) ) // Hint for "chnTask Hit" will fire@s3 val chn_Grant_s3 = task_s3.valid && !mshrReq_s3 && !need_mshr_s3 && isGrant(task_s3.bits) val chn_GrantData_s3 = task_s3.valid && !mshrReq_s3 && !need_mshr_s3 && isGrantData(task_s3.bits) - val enqValid_s3 = chn_Grant_s3 || chn_GrantData_s3 + val chn_AccessAckData_s3 = task_s3.valid && !mshrReq_s3 && !need_mshr_s3 && isAccessAckData(task_s3.bits) + val enqValid_s3 = chn_Grant_s3 || chn_GrantData_s3 || chn_AccessAckData_s3 val enqSource_s3 = task_s3.bits.sourceId val enqKeyWord_s3 = task_s3.bits.isKeyword.getOrElse(false.B) val enqOpcode_s3 = ParallelPriorityMux( Seq( chn_Grant_s3 -> Grant, - chn_GrantData_s3 -> GrantData + chn_GrantData_s3 -> GrantData, + chn_AccessAckData_s3 -> AccessAckData ) ) @@ -110,13 +115,17 @@ class CustomL1Hint(implicit p: Parameters) extends L2Module { assert(hint_s1Queue.io.enq.ready, "hint_s1Queue should never be full") assert(hintQueue.io.enq.ready, "hintQueue should never be full") + // For AccessAckData that would never go to LSU, insert a dequing bubble for channel delay accuracy + val lastDeque_AccessAckData = RegNext(hintQueue.io.deq.fire && hintQueue.io.deq.bits.opcode === AccessAckData) + val lastDequeBubble = lastDeque_AccessAckData + hintQueue.io.enq.valid := enqValid_s3 || hint_s1Queue.io.deq.valid hintQueue.io.enq.bits.opcode := Mux(enqValid_s3, enqOpcode_s3, hint_s1Queue.io.deq.bits.opcode) hintQueue.io.enq.bits.source := Mux(enqValid_s3, enqSource_s3, hint_s1Queue.io.deq.bits.source) hintQueue.io.enq.bits.isKeyword := Mux(enqValid_s3, enqKeyWord_s3, hint_s1Queue.io.deq.bits.isKeyword) - hintQueue.io.deq.ready := io.l1Hint.ready + hintQueue.io.deq.ready := !lastDequeBubble && io.l1Hint.ready - io.l1Hint.valid := hintQueue.io.deq.valid && hintQueue.io.deq.bits.opcode === GrantData + io.l1Hint.valid := !lastDequeBubble && hintQueue.io.deq.valid && hintQueue.io.deq.bits.opcode === GrantData io.l1Hint.bits.sourceId := hintQueue.io.deq.bits.source io.l1Hint.bits.isKeyword := hintQueue.io.deq.bits.isKeyword } \ No newline at end of file diff --git a/src/test/scala/chi/TestTop.scala b/src/test/scala/chi/TestTop.scala index 3aefb1ed8..53e4aaf73 100644 --- a/src/test/scala/chi/TestTop.scala +++ b/src/test/scala/chi/TestTop.scala @@ -168,6 +168,10 @@ class TestTop_CHIL2(numCores: Int = 1, numULAgents: Int = 0, banks: Int = 1, ext val nodeId = Input(UInt(NODEID_WIDTH.W)) })) + val io_l1 = IO(Vec(numCores, new Bundle() { + val l2Hint = Valid(new L2ToL1Hint) + })) + l2_nodes.zipWithIndex.foreach { case (l2, i) => if (!cacheParams.FPGAPlatform && cacheParams.enableCHILog) { @@ -189,6 +193,8 @@ class TestTop_CHIL2(numCores: Int = 1, numULAgents: Int = 0, banks: Int = 1, ext l2.module.io_chi <> io(i).chi + l2.module.io.l2_hint <> io_l1(i).l2Hint + dontTouch(l2.module.io) l2.module.io.hartId := i.U