library IEEE; use IEEE.STD_LOGIC_1164.all; use IEEE.std_logic_unsigned.all; use IEEE.std_logic_misc.all; use IEEE.numeric_std.all; -- clk wants to be so that the small feature is 3 ticks entity spdif_decoder is generic ( Z24 : std_logic_vector(23 downto 0) := (others => '0'); Z32 : std_logic_vector(31 downto 0) := (others => '0') ); port ( n_reset : in std_logic; spdif : in std_logic; clk : in std_logic; bmc_ready : out std_logic; bmc_e : out std_logic; bmc_l : out std_logic; bmc_d : out std_logic; d : out std_logic_vector(26 downto 0); ready : out std_logic; sof : out std_logic; bna : out std_logic; sos : out std_logic ); end spdif_decoder; architecture rtl of spdif_decoder is component bmc_decoder is port ( n_reset : in std_logic; clk : in std_logic; spdif : in std_logic; ready : out std_logic; e : out std_logic; l : out std_logic; d : out std_logic ); end component; signal b_ready : std_logic; signal b_e : std_logic; signal b_l : std_logic; signal b_d : std_logic; signal parity_valid : std_logic; signal e_sr : std_logic_vector(31 downto 0); signal d_sr : std_logic_vector(31 downto 0); signal l_sr : std_logic_vector(31 downto 0); signal d_buf : std_logic_vector(26 downto 0); signal sof_buf : std_logic; signal sos_buf : std_logic; signal ready_buf : std_logic; signal bna_buf : std_logic; begin bmc : bmc_decoder port map ( n_reset => n_reset, clk => clk, spdif => spdif, ready => b_ready, e => b_e, l => b_l, d => b_d ); bmc_ready <= b_ready; bmc_e <= b_e; bmc_l <= b_l; bmc_d <= b_d; process (clk, b_ready, b_e, b_l, b_d, n_reset) begin if n_reset = '0' then e_sr <= (others => '0'); d_sr <= (others => '0'); l_sr <= (others => '0'); elsif rising_edge(clk) then if (b_ready = '1') then e_sr <= b_e & e_sr(31 downto 1); d_sr <= b_d & d_sr(31 downto 1); l_sr <= b_l & l_sr(31 downto 1); end if; end if; end process; parity_valid <= not xor_reduce(d_sr(31 downto 4)); process (clk, b_ready, e_sr, l_sr, d_sr, parity_valid, n_reset) begin if n_reset = '0' then d_buf <= (others => '0'); sof_buf <= '0'; bna_buf <= '0'; ready_buf <= '0'; elsif rising_edge(clk) then if (b_ready = '1') and (parity_valid = '1') and (e_sr = Z32) then if (d_sr(3 downto 1) = "010") and (l_sr(3 downto 1) = "101") then --B code d_buf <= d_sr(29 downto 3); sof_buf <= '1'; sos_buf <= '1'; bna_buf <= '0'; ready_buf <= '1'; elsif (d_sr(3 downto 1) = "100") and (l_sr(3 downto 1) = "011") then --M code d_buf <= d_sr(29 downto 3); sof_buf <= '0'; sos_buf <= '1'; bna_buf <= '0'; ready_buf <= '1'; elsif (d_sr(3 downto 0) = "0100") and (l_sr(3 downto 0) = "0001") then --W code d_buf <= d_sr(30 downto 4); sof_buf <= '0'; sos_buf <= '0'; bna_buf <= '1'; ready_buf <= '1'; else sof_buf <= '0'; sos_buf <= '0'; bna_buf <= '1'; ready_buf <= '0'; end if; else sof_buf <= '0'; sos_buf <= '0'; bna_buf <= '1'; ready_buf <= '0'; end if; end if; end process; d <= d_buf; ready <= ready_buf; sof <= sof_buf; bna <= bna_buf; sos <= sos_buf; end rtl;