Skip to content

Commit 42d6a02

Browse files
authored
Increase CycleElement lookback for Cycles UI (#306)
* Add (failing) unit test for UI bug in #304 * Remove max cycles checks in E2E tests The timeouts are a more elegant way of achieving the same goal. * Increase CycleElement lookback This fixes #304, but may not work in all cases. * Remove unused variable * Add check for valid cycles at runtime It only emits a SEVERE log statement.
1 parent 71d1d59 commit 42d6a02

File tree

4 files changed

+86
-22
lines changed

4 files changed

+86
-22
lines changed

src/main/java/org/edumips64/ui/swing/CPUSwingWorker.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,13 @@ private synchronized void haltCPU() {
128128
logger.info("Halting the CPU.");
129129
front.updateComponents();
130130
cpu.setStatus(CPU.CPUStatus.HALTED);
131+
132+
// Check if the transactions in the CycleBuilder are all valid.
133+
for (CycleElement el : builder.getElementsList()) {
134+
if (!el.isValid()) {
135+
logger.severe("Invalid CycleElement for instruction " + el.getName());
136+
}
137+
}
131138
haltCallback.run();
132139
}
133140

src/main/java/org/edumips64/utils/CycleBuilder.java

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,10 +97,18 @@ public void step() {
9797
// View into the last N elements of the list. This list is used to search for CycleElements
9898
// corresponding to a given instruction in the getElementToUpdate() method.
9999
//
100+
// N is equal to the number of instructions in the pipeline plus the magic number 11, which represents
101+
// the maximum number of stages an instruction will traverse from IF to WB.
102+
//
103+
// TODO: this is not a permanent fix, as there is still potential for bugs if an instruction gets stuck in
104+
// the pipeline for too long (which may happen in case of MEM stalls, since the FP pipelines and EX have a
105+
// deterministic precedence ordering. A permanent fix would probably look into the maximum age of the instructions
106+
// in the pipeline and do something to enforce that ordering in the list of CycleElements.
107+
//
100108
// The max() statement is needed to avoid negative indexing (and therefore errors), in the case when the
101109
// size of the list of elements is smaller than the number of stages in the pipeline, which happens in the
102110
// first cycles of a program.
103-
int lookback = Math.max(elementsList.size() - instrInPipelineCount, 0);
111+
int lookback = Math.max(elementsList.size() - (instrInPipelineCount + 11), 0);
104112
lastElements = new ArrayList<>(elementsList.subList(lookback, elementsList.size()));
105113

106114
// If there are multiple elements for a given instruction (e.g., a fetched instruction that will not run)

src/test/java/org/edumips64/EndToEndTests.java

Lines changed: 12 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -143,27 +143,21 @@ public void testTearDown() {
143143
* @param testPath path of the test code.
144144
*/
145145
private CpuTestStatus runMipsTest(String testPath) throws Exception {
146-
return runMipsTest(testPath, false, 0);
146+
return runMipsTest(testPath, false);
147147
}
148148

149149
// Version of runMipsTest that allows to specify whether to write a trace file.
150150
// Writing the trace file can unnecessarily slow down the tests, so by default they are not written (see previous
151151
// override of this method).
152-
//
153-
// maxCycles is the maximum number of cycles to allow being executed before considering
154-
// the test failed. Necessary for test cases for bugs that throw the CPU in an infinite loop,
155-
// such as for example disappearing instructions that set a read/write semaphore, making
156-
// it impossible to test their values. If > 0, an exception will be thrown.
157-
private CpuTestStatus runMipsTest(String testPath, boolean writeTracefile, int maxCycles) throws Exception {
152+
private CpuTestStatus runMipsTest(String testPath, boolean writeTracefile) throws Exception {
158153
log.warning("================================= Starting test " + testPath + " (forwarding: " +
159-
config.getBoolean(ConfigKey.FORWARDING) + ") (max cycles: " + maxCycles + ")");
154+
config.getBoolean(ConfigKey.FORWARDING)+ ")");
160155
cpu.reset();
161156
dinero.reset();
162157
symTab.reset();
163158
builder.reset();
164159
testPath = testsLocation + testPath;
165160
String tracefile = null;
166-
int curCycles = 0;
167161

168162
try {
169163
try {
@@ -181,11 +175,6 @@ private CpuTestStatus runMipsTest(String testPath, boolean writeTracefile, int m
181175
cpu.setStatus(CPU.CPUStatus.RUNNING);
182176

183177
while (true) {
184-
curCycles++;
185-
if (maxCycles > 0 && curCycles > maxCycles) {
186-
log.severe("Exceeded maximum number of cycles allowed: " + maxCycles);
187-
throw new HaltException();
188-
}
189178
cpu.step();
190179
builder.step();
191180
}
@@ -202,11 +191,6 @@ private CpuTestStatus runMipsTest(String testPath, boolean writeTracefile, int m
202191
w.close();
203192
}
204193

205-
// Check if the execution exceeded the maximum allowed number of cycles.
206-
if (maxCycles > 0 && curCycles > maxCycles) {
207-
throw new TestTookTooLongException();
208-
}
209-
210194
// Check if the transactions in the CycleBuilder are all valid.
211195
boolean allValid = true;
212196
for (CycleElement el : builder.getElementsList()) {
@@ -258,7 +242,7 @@ private void runForwardingTest(String path, int expected_cycles_with_forwarding,
258242
}
259243

260244
private void runTestAndCompareTracefileWithGolden(String path) throws Exception {
261-
CpuTestStatus status = runMipsTest(path, true, 0);
245+
CpuTestStatus status = runMipsTest(path, true);
262246
String goldenTrace = testsLocation + path + ".xdin.golden";
263247

264248
String golden, trace;
@@ -615,6 +599,13 @@ public void testLdLargeImmediate() throws Exception {
615599
*/
616600
@Test(timeout=2000)
617601
public void testIssue304() throws Exception {
618-
runMipsTest("issue304.s", false, 30);
602+
runMipsTest("issue304.s", false);
603+
}
604+
605+
/* Issue #304: Missing MEM/WB in Cycles UI for some FPU instructions.
606+
*/
607+
@Test(timeout=2000)
608+
public void testIssue304UI() throws Exception {
609+
runMipsTest("infinite-bug-304.s", false);
619610
}
620611
}
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
;--------------------------------------------------------------------------
2+
;
3+
;
4+
; THIS CODE demonstrates an apparent bug in EDUMIPS.
5+
; Tested using EduMIPS64 v1.2.6 (standalone) and v1.2.5
6+
;
7+
;--------------------------------------------------------------------------
8+
.data ; start of data space
9+
10+
scalara: .double -3.7 ; first scalar
11+
scalarb: .double 5.1 ; second scalar
12+
vectorX: .double -5.78;
13+
vectorXnext: .double 10.26;
14+
vectorXnext2: .double -1.9, 0.001, 3.002, -1257.72, 1009.235, 899.0001, 9.9999, 0.000, -30.567, -10020.5 ; first vector
15+
vectorY: .double -4.88;
16+
vectorYnext: .double 202.21;
17+
vectorYnext2: .double 31.8, -206.112, 100.7, -88.12, 0.77, 10031.4, -3.02, 0.000, 15.5, 622.80 ; second vector
18+
vectorZ: .space 96 ; space set aside for result
19+
20+
;--------------------------------------------------------------------------
21+
; CODE SPACE
22+
;--------------------------------------------------------------------------
23+
.text ; start of code space
24+
25+
main:
26+
L.D f1, scalara(r0)
27+
L.D f2, scalarb(r0)
28+
DADDI r3, r0, 0
29+
30+
DADDI r1, r0, #88 ;
31+
32+
L.D f3, vectorX(r3)
33+
L.D f4, vectorY(r3)
34+
MUL.D f5, f1, f3
35+
MUL.D f6, f2, f4
36+
37+
L.D f3, vectorXnext(r3)
38+
L.D f4, vectorYnext(r3)
39+
40+
ADD.D f7, f5, f6
41+
42+
MUL.D f5, f1, f3 ; THIS INSTRUCTION'S WB HAPPENS, but the CYCLE WINDOW does not show the MEM and WB stages.
43+
MUL.D f6, f2, f4 ; THIS INSTRUCTION'S WB HAPPENS, but the CYCLE WINDOW does not show the M7, MEM and WB stages.
44+
45+
loop: S.D f7, vectorZ(r3)
46+
47+
L.D f3, vectorXnext2(r3)
48+
L.D f4, vectorYnext2(r3)
49+
;DADDI r5, r0, 0 ; DUMMY INSTRUCTION INSERTED TO CIRCUMVENT BUG.
50+
ADDI r3, r3, 8 ; THIS INSTRUCTION'S WB NEVER HAPPENS. CYCLE WINDOW shows no MEM OR WB stages.
51+
ADD.D f7, f5, f6
52+
MUL.D f5, f1, f3
53+
MUL.D f6, f2, f4
54+
BNE r3, r1, loop ; CONSEQUENTLY, THIS INSTRUCTION INFINITELY RAW STALLS.
55+
56+
SYSCALL 0
57+
58+

0 commit comments

Comments
 (0)