Skip to content

Commit

Permalink
misc: an official version of MCP2 hold check
Browse files Browse the repository at this point in the history
  • Loading branch information
Ivyfeather committed Sep 24, 2024
1 parent 23f8313 commit ac70743
Show file tree
Hide file tree
Showing 10 changed files with 51 additions and 40 deletions.
1 change: 1 addition & 0 deletions src/main/scala/coupledL2/CoupledL2.scala
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ trait HasCoupledL2Parameters {
def hasPrefetchSrc = prefetchers.exists(_.hasPrefetchSrc)
def hasCMO = cacheParams.hasCMO
def topDownOpt = if(cacheParams.elaboratedTopDown) Some(true) else None
def hasMPC2Check = cacheParams.MPC2Check

def enableHintGuidedGrant = true

Expand Down
7 changes: 7 additions & 0 deletions src/main/scala/coupledL2/Directory.scala
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ class Directory(implicit p: Parameters) extends L2Module {
val replResp = ValidIO(new ReplacerResult)
// used to count occWays for Grant to retry
val msInfo = Vec(mshrsAll, Flipped(ValidIO(new MSHRInfo)))
val mcp2Check = if(hasMPC2Check) Some(Input(new MCP2CheckEn)) else None
})

def invalid_way_sel(metaVec: Seq[MetaEntry], repl: UInt) = {
Expand Down Expand Up @@ -373,4 +374,10 @@ class Directory(implicit p: Parameters) extends L2Module {

XSPerfAccumulate("dirRead_cnt", io.read.fire)
XSPerfAccumulate("choose_busy_way", reqValid_s3 && !req_s3.wayMask(chosenWay))

// ===== for MCP2 hold check =====
if (hasMPC2Check) {
HoldChecker.check2(io.resp.bits, io.mcp2Check.get.en, "dirResp_s3")
HoldChecker.check2(io.replResp.bits, io.mcp2Check.get.en, "replResp_s3")
}
}
2 changes: 2 additions & 0 deletions src/main/scala/coupledL2/L2Param.scala
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,8 @@ case class L2Param(
FPGAPlatform: Boolean = false,
// CMO
hasCMO: Boolean = false,
// has DataStorage MCP2 Check
MPC2Check: Boolean = true,

// Network layer SAM
sam: Seq[(AddressSet, Int)] = Seq(AddressSet.everything -> 0)
Expand Down
10 changes: 5 additions & 5 deletions src/main/scala/coupledL2/MSHRBuffer.scala
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ import chisel3._
import chisel3.util._
import org.chipsalliance.cde.config.Parameters
import coupledL2.utils._
import chisel3.util.experimental.BoringUtils

class MSHRBufRead(implicit p: Parameters) extends L2Bundle {
val id = Output(UInt(mshrBits.W))
Expand All @@ -43,6 +42,7 @@ class MSHRBuffer(wPorts: Int = 1)(implicit p: Parameters) extends L2Module {
val r = Flipped(ValidIO(new MSHRBufRead))
val resp = new MSHRBufResp
val w = Vec(wPorts, Flipped(ValidIO(new MSHRBufWrite)))
val mcp2Check = if(hasMPC2Check) Some(Input(new MCP2CheckEn)) else None
})

val buffer = Reg(Vec(mshrsAll, Vec(beatSize, UInt((beatBytes * 8).W))))
Expand All @@ -65,10 +65,10 @@ class MSHRBuffer(wPorts: Int = 1)(implicit p: Parameters) extends L2Module {
val rdata = buffer(io.r.bits.id).asUInt
io.resp.data.data := RegEnable(rdata, 0.U.asTypeOf(rdata), io.r.valid)

val ds_wen = WireInit(false.B)
BoringUtils.addSink(ds_wen, "ds_wen")
assert(!io.r.valid || !RegNext(io.r.valid), "No continuous read")
HoldChecker.check2(io.resp.data.data, ds_wen, "mshrBuf_r")
if (hasMPC2Check) {
assert(!io.r.valid || !RegNext(io.r.valid), "No continuous read")
HoldChecker.check2(io.resp.data.data, io.mcp2Check.get.wen, "mshrBuf_wdata")
}
}

// may consider just choose an empty entry to insert
Expand Down
14 changes: 7 additions & 7 deletions src/main/scala/coupledL2/SinkC.scala
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,7 @@ import freechips.rocketchip.tilelink._
import freechips.rocketchip.tilelink.TLMessages._
import org.chipsalliance.cde.config.Parameters
import utility.{MemReqSource, XSPerfAccumulate, RRArbiterInit}
import chisel3.util.experimental.BoringUtils
import coupledL2.utils.HoldChecker
import coupledL2.utils._

class PipeBufferResp(implicit p: Parameters) extends L2Bundle {
val data = Vec(beatSize, UInt((beatBytes * 8).W))
Expand All @@ -43,6 +42,7 @@ class SinkC(implicit p: Parameters) extends L2Module {
val bufResp = Output(new PipeBufferResp)
val refillBufWrite = ValidIO(new MSHRBufWrite)
val msInfo = Vec(mshrsAll, Flipped(ValidIO(new MSHRInfo)))
val mcp2Check = if(hasMPC2Check) Some(Input(new MCP2CheckEn)) else None
})

val (first, last, _, beat) = edgeIn.count(io.c)
Expand Down Expand Up @@ -187,11 +187,6 @@ class SinkC(implicit p: Parameters) extends L2Module {
when(RegNext(io.task.fire)) {
beatValids(RegNext(io.task.bits.bufIdx)).foreach(_ := false.B)
}
// ===== for MCP2 hold check =====
val ds_wen = WireInit(false.B)
BoringUtils.addSink(ds_wen, "ds_wen")
assert(!io.task.fire || !RegNext(io.task.fire), "No continuous write @SinkC")
HoldChecker.check2(io.bufResp.data.asUInt, ds_wen, "sinkC_")

// Performance counters
val stall = io.c.valid && isRelease && !io.c.ready
Expand All @@ -203,4 +198,9 @@ class SinkC(implicit p: Parameters) extends L2Module {
XSPerfAccumulate("NewDataNestC", io.refillBufWrite.valid)
//!!WARNING: TODO: if this is zero, that means fucntion [Release-new-data written into refillBuf]
// is never tested, and may have flaws
// ===== for MCP2 hold check =====
if (hasMPC2Check) {
assert(!io.task.fire || !RegNext(io.task.fire), "No continuous write @SinkC")
HoldChecker.check2(io.bufResp.data.asUInt, io.mcp2Check.get.wen, "sinkC_wdata")
}
}
14 changes: 0 additions & 14 deletions src/main/scala/coupledL2/tl2chi/MainPipe.scala
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ import coupledL2.utils.HoldChecker
import coupledL2.prefetch.{PrefetchTrain, PfSource}
import coupledL2.tl2chi.CHICohStates._
import coupledL2.MetaData._
import chisel3.util.experimental.BoringUtils

class MainPipe(implicit p: Parameters) extends TL2CHIL2Module with HasCHIOpcodes {
val io = IO(new Bundle() {
Expand Down Expand Up @@ -416,19 +415,6 @@ class MainPipe(implicit p: Parameters) extends TL2CHIL2Module with HasCHIOpcodes
)
)

// ===== for MCP2 hold check =====
val en = io.toDS.en_s3
val w_en = io.toDS.en_s3 && io.toDS.req_s3.bits.wen
HoldChecker.check2(task_s3.bits, en, "task_s3.bits")
HoldChecker.check2(dirResult_s3, en, "dirResult_s3")
HoldChecker.check2(io.replResp.bits, en, "replResp_s3")

HoldChecker.check2(io.bufResp.data.asUInt, w_en, "sinkC_data_s3")
HoldChecker.check2(io.refillBufResp_s3.bits, w_en, "refillBufResp_data_s3")
HoldChecker.check2(io.releaseBufResp_s3.bits, w_en, "releaseBufResp_data_s3")

BoringUtils.addSource(w_en, "ds_wen")

/* ======== Read DS and store data in Buffer ======== */
// A: need_write_releaseBuf indicates that DS should be read and the data will be written into ReleaseBuffer
// need_write_releaseBuf is assigned true when:
Expand Down
12 changes: 12 additions & 0 deletions src/main/scala/coupledL2/tl2chi/Slice.scala
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import chisel3.util._
import freechips.rocketchip.tilelink._
import org.chipsalliance.cde.config.Parameters
import coupledL2._
import coupledL2.utils._
import coupledL2.prefetch.PrefetchIO

class OuterBundle(implicit p: Parameters) extends DecoupledPortIO with BaseOuterBundle
Expand Down Expand Up @@ -209,4 +210,15 @@ class Slice()(implicit p: Parameters) extends BaseSlice[OuterBundle]
rxrsp.io.out <> io.out.rx.rsp

io_pCrd <> mshrCtl.io.pCrd

if (hasMPC2Check) {
val dsEnable = WireInit(0.U.asTypeOf(new MCP2CheckEn))
dsEnable.en := dataStorage.io.en
dsEnable.wen := dataStorage.io.en && dataStorage.io.req.bits.wen

directory.io.mcp2Check.get := dsEnable
releaseBuf.io.mcp2Check.get := dsEnable
refillBuf.io.mcp2Check.get := dsEnable
sinkC.io.mcp2Check.get := dsEnable
}
}
14 changes: 0 additions & 14 deletions src/main/scala/coupledL2/tl2tl/MainPipe.scala
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ package coupledL2.tl2tl

import chisel3._
import chisel3.util._
import chisel3.util.experimental.BoringUtils
import utility._
import coupledL2.MetaData._
import org.chipsalliance.cde.config.Parameters
Expand Down Expand Up @@ -315,19 +314,6 @@ class MainPipe(implicit p: Parameters) extends L2Module {
)
)

// ===== for MCP2 hold check =====
val en = io.toDS.en_s3
val w_en = io.toDS.en_s3 && io.toDS.req_s3.bits.wen
HoldChecker.check2(task_s3.bits, en, "task_s3.bits")
HoldChecker.check2(dirResult_s3, en, "dirResult_s3")
HoldChecker.check2(io.replResp.bits, en, "replResp_s3")

HoldChecker.check2(io.bufResp.data.asUInt, w_en, "sinkC_data_s3")
HoldChecker.check2(io.refillBufResp_s3.bits, w_en, "refillBufResp_data_s3")
HoldChecker.check2(io.releaseBufResp_s3.bits, w_en, "releaseBufResp_data_s3")

BoringUtils.addSource(w_en, "ds_wen")

/* ======== Read DS and store data in Buffer ======== */
// A: need_write_releaseBuf indicates that DS should be read and the data will be written into ReleaseBuffer
// need_write_releaseBuf is assigned true when:
Expand Down
11 changes: 11 additions & 0 deletions src/main/scala/coupledL2/tl2tl/Slice.scala
Original file line number Diff line number Diff line change
Expand Up @@ -205,4 +205,15 @@ class Slice()(implicit p: Parameters) extends BaseSlice[OuterBundle] {

val monitor = Module(new Monitor())
monitor.io.fromMainPipe <> mainPipe.io.toMonitor

if (hasMPC2Check) {
val dsEnable = WireInit(0.U.asTypeOf(new MCP2CheckEn))
dsEnable.en := dataStorage.io.en
dsEnable.wen := dataStorage.io.en && dataStorage.io.req.bits.wen

directory.io.mcp2Check.get := dsEnable
releaseBuf.io.mcp2Check.get := dsEnable
refillBuf.io.mcp2Check.get := dsEnable
sinkC.io.mcp2Check.get := dsEnable
}
}
6 changes: 6 additions & 0 deletions src/main/scala/coupledL2/utils/HoldChecker.scala
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,12 @@ package coupledL2.utils
import chisel3._
import chisel3.util._

// enable signals, only used to check mcp2 hold condition of predecessor regs
class MCP2CheckEn extends Bundle {
val en = Bool()
val wen = Bool()
}

/**
* Assert the signal must hold for certain cycles when enable is high
*/
Expand Down

0 comments on commit ac70743

Please sign in to comment.