spdif.vhd

    1  -- title:              S/PDIF
    2  -- author:             ACK.space
    3  -- last change:        25.10.13
    4 
    5 
    6 library IEEE;
    7 use IEEE.std_logic_1164.all;
    8 use IEEE.numeric_std.all;
    9 use IEEE.math_real.all;
   10 
   11 entity spdif is
   12         generic
   13         (
   14                 prescaler       : natural := 8
   15         );
   16 
   17         port
   18         (
   19                 clk             : in std_logic;
   20                 ch0             : in std_logic_vector(23 downto 0);
   21                 ch1             : in std_logic_vector(23 downto 0);
   22                 sdo             : out std_logic
   23         );
   24 end entity;
   25 
   26 architecture behavioral of spdif is
   27 constant log2pre        : integer := integer(ceil(log2(real(prescaler))));
   28 signal pre              : unsigned(log2pre-1 downto 0) := (others => '0');
   29 signal data_in_buffer   : std_logic_vector(23 downto 0);
   30 signal bit_counter      : unsigned(5 downto 0) := (others => '0');
   31 signal frame_counter    : unsigned(8 downto 0) := (others => '0');
   32 signal data_biphase     : std_logic := '0';
   33 signal data_out_buffer  : std_logic_vector(7 downto 0);
   34 signal parity           : std_logic;
   35 signal channel_status_shift : std_logic_vector(23 downto 0);
   36 signal channel_status   : std_logic_vector(23 downto 0) := "001000000000000001000000";
   37 signal ch_sel           : std_logic := '0';
   38 signal clk_en           : std_logic := '0';
   39 begin
   40 
   41         clock : process begin
   42                 wait until rising_edge(clk);
   43                 pre <= pre + 1;
   44                 if pre = 0 then
   45                         clk_en <= '1';
   46                 else
   47                         clk_en <= '0';
   48                 end if;
   49         end process clock;
   50 
   51         bit_clock_counter : process begin
   52                 wait until rising_edge(clk);
   53                 if clk_en = '1' then
   54                         bit_counter <= bit_counter + 1;
   55                 end if;
   56         end process bit_clock_counter;
   57 
   58         data_latch : process begin
   59                 wait until rising_edge(clk);
   60                 if clk_en = '1' then
   61                         parity <= data_in_buffer(23)    xor data_in_buffer(22)  xor data_in_buffer(21)  xor data_in_buffer(20)  xor data_in_buffer(19)
   62                                                         xor data_in_buffer(18)  xor data_in_buffer(17)  xor data_in_buffer(16)  xor data_in_buffer(15)
   63                                                         xor data_in_buffer(14)  xor data_in_buffer(13)  xor data_in_buffer(12)  xor data_in_buffer(11)
   64                                                         xor data_in_buffer(10)  xor data_in_buffer(9)   xor data_in_buffer(8)   xor data_in_buffer(7)
   65                                                         xor data_in_buffer(6)   xor data_in_buffer(5)   xor data_in_buffer(4)   xor data_in_buffer(3)
   66                                                         xor data_in_buffer(2)   xor data_in_buffer(1)   xor data_in_buffer(0)   xor channel_status_shift(23);
   67                         if bit_counter = "000011" then
   68                                 if ch_sel = '0' then
   69                                         data_in_buffer <= ch0;
   70                                 else
   71                                         data_in_buffer <= ch1;
   72                                 end if;
   73                         end if;
   74                         if bit_counter = "111111" then
   75                                 if frame_counter = "101111111" then
   76                                         frame_counter <= (others => '0');
   77                                 else
   78                                         frame_counter <= frame_counter + 1;
   79                                 end if;
   80                         end if;
   81                 end if;
   82         end process data_latch;
   83 
   84         data_output : process begin
   85                 wait until rising_edge(clk);
   86                 if clk_en = '1' then
   87                         if bit_counter = "111111" then
   88                                 if frame_counter = "101111111" then
   89                                         -- next frame is 0, load preamble B
   90                                         ch_sel <= '0';
   91                                         channel_status_shift <= channel_status;
   92                                         data_out_buffer <= "10011100";
   93                                 else
   94                                         if frame_counter(0) = '1' then
   95                                                 -- next frame is even, load preamble M
   96                                                 ch_sel <= '0';
   97                                                 channel_status_shift <= channel_status_shift(22 downto 0) & '0';
   98                                                 data_out_buffer <= "10010011";
   99                                         else
  100                                                 -- next frame is odd, load preable W
  101                                                 ch_sel <= '1';
  102                                                 data_out_buffer <= "10010110";
  103                                         end if;
  104                                 end if;
  105                         else
  106                                 if bit_counter(2 downto 0) = "111" then
  107                                         -- load new part of data into buffer
  108                                         case bit_counter(5 downto 3) is
  109                                                 when "000" =>
  110                                                         data_out_buffer <= '1' & data_in_buffer(0) & '1' & data_in_buffer(1) & '1' & data_in_buffer(2) & '1' & data_in_buffer(3);
  111                                                 when "001" =>
  112                                                         data_out_buffer <= '1' & data_in_buffer(4) & '1' & data_in_buffer(5) & '1' & data_in_buffer(6) & '1' & data_in_buffer(7);
  113                                                 when "010" =>
  114                                                         data_out_buffer <= '1' & data_in_buffer(8) & '1' & data_in_buffer(9) & '1' & data_in_buffer(10) & '1' & data_in_buffer(11);
  115                                                 when "011" =>
  116                                                         data_out_buffer <= '1' & data_in_buffer(12) & '1' & data_in_buffer(13) & '1' & data_in_buffer(14) & '1' & data_in_buffer(15);
  117                                                 when "100" =>
  118                                                         data_out_buffer <= '1' & data_in_buffer(16) & '1' & data_in_buffer(17) & '1' & data_in_buffer(18) & '1' & data_in_buffer(19);
  119                                                 when "101" =>
  120                                                         data_out_buffer <= '1' & data_in_buffer(20) & '1' & data_in_buffer(21) & '1' & data_in_buffer(22) & '1' & data_in_buffer(23);
  121                                                 when "110" =>
  122                                                         data_out_buffer <= "10101" & channel_status_shift(23) & "1" & parity;
  123                                                 when others =>
  124                                         end case;
  125                                 else
  126                                         data_out_buffer <= data_out_buffer(6 downto 0) & '0';
  127                                 end if;
  128                         end if;
  129                 end if;
  130         end process data_output;
  131 
  132         biphaser : process
  133         begin
  134                 wait until rising_edge(clk);
  135                 if clk_en = '1' then
  136                         if data_out_buffer(data_out_buffer'left) = '1' then
  137                                 data_biphase <= not data_biphase;
  138                         end if;
  139                 end if;
  140         end process biphaser;
  141 
  142         sdo <= data_biphase;
  143 
  144 end behavioral;
  145 

This page was generated using GHDL 0.29 (20100109) [Sokcho edition], a program written by Tristan Gingold