0
\$\begingroup\$

As a way to improve my meagre FPGA skills, I'm moving some of my retrocomputing projects to purely FPGA implementations in VHDL, where each individual chips have the exact signals interface as they had in the old times. While having a lot of fun, I find that my exotic designs are not exactly what the FPGA manufacturers had in mind when producing chips and toolchains, and I don't get much help from their documentation. I'm intentionally asking a couple of questions together, as I suspect not many people will be interested in distinct detailed answers on the subject.

One of my next designs is a simulated retro DRAM chip (such as the 4164) using some block RAM. How can I duplicate the exact delays for the availability of data after asserting /RAS and /CAS? I found out that the VHDL "after" and "wait" statements are to be used only in test benches, as they are not synthetizable. So what could be the most efficient wait to do that? Should I add an additional high-frequency clock and an internal counter, so as to simulate an asynchronous chip by being internally synchronous? Could I use some kind of delay loop? Something else? As I don't have enough problems yet, I added this additional constraint: I don't want to use any "IP" inside a given simulated chip.

The other side of my quest is about clocks, a subjet I'm not really familiar with. Some of my favourite chips, such as the 68000, perform operations on the falling edge of their clock (e.g. 68000 states S1 and S7). When I learned the basics of FPGA design, I've seen a lot of scary warnings about using both the rising and falling edges in the same design. So how can I simulate such signals? For other chips, such as the 6809, there are sometimes two clocks, one leading the other (Q and E). Is it "safe" to use a PLL and happily drive a single simulated design with two clocks having a slightly distinct phase?

Bonus: I understand that both Vivado and Quartus have the ability to specify timing constraints and perform timing analysis of the designs. I never used them before, as I'm still learning and my main tool is still the waveform viewer. Could those tools be abused so as to assist me when I'm creating original retro-like designs connected to simulated retro components with timing constraints?

\$\endgroup\$
5
\$\begingroup\$

Asynchronous delays are effectively impossible in FPGAs. Running off anything but the system clock as a clock is fraught with difficulty. The correct way to do it, and by correct I mean a way that the timing and PAR tools will work with you rather than you having to fight them, is to use a system wide high speed clock, and use clock enables to qualify when any particular latch has to capture.

You could solve both problems by running a high speed system clock. This then runs a 'CPU clock' state machine, which outputs clock enables with names like 'leading edge', 'falling edge', 'data ready following CAS' and suchlike. If you have a 100 MHz system clock, and a 4 MHz 'CPU' cycle time, then there's plenty of resolution to get sub-cycle timings to be meaningful, even if they're not to the nanosecond. This does require a slight change in abstraction level, but how pure is your model anyway?

\$\endgroup\$
4
  • \$\begingroup\$ Fascinating. It does change the abstraction level, but not to the point I can't learn any more retro wisdom from the design. Do I have to use a single FSM for the whole system, or can I use an FSM for each individual simulated chip (e.g. one to provide CPU leadin/falling edge events, another to drive the workings of the DRAM chip)? Or will that cause new problems? \$\endgroup\$
    – airman
    May 12 at 18:33
  • 1
    \$\begingroup\$ All these sub-timings have to be synchronous, so by all means use one per simulated chip, as long as they all receive a synchronising signal as well as the fast clock, the 'leading edge' for instance. \$\endgroup\$
    – Neil_UK
    May 12 at 19:11
  • \$\begingroup\$ Sorry for the additional dumb question, but I'm still struggling with some aspects of register transfer design. If I understand correctly your comment, the FSM for the "DRAM" will use the "leading edge" enable from the "CPU" FSM in order to have its own outputs synchronized with that enable. But how is that actually done? And I would have thought that, both FSM being on the same high speed clock, no more synchronization would be necessary, their outputs being controlled by the high speed clock already. I feel like I'm missing something. \$\endgroup\$
    – airman
    May 13 at 6:50
  • 1
    \$\begingroup\$ @airman If both FSMs run from the same system clock, and both are initialised by the same chip-wide synchronous reset signal, then yes, they will continue indefinitely in phase. I come from an engineering background that doesn't trust that 'will run indefinetely from reset' idea, what with cosmic ray events etc, so if something can be re-synchronised every cycle, for more or less nothing, then I tend to do it. Perhaps FSM is too fancy a descrption for what is basically a counter with decoded outputs. Count through the states of the microcycle, and assert the CEs at the right times. \$\endgroup\$
    – Neil_UK
    May 13 at 7:05

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.