I'm working on a Microblaze-based system. I'm using FSL to shuttle data directly from an AC'97 controller core to my custom DSP core. The FSL buses are clocked at the 125MHz system clock. The DSP components have been designed with a 48kHz clock in mind (the codec sampling rate).

How do I go about clocking the samples through the DSP components at 48kHz?

FSL bus is essentially a FIFO, that signals when data is available for the slave to read. Through some experimentation, I'm seeing samples arrive at approximately 48 kHz (I was using a timer interrupt in the uBlaze to monitor this, hence the "approximately"). Is there any way I can generate a sane "clock" from this fact, and also allow XST to understand the timing requirements of what I'm doing?

  • 1
    \$\begingroup\$ While clock enable is clearly the answer, most DSP algorithms at audio rate use sequential implementations of dot-product type operations, such that you actually need a clock many times the sample rate. \$\endgroup\$ – Chris Stratton Sep 2 '13 at 16:52
  • \$\begingroup\$ Yep, at some point I figured I would have to take advantage of all those "extra clocks" not being used. So far, my algorithms have all been able to complete within one clock cycle. Thanks for confirming that suspicion! \$\endgroup\$ – Jonathon Reinhart Sep 2 '13 at 18:53
  • \$\begingroup\$ That one sentence really opened up my eyes to how more complex algorithms would be implemented. Thank you so much! \$\endgroup\$ – Jonathon Reinhart Sep 2 '13 at 18:56

Clock the DSP at 125MHz, but apply a "clock enable" signal to it that is pulsed active every 2604 clocks @ 125MHz; that will give you a DSP rate of 48,003Hz - well within the error you can expect on the original clock.

  • \$\begingroup\$ Like this? \$\endgroup\$ – Jonathon Reinhart Aug 29 '13 at 15:27
  • \$\begingroup\$ This doesn't really address the synchronization with the FSL FIFOs though. And the fact that I get a pulse every sample via the FSL_S_Exists line. \$\endgroup\$ – Jonathon Reinhart Aug 29 '13 at 15:37
  • \$\begingroup\$ Yes, like that. \$\endgroup\$ – markt Aug 30 '13 at 6:04
  • 1
    \$\begingroup\$ If you want to synchronise your DSP's operation to your codec, then maybe derive a CE signal for the DSP off the codec's control signals instead of using a divider. \$\endgroup\$ – markt Aug 30 '13 at 6:07
  • \$\begingroup\$ Your solution worked absolutely perfectly, thank you! \$\endgroup\$ – Jonathon Reinhart Sep 2 '13 at 16:17

As markt suggested, the solution is clock gating.

I have placed all of my project code on GitHub. You can see where I handle the FSL bus transactions here.

The entire design remains in the 125 MHz system clock domain, but a clock enable signal is used throughout the DSPs. Since this happens every sample, I named this signal samp_ena. Sample usage:

process (sys_clk) is
   if rising_edge(sys_clk) then
      if samp_ena = '1' then
         -- Register new sample
      end if;
   end if;
end process;

I'm generating this samp_ena signal in my FSL transaction state machine. An example:

case fsl_state is
   -- ...
   when FSL_SREAD =>
      if (FSL_S_Exists = '1') then
         new_sample <= FS_S_Data;
         samp_ena <= '1';
         fsl_state <= FSL_MWRITE;
      end if;
   -- ...
end case;

-- Pulse samp_ena for one sys_clk only
if (samp_ena = '1') then
   samp_ena <= '0';
end if;

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.