-- Hi Emacs, this is -*- mode: vhdl; -*- ---------------------------------------------------------------------------------------------------- -- Interface for AD7823 (1-ch 8-bit 200kSPS Analog To Digital Converter) -- -- 2007 Javier Valcarce García, javier.valcarce@gmail.com -- $Id$ -- ---------------------------------------------------------------------------------------------------- -- The MIT License -- -- Copyright (c) 2007 Javier Valcarce García -- -- Permission is hereby granted, free of charge, to any person obtaining a copy -- of this software and associated documentation files (the "Software"), to deal -- in the Software without restriction, including without limitation the rights -- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -- copies of the Software, and to permit persons to whom the Software is -- furnished to do so, subject to the following conditions: -- -- The above copyright notice and this permission notice shall be included in -- all copies or substantial portions of the Software. -- -- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -- THE SOFTWARE. -- ---------------------------------------------------------------------------------------------------- library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_arith.all; use ieee.std_logic_unsigned.all; entity ad7823 is port ( reset : in std_logic; clk : in std_logic; clk10MHz : in std_logic; start : in std_logic; eoc : out std_logic; do : buffer std_logic_vector(7 downto 0); di : in std_logic; -- to ad7823 sclk : out std_logic; -- to ad7823 convst : out std_logic); -- to ad7823 end ad7823; architecture Behavioral of ad7823 is -- async reset for all circuits of the block signal ctlrs : std_logic; -- received bit counter signal ctr_ce : std_logic; signal ctr_eq_8 : std_logic; -- serial to paralell shift register signal sh_ce : std_logic; -- timer signal tmr_ce : std_logic; -- private to tmr process (do not use) signal tmr_ini : std_logic; signal tmr_2_us : std_logic; signal tmr_5_us : std_logic; begin -- Serial To Paralell Shift Register ---------------------------------------------------------------------------------------------------- process (reset, clk) begin if reset = '1' then -- Inicializacion del registro do <= "00000000"; elsif rising_edge(clk) then if (sh_ce = '1') then do(0) <= di; do(7 downto 1) <= do(6 downto 0); end if; end if; end process; -- Received bit counter ---------------------------------------------------------------------------------------------------- process (reset, ctlrs, clk) variable c : integer range 0 to 15; begin if (reset = '1' or ctlrs = '1') then c := 0; elsif rising_edge(clk) then if ctr_ce = '1' then c := c + 1; end if; end if; -- Combinational if c = 8 then ctr_eq_8 <= '1'; else ctr_eq_8 <= '0'; end if; end process; -- Timer: tmr_ini ---------------------------------------------------------------------------------------------------- process (reset, ctlrs, clk, clk10MHz) variable c : integer range 0 to 50; begin -- Reset/Init all circuits if (reset = '1' or ctlrs = '1') then c := 0; tmr_ce <= '0'; tmr_2_us <= '0'; tmr_5_us <= '0'; else if rising_edge(clk) then if (tmr_ini = '1' and tmr_ce = '0') then tmr_ce <= '1'; end if; -- clock strikes! at 1'5 us and 5 us if c = 20 then tmr_2_us <= '1'; end if; if c = 50 then tmr_5_us <= '1'; end if; end if; if rising_edge(clk10MHz) then if tmr_ce = '1' then c := c + 1; end if; end if; end if; end process; ---------------------------------------------------------------------------------------------------- ---------------------------------------------------------------------------------------------------- -- Control Unit (Finite State Machine) ---------------------------------------------------------------------------------------------------- ---------------------------------------------------------------------------------------------------- ctl: block type type_sreg is (STATE0, STATE1, STATE2, STATE3, STATE4, STATE5, STATE6, STATE7, STATE8, STATE9, STATE10); signal sreg : type_sreg; signal next_sreg : type_sreg; signal next_convst : std_logic; signal next_ctlrs : std_logic; signal next_sclk : std_logic; begin -- Sequential process process (reset, clk) begin if (reset = '1') then sreg <= STATE0; sclk <= '0'; convst <= '0'; ctlrs <= '1'; elsif rising_edge(clk) then sreg <= next_sreg; convst <= next_convst; ctlrs <= next_ctlrs; sclk <= next_sclk; end if; end process; -- Combinational process for non-registered and registered outputs process (sreg, ctr_eq_8, tmr_2_us, tmr_5_us, start) begin next_convst <= '1'; eoc <= '0'; ctr_ce <= '0'; sh_ce <= '0'; tmr_ini <= '0'; next_ctlrs <= '0'; next_sclk <= '0'; next_sreg <= STATE0; if not ((sreg = STATE0) or (sreg = STATE1) or (sreg = STATE2) or (sreg = STATE3) or (sreg = STATE4) or (sreg = STATE5) or (sreg = STATE6) or (sreg = STATE7) or (sreg = STATE8) or (sreg = STATE9) or (sreg = STATE10)) then next_sreg <= STATE0; tmr_ini <= '0'; sh_ce <= '0'; ctr_ce <= '0'; eoc <= '0'; next_convst <= '0'; next_ctlrs <= '1'; else case sreg is when STATE0 => tmr_ini <= '0'; sh_ce <= '0'; ctr_ce <= '0'; eoc <= '0'; next_sreg <= STATE1; next_sclk <= '0'; next_ctlrs <= '0'; next_convst <= '1'; when STATE1 => sh_ce <= '0'; ctr_ce <= '0'; eoc <= '0'; tmr_ini <= '1'; if (tmr_2_us = '0') then next_sreg <= STATE1; next_sclk <= '0'; next_ctlrs <= '0'; next_convst <= '1'; end if; if (tmr_2_us = '1') then next_sreg <= STATE2; next_sclk <= '0'; next_ctlrs <= '0'; next_convst <= '1'; end if; when STATE2 => tmr_ini <= '0'; sh_ce <= '0'; ctr_ce <= '0'; eoc <= '0'; if (start = '0') then next_sreg <= STATE2; next_sclk <= '0'; next_ctlrs <= '0'; next_convst <= '1'; end if; if (start = '1') then next_sreg <= STATE3; next_sclk <= '0'; next_ctlrs <= '0'; next_convst <= '0'; end if; when STATE3 => sh_ce <= '0'; ctr_ce <= '0'; eoc <= '0'; tmr_ini <= '1'; next_sreg <= STATE4; next_sclk <= '0'; next_ctlrs <= '0'; next_convst <= '1'; when STATE4 => sh_ce <= '0'; ctr_ce <= '0'; eoc <= '0'; tmr_ini <= '1'; if (tmr_5_us = '0') then next_sreg <= STATE4; next_sclk <= '0'; next_ctlrs <= '0'; next_convst <= '1'; end if; if (tmr_5_us = '1') then next_sreg <= STATE5; next_sclk <= '0'; next_convst <= '1'; next_ctlrs <= '1'; end if; when STATE5 => tmr_ini <= '0'; sh_ce <= '0'; ctr_ce <= '0'; eoc <= '0'; next_sreg <= STATE6; next_ctlrs <= '0'; next_convst <= '1'; next_sclk <= '1'; when STATE6 => tmr_ini <= '0'; sh_ce <= '0'; ctr_ce <= '0'; eoc <= '0'; next_sreg <= STATE7; next_ctlrs <= '0'; next_convst <= '1'; next_sclk <= '1'; when STATE7 => tmr_ini <= '0'; eoc <= '0'; sh_ce <= '1'; ctr_ce <= '1'; next_sreg <= STATE8; next_sclk <= '0'; next_ctlrs <= '0'; next_convst <= '1'; when STATE8 => tmr_ini <= '0'; sh_ce <= '0'; ctr_ce <= '0'; eoc <= '0'; next_sreg <= STATE9; next_sclk <= '0'; next_ctlrs <= '0'; next_convst <= '1'; when STATE9 => tmr_ini <= '0'; sh_ce <= '0'; ctr_ce <= '0'; eoc <= '0'; if (ctr_eq_8 = '0') then next_sreg <= STATE6; next_ctlrs <= '0'; next_convst <= '1'; next_sclk <= '1'; end if; if (ctr_eq_8 = '1') then next_sreg <= STATE10; next_sclk <= '0'; next_convst <= '1'; next_ctlrs <= '1'; end if; when STATE10 => tmr_ini <= '0'; sh_ce <= '0'; ctr_ce <= '0'; eoc <= '1'; next_sreg <= STATE2; next_sclk <= '0'; next_ctlrs <= '0'; next_convst <= '1'; when others => end case; end if; end process; end block; ---------------------------------------------------------------------------------------------------- ---------------------------------------------------------------------------------------------------- ---------------------------------------------------------------------------------------------------- end Behavioral;