base.cc (13748:de3b813c4b90) base.cc (13749:b2486662285d)
1/*
2 * Copyright (c) 2012-2013, 2018 ARM Limited
3 * All rights reserved.
4 *
5 * The license below extends only to copyright in the software and shall
6 * not be construed as granting a license to any other intellectual
7 * property including but not limited to intellectual property relating
8 * to a hardware implementation of the functionality of the software

--- 876 unchanged lines hidden (view full) ---

885}
886
887/////////////////////////////////////////////////////
888//
889// Access path: requests coming in from the CPU side
890//
891/////////////////////////////////////////////////////
892Cycles
1/*
2 * Copyright (c) 2012-2013, 2018 ARM Limited
3 * All rights reserved.
4 *
5 * The license below extends only to copyright in the software and shall
6 * not be construed as granting a license to any other intellectual
7 * property including but not limited to intellectual property relating
8 * to a hardware implementation of the functionality of the software

--- 876 unchanged lines hidden (view full) ---

885}
886
887/////////////////////////////////////////////////////
888//
889// Access path: requests coming in from the CPU side
890//
891/////////////////////////////////////////////////////
892Cycles
893BaseCache::calculateTagOnlyLatency(const uint32_t delay,
894 const Cycles lookup_lat) const
895{
896 // A tag-only access has to wait for the packet to arrive in order to
897 // perform the tag lookup.
898 return ticksToCycles(delay) + lookup_lat;
899}
900
901Cycles
893BaseCache::calculateAccessLatency(const CacheBlk* blk, const uint32_t delay,
894 const Cycles lookup_lat) const
895{
896 Cycles lat(0);
897
898 if (blk != nullptr) {
899 // As soon as the access arrives, for sequential accesses first access
900 // tags, then the data entry. In the case of parallel accesses the

--- 8 unchanged lines hidden (view full) ---

909 // access latency on top of when the block is ready to be accessed.
910 const Tick tick = curTick() + delay;
911 const Tick when_ready = blk->getWhenReady();
912 if (when_ready > tick &&
913 ticksToCycles(when_ready - tick) > lat) {
914 lat += ticksToCycles(when_ready - tick);
915 }
916 } else {
902BaseCache::calculateAccessLatency(const CacheBlk* blk, const uint32_t delay,
903 const Cycles lookup_lat) const
904{
905 Cycles lat(0);
906
907 if (blk != nullptr) {
908 // As soon as the access arrives, for sequential accesses first access
909 // tags, then the data entry. In the case of parallel accesses the

--- 8 unchanged lines hidden (view full) ---

918 // access latency on top of when the block is ready to be accessed.
919 const Tick tick = curTick() + delay;
920 const Tick when_ready = blk->getWhenReady();
921 if (when_ready > tick &&
922 ticksToCycles(when_ready - tick) > lat) {
923 lat += ticksToCycles(when_ready - tick);
924 }
925 } else {
917 // In case of a miss, apply lookup latency on top of the metadata
918 // delay, as the access can only start when it arrives.
919 lat = ticksToCycles(delay) + lookup_lat;
926 // In case of a miss, we neglect the data access in a parallel
927 // configuration (i.e., the data access will be stopped as soon as
928 // we find out it is a miss), and use the tag-only latency.
929 lat = calculateTagOnlyLatency(delay, lookup_lat);
920 }
921
922 return lat;
923}
924
925bool
926BaseCache::access(PacketPtr pkt, CacheBlk *&blk, Cycles &lat,
927 PacketList &writebacks)

--- 4 unchanged lines hidden (view full) ---

932 chatty_assert(!(isReadOnly && pkt->isWrite()),
933 "Should never see a write in a read-only cache %s\n",
934 name());
935
936 // Access block in the tags
937 Cycles tag_latency(0);
938 blk = tags->accessBlock(pkt->getAddr(), pkt->isSecure(), tag_latency);
939
930 }
931
932 return lat;
933}
934
935bool
936BaseCache::access(PacketPtr pkt, CacheBlk *&blk, Cycles &lat,
937 PacketList &writebacks)

--- 4 unchanged lines hidden (view full) ---

942 chatty_assert(!(isReadOnly && pkt->isWrite()),
943 "Should never see a write in a read-only cache %s\n",
944 name());
945
946 // Access block in the tags
947 Cycles tag_latency(0);
948 blk = tags->accessBlock(pkt->getAddr(), pkt->isSecure(), tag_latency);
949
940 // Calculate access latency on top of when the packet arrives. This
941 // takes into account the bus delay.
942 lat = calculateAccessLatency(blk, pkt->headerDelay,
943 tag_latency);
944
945 DPRINTF(Cache, "%s for %s %s\n", __func__, pkt->print(),
946 blk ? "hit " + blk->print() : "miss");
947
948 if (pkt->req->isCacheMaintenance()) {
949 // A cache maintenance operation is always forwarded to the
950 // memory below even if the block is found in dirty state.
951
952 // We defer any changes to the state of the block until we
953 // create and mark as in service the mshr for the downstream
954 // packet.
950 DPRINTF(Cache, "%s for %s %s\n", __func__, pkt->print(),
951 blk ? "hit " + blk->print() : "miss");
952
953 if (pkt->req->isCacheMaintenance()) {
954 // A cache maintenance operation is always forwarded to the
955 // memory below even if the block is found in dirty state.
956
957 // We defer any changes to the state of the block until we
958 // create and mark as in service the mshr for the downstream
959 // packet.
960
961 // Calculate access latency on top of when the packet arrives. This
962 // takes into account the bus delay.
963 lat = calculateTagOnlyLatency(pkt->headerDelay, tag_latency);
964
955 return false;
956 }
957
958 if (pkt->isEviction()) {
959 // We check for presence of block in above caches before issuing
960 // Writeback or CleanEvict to write buffer. Therefore the only
961 // possible cases can be of a CleanEvict packet coming from above
962 // encountering a Writeback generated in this cache peer cache and

--- 13 unchanged lines hidden (view full) ---

976 // peer caches of the same level while traversing the
977 // crossbar. If a copy of the block is found, the
978 // packet is deleted in the crossbar. Hence, none of
979 // the other upper level caches connected to this
980 // cache have the block, so we can clear the
981 // BLOCK_CACHED flag in the Writeback if set and
982 // discard the CleanEvict by returning true.
983 wbPkt->clearBlockCached();
965 return false;
966 }
967
968 if (pkt->isEviction()) {
969 // We check for presence of block in above caches before issuing
970 // Writeback or CleanEvict to write buffer. Therefore the only
971 // possible cases can be of a CleanEvict packet coming from above
972 // encountering a Writeback generated in this cache peer cache and

--- 13 unchanged lines hidden (view full) ---

986 // peer caches of the same level while traversing the
987 // crossbar. If a copy of the block is found, the
988 // packet is deleted in the crossbar. Hence, none of
989 // the other upper level caches connected to this
990 // cache have the block, so we can clear the
991 // BLOCK_CACHED flag in the Writeback if set and
992 // discard the CleanEvict by returning true.
993 wbPkt->clearBlockCached();
994
995 // A clean evict does not need to access the data array
996 lat = calculateTagOnlyLatency(pkt->headerDelay, tag_latency);
997
984 return true;
985 } else {
986 assert(pkt->cmd == MemCmd::WritebackDirty);
987 // Dirty writeback from above trumps our clean
988 // writeback... discard here
989 // Note: markInService will remove entry from writeback buffer.
990 markInService(wb_entry);
991 delete wbPkt;

--- 9 unchanged lines hidden (view full) ---

1001 // we could get a clean writeback while we are having
1002 // outstanding accesses to a block, do the simple thing for
1003 // now and drop the clean writeback so that we do not upset
1004 // any ordering/decisions about ownership already taken
1005 if (pkt->cmd == MemCmd::WritebackClean &&
1006 mshrQueue.findMatch(pkt->getAddr(), pkt->isSecure())) {
1007 DPRINTF(Cache, "Clean writeback %#llx to block with MSHR, "
1008 "dropping\n", pkt->getAddr());
998 return true;
999 } else {
1000 assert(pkt->cmd == MemCmd::WritebackDirty);
1001 // Dirty writeback from above trumps our clean
1002 // writeback... discard here
1003 // Note: markInService will remove entry from writeback buffer.
1004 markInService(wb_entry);
1005 delete wbPkt;

--- 9 unchanged lines hidden (view full) ---

1015 // we could get a clean writeback while we are having
1016 // outstanding accesses to a block, do the simple thing for
1017 // now and drop the clean writeback so that we do not upset
1018 // any ordering/decisions about ownership already taken
1019 if (pkt->cmd == MemCmd::WritebackClean &&
1020 mshrQueue.findMatch(pkt->getAddr(), pkt->isSecure())) {
1021 DPRINTF(Cache, "Clean writeback %#llx to block with MSHR, "
1022 "dropping\n", pkt->getAddr());
1023
1024 // A writeback searches for the block, then writes the data.
1025 // As the writeback is being dropped, the data is not touched,
1026 // and we just had to wait for the time to find a match in the
1027 // MSHR. As of now assume a mshr queue search takes as long as
1028 // a tag lookup for simplicity.
1029 lat = calculateTagOnlyLatency(pkt->headerDelay, tag_latency);
1030
1009 return true;
1010 }
1011
1012 if (!blk) {
1013 // need to do a replacement
1014 blk = allocateBlock(pkt, writebacks);
1015 if (!blk) {
1016 // no replaceable block available: give up, fwd to next level.
1017 incMissCount(pkt);
1031 return true;
1032 }
1033
1034 if (!blk) {
1035 // need to do a replacement
1036 blk = allocateBlock(pkt, writebacks);
1037 if (!blk) {
1038 // no replaceable block available: give up, fwd to next level.
1039 incMissCount(pkt);
1040
1041 // A writeback searches for the block, then writes the data.
1042 // As the block could not be found, it was a tag-only access.
1043 lat = calculateTagOnlyLatency(pkt->headerDelay, tag_latency);
1044
1018 return false;
1019 }
1020
1021 blk->status |= BlkReadable;
1022 }
1023 // only mark the block dirty if we got a writeback command,
1024 // and leave it as is for a clean writeback
1025 if (pkt->cmd == MemCmd::WritebackDirty) {

--- 12 unchanged lines hidden (view full) ---

1038 DPRINTF(Cache, "%s new state is %s\n", __func__, blk->print());
1039 incHitCount(pkt);
1040
1041 // When the packet metadata arrives, the tag lookup will be done while
1042 // the payload is arriving. Then the block will be ready to access as
1043 // soon as the fill is done
1044 blk->setWhenReady(clockEdge(fillLatency) + pkt->headerDelay +
1045 std::max(cyclesToTicks(tag_latency), (uint64_t)pkt->payloadDelay));
1045 return false;
1046 }
1047
1048 blk->status |= BlkReadable;
1049 }
1050 // only mark the block dirty if we got a writeback command,
1051 // and leave it as is for a clean writeback
1052 if (pkt->cmd == MemCmd::WritebackDirty) {

--- 12 unchanged lines hidden (view full) ---

1065 DPRINTF(Cache, "%s new state is %s\n", __func__, blk->print());
1066 incHitCount(pkt);
1067
1068 // When the packet metadata arrives, the tag lookup will be done while
1069 // the payload is arriving. Then the block will be ready to access as
1070 // soon as the fill is done
1071 blk->setWhenReady(clockEdge(fillLatency) + pkt->headerDelay +
1072 std::max(cyclesToTicks(tag_latency), (uint64_t)pkt->payloadDelay));
1073
1074 // A writeback searches for the block, then writes the data
1075 lat = calculateAccessLatency(blk, pkt->headerDelay, tag_latency);
1076
1046 return true;
1047 } else if (pkt->cmd == MemCmd::CleanEvict) {
1077 return true;
1078 } else if (pkt->cmd == MemCmd::CleanEvict) {
1079 // A CleanEvict does not need to access the data array
1080 lat = calculateTagOnlyLatency(pkt->headerDelay, tag_latency);
1081
1048 if (blk) {
1049 // Found the block in the tags, need to stop CleanEvict from
1050 // propagating further down the hierarchy. Returning true will
1051 // treat the CleanEvict like a satisfied write request and delete
1052 // it.
1053 return true;
1054 }
1055 // We didn't find the block here, propagate the CleanEvict further

--- 5 unchanged lines hidden (view full) ---

1061 // WriteClean handling is a special case. We can allocate a
1062 // block directly if it doesn't exist and we can update the
1063 // block immediately. The WriteClean transfers the ownership
1064 // of the block as well.
1065 assert(blkSize == pkt->getSize());
1066
1067 if (!blk) {
1068 if (pkt->writeThrough()) {
1082 if (blk) {
1083 // Found the block in the tags, need to stop CleanEvict from
1084 // propagating further down the hierarchy. Returning true will
1085 // treat the CleanEvict like a satisfied write request and delete
1086 // it.
1087 return true;
1088 }
1089 // We didn't find the block here, propagate the CleanEvict further

--- 5 unchanged lines hidden (view full) ---

1095 // WriteClean handling is a special case. We can allocate a
1096 // block directly if it doesn't exist and we can update the
1097 // block immediately. The WriteClean transfers the ownership
1098 // of the block as well.
1099 assert(blkSize == pkt->getSize());
1100
1101 if (!blk) {
1102 if (pkt->writeThrough()) {
1103 // A writeback searches for the block, then writes the data.
1104 // As the block could not be found, it was a tag-only access.
1105 lat = calculateTagOnlyLatency(pkt->headerDelay, tag_latency);
1106
1069 // if this is a write through packet, we don't try to
1070 // allocate if the block is not present
1071 return false;
1072 } else {
1073 // a writeback that misses needs to allocate a new block
1074 blk = allocateBlock(pkt, writebacks);
1075 if (!blk) {
1076 // no replaceable block available: give up, fwd to
1077 // next level.
1078 incMissCount(pkt);
1107 // if this is a write through packet, we don't try to
1108 // allocate if the block is not present
1109 return false;
1110 } else {
1111 // a writeback that misses needs to allocate a new block
1112 blk = allocateBlock(pkt, writebacks);
1113 if (!blk) {
1114 // no replaceable block available: give up, fwd to
1115 // next level.
1116 incMissCount(pkt);
1117
1118 // A writeback searches for the block, then writes the
1119 // data. As the block could not be found, it was a tag-only
1120 // access.
1121 lat = calculateTagOnlyLatency(pkt->headerDelay,
1122 tag_latency);
1123
1079 return false;
1080 }
1081
1082 blk->status |= BlkReadable;
1083 }
1084 }
1085
1086 // at this point either this is a writeback or a write-through

--- 12 unchanged lines hidden (view full) ---

1099 incHitCount(pkt);
1100
1101 // When the packet metadata arrives, the tag lookup will be done while
1102 // the payload is arriving. Then the block will be ready to access as
1103 // soon as the fill is done
1104 blk->setWhenReady(clockEdge(fillLatency) + pkt->headerDelay +
1105 std::max(cyclesToTicks(tag_latency), (uint64_t)pkt->payloadDelay));
1106
1124 return false;
1125 }
1126
1127 blk->status |= BlkReadable;
1128 }
1129 }
1130
1131 // at this point either this is a writeback or a write-through

--- 12 unchanged lines hidden (view full) ---

1144 incHitCount(pkt);
1145
1146 // When the packet metadata arrives, the tag lookup will be done while
1147 // the payload is arriving. Then the block will be ready to access as
1148 // soon as the fill is done
1149 blk->setWhenReady(clockEdge(fillLatency) + pkt->headerDelay +
1150 std::max(cyclesToTicks(tag_latency), (uint64_t)pkt->payloadDelay));
1151
1152 // A writeback searches for the block, then writes the data
1153 lat = calculateAccessLatency(blk, pkt->headerDelay, tag_latency);
1154
1107 // if this a write-through packet it will be sent to cache
1108 // below
1109 return !pkt->writeThrough();
1110 } else if (blk && (pkt->needsWritable() ? blk->isWritable() :
1111 blk->isReadable())) {
1112 // OK to satisfy access
1113 incHitCount(pkt);
1114 satisfyRequest(pkt, blk);
1115 maintainClusivity(pkt->fromCache(), blk);
1116
1155 // if this a write-through packet it will be sent to cache
1156 // below
1157 return !pkt->writeThrough();
1158 } else if (blk && (pkt->needsWritable() ? blk->isWritable() :
1159 blk->isReadable())) {
1160 // OK to satisfy access
1161 incHitCount(pkt);
1162 satisfyRequest(pkt, blk);
1163 maintainClusivity(pkt->fromCache(), blk);
1164
1165 // Calculate access latency based on the need to access the data array
1166 if (pkt->isRead() || pkt->isWrite()) {
1167 lat = calculateAccessLatency(blk, pkt->headerDelay, tag_latency);
1168 } else {
1169 lat = calculateTagOnlyLatency(pkt->headerDelay, tag_latency);
1170 }
1171
1117 return true;
1118 }
1119
1120 // Can't satisfy access normally... either no block (blk == nullptr)
1121 // or have block but need writable
1122
1123 incMissCount(pkt);
1124
1172 return true;
1173 }
1174
1175 // Can't satisfy access normally... either no block (blk == nullptr)
1176 // or have block but need writable
1177
1178 incMissCount(pkt);
1179
1180 lat = calculateAccessLatency(blk, pkt->headerDelay, tag_latency);
1181
1125 if (!blk && pkt->isLLSC() && pkt->isWrite()) {
1126 // complete miss on store conditional... just give up now
1127 pkt->req->setExtraData(0);
1128 return true;
1129 }
1130
1131 return false;
1132}

--- 1334 unchanged lines hidden ---
1182 if (!blk && pkt->isLLSC() && pkt->isWrite()) {
1183 // complete miss on store conditional... just give up now
1184 pkt->req->setExtraData(0);
1185 return true;
1186 }
1187
1188 return false;
1189}

--- 1334 unchanged lines hidden ---