Monday, June 29, 2020

More bugs in the i4004 CPU emulation

I knew there was at least one lingering bug in the emulated i4004 CPU because I didn't see the contents of the OPA "register" output on the data bus during the X1 subcycle. But apparently the problems are bigger than that.

In my all-in test of the Busicom 141‑PF reconstruction, I noted several problems. To try and isolate the problem to one of the four emulated MCS-4 chips I decided I needed to test each of the emulated chips separately, starting with the i4001 ROM.

When I wrote the behavioral simulation testbench for the i4001 emulation, I took code from the i4004's bus interface so the bus interface signals would behave as realistically as possible. This, and much of the test code behind it, is synthesizable, so I grafted it into a test top module. The behavior observed in the real Spartan-6 matched both the simulated output and the data sheets.

Next came the i4004 CPU. After pondering the problem for a while I decided the best thing to do was just let the thing run with nothing connected to the data bus. Since I'd observed zeros when I expected ones, I connected the i4004's data bus interface directly to the debug ports. These are physical pins on the FPGA wired directly to a 40-pin header and connected to my logic analyzer using a ribbon cable.

By running the test once with the FPGA's weak pull-ups enabled, and then again with the weak pull-downs enabled, I'm able to determine when the data bus is being driven by the CPU and when it is floating. It appears the CPU is controlling the direction correctly:
  • The CPU drives the bus in A1/A2/A3 and X1/X3.
  • The CPU floats the bus in M1/M2 and X2.
I found one electrical problem on my board: when debug signal D28 is floating it tends to follow D31. These two signals are on adjacent pins on the FPGA, and may have a high-resistance connection between them. They do not seem to influence each other when both are driven strongly so it's unlikely to be a hard short.

However, I also noted behaviors that make it clear there are problems in the CPU emulation:
  • The instruction pointer value output during the A1/A2/A3 subcycles did not increment from one instruction cycle to the next. The address output is always 12'h000.
  • The OPA register value does not appear on the bus during the X1 subcycle; I see 4'b1111 instead. This was a known problem but I never looked into it because nothing uses this value.
  • Behavioral simulations indicate the CMROM output goes invalid during the M2 and X2 subcycles when it should output a zero.

There are seven synthesis warnings about combinatorial loops in the instruction pointer and scratchpad modules of the CPU. This didn't appear to cause problems in the Spartan-3E, but maybe I just got lucky.

I just ran a post-P&R simulation and I'm seeing a similar issue with the instruction address always being zero on the data bus during A1/A2/A3.  Maybe this will let me avoid having to debug this in the hardware. But that will have to wait for another evening.

No comments:

Post a Comment