I have DE1-SoC board which contains 1 MSPS ADC, I am trying to take samples from ADC and process them. ADC Controller clock is 20 MHz and data is available every 16 clock cycles. The module that takes samples operates on 100 MHz clock. The problem is how can I interface these two modules?

My first thought was to use an asynchronous FIFO, but after search I figured out that it is impossible! Writing clock is much slower than reading side. I found a formula to calculate the depth of the FIFO (here) but it failed, giving me a negative answer! I didn't know what my "burst" is, so I assumed it to be 1 as the controller gives one sample every 16 clock cycles.

So, do you have any clue of solving this problem?


1 Answer 1


Normally, FIFOs are self controlled to prevent overflows and underflows. This is done by implementing a forward and backward flow control. Forward flow control means that data words are marked valid in the FIFO so that the read side can distinguish valid from invalid words. Backward flow control is achieved by exporting fill state of a FIFO to the write side. If the FIFO is full it creates a 'full' signal signaling the writer that it can handle more data.

In your case the ADC is transmitting data at a constant rate, so you have to dimension the FIFO correct to prevent an overflow.

\$Write\,speed = 20\,MHz \cdot \frac{1\ ADC\,Words}{16\ Cycles} = 1.25\,M\frac{Words}{sec}\$

\$Read\,speed = 100\,MHz \cdot \frac{1\,Word}{1\,Cycle} = 100\,M\frac{Words}{sec}\$

Because read speed is faster then write speed and write burst length is one, you don't need to worry about FIFO depth or burst length and overflows. Note cross clock FIFOs have a minimum dephs, e.g. 3 words.

Lets have a look to a common FIFO interface:

entity fifo_ic_got is
    generic (
        D_BITS         : positive;          -- Data Width
        MIN_DEPTH      : positive           -- Minimum FIFO Depth
    port (
        -- Write Interface
        clk_wr    : in  std_logic;
        rst_wr    : in  std_logic;
        put       : in  std_logic;
        din       : in  std_logic_vector(D_BITS-1 downto 0);
        full      : out std_logic;

        -- Read Interface
        clk_rd    : in  std_logic;
        rst_rd    : in  std_logic;
        got       : in  std_logic;
        valid     : out std_logic;
        dout      : out std_logic_vector(D_BITS-1 downto 0)

This FIFO has 2 clock inputs, one for each clock domain (read (rd) and write (wr)) as well as one resets for each side.

The data path din to dout is surrounded by 4 signals:

  • put - din is valid -> store word in the FIFO
  • full - the FIFO is full -> no more data can be stored, put has no effect
  • valid - the FIFO has at least one data word, which can be seen at dout
  • got - the current word on dout was read and the circuit is ready for the next word

Writing at every 16th clock cycle means to assign put every 16 cycles to 1. She signal full can be ignored, because the read side is always faster then the write side.

Here is a waveform for the FIFO: enter image description here

Wavedrome online waveform editor

  • \$\begingroup\$ Ok, but what about underflow? the processing module will have to wait 80 clock cycles for the next sample to come. That means there is no need to FIFO, right? \$\endgroup\$ Dec 8, 2014 at 13:57
  • 1
    \$\begingroup\$ The underflow condition is prevented by the forward flow control. So if valid is not high, you can't use dout. This prevents the reader from taking more word out than stored in the FIFO. A FIFO is still needed because you are using two different unrelated clocks. This clock domain boundary can only be crossed by a cross clock FIFO or a complex handshake protocol. If you don't use a cross clock FIFO or a appropriate clock domain crossing circuit, you will read false data from your ADC. \$\endgroup\$
    – Paebbels
    Dec 8, 2014 at 14:20
  • \$\begingroup\$ So there is no chance for the processing module to continuously take samples from FIFO? It must wait a particular number of cycles until the next sample to come? \$\endgroup\$ Dec 8, 2014 at 16:26
  • 1
    \$\begingroup\$ Yes, the valid signal indicates when the processing module can take a word from the FIFO. Continues consuming can only be done if write speed equals read speed. As you described, the writer operates at \$\frac{1}{16}\$ of 20 MHz and the reader at 100 MHz. \$\endgroup\$
    – Paebbels
    Dec 8, 2014 at 17:07
  • 1
    \$\begingroup\$ Actually, as the datasheet describes the device, it is a 1 MSPS ADC, however, when they described modes of operation and other things, they said that you need to operate it at 20 MHz clock if you want to get the highest data rate, that is the 1 MSPS. I don't know if the conversion rate is different than the transmitting rate. \$\endgroup\$ Dec 8, 2014 at 17:15

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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