Skip to content

Commit

Permalink
feat(OpenLLC): add support for WriteCleanFull transaction (OpenXiangS…
Browse files Browse the repository at this point in the history
  • Loading branch information
sumailyyc authored Dec 9, 2024
1 parent 8405928 commit 9a66de2
Show file tree
Hide file tree
Showing 5 changed files with 35 additions and 30 deletions.
13 changes: 9 additions & 4 deletions src/main/scala/openLLC/MainPipe.scala
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,10 @@ class MainPipe(implicit p: Parameters) extends LLCModule with HasCHIOpcodes {
val makeInvalid_s3 = !refill_task_s3 && opcode_s3 === MakeInvalid
val cleanInvalid_s3 = !refill_task_s3 && opcode_s3 === CleanInvalid
val cleanShared_s3 = !refill_task_s3 && opcode_s3 === CleanShared
val writeCleanFull_s3 = !refill_task_s3 && opcode_s3 === WriteCleanFull

assert(!task_s3.valid || refill_task_s3 || readNotSharedDirty_s3 || readUnique_s3 || makeUnique_s3 || writeBackFull_s3 ||
evict_s3 || makeInvalid_s3 || cleanInvalid_s3 || cleanShared_s3 || writeCleanFull_s3, "Unsupported opcode")

/**
* Requests have different coherence states after processing
Expand Down Expand Up @@ -252,6 +256,7 @@ class MainPipe(implicit p: Parameters) extends LLCModule with HasCHIOpcodes {
val makeInvalid_s4 = RegNext(makeInvalid_s3, false.B)
val cleanInvalid_s4 = RegNext(cleanInvalid_s3, false.B)
val cleanShared_s4 = RegNext(cleanShared_s3, false.B)
val writeCleanFull_s4 = RegNext(writeCleanFull_s3, false.B)
val sharedReq_s4 = RegNext(sharedReq_s3, false.B)
val exclusiveReq_s4 = RegNext(exclusiveReq_s3, false.B)
val releaseReq_s4 = RegNext(releaseReq_s3, false.B)
Expand Down Expand Up @@ -369,7 +374,7 @@ class MainPipe(implicit p: Parameters) extends LLCModule with HasCHIOpcodes {
val respSC_s4 = sharedReq_s4
val respUC_s4 = makeUnique_s4 || !makeUnique_s4 && exclusiveReq_s4 && (!selfDirty_s4 || !self_hit_s4)
val respUD_s4 = !makeUnique_s4 && exclusiveReq_s4 && self_hit_s4 && selfDirty_s4
val respI_s4 = releaseReq_s4 || invalidReq_s4 || cleanReq_s4
val respI_s4 = releaseReq_s4 || invalidReq_s4 || cleanReq_s4 || writeCleanFull_s4
val snpVec_comp_s4 = VecInit(
Mux(
request_snoop_s4,
Expand All @@ -389,7 +394,7 @@ class MainPipe(implicit p: Parameters) extends LLCModule with HasCHIOpcodes {
)

comp_s4.valid := task_s4.valid && (
releaseReq_s4 || invalidReq_s4 || cleanReq_s4 || makeUnique_s4 ||
releaseReq_s4 || invalidReq_s4 || cleanReq_s4 || makeUnique_s4 || writeCleanFull_s4 ||
(readNotSharedDirty_s4 || readUnique_s4) && !self_hit_s4
)
comp_s4.bits.state.s_comp := false.B
Expand All @@ -406,7 +411,7 @@ class MainPipe(implicit p: Parameters) extends LLCModule with HasCHIOpcodes {
mem_task_s4.set := Mux(refill_task_s4, selfDirResp_s4.set, req_s4.set)
mem_task_s4.txnID := req_s4.reqID
mem_task_s4.homeNID := req_s4.tgtID
mem_task_s4.chiOpcode := Mux(refill_task_s4 || cleanReq_s4, WriteNoSnpFull, ReadNoSnp)
mem_task_s4.chiOpcode := Mux(refill_task_s4 || cleanReq_s4 || writeCleanFull_s4, WriteNoSnpFull, ReadNoSnp)
mem_task_s4.size := log2Ceil(64).U
mem_task_s4.allowRetry := true.B
mem_task_s4.order := OrderEncodings.None // TODO: order requirement?
Expand All @@ -416,7 +421,7 @@ class MainPipe(implicit p: Parameters) extends LLCModule with HasCHIOpcodes {

// need ReadNoSnp/WriteNoSnp downwards
val memRead_s4 = (readNotSharedDirty_s4 || readUnique_s4) && !self_hit_s4 && !peerRNs_hit_s4
val memWrite_s4 = cleanReq_s4 && unique_peerRN_s4
val memWrite_s4 = cleanReq_s4 && unique_peerRN_s4 || writeCleanFull_s4
mem_s4.valid := task_s4.valid && (memRead_s4 || memWrite_s4)
mem_s4.bits.state.s_issueReq := false.B
mem_s4.bits.state.s_issueDat := !memWrite_s4
Expand Down
27 changes: 16 additions & 11 deletions src/main/scala/openLLC/MemUnit.scala
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@ class MemRequest(withData: Boolean)(implicit p: Parameters) extends LLCBundle {
val data = if (withData) Some(new DSBlock()) else None
}

class MemInfo(implicit p: Parameters) extends BlockInfo {
val w_datRsp = Bool()
}

class MemEntry(implicit p: Parameters) extends TaskEntry {
val state = new MemState()
val data = new DSBlock()
Expand Down Expand Up @@ -68,7 +72,7 @@ class MemUnit(implicit p: Parameters) extends LLCModule with HasCHIOpcodes {
/* response from downstream RXRSP channel */
val snRxrsp = Flipped(ValidIO(new Resp()))

/* snoop response from upper-level cache */
/* response from upper-level cache */
val rnRxdat = Flipped(ValidIO(new RespWithData()))
val rnRxrsp = Flipped(ValidIO(new Resp()))

Expand All @@ -80,15 +84,15 @@ class MemUnit(implicit p: Parameters) extends LLCModule with HasCHIOpcodes {
val bypassData = Vec(beatSize, ValidIO(new RespWithData()))

/* memory access buffers info */
val memInfo = Vec(mshrs.memory, ValidIO(new BlockInfo()))
val memInfo = Vec(mshrs.memory, ValidIO(new MemInfo()))

/* block info from ResponseUnit */
val respInfo = Flipped(Vec(mshrs.response, ValidIO(new ResponseInfo())))
})

val memResp = io.snRxrsp
val snpData = io.rnRxdat
val snpResp = io.rnRxrsp
val coreData = io.rnRxdat
val coreResp = io.rnRxrsp
val txreq = io.txreq
val txdat = io.txdat
val alloc_s6 = io.fromMainPipe.alloc_s6
Expand Down Expand Up @@ -214,29 +218,29 @@ class MemUnit(implicit p: Parameters) extends LLCModule with HasCHIOpcodes {
}
}

