I have been playing with recreating the Atari TIA chip as used in the original 2600 in an FPGA. I know this has been done a few times already, but I'm hoping to use this project as a warmup for bigger and better things. Furthermore, I'd like to be able to produce actual hardware replacements for the original chips.
For the TIA, there are original schematics available, as well as many notes and forum posts about all the details of its operation. There are other FPGA cores as well. You would think this kind of project is incredibly straightforward - just implement what's in the schematic using Verilog or VHDL, and everything will just work. I'd like to explore two reasons why this is quite a bit harder than that.
1) Custom ICs back in the day were extremely limited. Clock speeds were low. The total number of transistors were extremely limited.
For these reasons, and by today's standards, lots of "shortcuts" were taken. Circuits would be clocked on rising and falling edges, to double the effective clock rate. Elements would be chained together in complex ways, where one state transition would set off a cascade of downstream state changes, affected by propagation delays. A single bit of state might be represented by a full D flip-flop, or in might be simply the output of one transistor which is "refreshed" with a new value on a regular basis.
Contrast this with modern FPGA design principles - namely "synchronous design". Essentially, all state should be in the form of clocked flip flops, which are all clocked at the same time, and whose input states are a simple combination of the output states. Since you can't really imitate the tricks used back in the day exactly, you generate logic circuits that do the same thing. (The intermediate states should be the same as what you have in the original design.) But, in order for clocking to be synchronous, sometimes you need to create additional signals that didn't exist in the original design. For example - a clock pulse causes A, but under some additional circumstance A then causes B. If the delay between A and B is not significant, surely you want A and B to happen at the same time in the new design. But, you probably need a new signal that tells you that A is going to happen _and_ it's the special circumstance, so that B can happen at the same time.
Since you can't count on delays in an FPGA, you end up reverse-engineering the behavior of the original design, and implementing the equivalent behavior, even if it's not exactly 1-to-1.
I don't do FPGA design much professionally. I'm not even exactly sure how much I can deviate from "good" FPGA design principles and get a reliable design. That's one thing I'd really like to learn from this experience.
2) Sometimes, maybe most of the time, there is analog on the original chip along with the digital.
For example, the paddle controllers on the 2600 use an analog discharge curve from 5V to set their timing. A better example, Atari used an analog phase delay chain to generate the color palette. These require new adaptations to work with a fully digital design.
On top of this, 5V logic is largely obsolete. You need to examine how all the pins are being used in your system, and make sure there are compatible signals getting to/from your FPGA.
In the next blog post, I will discuss the first hurdle I faced. Setting up clocking so that I can generate all the signals needed by a fully digital version of the TIA.