From e27cb5f885366ffe7c19372d9753f8d103ec8855 Mon Sep 17 00:00:00 2001 From: Howard Mao Date: Wed, 6 Jul 2016 14:59:40 -0700 Subject: [PATCH] fix voluntary release issue in L2 cache --- scripts/check_cache_trace.py | 65 ++++++++++++++++++++++++++++++++++++ src/main/scala/Configs.scala | 1 + uncore | 2 +- 3 files changed, 67 insertions(+), 1 deletion(-) create mode 100644 scripts/check_cache_trace.py diff --git a/scripts/check_cache_trace.py b/scripts/check_cache_trace.py new file mode 100644 index 00000000..5d59faa1 --- /dev/null +++ b/scripts/check_cache_trace.py @@ -0,0 +1,65 @@ +import sys +from collections import defaultdict + +# Checks a trace of cache transactions to make sure the data is correct +# Note: this will only work if the L2 agent only receives cached traffic +# (either caching Acquires or Releases). If there are any builtin +# Put or PutBlock requests, they will not be reflected in the trace +# and the data will appear to be incorrect. + +DATA_BEATS = 8 + +def parse_prm(fname): + mem_data_bits = 0 + cache_block_bytes = 0 + with open(fname) as f: + for line in f: + line = line.strip("() \t\n") + parts = line.split(",") + if parts[0] == "MEM_DATA_BITS": + mem_data_bits = int(parts[1]) + elif parts[1] == "CACHE_BLOCK_BYTES": + cache_block_bytes = int(parts[1]) + DATA_BEATS = (cache_block_bytes * 8) / mem_data_bits + +def data_block(): + return [0] * DATA_BEATS + +blocks = defaultdict(data_block) + +def process_release(addr_block, addr_beat, data): + blocks[addr_block][addr_beat] = data + +def process_get(addr_block, addr_beat, data): + stored_data = blocks[addr_block][addr_beat] + if stored_data != data: + print("Error {:07x},{}: {:016x} != {:016x}".format( + addr_block, addr_beat, stored_data, data)) + +def process_line(line): + if not line: + return + pieces = line.split() + if pieces[0] == "[release]": + addr_block = int(pieces[1].split('=')[1], 16) + addr_beat = int(pieces[2].split('=')[1]) + data = int(pieces[3].split('=')[1], 16) + process_release(addr_block, addr_beat, data) + if pieces[0] == "[get]": + addr_block = int(pieces[1].split('=')[1], 16) + addr_beat = int(pieces[2].split('=')[1]) + data = int(pieces[3].split('=')[1], 16) + process_get(addr_block, addr_beat, data) + +def check_trace(fname): + with open(fname) as f: + for line in f: + process_line(line.strip()) + +if __name__ == "__main__": + if len(sys.argv) < 2: + print("Usage: {} trace.out [params.prm]".format(sys.argv[0])) + sys.exit(-1) + if len(sys.argv) > 2: + parse_prm(sys.argv[2]) + check_trace(sys.argv[1]) diff --git a/src/main/scala/Configs.scala b/src/main/scala/Configs.scala index 13a56beb..06168752 100644 --- a/src/main/scala/Configs.scala +++ b/src/main/scala/Configs.scala @@ -306,6 +306,7 @@ class BaseConfig extends Config ( case CacheBlockOffsetBits => log2Up(here(CacheBlockBytes)) case ConfigString => makeConfigString() case GlobalAddrMap => globalAddrMap + case EnableL2Logging => false case _ => throw new CDEMatchError }}, knobValues = { diff --git a/uncore b/uncore index d5d1e649..8d28d89b 160000 --- a/uncore +++ b/uncore @@ -1 +1 @@ -Subproject commit d5d1e649cf7e45b8d5dba5cde89c4afa77b78757 +Subproject commit 8d28d89b18b24cf3b354fab8fc5173344bc546f7