library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; use work.util_pkg.all; use work.lx_dad_pkg.all; entity lx_adc_if is generic ( adc_res : positive := 18; conv_cycles : integer := 85 ); port ( clk_i : in std_logic; rst_i : in std_logic; conv_start : in std_logic; sck_o : out std_logic; cnv_o : out std_logic; data_o : out std_logic_vector((adc_res-1) downto 0); drdy_o : out std_logic; sck_i : in std_logic; SDI : in std_logic ); end lx_adc_if; architecture rtl of lx_adc_if is signal received : std_logic_vector((adc_res-1) downto 0); signal ckout : std_logic; --signal active_bit_t integer range 0 to (adc_res-1); signal active_bit_r : integer range 0 to (adc_res-1); signal conv_cnter : integer range 0 to conv_cycles; type states_i is (conv, reading, iddle); signal state_i : states_i; signal convert : std_logic; signal odd_even : std_logic; signal odd_even_r : std_logic; signal odd_even_last : std_logic; signal drdy_i : std_logic; signal drdy_i_last : std_logic; signal drdy_i_last_last : std_logic; attribute REGISTER_DUPLICATION : string; attribute REGISTER_DUPLICATION of received : signal is "NO"; attribute REGISTER_DUPLICATION of drdy_i : signal is "NO"; attribute REGISTER_DUPLICATION of drdy_i_last : signal is "NO"; attribute REGISTER_DUPLICATION of drdy_i_last_last : signal is "NO"; attribute REGISTER_DUPLICATION of odd_even : signal is "NO"; attribute REGISTER_DUPLICATION of odd_even_r : signal is "NO"; begin data_sync: process(clk_i,rst_i) begin if rst_i = '1' then drdy_o <= '0'; drdy_i_last <= '0'; drdy_i_last_last <= '0'; data_o <= (others => '0'); odd_even_r <= '0'; elsif rising_edge(clk_i) then drdy_i_last_last <= drdy_i_last; drdy_i_last <= drdy_i; drdy_o <= '0'; if drdy_i = '1' and drdy_i_last = '1' and drdy_i_last_last = '0' then data_o <= received; drdy_o <= '1'; end if; odd_even_r <= odd_even; end if; end process; adc_readout: process(sck_i,rst_i) begin if rst_i= '1' then active_bit_r <= 17; drdy_i <= '0'; received <= (others => '0'); odd_even_last <= '0'; elsif rising_edge(sck_i) then if convert = '1' and ((active_bit_r = adc_res - 1) or (odd_even_last /= odd_even_r)) then received(adc_res - 1) <= SDI; active_bit_r <= adc_res - 2; drdy_i <= '0'; odd_even_last <= odd_even_r; elsif active_bit_r /= 17 then received(active_bit_r) <= SDI; if active_bit_r = 0 then drdy_i <= '1'; active_bit_r <= adc_res - 1; else active_bit_r <= active_bit_r - 1; end if; end if; end if; end process; sck_o <= ckout; adc_control: process(clk_i, rst_i) begin if rst_i = '1' then ckout <= '0'; conv_cnter <= 0; odd_even <= '0'; elsif rising_edge(clk_i) then case state_i is when iddle => if conv_start = '1' then state_i <= conv; cnv_o <= '1'; convert <= '1'; odd_even <= not odd_even; end if; when conv => if conv_cnter = (conv_cycles - 1) then conv_cnter <= 0; state_i <= reading; else conv_cnter <= conv_cnter + 1; end if; when reading => if conv_cnter < (adc_res) then if ckout = '1' then conv_cnter <= conv_cnter + 1; end if; ckout <= not ckout; else state_i <= iddle; conv_cnter <= 0; cnv_o <= '0'; convert <= '0'; end if; end case; end if; end process; end architecture;