Skip to content

Commit adaeb07

Browse files
committed
refactor(SBuffer, StoreDifftest): move diff store
event calculate part from scala to cpp BREAKING CHANGE: struct DifftestStoreEvent is changed and broke backward compatibility!
1 parent 7b5fc3b commit adaeb07

File tree

2 files changed

+98
-15
lines changed

2 files changed

+98
-15
lines changed

src/main/scala/Bundles.scala

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -245,16 +245,23 @@ class UncacheMMStoreEvent extends DifftestBaseBundle with HasValid {
245245
}
246246

247247
class StoreEvent extends DifftestBaseBundle with HasValid {
248-
val addr = UInt(64.W)
249-
val data = UInt(64.W)
250-
val highData = UInt(64.W)
251-
val mask = UInt(16.W)
252248
val wLine = Bool()
253-
val vecNeedSplit = Bool()
254-
val eew = UInt(8.W)
255249
val offset = UInt(16.W)
256250
val pc = UInt(64.W)
257251
val robidx = UInt(10.W)
252+
253+
val isNonCacheable = Bool()
254+
val isVStore = Bool()
255+
val isUStride = Bool()
256+
val isMasked = Bool()
257+
val isWhole = Bool()
258+
val veew = UInt(8.W)
259+
val nf = UInt(8.W)
260+
val rawDataLow = UInt(64.W)
261+
val rawDataHigh = UInt(64.W)
262+
val rawMask = UInt(16.W)
263+
val rawAddr = UInt(64.W)
264+
val isHighPart = Bool()
258265
}
259266

260267
class LoadEvent extends DifftestBaseBundle with HasValid {

src/test/csrc/difftest/checkers/store.cpp

Lines changed: 85 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,13 @@ void StoreRecorder::clear_valid(DifftestStoreEvent &probe) {
2727
probe.valid = 0;
2828
}
2929

30+
// Expand 8-bit mask to bit-and with 64-bit wide data
31+
static uint64_t MaskExpand(uint8_t mask) {
32+
uint64_t expander = 0x0101010101010101ULL;
33+
uint64_t selector = 0x8040201008040201ULL;
34+
return (((((mask * expander) & selector) * 0xFFULL) >> 7) & expander) * 0xFFULL;
35+
}
36+
3037
int StoreRecorder::check(const DifftestStoreEvent &probe) {
3138
if (!probe.valid)
3239
return STATE_OK;
@@ -35,18 +42,87 @@ int StoreRecorder::check(const DifftestStoreEvent &probe) {
3542
int WORDBYTES = 8;
3643
int COMMITBYTES = 16;
3744

38-
auto addr = probe.addr;
39-
auto lowData = probe.data;
40-
auto highData = probe.highData;
41-
auto mask = probe.mask;
45+
uint64_t calcAddr;
46+
uint64_t calcDataLow;
47+
uint64_t calcDataHigh;
48+
uint16_t calcMask;
49+
uint8_t calcEEW;
50+
bool calcIsVSLine;
51+
52+
auto isNonCacheable = probe.isNonCacheable;
53+
auto isVStore = probe.isVStore;
54+
auto isUStride = probe.isUStride;
55+
auto isMasked = probe.isMasked;
56+
auto isWhole = probe.isWhole;
57+
auto veew = probe.veew;
58+
auto nf = probe.nf;
59+
auto rawDataLow = probe.rawDataLow;
60+
auto rawDataHigh = probe.rawDataHigh;
61+
auto rawMask = probe.rawMask;
62+
auto rawAddr = probe.rawAddr;
63+
auto wLine = probe.wLine;
64+
auto isHighPart = probe.isHighPart;
65+
66+
if (!isNonCacheable) {
67+
bool isVse = isVStore && isUStride;
68+
bool isVsm = isVStore && isMasked;
69+
bool isVsr = isVStore && isWhole;
70+
71+
uint8_t eew = veew;
72+
uint32_t EEB = 1 << eew;
73+
uint8_t nf2 = isVsr ? 0 : nf;
74+
75+
bool isSegment = nf2 != 0 && !isVsm;
76+
bool isVSLine = (isVse || isVsm || isVsr) && !isSegment;
77+
bool isWline = wLine;
78+
calcIsVSLine = isVSLine;
79+
80+
if (isVSLine) {
81+
calcAddr = rawAddr;
82+
calcDataLow = rawDataLow;
83+
calcDataHigh = rawDataHigh;
84+
calcMask = rawMask;
85+
} else if (isWline) {
86+
calcAddr = rawAddr;
87+
calcDataLow = rawDataLow;
88+
calcDataHigh = rawDataHigh;
89+
calcMask = rawMask;
90+
Assert(rawDataLow == 0 && rawDataHigh == 0, "wLine only supports whole zero write now");
91+
} else if (isHighPart) {
92+
calcAddr = (rawAddr & (~0xFULL)) | 0b1000;
93+
calcMask = (rawMask >> 8) & 0xFF;
94+
uint64_t tmpData = rawDataHigh;
95+
calcDataLow = tmpData & MaskExpand(calcMask);
96+
calcDataHigh = 0;
97+
} else {
98+
calcAddr = rawAddr & (~0xFULL);
99+
calcMask = rawMask & 0xFF;
100+
uint64_t tmpData = rawDataLow;
101+
calcDataLow = tmpData & MaskExpand(calcMask);
102+
calcDataHigh = 0;
103+
}
104+
calcEEW = EEB;
105+
} else {
106+
calcAddr = rawAddr & (~7ULL);
107+
calcMask = rawMask;
108+
calcDataLow = rawDataLow & MaskExpand(calcMask);
109+
calcDataHigh = 0;
110+
calcEEW = 0;
111+
calcIsVSLine = false;
112+
}
113+
114+
auto addr = calcAddr;
115+
auto lowData = calcDataLow;
116+
auto highData = calcDataHigh;
117+
auto mask = calcMask;
42118
auto offset = probe.offset;
43-
auto eew = probe.eew;
119+
auto eew = calcEEW;
44120
auto pc = probe.pc;
45121
auto robIdx = probe.robidx;
46122

47123
uint64_t rawVecAddr = addr + offset;
48124

49-
if (probe.vecNeedSplit) {
125+
if (calcIsVSLine) {
50126
uint16_t flow = COMMITBYTES / eew;
51127
uint64_t flowMask = (eew == 1) ? 0x1ULL : (eew == 2) ? 0x3ULL : (eew == 4) ? 0xfULL : (eew == 8) ? 0xffULL : 0x0ULL;
52128
uint64_t flowMaskBit = (eew == 1) ? 0xffULL
@@ -103,7 +179,7 @@ int StoreRecorder::check(const DifftestStoreEvent &probe) {
103179

104180
nextOffset = 8 - rawOffset;
105181
auto nextDataOffset = nextOffset * 8;
106-
auto nextData = probe.highData << nextDataOffset;
182+
auto nextData = calcDataHigh << nextDataOffset;
107183

108184
refStoreCommitData = (nextData + presentData) & flowMaskBit;
109185
} else {
@@ -145,9 +221,9 @@ int StoreRecorder::check(const DifftestStoreEvent &probe) {
145221
}
146222
} else {
147223
DiffState::StoreCommit storeCommit = {probe.valid,
148-
probe.addr,
224+
calcAddr,
149225
lowData,
150-
static_cast<uint8_t>(probe.mask & 0xFF),
226+
static_cast<uint8_t>(calcMask & 0xFF),
151227
pc,
152228
robIdx
153229
#ifdef CONFIG_DIFFTEST_SQUASH

0 commit comments

Comments
 (0)