Simulation is going to be extremely important for this project to be successful. The most obvious reason is that PCB errors are going to be expensive and painful to debug, but there’s a handful of reasons specific to the AGC:
- The available schematics are incomplete. All of the Tray A modules are there, which is the really important bit. But we’re missing almost all of Tray B. That means all of the memory-interfacing circuitry needs to be recreated to work well with the core logic. (To be fair, I was probably going to do this anyways; building ferrite core memory is currently out of scope for this project).
- The AGC uses chains of NOTs to create delays in some places. The below image, is an example from the Timer module, puts the CT signal through three inversion stages before driving the main line everything that uses the signal is connected to.
The propagation delay for AGC NOR gates was 20us nominal, and 30us worst case. Both 74HC and 74LS NOR gate components are roughly twice as fast as this, so the timing surrounding such circuits in my computer will be quite different, and very well may require modification.
- The scans of the schematics aren’t perfect.
- There’s errors in the schematics. This is a list of errors compiled from a signal list, made by Jim Lawton. Most of the things in this list aren’t concerning. Signals with no sinks have no negative impact whatsoever, it just means a signal got put out on a pin and it never ended up needing to be used. Even most of the seemingly more egregious “signals with multiple sources” can safely be ignored; almost all of the entries here are actually instances of fan-out expansion gates or open-collector buses, being incorrectly marked as errors. The really concerning ones are the signals with no source. Those I’ll need to figure out.
My initial reaction to simulating a processor was to put it into an FPGA, but I learned quite quickly that this is a Bad Idea. The AGC is built mostly on asynchronous logic, which doesn’t translate well at all to the Look-Up Tables of FPGAs (and makes replication of timing quite difficult, even outside of an FPGA).
With all that said, an attempt to do exactly that has already been made by Dave Roberts. However, it doesn’t appear he ever got it fully working (though he got pretty close), and comments in the files he provides allude to issues with timing. Still, the fact that he got as far as he did is both very cool, and very promising!
Anyways, with the FPGA idea gone, I started testing out some digital simulation programs. I very quickly learned that doing any sort of digital simulation for the AGC is going to be an interesting challenge.
To demonstrate, I’m going to focus on a specific circuit, whose properties have been driving my selection of an approach to simulation.
The entry point of the 2.048MHz oscillator into the Tray A logic modules is Module A2, the Timer. It immediately runs into a rather interesting structure of 6 NOR gates (ignore the one in the upper right). This circuit accomplishes something pretty remarkable. And as it turns out, it’s a pain to simulate.
For the purposes of this discussion, I’ll focus on another instance of this circuit, also in the Timer module. It’s exactly the same, but all of the nodes have labels, which makes it easier to show what’s going on.
I was pretty confused by this thing when I first started looking at it. Normally you only see NOR gates cross coupled in pairs to build SR latches, but here we have four gates that are all cross-coupled, feeding another, more common cross-coupled pair (which then feed back into the group of four).
So, let’s throw it into a simulator to see what it does. My first attempt was to implement it in Logisim, which some people have used to implement fully working processors. Unfortunately, this didn’t really work out too well.
It thinks the entire circuit is an error! Circuitmaker 2000, which John Pultorak used to simulate his AGC, gives a bit more insight into why Logisim is so upset about this:
The entire circuit flashing on and off nonstop! Circuitmaker 2000 initializes all nodes to 0 during the first time step of the simulation. Because everything here is a NOR gate, that means the next time step, all of them will put out a 1. However this makes all inputs a 1, so the next time step, all of their outputs will go to 0, and so on and so forth. Logisim fails for a similar reason: it tries to derive the initial state of the circuit through propagation, and quite simply can’t. Another interesting thing about this circuit: watch what happens as the input signal (P01/ in the sample circuit) changes. The two gates it feeds into are prevented from oscillating, but only while P01/ is high. In other words, there’s no input you can give this circuit to make it settle on a state, like you can with an SR latch (which will also oscillate forever in a simulator like this given bad inputs).
The core of the problem is that simulators like this implement ideal gates. In the real world, small variations in the construction of the components will cause the circuit to settle into a stable state quite quickly, preventing oscillations like this from occurring for too long. Analog simulators like SPICE, which also model ideal components, typically let you set initial conditions on the circuit to force the circuit into a known state at the beginning of a simulation (otherwise, they’re subject to the same oscillations). But unfortunately, it seems that this is not a common thing for digital engines, or at least the free ones I was able to get my hands on. Even Verilog doesn’t let you set initial values on wires.
So what to do? It’s possible to force the clock divider into a known state by increasing the number of inputs on the NOR gates and adding additional circuitry:
This approach doesn’t sit well with me, though, because it means the circuit being simulated isn’t the same as the one being built. Moreover, I’d have to sketch out two separate versions of the schematic, one for PCB layout and one for simulation, and that’s just asking for errors.
After doing a lot of research, I’ve decided to take a three-pronged approach to simulation. First, I’ll be using LTSpice for analog simulation, in small-to-medium-sized doses. That’ll be important both for signal integrity, and to be sure the propagation delays I put into the digital simulation are at least somewhat accurate.
Second, I patched Logisim to accept initial conditions for gates.
Logisim will be primarily used for simple circuits like this, just to figure out what’s going on. It’s got a few features that prevent it from being more useful beyond that without further modification, but for simple stuff, it’s great.
The bulk of the work will be done in KiCAD, an open-source PCB design program that’s roughly comparable to Eagle. KiCAD doesn’t have any simulation built in, aside from very basic SPICE integration that can call out to LTSpice. Instead, I’ll be using Icarus Verilog as the primary simulation engine. I’ve been working on a Verilog exporter to generate Verilog from KiCAD-exported netlists. This approach has a lot of advantages: there’ll be one source of truth for both PCB layout and simulation (what is simulated is what will be built), and I can insert the additional circuitry shown above automatically into the generated Verilog without having any of it in the schematic or PCB. Verilog is also more or less an industry standard for digital design and simulation. It’s really fast compared to the graphical tools, and I’ll be able to do a lot with it. (Incidentally, it’s the simulation-only features of Verilog that allow me to simulate the AGC at all; the generated Verilog won’t be synthesizable, so unfortunately it still can’t be put into real hardware).
KiCAD’s generic netlist exporter also requires some patches to fully support everything we need.
The modified netlist exporter makes sure the 1’s circled on U1C and U2B in the above image make it into the netlist file. I’ve placed these as markers for gates that have their “ResetValue” attribute set to 1. This attribute tells the Verilog generator what to use as the reset value for each gate.
I’ll go into more detail on the Verilog generator in a later post. For now, let’s wrap this one up by using the patched Logisim and Icarus Verilog to analyze the clock divider circuit.
As expected, FS01 is a square wave with half the frequency of P01/. But more interesting are F01A, F01B, F01C, and F01D — they constitute a four-phase clock of the same frequency as FS01. And as described in R-393, “signals FxA, FxB, FxC, FxD represent pulses 90° (electrical) out of phase. A leads C (not B) by 90°; C leads B by 90°; B leads D by 90°”. This is actually a really neat circuit — only 6 gates, and it produces 6 useful clocking signals. No wonder it’s used so much throughout the AGC!
Finally, here’s a waveform output from the same circuit, simulated in Icarus Verilog:
Exactly as expected! Unlike Logisim, my Verilog models are taking the propagation delays of the individual NOR gates into account. You can see the results of this as overlapping signals — most conspicuously in the above image, F01B overlapping with F01C.
That’s all for simulation for now! The Verilog generator should be done shortly, after which the analysis can really take off. Until then!