Sunday, September 9, 2012

Test jig firmware

It's been a busy weekend, so I'm splitting this update into several posts.

I spent part of this weekend working on the test jig. I reacquainted myself with Verilog (the FPGA coding language I use) and whipped up a behavioral implementation of a two-phase clock generator and the i4004 timing chain.

As I mentioned before, the Spartan-3E's DCMs and PLLs won't run slowly enough to generate the i4004's clocks. Instead, I put the input from the on-board 50 MHz crystal oscillator onto a global clock line and use that to clock a divide-by-100 counter. The two clock phases' start and end points are triggered at pre-determined points in this counter's cycle. This is made more complex since I intend to drive the boards through a Microchip TC4427A clock driver, which introduces about 75ns of delay. Rather than have the timing chain outputs arrive before the signal that supposedly generated them, I generate both internal and external flavors of CLK1 and CLK2, with the external flavor being advanced by 4 counter steps (80ns). The result is that the output of the TC4427A arrives at the inter-board connector shortly before the other timing signals.

The i4004 executes instructions in eight distinct phases. During phases A1, A2, and A3, the i4004 outputs the three nibbles (4-bits) of the 12-bit instruction address. These are followed by phases M1 and M2, during which the external ROMs containing the program supply the two nibbles of the 8-bit instruction code. The last three phases, X1, X2, and X3, are used to execute the instruction.

The i4004 generates the eight signals identifying the eight execution phases from the two-phase input clock through a shift register. Its operation seems ingenious to me: the first seven phase signals are NORed together to produce the input to the shift register. Thus it will clock in zeros until the first seven bits are all zero, and only then will a one bit be clocked in. Regardless of the shift register's initial state, and with no need for special initialization circuitry, it will self-initialize within eight clock cycles.

The only non-obviousness in my implementation is that I clock all the FPGA logic with the 50 MHz oscillator input, and the CLK1 and CLK2 signals are used as clock enables. Much like in the real i4004, CLK2 enables the clocking of new inputs and CLK1 enables the clocking of the new outputs, but my implementation uses (inferred) clocked D flip-flops rather than the pass-through latches of the original. This avoids a huge range of problems I encountered when I tried to implement the circuitry in the FPGA with two clocks and latches. Too much of the i4004 depends on the inertia in floating input signals for a direct implementation.

By the time I was done I had all the appropriate timing control outputs in place. This I first simulated, then loaded it into the real Spartan-3E for a look-see with my logic analyzer. Both results match what the i4004 simulator produces, which gives me a sense of confidence.

In order to fully test the Instruction Pointer board I'll need to properly emulate a number of Instruction Decode and ALU board outputs, but for initial testing it should be sufficient to have the correct static values asserted on these lines.

No comments:

Post a Comment