when(snpData.valid) {
when(coreData.valid) {
val match_vec = buffer.map(e => e.valid && !e.state.w_datRsp && e.task.chiOpcode === WriteNoSnpFull &&
e.task.reqID === snpData.bits.txnID)
e.task.reqID === coreData.bits.txnID)
assert(PopCount(match_vec) < 2.U, "Mem task repeated")
val update = Cat(match_vec).orR
val bufID = PriorityEncoder(match_vec)
when(update) {
val entry = buffer(bufID)
when(!snpData.bits.resp(2)) {
when(!coreData.bits.resp(2)) {
entry.valid := false.B
}.otherwise {
val beatId = snpData.bits.dataID >> log2Ceil(beatBytes / 16)
val beatId = coreData.bits.dataID >> log2Ceil(beatBytes / 16)
val newBeatValids = entry.beatValids.asUInt | UIntToOH(beatId)
entry.beatValids := VecInit(newBeatValids.asBools)
entry.state.w_datRsp := newBeatValids.andR
entry.data.data(beatId) := snpData.bits.data
entry.data.data(beatId) := coreData.bits.data
}
}
}

when(snpResp.valid) {
when(coreResp.valid) {
val match_vec = buffer.map(e => e.valid && !e.state.w_datRsp && e.task.chiOpcode === WriteNoSnpFull &&
e.task.reqID === snpResp.bits.txnID)
e.task.reqID === coreResp.bits.txnID)
assert(PopCount(match_vec) < 2.U, "Mem task repeated")
val update = Cat(match_vec).orR
val bufID = PriorityEncoder(match_vec)
Expand Down Expand Up @@ -286,6 +290,7 @@ class MemUnit(implicit p: Parameters) extends LLCModule with HasCHIOpcodes {
m.bits.set := buffer(i).task.set
m.bits.opcode := buffer(i).task.chiOpcode
m.bits.reqID := buffer(i).task.reqID
m.bits.w_datRsp := buffer(i).state.w_datRsp
}

/* Performance Counter */
Expand Down
13 changes: 9 additions & 4 deletions src/main/scala/openLLC/RequestArb.scala
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,8 @@ class RequestArb(implicit p: Parameters) extends LLCModule with HasClientInfo wi
val pipeInfo = Input(new PipeStatus())
val refillInfo = Flipped(Vec(mshrs.refill, ValidIO(new BlockInfo())))
val respInfo = Flipped(Vec(mshrs.response, ValidIO(new ResponseInfo())))
val snpInfo = Flipped(Vec(mshrs.snoop, ValidIO(new BlockInfo)))
val memInfo = Flipped(Vec(mshrs.memory, ValidIO(new BlockInfo)))
val snpInfo = Flipped(Vec(mshrs.snoop, ValidIO(new BlockInfo())))
val memInfo = Flipped(Vec(mshrs.memory, ValidIO(new MemInfo())))
})

