mem-ruby: start using txnid and DBID identifiers in CHI transactions (#288)
With this PR our CHI implementation starts making use of the txnid and DBID identifiers. Note: we were already making use of the txnId for DVM messages to convey the DVM address. This is still the case. In the future we should realign the DVM logic so that the txnId is solely used as a transaction identifier.
This commit is contained in:
@@ -63,6 +63,7 @@ action(AllocateTBE_Request, desc="") {
|
||||
out_msg.usesTxnId := false;
|
||||
out_msg.event := Event:SendRetryAck;
|
||||
out_msg.retryDest := in_msg.requestor;
|
||||
out_msg.txnId := in_msg.txnId;
|
||||
retryQueue.emplace(in_msg.addr,false,in_msg.requestor);
|
||||
}
|
||||
}
|
||||
@@ -145,6 +146,7 @@ action(AllocateTBE_SeqRequest, desc="") {
|
||||
assert(in_msg.Prefetch == PrefetchBit:No);
|
||||
out_msg.is_local_pf := false;
|
||||
out_msg.is_remote_pf := false;
|
||||
out_msg.txnId := max_outstanding_transactions;
|
||||
|
||||
if ((in_msg.Type == RubyRequestType:LD) ||
|
||||
(in_msg.Type == RubyRequestType:IFETCH)) {
|
||||
@@ -2133,6 +2135,16 @@ action(Receive_ReqResp_WUComp, desc="") {
|
||||
}
|
||||
}
|
||||
|
||||
action(Receive_ReqResp_CopyDBID, desc="Copy the rsp DBID into the TBE") {
|
||||
if (tbe.expected_req_resp.receivedRespType(CHIResponseType:DBIDResp) == false &&
|
||||
tbe.expected_req_resp.receivedRespType(CHIResponseType:CompDBIDResp) == false) {
|
||||
error("Received unexpected message");
|
||||
}
|
||||
peek(rspInPort, CHIResponseMsg) {
|
||||
tbe.txnId := in_msg.dbid;
|
||||
}
|
||||
}
|
||||
|
||||
action(Receive_SnpResp, desc="") {
|
||||
assert(tbe.expected_snp_resp.hasExpected());
|
||||
peek(rspInPort, CHIResponseMsg) {
|
||||
@@ -2508,6 +2520,7 @@ action(Send_Data, desc="") {
|
||||
enqueue(datOutPort, CHIDataMsg, data_latency) {
|
||||
out_msg.addr := tbe.addr;
|
||||
out_msg.type := tbe.snd_msgType;
|
||||
out_msg.txnId := tbe.txnId;
|
||||
|
||||
int offset := tbe.snd_pendBytes.firstBitSet(true);
|
||||
assert(offset < blockSize);
|
||||
@@ -2554,6 +2567,9 @@ action(Send_CompI, desc="") {
|
||||
out_msg.type := CHIResponseType:Comp_I;
|
||||
out_msg.responder := machineID;
|
||||
out_msg.Destination.add(tbe.requestor);
|
||||
out_msg.Destination.add(tbe.requestor);
|
||||
out_msg.txnId := tbe.txnId;
|
||||
out_msg.dbid := tbe.txnId;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2564,6 +2580,8 @@ action(Send_CompUC, desc="") {
|
||||
out_msg.type := CHIResponseType:Comp_UC;
|
||||
out_msg.responder := machineID;
|
||||
out_msg.Destination.add(tbe.requestor);
|
||||
out_msg.txnId := tbe.txnId;
|
||||
out_msg.dbid := tbe.txnId;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2574,6 +2592,8 @@ action(Send_CompUC_Stale, desc="") {
|
||||
out_msg.type := CHIResponseType:Comp_UC;
|
||||
out_msg.responder := machineID;
|
||||
out_msg.Destination.add(tbe.requestor);
|
||||
out_msg.txnId := tbe.txnId;
|
||||
out_msg.dbid := tbe.txnId;
|
||||
// We don't know if this is a stale clean unique or a bug, so flag the
|
||||
// reponse so the requestor can make further checks
|
||||
out_msg.stale := true;
|
||||
@@ -2587,6 +2607,7 @@ action(Send_CompAck, desc="") {
|
||||
out_msg.type := CHIResponseType:CompAck;
|
||||
out_msg.responder := machineID;
|
||||
out_msg.Destination.add(mapAddressToDownstreamMachine(tbe.addr));
|
||||
out_msg.txnId := tbe.txnId;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2597,6 +2618,7 @@ action(Send_CompI_Stale, desc="") {
|
||||
out_msg.type := CHIResponseType:Comp_I;
|
||||
out_msg.responder := machineID;
|
||||
out_msg.Destination.add(tbe.requestor);
|
||||
out_msg.dbid := tbe.txnId;
|
||||
// We don't know if this is a stale writeback or a bug, so flag the
|
||||
// reponse so the requestor can make further checks
|
||||
out_msg.stale := true;
|
||||
@@ -2610,6 +2632,8 @@ action(Send_CompDBIDResp, desc="") {
|
||||
out_msg.type := CHIResponseType:CompDBIDResp;
|
||||
out_msg.responder := machineID;
|
||||
out_msg.Destination.add(tbe.requestor);
|
||||
out_msg.txnId := tbe.txnId;
|
||||
out_msg.dbid := tbe.txnId;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2620,6 +2644,8 @@ action(Send_CompDBIDResp_Stale, desc="") {
|
||||
out_msg.type := CHIResponseType:CompDBIDResp;
|
||||
out_msg.responder := machineID;
|
||||
out_msg.Destination.add(tbe.requestor);
|
||||
out_msg.txnId := tbe.txnId;
|
||||
out_msg.dbid := tbe.txnId;
|
||||
// We don't know if this is a stale writeback or a bug, so flag the
|
||||
// reponse so the requestor can make further checks
|
||||
out_msg.stale := true;
|
||||
@@ -2633,6 +2659,7 @@ action(Send_DBIDResp, desc="") {
|
||||
out_msg.type := CHIResponseType:DBIDResp;
|
||||
out_msg.responder := machineID;
|
||||
out_msg.Destination.add(tbe.requestor);
|
||||
out_msg.dbid := tbe.txnId;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2667,6 +2694,7 @@ action(Send_RetryAck, desc="") {
|
||||
out_msg.type := CHIResponseType:RetryAck;
|
||||
out_msg.responder := machineID;
|
||||
out_msg.Destination.add(in_msg.retryDest);
|
||||
out_msg.txnId := in_msg.txnId;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3155,9 +3183,7 @@ action(Profile_OutgoingEnd_DatalessResp, desc="") {
|
||||
action(TagArrayRead, desc="") {
|
||||
assert(is_valid(tbe));
|
||||
tbe.delayNextAction := curTick() + cyclesToTicks(
|
||||
tagLatency((tbe.reqType == CHIRequestType:Load) ||
|
||||
(tbe.reqType == CHIRequestType:Store) ||
|
||||
(tbe.reqType == CHIRequestType:StoreLine)));
|
||||
tagLatency(fromSequencer(tbe.reqType)));
|
||||
}
|
||||
|
||||
action(TagArrayWrite, desc="") {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2021-2022 ARM Limited
|
||||
* Copyright (c) 2021-2023 Arm Limited
|
||||
* All rights reserved
|
||||
*
|
||||
* The license below extends only to copyright in the software and shall
|
||||
@@ -299,6 +299,12 @@ Cycles dataLatency() {
|
||||
return cache.getDataLatency();
|
||||
}
|
||||
|
||||
bool fromSequencer(CHIRequestType reqType) {
|
||||
return reqType == CHIRequestType:Load ||
|
||||
reqType == CHIRequestType:Store ||
|
||||
reqType == CHIRequestType:StoreLine;
|
||||
}
|
||||
|
||||
bool inCache(Addr addr) {
|
||||
CacheEntry entry := getCacheEntry(makeLineAddress(addr));
|
||||
// NOTE: we consider data for the addr to be in cache if it exists in local,
|
||||
@@ -405,6 +411,12 @@ TBE allocateRequestTBE(Addr addr, CHIRequestMsg in_msg), return_by_pointer="yes"
|
||||
TBE tbe := TBEs[addr];
|
||||
|
||||
initializeTBE(tbe, addr, storTBEs.addEntryToNewSlot());
|
||||
if (fromSequencer(in_msg.type)) {
|
||||
assert(in_msg.txnId == max_outstanding_transactions);
|
||||
tbe.txnId := static_cast(Addr, "value", tbe.storSlot);
|
||||
} else {
|
||||
tbe.txnId := in_msg.txnId;
|
||||
}
|
||||
|
||||
assert(tbe.is_snp_tbe == false);
|
||||
assert(tbe.is_repl_tbe == false);
|
||||
@@ -486,6 +498,7 @@ TBE allocateSnoopTBE(Addr addr, CHIRequestMsg in_msg), return_by_pointer="yes" {
|
||||
tbe.requestor := in_msg.requestor;
|
||||
tbe.fwdRequestor := in_msg.fwdRequestor;
|
||||
tbe.reqType := in_msg.type;
|
||||
tbe.txnId := in_msg.txnId;
|
||||
|
||||
tbe.snpNeedsData := in_msg.retToSrc;
|
||||
|
||||
@@ -538,6 +551,8 @@ TBE _allocateReplacementTBE(Addr addr, int storSlot), return_by_pointer="yes" {
|
||||
tbe.accSize := blockSize;
|
||||
tbe.requestor := machineID;
|
||||
tbe.reqType := CHIRequestType:null;
|
||||
// This is an internal event and should generate a new TxnId
|
||||
tbe.txnId := static_cast(Addr, "value", storSlot);
|
||||
|
||||
tbe.use_DMT := false;
|
||||
tbe.use_DCT := false;
|
||||
@@ -624,6 +639,9 @@ void prepareRequest(TBE tbe, CHIRequestType type, CHIRequestMsg & out_msg) {
|
||||
out_msg.seqReq := tbe.seqReq;
|
||||
out_msg.is_local_pf := false;
|
||||
out_msg.is_remote_pf := tbe.is_local_pf || tbe.is_remote_pf;
|
||||
out_msg.txnId := tbe.txnId;
|
||||
|
||||
assert(tbe.txnId != static_cast(Addr, "value", -1));
|
||||
}
|
||||
|
||||
void allowRequestRetry(TBE tbe, CHIRequestMsg & out_msg) {
|
||||
@@ -780,12 +798,12 @@ bool upstreamHasShared(State state) {
|
||||
}
|
||||
|
||||
void printTBEState(TBE tbe) {
|
||||
DPRINTF(RubySlicc, "STATE: addr: %#x data present=%d valid=%d unique=%d dirty=%d mu_dirty=%d dir ownerV=%d ownerE=%d sharers=%d tobe_I=%d tobe_SC=%d doFill=%d pendAction=%s\n",
|
||||
DPRINTF(RubySlicc, "STATE: addr: %#x data present=%d valid=%d unique=%d dirty=%d mu_dirty=%d dir ownerV=%d ownerE=%d sharers=%d tobe_I=%d tobe_SC=%d doFill=%d pendAction=%s txnId=%d\n",
|
||||
tbe.addr, tbe.dataBlkValid.isFull(), tbe.dataValid, tbe.dataUnique,
|
||||
tbe.dataDirty, tbe.dataMaybeDirtyUpstream, tbe.dir_ownerExists,
|
||||
tbe.dir_ownerIsExcl,tbe.dir_sharers.count(),
|
||||
tbe.dataToBeInvalid, tbe.dataToBeSharedClean,
|
||||
tbe.doCacheFill, tbe.pendAction);
|
||||
tbe.doCacheFill, tbe.pendAction, tbe.txnId);
|
||||
DPRINTF(RubySlicc, "dataBlkValid = %s\n", tbe.dataBlkValid);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2021-2022 ARM Limited
|
||||
* Copyright (c) 2021-2023 Arm Limited
|
||||
* All rights reserved
|
||||
*
|
||||
* The license below extends only to copyright in the software and shall
|
||||
@@ -1212,8 +1212,7 @@ transition(BUSY_BLKD,
|
||||
}
|
||||
|
||||
// waiting for WB or evict ack
|
||||
transition(BUSY_INTR,
|
||||
{CompDBIDResp,Comp_I}, BUSY_BLKD) {
|
||||
transition(BUSY_INTR, Comp_I, BUSY_BLKD) {
|
||||
Receive_ReqResp;
|
||||
Profile_OutgoingEnd_DatalessResp;
|
||||
Pop_RespInQueue;
|
||||
@@ -1229,9 +1228,19 @@ transition(BUSY_INTR, Comp_UC, BUSY_BLKD) {
|
||||
ProcessNextState;
|
||||
}
|
||||
|
||||
// waiting for WB or evict ack
|
||||
transition(BUSY_INTR, CompDBIDResp, BUSY_BLKD) {
|
||||
Receive_ReqResp;
|
||||
Receive_ReqResp_CopyDBID;
|
||||
Profile_OutgoingEnd_DatalessResp;
|
||||
Pop_RespInQueue;
|
||||
ProcessNextState;
|
||||
}
|
||||
|
||||
// alternative flow for WU with separate Comp
|
||||
transition(BUSY_INTR, DBIDResp, BUSY_BLKD) {
|
||||
Receive_ReqResp;
|
||||
Receive_ReqResp_CopyDBID;
|
||||
Receive_ReqResp_WUNeedComp;
|
||||
Pop_RespInQueue;
|
||||
ProcessNextState;
|
||||
|
||||
@@ -81,6 +81,9 @@ machine(MachineType:Cache, "Cache coherency protocol") :
|
||||
int sc_lock_multiplier_max := 256;
|
||||
bool sc_lock_enabled;
|
||||
|
||||
// Maximum number of outstanding transactions from a single requester
|
||||
Addr max_outstanding_transactions := 1024;
|
||||
|
||||
// Recycle latency on resource stalls
|
||||
Cycles stall_recycle_lat := 1;
|
||||
|
||||
@@ -599,6 +602,7 @@ machine(MachineType:Cache, "Cache coherency protocol") :
|
||||
Addr accAddr, desc="Access address for Load/Store/WriteUniquePtl; otherwisse == addr";
|
||||
int accSize, desc="Access size for Load/Store/WriteUniquePtl; otherwisse == blockSize";
|
||||
CHIRequestType reqType, desc="Request type that initiated this transaction";
|
||||
Addr txnId, desc="Transaction ID. We default to -1 for debug purposes", default="-1";
|
||||
MachineID requestor, desc="Requestor ID";
|
||||
MachineID fwdRequestor, desc="Requestor to receive data on fwding snoops";
|
||||
bool use_DMT, desc="Use DMT for this transaction";
|
||||
@@ -785,6 +789,7 @@ machine(MachineType:Cache, "Cache coherency protocol") :
|
||||
Event event;
|
||||
MachineID retryDest;
|
||||
bool usesTxnId;
|
||||
Addr txnId;
|
||||
|
||||
bool functionalRead(Packet *pkt) { return false; }
|
||||
bool functionalRead(Packet *pkt, WriteMask &mask) { return false; }
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2021,2022 ARM Limited
|
||||
* Copyright (c) 2021-2023 Arm Limited
|
||||
* All rights reserved
|
||||
*
|
||||
* The license below extends only to copyright in the software and shall
|
||||
@@ -164,6 +164,7 @@ machine(MachineType:Memory, "Memory controller interface") :
|
||||
int storSlot, desc="Slot in the storage tracker occupied by this entry";
|
||||
Addr addr, desc="Line address for this TBE";
|
||||
Addr accAddr, desc="Original access address. Set only for Write*Ptl";
|
||||
Addr txnId, desc="Transaction ID";
|
||||
int accSize, desc="Access size. Set only for Write*Ptl";
|
||||
State state, desc="Current line state";
|
||||
DataBlock dataBlk, desc="Transaction data";
|
||||
@@ -503,6 +504,7 @@ machine(MachineType:Memory, "Memory controller interface") :
|
||||
}
|
||||
tbe.accAddr := in_msg.accAddr;
|
||||
tbe.accSize := in_msg.accSize;
|
||||
tbe.txnId := in_msg.txnId;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -608,6 +610,7 @@ machine(MachineType:Memory, "Memory controller interface") :
|
||||
assert(tbe.rxtxBytes < blockSize);
|
||||
enqueue(datOutPort, CHIDataMsg, data_latency) {
|
||||
out_msg.addr := tbe.addr;
|
||||
out_msg.txnId := tbe.txnId;
|
||||
if (tbe.useDataSepResp) {
|
||||
out_msg.type := CHIDataType:DataSepResp_UC;
|
||||
} else {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2021 ARM Limited
|
||||
* Copyright (c) 2021, 2023 Arm Limited
|
||||
* All rights reserved
|
||||
*
|
||||
* The license below extends only to copyright in the software and shall
|
||||
@@ -156,6 +156,7 @@ structure(CHIResponseMsg, desc="", interface="Message") {
|
||||
bool stale, desc="Response to a stale request";
|
||||
bool usesTxnId, desc="True if using a Transaction ID", default="false";
|
||||
Addr txnId, desc="Transaction ID", default="0";
|
||||
Addr dbid, desc="Data Buffer ID", default="0";
|
||||
//NOTE: not in CHI and for debuging only
|
||||
|
||||
MessageSizeType MessageSize, default="MessageSizeType_Control";
|
||||
|
||||
@@ -1,3 +1,15 @@
|
||||
# Copyright (c) 2023 Arm Limited
|
||||
# All rights reserved.
|
||||
#
|
||||
# The license below extends only to copyright in the software and shall
|
||||
# not be construed as granting a license to any other intellectual
|
||||
# property including but not limited to intellectual property relating
|
||||
# to a hardware implementation of the functionality of the software
|
||||
# licensed hereunder. You may use the software subject to the license
|
||||
# terms below provided that you ensure that this notice is replicated
|
||||
# unmodified and in its entirety in all distributions of the software,
|
||||
# modified or unmodified, in source code or in binary form.
|
||||
#
|
||||
# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
|
||||
# Copyright (c) 2009 The Hewlett-Packard Development Company
|
||||
# All rights reserved.
|
||||
@@ -76,11 +88,14 @@ class InfixOperatorExprAST(ExprAST):
|
||||
("int", "int", "int"),
|
||||
("Cycles", "Cycles", "Cycles"),
|
||||
("Tick", "Tick", "Tick"),
|
||||
("Addr", "Addr", "Addr"),
|
||||
("Cycles", "int", "Cycles"),
|
||||
("Scalar", "int", "Scalar"),
|
||||
("int", "bool", "int"),
|
||||
("bool", "int", "int"),
|
||||
("int", "Cycles", "Cycles"),
|
||||
("Addr", "int", "Addr"),
|
||||
("int", "Addr", "Addr"),
|
||||
]
|
||||
else:
|
||||
self.error(f"No operator matched with {self.op}!")
|
||||
|
||||
@@ -1,3 +1,15 @@
|
||||
# Copyright (c) 2023 Arm Limited
|
||||
# All rights reserved.
|
||||
#
|
||||
# The license below extends only to copyright in the software and shall
|
||||
# not be construed as granting a license to any other intellectual
|
||||
# property including but not limited to intellectual property relating
|
||||
# to a hardware implementation of the functionality of the software
|
||||
# licensed hereunder. You may use the software subject to the license
|
||||
# terms below provided that you ensure that this notice is replicated
|
||||
# unmodified and in its entirety in all distributions of the software,
|
||||
# modified or unmodified, in source code or in binary form.
|
||||
#
|
||||
# Copyright (c) 2009 Advanced Micro Devices, Inc.
|
||||
# All rights reserved.
|
||||
#
|
||||
@@ -42,22 +54,9 @@ class StaticCastAST(ExprAST):
|
||||
actual_type, ecode = self.expr_ast.inline(True)
|
||||
if self.type_modifier == "pointer":
|
||||
code("static_cast<${{self.type_ast.type.c_ident}} *>($ecode)")
|
||||
elif self.type_modifier == "value":
|
||||
code("static_cast<${{self.type_ast.type.c_ident}} >($ecode)")
|
||||
else:
|
||||
code("static_cast<${{self.type_ast.type.c_ident}} &>($ecode)")
|
||||
|
||||
if not "interface" in self.type_ast.type:
|
||||
self.expr_ast.error(
|
||||
"static cast only premitted for those types "
|
||||
"that implement inherit an interface"
|
||||
)
|
||||
|
||||
# The interface type should match
|
||||
if str(actual_type) != str(self.type_ast.type["interface"]):
|
||||
self.expr_ast.error(
|
||||
"static cast miss-match, type is '%s',"
|
||||
"but inherited type is '%s'",
|
||||
actual_type,
|
||||
self.type_ast.type["interface"],
|
||||
)
|
||||
|
||||
return self.type_ast.type
|
||||
|
||||
@@ -64,6 +64,7 @@ python_class_map = {
|
||||
"DMASequencer": "DMASequencer",
|
||||
"RubyPrefetcher": "RubyPrefetcher",
|
||||
"Cycles": "Cycles",
|
||||
"Addr": "Addr",
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user