diff --git a/src/main/scala/coupledL2/tl2chi/MMIOBridge.scala b/src/main/scala/coupledL2/tl2chi/MMIOBridge.scala index c4cd2ce9..f0806d75 100644 --- a/src/main/scala/coupledL2/tl2chi/MMIOBridge.scala +++ b/src/main/scala/coupledL2/tl2chi/MMIOBridge.scala @@ -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 @@ -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) @@ -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 @@ -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 @@ -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)) diff --git a/src/main/scala/coupledL2/tl2chi/chi/Message.scala b/src/main/scala/coupledL2/tl2chi/chi/Message.scala index 57b3eb62..34398142 100644 --- a/src/main/scala/coupledL2/tl2chi/chi/Message.scala +++ b/src/main/scala/coupledL2/tl2chi/chi/Message.scala @@ -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) @@ -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 @@ -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 @@ -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 @@ -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 { @@ -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 */ }