summaryrefslogtreecommitdiffstats
path: root/spdif_decoder.vhd
diff options
context:
space:
mode:
Diffstat (limited to 'spdif_decoder.vhd')
-rw-r--r--spdif_decoder.vhd143
1 files changed, 143 insertions, 0 deletions
diff --git a/spdif_decoder.vhd b/spdif_decoder.vhd
new file mode 100644
index 0000000..d9e8a23
--- /dev/null
+++ b/spdif_decoder.vhd
@@ -0,0 +1,143 @@
+library IEEE;
+use IEEE.STD_LOGIC_1164.all;
+use IEEE.std_logic_unsigned.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;
+ clk : in std_logic;
+ spdif : in std_logic;
+ bmc_ready : out std_logic;
+ bmc_e : out std_logic;
+ bmc_l : out std_logic;
+ bmc_d : out std_logic;
+ sof : out std_logic;
+ bna : out std_logic;
+ d : out std_logic_vector(26 downto 0);
+ ready : 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 : 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 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<=xor_reduce(d_sr(31 downto 4));
+ parity <= '1';
+
+ process (clk, b_ready, e_sr, l_sr, d_sr, parity, 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 = '1') and (e_sr = Z32) then
+ if (d_sr(2 downto 0) = "010") and (l_sr(2 downto 0) = "101") then --B code
+ d_buf <= d_sr(29 downto 3);
+ sof_buf <= '1';
+ bna_buf <= '0';
+ ready_buf <= '1';
+ elsif (d_sr(2 downto 0) = "001") and (l_sr(2 downto 0) = "110") then --M code
+ d_buf <= d_sr(29 downto 3);
+ sof_buf <= '0';
+ bna_buf <= '0';
+ ready_buf <= '1';
+ elsif (d_sr(3 downto 0) = "0010") and (l_sr(3 downto 0) = "1000") then --W code
+ d_buf <= d_sr(30 downto 4);
+ sof_buf <= '0';
+ bna_buf <= '1';
+ ready_buf <= '1';
+ else
+ ready_buf <= '0';
+ end if;
+ else
+ ready_buf <= '0';
+ end if;
+ end if;
+
+ end process;
+
+ d <= d_buf;
+ ready <= ready_buf;
+ sof <= sof_buf;
+ bna <= bna_buf;
+
+
+
+end rtl;
+