val pipeInfo = io.pipeInfo
Expand All @@ -62,9 +62,14 @@ class RequestArb(implicit p: Parameters) extends LLCModule with HasClientInfo wi
val set_s1 = task_s1.bits.set
val reqID_s1 = task_s1.bits.reqID

val isReadNotSharedDirty_s1 = !task_s1.bits.refillTask && task_s1.bits.chiOpcode === ReadNotSharedDirty
val isReadUnique_s1 = !task_s1.bits.refillTask && task_s1.bits.chiOpcode === ReadUnique
val isCleanInvalid_s1 = !task_s1.bits.refillTask && task_s1.bits.chiOpcode === CleanInvalid
val isCleanShared_s1 = !task_s1.bits.refillTask && task_s1.bits.chiOpcode === CleanShared
val isClean_s1 = isCleanInvalid_s1 || isCleanShared_s1
val isWriteCleanFull_s1 = !task_s1.bits.refillTask && task_s1.bits.chiOpcode === WriteCleanFull

val isRead_s1 = isReadNotSharedDirty_s1 || isReadUnique_s1
val isClean_s1 = isCleanInvalid_s1 || isCleanShared_s1 || isWriteCleanFull_s1

// To prevent data hazards caused by read-after-write conflicts in the directory,
// blocking is required when the set of s1 is the same as that of s2 or s3
Expand Down Expand Up @@ -109,7 +114,7 @@ class RequestArb(implicit p: Parameters) extends LLCModule with HasClientInfo wi
(inflight_snoop +& potential_snoop) >= mshrs.snoop.U
)
val blockByMem = Cat(memInfo.map(e => e.valid && Cat(e.bits.tag, e.bits.set) === Cat(tag_s1, set_s1) &&
e.bits.opcode === WriteNoSnpFull && (task_s1.bits.refillTask || isClean_s1))).orR ||
e.bits.opcode === WriteNoSnpFull && (task_s1.bits.refillTask || isClean_s1 || !e.bits.w_datRsp && isRead_s1))).orR ||
Cat(memInfo.map(e => e.valid && e.bits.reqID === reqID_s1 && !task_s1.bits.refillTask)).orR ||
(inflight_memAccess +& potential_memAccess) >= mshrs.memory.U

Expand Down
10 changes: 0 additions & 10 deletions src/main/scala/openLLC/RequestBuffer.scala
Original file line number Diff line number Diff line change
Expand Up @@ -43,16 +43,6 @@ class RequestBuffer(entries: Int = 8)(implicit p: Parameters) extends LLCModule
val insertIdx = PriorityEncoder(buffer.map(!_.valid))
val alloc = in.fire
when(alloc) {
val isReadNotSharedDirty = in.bits.chiOpcode === ReadNotSharedDirty
val isReadUnique = in.bits.chiOpcode === ReadUnique
val isMakeUnique = in.bits.chiOpcode === MakeUnique
val isWriteBackFull = in.bits.chiOpcode === WriteBackFull
val isEvict = in.bits.chiOpcode === Evict
val isMakeInvalid = in.bits.chiOpcode === MakeInvalid
val isCleanInvalid = in.bits.chiOpcode === CleanInvalid
val isCleanShared = in.bits.chiOpcode === CleanShared
assert(isReadNotSharedDirty || isReadUnique || isMakeUnique || isWriteBackFull || isEvict || isMakeInvalid ||
isCleanInvalid || isCleanShared, "Unsupported opcode")
val entry = buffer(insertIdx)
entry.valid := true.B
entry.bits := in.bits
Expand Down
2 changes: 1 addition & 1 deletion src/main/scala/openLLC/ResponseUnit.scala
Original file line number Diff line number Diff line change
Expand Up @@ -289,7 +289,7 @@ class ResponseUnit(implicit p: Parameters) extends LLCModule with HasCHIOpcodes
txrsp.valid := txrspArb.io.out.valid
txrsp.bits := txrspArb.io.out.bits
txrsp.bits.chiOpcode := Mux(
txrspArb.io.out.bits.chiOpcode === WriteBackFull,
txrspArb.io.out.bits.chiOpcode === WriteBackFull || txrspArb.io.out.bits.chiOpcode === WriteCleanFull,
CompDBIDResp,
Comp
)
Expand Down

0 comments on commit 9a66de2

Please sign in to comment.