@@ -36,6 +36,7 @@ class CustomL1HintIOBundle(implicit p: Parameters) extends L2Bundle {
3636 val s3 = new L2Bundle {
3737 val task = Flipped (ValidIO (new TaskBundle ()))
3838 val need_mshr = Input (Bool ())
39+ val retry = Input (Bool ())
3940 }
4041
4142 // output hint
@@ -58,16 +59,22 @@ class CustomL1Hint(implicit p: Parameters) extends L2Module {
5859 def isGrant (t : TaskBundle ): Bool = t.fromA && t.opcode === Grant
5960 def isHintAck (t : TaskBundle ): Bool = t.fromA && t.opcode === HintAck // HintAck has no effect on Hint
6061 def isRelease (t : TaskBundle ): Bool = t.fromC && (t.opcode === Release || t.opcode === ReleaseData )
62+ def isReleaseAck (t : TaskBundle ): Bool = t.fromC && t.opcode === ReleaseAck
63+ def isCBOAck (t : TaskBundle ): Bool = t.fromA && t.opcode === CBOAck
6164 def isMergeGrantData (t : TaskBundle ): Bool = t.fromA && t.mergeA && t.aMergeTask.opcode === GrantData
6265 def isMergeGrant (t : TaskBundle ): Bool = t.fromA && t.mergeA && t.aMergeTask.opcode === Grant
66+ def isAccessAckData (t : TaskBundle ): Bool = t.fromA && t.opcode === AccessAckData
6367
6468 // ==================== Hint Generation ====================
6569 // Hint for "MSHRTask and ReleaseAck" will fire@s1
66- val mshr_GrantData_s1 = task_s1.valid && mshrReq_s1 && (isGrantData(task_s1.bits) || isMergeGrantData(task_s1.bits))
67- val mshr_Grant_s1 = task_s1.valid && mshrReq_s1 && (isGrant(task_s1.bits) || isMergeGrant(task_s1.bits))
68- val chn_Release_s1 = task_s1.valid && ! mshrReq_s1 && isRelease(task_s1.bits)
70+ val mshr_GrantData_s1 = task_s1.valid && mshrReq_s1 && (isGrantData(task_s1.bits) || isMergeGrantData(task_s1.bits))
71+ val mshr_Grant_s1 = task_s1.valid && mshrReq_s1 && (isGrant(task_s1.bits) || isMergeGrant(task_s1.bits))
72+ val chn_CBOAck_s1 = task_s1.valid && mshrReq_s1 && isCBOAck(task_s1.bits)
73+ val chn_Release_s1 = task_s1.valid && ! mshrReq_s1 && isRelease(task_s1.bits)
74+ val chn_ReleaseAck_s1 = task_s1.valid && ! mshrReq_s1 && isReleaseAck(task_s1.bits)
75+ val chn_AccessAckData_s1 = task_s1.valid && mshrReq_s1 && isAccessAckData(task_s1.bits)
6976
70- val enqValid_s1 = mshr_GrantData_s1 || mshr_Grant_s1 || chn_Release_s1
77+ val enqValid_s1 = mshr_GrantData_s1 || mshr_Grant_s1 || chn_Release_s1 || chn_AccessAckData_s1 || chn_CBOAck_s1
7178 val enqSource_s1 = Mux (task_s1.bits.mergeA, task_s1.bits.aMergeTask.sourceId, task_s1.bits.sourceId)
7279 val enqKeyWord_s1 = Mux (task_s1.bits.mergeA,
7380 task_s1.bits.aMergeTask.isKeyword.getOrElse(false .B ),
@@ -77,20 +84,25 @@ class CustomL1Hint(implicit p: Parameters) extends L2Module {
7784 Seq (
7885 mshr_Grant_s1 -> Grant ,
7986 mshr_GrantData_s1 -> GrantData ,
80- chn_Release_s1 -> ReleaseAck
87+ chn_Release_s1 -> ReleaseAck ,
88+ chn_AccessAckData_s1 -> AccessAckData ,
89+ chn_CBOAck_s1 -> CBOAck
8190 )
8291 )
8392
8493 // Hint for "chnTask Hit" will fire@s3
8594 val chn_Grant_s3 = task_s3.valid && ! mshrReq_s3 && ! need_mshr_s3 && isGrant(task_s3.bits)
8695 val chn_GrantData_s3 = task_s3.valid && ! mshrReq_s3 && ! need_mshr_s3 && isGrantData(task_s3.bits)
87- val enqValid_s3 = chn_Grant_s3 || chn_GrantData_s3
96+ val chn_AccessAckData_s3 = task_s3.valid && ! mshrReq_s3 && ! need_mshr_s3 && isAccessAckData(task_s3.bits)
97+
98+ val enqValid_s3 = chn_Grant_s3 || chn_GrantData_s3 || chn_AccessAckData_s3
8899 val enqSource_s3 = task_s3.bits.sourceId
89100 val enqKeyWord_s3 = task_s3.bits.isKeyword.getOrElse(false .B )
90101 val enqOpcode_s3 = ParallelPriorityMux (
91102 Seq (
92103 chn_Grant_s3 -> Grant ,
93- chn_GrantData_s3 -> GrantData
104+ chn_GrantData_s3 -> GrantData ,
105+ chn_AccessAckData_s3 -> AccessAckData
94106 )
95107 )
96108
@@ -108,15 +120,21 @@ class CustomL1Hint(implicit p: Parameters) extends L2Module {
108120 hint_s1Queue.io.deq.ready := hintQueue.io.enq.ready && ! enqValid_s3
109121 // WARNING:TODO: ensure queue will never overflow
110122 assert(hint_s1Queue.io.enq.ready, " hint_s1Queue should never be full" )
111- assert(hintQueue.io.enq.ready, " hintQueue should never be full" )
123+ // *NOTICE: 'hintQueue' is now possible to be full and backpressing 'hint_s1Queue'.
124+ // Hence, this assertion here was currently unnecessary and overkilled.
125+ // assert(hintQueue.io.enq.ready, "hintQueue should never be full")
126+
127+ val deqLatency = RegNext (io.l1Hint.fire && io.l1Hint.bits.isGrantData)
128+ val hintEnqValid = enqValid_s3 || hint_s1Queue.io.deq.valid
112129
113- hintQueue.io.enq.valid := enqValid_s3 || hint_s1Queue.io.deq.valid
114- hintQueue.io.enq.bits.opcode := Mux (enqValid_s3, enqOpcode_s3, hint_s1Queue.io.deq.bits.opcode)
115- hintQueue.io.enq.bits.source := Mux (enqValid_s3, enqSource_s3, hint_s1Queue.io.deq.bits.source)
116- hintQueue.io.enq.bits.isKeyword := Mux (enqValid_s3, enqKeyWord_s3, hint_s1Queue.io.deq.bits.isKeyword)
117- hintQueue.io.deq.ready := io.l1Hint.ready
130+ hintQueue.io.enq.valid := RegNext (hintEnqValid)
131+ hintQueue.io.enq.bits.opcode := RegEnable ( Mux (enqValid_s3, enqOpcode_s3, hint_s1Queue.io.deq.bits.opcode), hintEnqValid )
132+ hintQueue.io.enq.bits.source := RegEnable ( Mux (enqValid_s3, enqSource_s3, hint_s1Queue.io.deq.bits.source), hintEnqValid )
133+ hintQueue.io.enq.bits.isKeyword := RegEnable ( Mux (enqValid_s3, enqKeyWord_s3, hint_s1Queue.io.deq.bits.isKeyword), hintEnqValid )
134+ hintQueue.io.deq.ready := io.l1Hint.ready && ! deqLatency
118135
119- io.l1Hint.valid := hintQueue.io.deq.valid && hintQueue. io.deq.bits.opcode === GrantData
136+ io.l1Hint.valid := hintQueue.io.deq.valid && ! deqLatency && ! io.s3.retry
120137 io.l1Hint.bits.sourceId := hintQueue.io.deq.bits.source
121138 io.l1Hint.bits.isKeyword := hintQueue.io.deq.bits.isKeyword
139+ io.l1Hint.bits.isGrantData := hintQueue.io.deq.bits.opcode === GrantData || hintQueue.io.deq.bits.opcode === AccessAckData
122140}
0 commit comments