Rate matcher.vhd

From Hamsterworks Wiki!

Jump to: navigation, search

Tells the bitclock generator to speed up or slow down in the SPDIF_Thru FPGA project.

----------------------------------------------------------------------------------
-- Engineer:   Mike Field (hamster@snap.net.nz 
-- 
-- Create Date:   20:09:58 09/04/2011 
-- Module Name:   data_rate_matcher - Behavioral 
-- Project Name:    SPDIF_thru
-- Description:    Matches the TX rate to the RX rate. Checks the fifo every 1/10th 
--                of a second, and signals the fractional clock generator to 
--                either speed up or slow down if the FIFO is too full/empty.
--
--                The rate of trimming must be carefully matched to avoid ping-ponging
--                between limits
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity data_rate_matcher is
    Port ( clock100           : in  STD_LOGIC;
           data_count        : in  STD_LOGIC_VECTOR (8 downto 0);
           adj_quicker_lots : out  STD_LOGIC;
           adj_quicker        : out  STD_LOGIC;
           adj_slower        : out  STD_LOGIC;
           adj_slower_lots  : out  STD_LOGIC);
end data_rate_matcher;

architecture Behavioral of data_rate_matcher is
   type reg is record 
      count          : std_logic_vector(23 downto 0);
      last_count      : std_logic_vector(8 downto 0);
      current_count   : std_logic_vector(8 downto 0);
      adj_quicker_lots : std_logic;
      adj_quicker      : std_logic;
      adj_slower       : std_logic;
      adj_slower_lots  : std_logic;
   end record;
   signal r : reg := ((others => '0'),(others => '0'),(others => '0'),'0','0','0','0');
   signal n : reg;
begin

   adj_quicker_lots <= r.adj_quicker_lots;
   adj_quicker      <= r.adj_quicker;
   adj_slower       <= r.adj_slower;
   adj_slower_lots  <= r.adj_slower_lots;


   process(r, data_count)
   begin
      n <= r;
      n.current_count <= data_count;
      n.adj_quicker_lots <= '0';
      n.adj_quicker      <= '0';
      n.adj_slower       <= '0';
      n.adj_slower_lots  <= '0';

      -- DO this every 1/10th of a second
      if r.count = 9999999 then
         n.count        <= (others => '0');
         n.last_count <= r.current_count;
         
         -- Do we need to slow down?
         if  r.current_count <= r.last_count and r.current_count < 64 then
            n.adj_slower_lots <= '1';
         elsif  r.current_count < r.last_count and r.current_count < 240 then
            n.adj_slower <= '1';
         end if;

         -- Do we need to speed up?         
         if r.current_count >= r.last_count and r.current_count > 446 then
            n.adj_quicker_lots <= '1';
         elsif r.current_count > r.last_count and r.current_count > 262 then
            n.adj_quicker <= '1';
         end if;         
      else
         n.count <= r.count+1;
      end if;
   end process;
      
   process (clock100, n)
   begin
      if rising_edge(clock100) then
         r <= n;
      end if;
   end process;
   
end Behavioral;

Personal tools