From 22bcde813e924f2cca7b96941465ae0737b82fc3 Mon Sep 17 00:00:00 2001 From: root Date: Thu, 17 May 2018 17:43:06 +0100 Subject: working 3 detectors with parity checks --- Makefile | 2 +- counter.vhd | 9 +-- silence_detector.vhd | 74 +++++++++++++++++++---- spdif.qsf | 21 ++++--- spdif.vhd | 161 +++++++++++++++++++-------------------------------- spdif_decoder.vhd | 64 +++++++++++--------- 6 files changed, 177 insertions(+), 154 deletions(-) diff --git a/Makefile b/Makefile index b4eb14e..d3b7732 100644 --- a/Makefile +++ b/Makefile @@ -3,7 +3,7 @@ PROJ=spdif SRCS=$(wildcard *.vhd *.v *.qsf *.qpf ) TIDY_SRC= bmc_decoder.vhd ccd.vhd silence_detector.vhd counter.vhd dflipflop.vhd spdif_decoder.vhd spdif.vhd -SOF=${PROJ}.sof +SOF=output_files/${PROJ}.sof POF=${PROJ}.pof JIC=${PROJ}.jic diff --git a/counter.vhd b/counter.vhd index 0be542f..9fad8b3 100644 --- a/counter.vhd +++ b/counter.vhd @@ -11,7 +11,7 @@ entity counter is divisor : in integer; clk : in std_logic; n_reset : in std_logic; - clk_out : out std_logic + pulse_out : out std_logic ); end counter; @@ -19,12 +19,12 @@ end counter; architecture rtl of counter is signal d : - std_logic_vector (15 downto 0); + std_logic_vector (31 downto 0); signal q : std_logic; begin - clk_out <= q; + pulse_out <= q; process (clk, d, q, divisor, n_reset) begin if n_reset = '0' then @@ -34,9 +34,10 @@ begin if d < divisor then d <= d + 1; + q<='0'; else d <= (others => '0'); - q <= not q; + q <= '1'; end if; end if; end process; diff --git a/silence_detector.vhd b/silence_detector.vhd index fe85824..5556e68 100644 --- a/silence_detector.vhd +++ b/silence_detector.vhd @@ -8,47 +8,97 @@ use IEEE.numeric_std.all; entity silence_detector is port ( - max_ticks : in integer; + silent_thresh : in integer; + valid_thresh : in integer; + valid_divisor : in integer; + clk : in std_logic; + sos : in std_logic; d : in std_logic_vector(23 downto 0); n_reset : in std_logic; - silent : out std_logic + silent : out std_logic; + valid : out std_logic; + dbg : out std_logic ); end silence_detector; architecture rtl of silence_detector is - signal ticks : std_logic_vector (31 downto 0); + component counter is + port + ( + divisor : in integer; + clk : in std_logic; + n_reset : in std_logic; + pulse_out : out std_logic + ); + end component; + + + signal silence : std_logic_vector (31 downto 0); signal last_d : std_logic_vector (23 downto 0); signal silent_buf : std_logic; + signal valid_buf : std_logic; + signal validity : std_logic_vector(31 downto 0); + + signal interval : std_logic; begin - process (last_d, d, clk, max_ticks, ticks) + vcnt : counter port map ( + n_reset => n_reset, + clk => clk, + divisor => valid_divisor, + pulse_out =>interval + ); + + process (last_d, d, clk, sos, silent_thresh, silence) begin if n_reset = '0' then - ticks <= (others => '0'); - silent_buf <= '0'; - last_d <= (others => '0'); - elsif rising_edge(clk) then + silence <= (others => '0'); + silent_buf <= '0'; + last_d <= (others => '0'); + elsif rising_edge(clk) and sos='1' then last_d <= d; - if last_d = d then - if ticks < max_ticks then - ticks <= ticks +1; + if silence < silent_thresh then + silence <= silence +1; else silent_buf <= '1'; end if; else - ticks <= (others => '0'); + silence <= (others => '0'); silent_buf <= '0'; end if; end if; end process; + process (clk, sos, interval, valid_thresh,validity ) + begin + if n_reset = '0' then + validity <= (others => '0'); + valid_buf <= '0'; + elsif rising_edge(clk) then + if interval='1' then + + validity <= (others => '0'); + if validity > valid_thresh then + valid_buf <='1'; + else + valid_buf <='0'; + end if; + elsif sos='1' then + validity <= validity + 1; + end if; + end if; + end process; silent <= silent_buf; + valid <= valid_buf; + + dbg<=interval; + end rtl; diff --git a/spdif.qsf b/spdif.qsf index e1ddff1..e8889ac 100644 --- a/spdif.qsf +++ b/spdif.qsf @@ -28,8 +28,6 @@ set_location_assignment PIN_73 -to n_rst_in set_instance_assignment -name WEAK_PULL_UP_RESISTOR OFF -to spdif_in set_location_assignment PIN_112 -to n_mute_out set_location_assignment PIN_114 -to n_stby_out -set_location_assignment PIN_41 -to dbg1 -set_location_assignment PIN_101 -to dbg2 set_global_assignment -name VHDL_FILE ccd.vhd set_global_assignment -name VHDL_FILE counter.vhd set_global_assignment -name VHDL_FILE dflipflop.vhd @@ -39,15 +37,22 @@ set_global_assignment -name VHDL_FILE spdif.vhd set_global_assignment -name VHDL_FILE bmc_decoder.vhd set_global_assignment -name VHDL_FILE spdif_decoder.vhd set_global_assignment -name VHDL_FILE silence_detector.vhd +set_global_assignment -name VHDL_FILE detector.vhd +set_global_assignment -name VHDL_FILE divider.vhd set_global_assignment -name SOURCE_FILE db/spdif.cmp.rdb set_global_assignment -name SDC_FILE spdif.sdc -set_location_assignment PIN_103 -to dbg3 -set_location_assignment PIN_104 -to dbg4 -set_location_assignment PIN_113 -to dbg5 -set_location_assignment PIN_115 -to dbg6 -set_location_assignment PIN_118 -to dbg7 -set_location_assignment PIN_119 -to dbg8 +set_location_assignment PIN_41 -to dbg[0] +set_location_assignment PIN_101 -to dbg[1] +set_location_assignment PIN_103 -to dbg[2] +set_location_assignment PIN_104 -to dbg[3] +set_location_assignment PIN_113 -to dbg[4] +set_location_assignment PIN_115 -to dbg[5] +set_location_assignment PIN_118 -to dbg[6] +set_location_assignment PIN_119 -to dbg[7] set_global_assignment -name USE_CONFIGURATION_DEVICE ON set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top set_global_assignment -name RESERVE_ALL_UNUSED_PINS "AS OUTPUT DRIVING GROUND" + +set_global_assignment -name EDA_SIMULATION_TOOL "ModelSim (Verilog)" +set_global_assignment -name EDA_OUTPUT_DATA_FORMAT "VERILOG HDL" -section_id eda_simulation diff --git a/spdif.vhd b/spdif.vhd index 5ee9a3c..cf78f55 100644 --- a/spdif.vhd +++ b/spdif.vhd @@ -12,29 +12,27 @@ entity spdif is n_leds : out std_logic_vector(2 downto 0); n_mute_out : out std_logic; n_stby_out : out std_logic; + dbg : out std_logic_vector(7 downto 0) - dbg1 : out std_logic; - dbg2 : out std_logic; - dbg3 : out std_logic; - dbg4 : out std_logic; - dbg5 : out std_logic; - dbg6 : out std_logic; - dbg7 : out std_logic; - dbg8 : out std_logic ); end spdif; architecture rtl of spdif is - component ccd is - port - ( - n_reset : in std_logic; - clk : in std_logic; - d : in std_logic; - q : out std_logic - ); - end component; + +component detector is + port ( + clk_in : in std_logic; + spdif_in: in std_logic; + n_reset : in std_logic; + divisor : in integer; + silent_thresh : in integer; + valid_divisor: in integer; + valid_thresh : in integer; + mute : out std_logic; + dbg:out std_logic_vector(7 downto 0) + ); +end component; component pll100 is port ( @@ -53,63 +51,17 @@ architecture rtl of spdif is ); end component; - component counter is - port - ( - divisor : in integer; - clk : in std_logic; - n_reset : in std_logic; - clk_out : out std_logic - ); - end component; - - component spdif_decoder is - 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 component; - - - component silence_detector is - port - ( - max_ticks : in integer; - clk : in std_logic; - d : in std_logic_vector(23 downto 0); - n_reset : in std_logic; - silent : out std_logic - ); - end component; - - - signal n_reset : std_logic; signal clk_200mhz : std_logic; -- signal clk_100mhz : -- std_logic; - signal spdif_clkd1 : - std_logic; - signal clk1 : - std_logic; - signal d1 : std_logic_vector(26 downto 0); - signal bna1 : std_logic; - signal sof1 : std_logic; - signal ready1 : std_logic; signal mute1 : std_logic; + signal mute2 : std_logic; + signal mute3 : std_logic; + signal mute : std_logic; begin n_reset <= n_rst_in; @@ -122,55 +74,58 @@ begin c0 => clk_200mhz ); - div1 : counter port map ( - n_reset => n_reset, - clk => clk_200mhz, - divisor => 6, - clk_out => clk1 + -- 96000Hz + det1 : detector port map ( + n_reset => n_reset, + clk_in => clk_200mhz, + spdif_in => spdif_in, + + divisor => 2, -- divisor to turn clk_in into 6x spdif base frequency + silent_thresh => 96000, -- number of samples of same sample before we declare silence + valid_divisor => 100000000, -- (clk_in/(divisor*valid_divisor)) is period for validity checks + valid_thresh => 90000, -- number of valid samples that must be received in validity period to declare it's all ok. + + mute => mute1 ); - b1 : - ccd port map ( - n_reset => n_reset, - clk => clk1, - d => spdif_in, - q => spdif_clkd1 - ); - dec1 : spdif_decoder port map ( + -- 44100Hz + det2 : detector port map ( n_reset => n_reset, - clk => clk1, - spdif => spdif_clkd1, - bmc_ready => dbg3, - bmc_e => dbg4, - bmc_l => dbg5, - bmc_d => dbg6, - bna => bna1, - d => d1, - ready => ready1 - ); + clk_in => clk_200mhz, + spdif_in => spdif_in, + divisor => 5, -- divisor to turn clk_in into 6x spdif base frequency + silent_thresh => 44100, -- number of samples of same sample before we declare silence + valid_divisor => 40000000, -- (clk_in/(divisor*valid_divisor)) is period for validity checks + valid_thresh => 40000, -- number of valid samples that must be received in validity period to declare it's all ok. - dbg8 <= bna1; + mute => mute2, + dbg => dbg + ); - sd1 : silence_detector port map( + -- 32000Hz + det3 : detector port map ( n_reset => n_reset, - clk => clk1, - d => d1(26 downto 3), - max_ticks => 33333333, -- 1 second - silent => mute1 + clk_in => clk_200mhz, + spdif_in => spdif_in, + + divisor => 8, -- divisor to turn clk_in into 6x spdif base frequency + silent_thresh => 32000, -- number of samples of same sample before we declare silence + valid_divisor => 25000000, -- (clk_in/(divisor*valid_divisor)) is period for validity checks + valid_thresh => 30000, -- number of valid samples that must be received in validity period to declare it's all ok. + + mute => mute3 ); - n_mute_out <= not mute1; - n_stby_out <= '0'; +mute <= mute1 or mute2 or mute3; - dbg1 <= spdif_clkd1; - dbg2 <= clk1; - dbg7 <= ready1; + n_mute_out <= not mute; + n_stby_out <= not mute; - n_leds(0) <= d1(26); - n_leds(1) <= d1(25); - n_leds(2) <= not mute1; + n_leds(0) <= mute1; + n_leds(1) <= mute2; + n_leds(2) <= mute3; diff --git a/spdif_decoder.vhd b/spdif_decoder.vhd index d9e8a23..a8e9d94 100644 --- a/spdif_decoder.vhd +++ b/spdif_decoder.vhd @@ -1,6 +1,7 @@ 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; @@ -12,22 +13,25 @@ entity spdif_decoder is 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; +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 @@ -50,7 +54,7 @@ architecture rtl of spdif_decoder is signal b_l : std_logic; signal b_d : std_logic; - signal parity : 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); @@ -58,6 +62,7 @@ architecture rtl of spdif_decoder is 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 @@ -95,10 +100,9 @@ begin end process; --- parity<=xor_reduce(d_sr(31 downto 4)); - parity <= '1'; + parity_valid<= not xor_reduce(d_sr(31 downto 4)); - process (clk, b_ready, e_sr, l_sr, d_sr, parity, n_reset) + process (clk, b_ready, e_sr, l_sr, d_sr, parity_valid, n_reset) begin if n_reset = '0' then d_buf <= (others => '0'); @@ -106,26 +110,35 @@ begin 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 + 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(2 downto 0) = "001") and (l_sr(2 downto 0) = "110") then --M code + 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) = "0010") and (l_sr(3 downto 0) = "1000") then --W code + 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 - ready_buf <= '0'; + 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; @@ -136,8 +149,7 @@ begin ready <= ready_buf; sof <= sof_buf; bna <= bna_buf; - - + sos <= sos_buf; end rtl; -- cgit v1.2.3