Device Clock Generation

mfiguiere2 pts0 comments

Device Clock Generation

After building a CPU, utilities for<br>handling bus interconnects, several DMAs<br>and memory controllers, I often find my time focused on building interfaces<br>between designs and external peripherals. This seems to be where most of the<br>business has landed for me. Often, these peripherals require a clock output,<br>coming from the design, and so I’d like to spend some time describing how to<br>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<br>high speed peripheral design. One of them is generating the clock to be sent<br>to the peripheral, such as Fig. 1 above illustrates. The second one involves<br>processing a clock returned from the peripheral, as shown in Fig. 2 below.<br>This is a key component of high speed designs such as DDR memories, eMMC,<br>HyperRAM, or even NAND flash protocols. This second topic is one we shall<br>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<br>device interaction.

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

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

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

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

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

Just to add another twist to the problem, many protocols require data<br>transitions on both edges of the clock, a protocol often known as<br>“Dual Data Rate” (DDR). Unlike the other designs above, these often require a<br>clock that is 90 degrees offset from the data–so that each clock transition<br>takes place in the middle of each data valid window, rather than on the edges<br>of the window. This sort of “offset” clock is necessary to guarantee setup and<br>hold times within the slave peripheral. An example of the clock and data<br>relationship required by DDR as opposed to a traditional “single data rate”<br>(SDR) clock is shown in Fig. 3.

By the time I got to my SDIO/eMMC controller,<br>I think I finally had the clock division problem handled. An<br>SDIO controller needs bring up the SD card<br>at 400kHz, and then depending upon the card, the PCB, and the controller, the<br>speed may then be raised to 25MHz, 50MHz, 100MHz, or even 200MHz. The clock<br>may also be stopped whenever either there’s nothing to send or receive, or<br>when the SOC can’t load or unload the data to the controller. For example, you<br>might ask an SD card to read and thus produce many blocks of data, then read<br>the first two of these blocks into your internal buffers only to find that the<br>CPU is slow in draining those buffers. In that case, you would need to stop<br>the interface clock before the external card tries to send you a third block<br>of data that would have nowhere to go.

Other devices require user programmable device clock controllers, such as:

10M/100M/1Gb Ethernet controllers

While each of these speeds might use a single clock, building a truly<br>trimode controller requires some extra work.

(DDR) SDRAM controllers

SDRAM controllers from an FPGA standpoint...

clock data design time controller speed

Related Articles