library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.NUMERIC_STD.ALL; -- Module to communicate with LTC1407 -- can be used for single-shot conversion (both channels) or -- free running conversion. -- At free running conversion, memory address lines will be incremented on each sample entity sr_adc5 is Port ( cs : in STD_LOGIC; -- chip-select: ADC starts with setting cs high frc : in STD_LOGIC; -- free running conversion (high) or single shot (low) i_clock : in STD_LOGIC; -- system clock adata : in STD_LOGIC; -- serial data from ADC o_clock : inout STD_LOGIC; -- clock line to ADC, will be internal clock too aconv : inout STD_LOGIC; -- trigger to start conversion nWE : out STD_LOGIC; -- negated write enable (memory) oChA : out STD_LOGIC_VECTOR (15 downto 0); -- channel A result data from ADC oChB : out STD_LOGIC_VECTOR (15 downto 0); -- channel B result data from ADC oaddr : out STD_LOGIC_VECTOR (19 downto 0)); -- self incrementing memory address in free running mode end sr_adc5; architecture std of sr_adc5 is SIGNAL scounter : STD_LOGIC_VECTOR (5 downto 0); SIGNAL acounter : STD_LOGIC_VECTOR (19 downto 0); SIGNAL shiftreg : STD_LOGIC_VECTOR (31 downto 0); SIGNAL doADC : STD_LOGIC := '1'; begin -- generate serial and internal clock process (cs, i_clock) begin if (cs = '0') then o_clock <= '0'; elsif rising_edge(i_clock) then o_clock <= not o_clock; end if; end process; -- generate serial data counter process (cs, o_clock) begin if (cs = '0') then scounter <= (others=>'1'); shiftreg <= (others=>'0'); elsif falling_edge(o_clock) then if (doADC = '1') then if (scounter = "101001") then -- don't wait for counter wrapping scounter <= (others=>'0'); else scounter <= std_logic_vector(unsigned(scounter) + 1); end if; shiftreg <= shiftreg(31 downto 1) & adata; end if; end if; end process; -- process serial data counter process (cs, o_clock, scounter) begin if (cs = '0') then acounter <= (others=>'0'); nWE <= '1'; elsif rising_edge(o_clock) then case scounter is when "000000" => -- 0 aconv <= '1'; when "000010" => -- 2 aconv <= '0'; when "011111" => -- 31 acounter <= std_logic_vector(unsigned(acounter) + 1); when "100000" => -- 32 oChB <= "0000" & shiftreg(31 downto 20); oChA <= "0000" & shiftreg(15 downto 4); oaddr <= acounter; when "100001" => -- 33 nWE <= '0'; when "101000" => -- 40 nWE <= '1'; doADC <= frc; when others => doADC <= doADC; -- TODO: do nothing? end case; end if; end process; end std;