Debugging decrement bugs
Posted on Thu 24 October 2024 in MUPS16
Since I added the hacked up display module, I've noticed an issue that's cropped up a few times. Since I haven't properly implemented reading the status register from the LCD controller yet, I've had to put small delay loops between character writes to avoid sending data too quickly. These are just a simple asm sequence:
.lcd_delay:
liw r1, 255
addi r1, r1, -1
bnz r1, .lcd_delay
This is very crude, but adds enough delay at the slow clock speed I'm running it right now. The problem is that sometimes, addi, r1, r1, -1 ends up adding some small number. I haven't worked out why.
Notes:
not 100% consistent, but happens often enough that we get stuck in infinite delay loops (i.e. once it starts happening it won't stop of its own accord)
first thought was bus contention on the data bus, but nothing obvious on the voltage levels of the data bus feeding back into the register unit
added collection of data, bus_a and bus_b on every step in debugger, and this shows the problem:
0x00ea 01 3f addi r1, r1, -1 Step 0 data: 0x0000 bus_a: 0x00ea bus_b: 0x0000 # Map address Step 1 data: 0x013f bus_a: 0x0000 bus_b: 0x0000 # Read instruction word Step 2 data: 0x00fb bus_a: 0x00fc bus_b: 0xffff # r1 = r1 - 1 0x00ec b9 fe bnz r1, -4 Step 0 data: 0x0000 bus_a: 0x00ec bus_b: 0x0000 # Map address Step 1 data: 0xb9fe bus_a: 0x0000 bus_b: 0x0000 # Read instruction word Step 2 data: 0x0000 bus_a: 0x00fb bus_b: 0x0000 # Compare r1 == 0 Step 3 data: 0x00ea bus_a: 0x00ee bus_b: 0xfffc # Branch to 0xea if not 0x00ea 01 3f addi r1, r1, -1 Step 0 data: 0x0000 bus_a: 0x00ea bus_b: 0x0000 # Map address Step 1 data: 0x013f bus_a: 0x0000 bus_b: 0x0000 # Read instruction word Step 2 data: 0x00fd bus_a: 0x00fe bus_b: 0xffff # r1 = r1 -1
We add -1 to 0xfc and get 0xfb on the data bus (correct), and save that to r1. We then output r1 to bus_a in the bnz instruction, and that shows 0xfb (correct). We take the jump, but now when the register unit outputs r1 we see 0xfe. What happened? Somehow between step 2 of the bnz instruction and step 2 of the addi instruction we overwrote the contents of the register. At no point between those points did we see 0xfe on the data bus, so it doesn't feel like a transient set line going low or something like that.