Skip to content
Tech News
← Back to articles

Device Clock Generation (2025)

read original more articles

After building a CPU, utilities for handling bus interconnects, several DMAs and memory controllers, I often find my time focused on building interfaces between designs and external peripherals. This seems to be where most of the business has landed for me. Often, these peripherals require a clock output, coming from the design, and so I’d like to spend some time describing how to generate such a “device” clock.

Fig 1. A Basic SOC with Peripherals

There’s actually two topics that need to be discussed when working with modern high speed peripheral design. One of them is generating the clock to be sent to the peripheral, such as Fig. 1 above illustrates. The second one involves processing a clock returned from the peripheral, as shown in Fig. 2 below. This is a key component of high speed designs such as DDR memories, eMMC, HyperRAM, or even NAND flash protocols. This second topic is one we shall need to come back to at a later date.

Fig 2. Data returned with a clock

Today, I’d like to discuss how to go about generating a clock to control device interaction.

I first came across this problem when building a NOR flash controller, based on first a SPI interface and later a Quad SPI interface. My controller was designed for FPGAs, and so the clock could be built with a single frequency. This design had the added complication that the clock needed to be paused from time to time. Specifically, the clock needed to be turned off when nothing was going on. Likewise, the clock needed to be turned off for one cycle after dropping (i.e. activating) the chip select pin, and for a couple cycles after the transaction was complete but before raising (deactivating) the chip select.

I had to deal with a similar problem when controlling a HyperRAM, but … that design failed when I wasn’t (yet) prepared to handle the return clock properly. I did say this deserved an article in its own right, did I not? Processing data on a return clock properly can be a challenge.

I then built a similar design for ASIC platforms. Unlike the FPGA, the final clock speed wouldn’t be known until run time. It might be that the design started at a slower clock speed, only to later speed up to the full rate at run time. Unlike an FPGA which can be fixed later, there’s really no room for failure in ASIC work. At least with an FPGA, if my board didn’t support a particular frequency, I could just rebuild the design for the clock frequency it did support. This doesn’t work, though, for an ASIC–since it tends to be cost prohibitive to rebuild the design at a later time when you decide to connect it to a slower part than the one you designed it for.

The next design I worked with was a NAND flash design. NAND flash can be a challenge, since the protocol requires you to start at a slow frequency and only after you bring up the connection are you allowed to change to a faster frequency. This particular design was built for ASIC environments, and so it depended upon an analog component generating all the clocks I needed. This worked great, up until someone wanted to purchase the design to work on an FPGA, then another wanted it to work on an FPGA, and another and so on.

Fig 3. Single Data Rate (SDR) vs Dual Data Rate (DDR) SDR DDR

... continue reading