MMU board soldered, and debugged

Posted on Tue 01 September 2020 in MUPS16

I finally put together the MMU, the fourth of the seven PCBs that arrived in my August batch. A couple of things were obvious right off the bat: 1. I'd somehow screwed up the silkscreening, and all the text labels for the current MMU mode on the left of the board were missing. I've no idea how this happened: the text is on the correct layer in Kicad and it's visible, but somehow it's missing from the Gerbers. It's annoying, but not a fatal error. 2. More frustratingly, I'd messed up the location of the second A-bus connection, and it didn't line up with the connections on the backplane below. I think this was because I have generally laid out my boards using a metric grid for the outlines and connectors (because I want a nice straightforward 20cm x 5cm board), but used an imperial grid for the tracks and components, because the components pins are (almost) all using imperial pitches. I think I probably accidentally left the grid on imperial when I moved that one connector, and it snapped about a millimeter off to the right.

Debugging

MapAddr LED not lighting up

Setting the mode to MapAddr when in boot mode doesn't cause the first LED to light up. This was easy to diagnose just by looking at the schematic:

The LED is connected to the MAP_ADDR signal, which is meant to indicate that we should be doing a full mapping using the page tables. It should have been tied directly to pin 1 of the demux.

This is actually a much bigger problem than just the LED not lighting up, however. I made the same mistake on the other end of the board, where the signal that causes the latches that drive the physical address bus to store the current value was also tied to this MAP_ADDR signal, instead of the raw mux output. This means that boot mode is effectively useless, as the latches will never store the mapped address, and hence the next cycle when the address is output to the physical address bus it will always be whatever was in the latches on startup. Not good. This might be fixable with the usual knife and bodge wire, if I can find a good place to patch it in (the wiring on this board is a bit more dense than most of the others, so it's harder to find a spot where a signal has no neighbouring wires to worry about accidentally cutting).

Table entry and index reading half-zeros

Next up I tried writing an entry to the page tables and reading it back. This wasn't very successful. Whatever I wrote, I was getting back completely zero permissions, and my physical page mappings were completely wrong. When I turned on debugging in my Arduino debug server, I could see that I was reading mostly correct values, but they were completely wrong when they made it back to the Python shell:

Remote: b'read data for pin 0x26:047 (39) as 1'
Remote: b'read data for pin 0x26:046 (38) as 1'
Remote: b'read data for pin 0x26:045 (37) as 1'
Remote: b'read data for pin 0x26:044 (36) as 1'
Remote: b'read data for pin 0x26:043 (35) as 1'
Remote: b'read data for pin 0x26:042 (34) as 1'
Remote: b'read data for pin 0x26:041 (33) as 0'
Remote: b'read data for pin 0x26:040 (32) as 0'
Remote: b'read data for pin 0x26:037 (31) as 1'
Remote: b'read data for pin 0x26:036 (30) as 1'
Remote: b'read data for pin 0x26:035 (29) as 1'
Remote: b'read data for pin 0x26:034 (28) as 1'
Remote: b'read data for pin 0x26:033 (27) as 1'
Remote: b'read data for pin 0x26:032 (26) as 1'
Remote: b'read data for pin 0x26:031 (25) as 0'
Remote: b'read data for pin 0x26:030 (24) as 0'
...
Mapped: 0, Sys: 0, Writable: 0, Physical Page: 0x003f

This was consistent: whatever I wrote as the physical page, I'd get back a sligtly mangled version of the bottom half of that address, but with the top half completely empty. Since it looked like the board was outputting something at least partly correct the problem was more likely in my software on the Arduino that was handling the I2C to serial conversion. Sure enough, I'd got an off-by-one error in the code that packed the result into bytes to send over the Serial connection, so the top byte was always missed.

Table entry bits 6, 7, 14 and 15 are always zero

Table entry output changes on second read

It took me a while to realise this, as I was generally setting a value, then reading it back, then trying a different value, to look for patterns, but eventually I noticed that reading a table entry twice gave very different results: first time it showed the bit pattern above, but the second time would almost always be zero.

NOTES: - voltage on the ~RAMOUT line was 0.9V on the second read - short-circuit between tableaddr 10, 11 and ~RAMOUT

Debugging diary

2020/09/02

9:05 Thought: if the issue is that the address pin(s) are shorted to ~OE, why would that affect the data? Surely it would mean that on writing we'd always have those address bits high, then on reading we'd have them low, so we'd read a different address than we wrote, but it appears that we're reading something that's at least mostly the same data we wrote. Feels more like there's a problem with the data lines too. No obvious shorts on those, though, either to each other or to ground.