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