While browsing the web I came across some interesting references to a
I've been tinkering with digital electronics since the Intel 8080 was new. I built a Science Fair project from TTL gates and circuits when I was in 9th grade (1976-ish). Thus the basics of digital electronics in general, and TTL circuitry in specific, are quite familiar to me. However, the opportunity to look at the instruction decoding and state transitions of a computer was quite appealing, and I hunted down a copy.
As is to be expected of a book last updated 25 years ago, the material is somewhat dated. The low-power Schottky TTL gates that were cutting edge then have been all but replaced by faster, more efficient CMOS technologies that this book notes in passing as low-power but very slow. That said, the design techniques are still valid. A NAND gate is still a NAND gate, even if the technology used to implement it is different.
As tempting as it is to build a SAP-1 computer on a big breadboard, I have too many projects going on already to do this. However, I decided to "build" one using Verilog. After all, Verilog was developed for the purpose of simulating and validating digital designs. To that end I created behavioral models for each of the 11 components in the SAP-1. Eventually I want to enhance these with propagation delays appropriate to the physical devices, but for the moment I've left them with zero delay.
The book works through the development of all the SAP-1 circuitry in modular chunks, explaining how each chunk works in isolation, then assembles the system from those. Contrary to this quite-normal design practice, which would have meant writing a series of small Verilog modules with individual testbenches, I chose to translate the final schematic into one big module that totaled almost 700 lines of Verilog. That was a mistake.
When I tried to run the simulation, the first problem I encountered was of my own creation: the one-hot ring counter that generates the six CPU state signals didn't work. So I pulled that chunk of circuitry out (6 module instantiations, representing three 74LS107 dual J-K flip-flop ICs) and wrote a testbench to drive it. Fairly quickly I discovered I'd mis-wired the flip-flop that generates the T1 state signal. This was easy to find and fix, but rather than just fix it in the big top module I modified the top module to instantiate the small ring counter module. That way I could re-run the ring counter testbench and not worry about keeping the test and real code in sync.
However, fixing the state ring counter didn't make the computer work. The program counter didn't count properly at all. It would start at 0, step to 1, and then go back to 0. This also used the 74LS107 module, which worked fine in the ring counter. I pulled the code for the program counter (4 instantiations of the 74LS107 module, representing 2 ICs) out of the top module and created a small, testable module from it. I also created a testbench which reproduced the input signals I observed from the failing simulation. The testbench reproduced the failure faithfully.
I dug out the datasheet (last updated in 1988!) and took a really close look at it. What I found suggests a problem in the book. All the datasheets I found online describe two different parts: the 74107 and the 74LS107A. I could not find any description of the LS part without the A suffix, yet this is what the schematic in the book called for. This is important because the 74107 is a pulse-triggered master/slave device, while the 74LS107A is a negative-edge triggered device. These behave differently in a subtle way. The pulse-triggered device latches the J and K inputs in the master FF while the clock line is high, then transfers the master outputs into the slave FF and chip outputs when the clock goes low. This requires the J and K inputs to be stable for the entire period when the clock is high. In contrast, the 74LS107A latches the J & K inputs as the clock transitions from high to low, and the J and K inputs need only need to be stable during the minimum set-up time before the falling edge of the clock.
I read the section of the book on flip-flops carefully, and came to the conclusion that it describes the 74107 master-slave behavior. Looking at my Verilog code I discovered I'd implemented this module as if it was clocked on the rising edge, which was wrong for both variants. I rewrote the Verilog module for this part to properly represent a master-slave JK flip-flop and retested. This also failed. The SAP-1 design changes the J and K inputs while the clock is high which violates the datasheet requirements. Changing the flip-flop module once more, to implement the falling edge-triggered "A"-suffix behavior, resolved the problem in the PC testbench but not the full CPU. It counts 0000 -> 0001 -> 0010 -> 0011 -> 0000.
I've run out of time to work on this for the moment. I'll come back to it soon.