Monday, February 26, 2024

Internal data bus pre-charging

I "discovered" an interesting feature in the i4004 internal data bus management this weekend. Maybe the rest of you already discovered this, but it's new to me.

With the Scrachpad Register board working with my test program, I decided to mate it with the Instruction Pointer board I built in 2012. One of my goals was to see if the CLK1 and CLK2 circuits would ring, or if the rise and fall times are slow enough to avoid problems. To my great relief, I see no significant undershoot or overshoot on these circuits, and no ringing at all. Whew!

However, my logic analyzer showed some suspicious timing on the internal data bus. At first it wasn't clear to me what was happening, so I probed around a bit with my oscilloscope. As I was making notes of my observations I realized what was happening, and this also explained a bit of circuitry in the original chip I didn't previously understand.

Since there are many connections to the internal data bus, circuits that drive the bus see a significant capacitive load. Although all the internal data bus drivers have active pull-downs (transistors that, when turned on, will pull the circuit to ground), few have active pull-ups (I counted four). The rest only have passive pull-ups (resistors that pull the circuit to Vdd). This means that 1->0 transitions will be fast, but 0->1 transitions will be slower.

How much slower? With my logic analyzer sampling every 20ns, I saw some transitions that took as long as 500ns between entering the instruction phase when the data read begins and the output rising to 1.7V (my configured Vih threshold). That's far too long for reliable operation. So how does the real i4004 handle this?

This picture shows the schematic for the Input/Output Buffer circuit in the i4004. It's a bidirectional buffer that passes data between bit 0 of the internal data bus and the external D0 pin. There are three more such circuits just like it, one for each of the other data bus bits.

See the transistor I've highlighted? When I first looked at the i4004 schematic many years ago, I didn't understand why these transistors were there. They're obviously intended to pull the internal data bus to Vdd at some point, but why would this be needed? I/O Buffer has a tri-state push-pull driver right below it, so it's not used to drive inbound data onto the internal bus.

The answer is that it really is not part of the I/O Buffer at all; it is not involved in moving data either into or out of the i4004. Its function is to pre-charge the internal data bus to Vdd (a "1" state) before internal bus drivers are activated. This makes all bus transitions 1->0 (fast) or 1->1 (really fast), even those with passive pull-ups.

So what was wrong with my test setup? Because I'm testing only the Scratchpad board (and now the Instruction pointer board) I didn't include any of the I/O buffer functionality in my test setup. Without pre-charging the data bus, 0->1  transitions took forever. The fix was simple: the FPGA now drives ones onto the bus when these transistors would have been on. This eliminated most of my timing issues.

I still have a few anomalies to look at. In this 'scope screenshot, the yellow trace is CLK1, the red trace is CLK2, and the blue trace is X32.

The green trace is bit 0 of the internal data bus during the execution of an LD instruction. The bus pre-charge occurs in subcycles X12/X22/X32 during CLK2, but when CLK1 goes active in X32 180ns later the bit gets pulled down to just under 2.0V. I think the bus should be floating at this point, so why isn't it staying at its pre-charged voltage? Oddly, the LD instruction is not part of the test program that comes with the emulator, so I need to write my own program.

Separately, while the data bus transitions are pretty fast when driven by the Scratchpad Register board, there seems to be some jitter in the data being output by the Instruction Pointer board. It settles down fairly quickly, but I want to understand why it's happening.

2 comments:

  1. Hi Reece, very interesting. What is your supply voltage currently? Something like 3.3V? Also your clock frequency is pretty high, about 660kHz, and somewhat asymmetric? Is anything connected to internal D0 that causes the drop to 2V? But I saw similar effects
    Klaus

    ReplyDelete
    Replies
    1. Hi Klaus! Yes, it's a head-scratcher.

      The i4004 boards have a Vdd of +5.0V. The FPGA has 3.3V I/Os, and can drive the i4004 circuits to about 3.1V.

      The clock period is 1.5us (666 KHz), with Tϕpw of 440ns, Tϕd1 of 440ns, and Tϕd2 of 180ns. This is consistent with my goal of matching the original i4004 timing.

      The only things connected are the Instruction Pointer board, the Scratchpad Register board, the FPGA interface board, and a 1 Mohm 'scope probe. I *think* the bus should be floating during X32/CLK1 when executing a "LD" instruction, but it sure looks like something is driving the bus.

      The FPGA interface board has FDV301N FETs between the FPGA I/Os and the i4004 circuits, with their gates hard-wired to 3.3V. These allow either side to pull down to within 0.6V of ground, but limit the voltage the FPGA sees to 3.0V when driven with 5.0V on the i4004 side. With the FPGA pin in a Hi-Z state, it shouldn't draw current from the i4004 side because the FET is turned off (Vgs < Vth).

      I really think CLK1 (or maybe X32) is turning something on. Although the FPGA drives ones onto the data bus during X22/CLK2, the bus floats in the interval between CLK2 and CLK1. The 'scope trace shows the voltage on D0 (green trace) falls only slightly in this interval. When CLK1 goes active, D0 drops abruptly from 3.1V to 1.9V and stays. That's not a floating circuit leaking down.

      I'll keep banging my head on this until I figure it out!

      Delete