Skip to content

Commit

Permalink
MMIOBridge, Message: support non-data error handling (#181)
Browse files Browse the repository at this point in the history
  • Loading branch information
linjuanZ authored Jun 5, 2024
1 parent 9dcef18 commit a8f545f
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 35 deletions.
14 changes: 12 additions & 2 deletions src/main/scala/coupledL2/tl2chi/MMIOBridge.scala
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,8 @@ class MMIOBridgeEntry(edge: TLEdgeIn)(implicit p: Parameters) extends TL2CHIL2Mo
val dbID = Reg(UInt(DBID_WIDTH.W))
val allowRetry = RegInit(true.B)
val pCrdType = Reg(UInt(PCRDTYPE_WIDTH.W))
val denied = Reg(Bool())
val corrupt = Reg(Bool())
val isRead = req.opcode === Get

val wordBits = io.req.bits.data.getWidth // 64
Expand All @@ -117,6 +119,8 @@ class MMIOBridgeEntry(edge: TLEdgeIn)(implicit p: Parameters) extends TL2CHIL2Mo
s_txreq := false.B
s_resp := false.B
allowRetry := true.B
denied := false.B
corrupt := false.B
when (io.req.bits.opcode === Get) {
w_compdata := false.B
w_readreceipt.foreach(_ := false.B)
Expand All @@ -136,6 +140,8 @@ class MMIOBridgeEntry(edge: TLEdgeIn)(implicit p: Parameters) extends TL2CHIL2Mo
when (rxdat.fire) {
w_compdata := true.B
rdata := rxdat.bits.data
denied := denied || rxdat.bits.respErr === RespErrEncodings.NDERR
corrupt := corrupt || rxdat.bits.respErr === RespErrEncodings.DERR
}
when (io.resp.fire) {
s_resp := true.B
Expand All @@ -149,6 +155,10 @@ class MMIOBridgeEntry(edge: TLEdgeIn)(implicit p: Parameters) extends TL2CHIL2Mo
srcID := rxrsp.bits.srcID
dbID := rxrsp.bits.dbID
}
when (rxrsp.bits.opcode === RSPOpcodes.CompDBIDResp || rxrsp.bits.opcode === RSPOpcodes.Comp) {
denied := denied || rxrsp.bits.respErr === RespErrEncodings.NDERR
// TODO: d_corrupt is reserved and must be 0 in TileLink
}
when (rxrsp.bits.opcode === RSPOpcodes.RetryAck) {
s_txreq := false.B
w_pcrdgrant := false.B
Expand Down Expand Up @@ -193,8 +203,8 @@ class MMIOBridgeEntry(edge: TLEdgeIn)(implicit p: Parameters) extends TL2CHIL2Mo
io.resp.bits.size := req.size
io.resp.bits.source := req.source
io.resp.bits.sink := 0.U // ignored
io.resp.bits.denied := false.B
io.resp.bits.corrupt := false.B
io.resp.bits.denied := denied
io.resp.bits.corrupt := isRead && corrupt
io.resp.bits.data := ParallelLookUp(
reqWordIdx,
List.tabulate(words)(i => i.U -> rdata((i + 1) * wordBits - 1, i * wordBits))
Expand Down
72 changes: 39 additions & 33 deletions src/main/scala/coupledL2/tl2chi/chi/Message.scala
Original file line number Diff line number Diff line change
Expand Up @@ -58,35 +58,16 @@ object OrderEncodings {
def isRequestOrder(order: UInt): Bool = order >= RequestOrder
}

class MemAttr extends Bundle {
// The Allocate attribute is a an allocation hint.
// It indicates the recommended allocation policy for a transaction.
val allocate = Bool()
// The Cacheable attribute indicates if a transaction must perform a cache lookup.
val cacheable = Bool()
// Device attribute indicates if the memory type is either Device or Normal.
val device = Bool()
// Early Write Acknowledge (EWA)
// EWA indicates whether the write completion response for a transaction:
// If true, comp is permitted to come from an intermediate point in the interconnect, such as a Home Node.
// If false, comp must come from the final endpoint that a transaction is destined for.
val ewa = Bool()
}
object RespErrEncodings {
val width = 2

object MemAttr extends HasCHIMsgParameters {
def apply(allocate: Bool, cacheable: Bool, device: Bool, ewa: Bool): MemAttr = {
val memAttr = Wire(new MemAttr)
memAttr.allocate := allocate
memAttr.cacheable := cacheable
memAttr.device := device
memAttr.ewa := ewa
memAttr
}
def apply(): MemAttr = apply(false.B, false.B, false.B, false.B)
def OK = "b00".U(width.W) // Okay
def EXOK = "b01".U(width.W) // Exclusive Okay
def DERR = "b10".U(width.W) // Data Error
def NDERR = "b11".U(width.W) // Non-data Error
}

trait HasCHIMsgParameters {
// TODO: Comfirm the fields and their corresponding width
def NODEID_WIDTH = 7
require(NODEID_WIDTH >= 7 && NODEID_WIDTH <= 11)

Expand All @@ -95,12 +76,11 @@ trait HasCHIMsgParameters {
def TGTID_WIDTH = NODEID_WIDTH
def SRCID_WIDTH = NODEID_WIDTH
def TXNID_WIDTH = 8 // An 8-bit field is defined for the TxnID to accommodate up to 256 outstanding transactions
def LPID_WIDTH = 5 // TODO: To be confirmed
def LPID_WIDTH = 5
def RETURNNID_WIDTH = NODEID_WIDTH
def RETURNTXNID_WIDTH = TXNID_WIDTH
def STASHNID_WIDTH = NODEID_WIDTH
def STASHLPID_WIDTH = LPID_WIDTH
// def STASHINFO_WIDTH = 2 //TODO


def REQ_OPCODE_WIDTH = CHIOpcode.REQOpcodes.width
Expand All @@ -109,7 +89,7 @@ trait HasCHIMsgParameters {
def DAT_OPCODE_WIDTH = CHIOpcode.DATOpcodes.width
def OPCODE_WIDTH = max(REQ_OPCODE_WIDTH, max(RSP_OPCODE_WIDTH, max(SNP_OPCODE_WIDTH, DAT_OPCODE_WIDTH)))

def ADDR_WIDTH = 48 // TODO: To be confirmed
def ADDR_WIDTH = 48
def SNP_ADDR_WIDTH = ADDR_WIDTH - 3
def SIZE_WIDTH = 3
def PCRDTYPE_WIDTH = 4
Expand All @@ -119,18 +99,18 @@ trait HasCHIMsgParameters {
// Snoop request fields
def FWDNID_WIDTH = NODEID_WIDTH
def FWDTXNID_WIDTH = TXNID_WIDTH
def VMIDEXT_WIDTH = 8 // TODO: To be confirmed
def VMIDEXT_WIDTH = 8

// Data fields && Response fields
def HOMENID_WIDTH = NODEID_WIDTH
def DBID_WIDTH = TXNID_WIDTH
def RESPERR_WIDTH = 2
def RESPERR_WIDTH = RespErrEncodings.width
def RESP_WIDTH = CHICohStates.width
def FWDSTATE_WIDTH = CHICohStates.width
def DATAPULL_WIDTH = 3
def DATASOURCE_WIDTH = 3
def CCID_WIDTH = 2 // TODO: To be confirmed
def DATAID_WIDTH = 2 // TODO: To be confirmed
def CCID_WIDTH = 2
def DATAID_WIDTH = 2
def BE_WIDTH = DATA_WIDTH / 8
def DATA_WIDTH = 256
def DATACHECK_WIDTH = DATA_WIDTH / 8
Expand All @@ -143,6 +123,33 @@ trait HasCHIMsgParameters {
def DAT_RSVDC_WIDTH = 4 // Permitted RSVDC bus widths Y = 0, 4, 12, 16, 24, 32
}

class MemAttr extends Bundle {
// The Allocate attribute is a an allocation hint.
// It indicates the recommended allocation policy for a transaction.
val allocate = Bool()
// The Cacheable attribute indicates if a transaction must perform a cache lookup.
val cacheable = Bool()
// Device attribute indicates if the memory type is either Device or Normal.
val device = Bool()
// Early Write Acknowledge (EWA)
// EWA indicates whether the write completion response for a transaction:
// If true, comp is permitted to come from an intermediate point in the interconnect, such as a Home Node.
// If false, comp must come from the final endpoint that a transaction is destined for.
val ewa = Bool()
}

object MemAttr extends HasCHIMsgParameters {
def apply(allocate: Bool, cacheable: Bool, device: Bool, ewa: Bool): MemAttr = {
val memAttr = Wire(new MemAttr)
memAttr.allocate := allocate
memAttr.cacheable := cacheable
memAttr.device := device
memAttr.ewa := ewa
memAttr
}
def apply(): MemAttr = apply(false.B, false.B, false.B, false.B)
}

abstract class CHIBundle extends Bundle with HasCHIMsgParameters

class CHIREQ extends CHIBundle {
Expand Down Expand Up @@ -237,7 +244,6 @@ class CHIDAT extends CHIBundle {
val rsvdc = UInt(DAT_RSVDC_WIDTH.W)
val be = UInt(BE_WIDTH.W)
val data = UInt(DATA_WIDTH.W)
// TODO: maybe Data Check and Poison

/* MSB */
}
Expand Down

0 comments on commit a8f545f

Please sign in to comment.