-- Hi Emacs, this is -*- mode: vhdl; -*- ---------------------------------------------------------------------------------------------------- -- Interface for AD7303 (2-ch 8-bit 1MHz Digital To Analog Converter) -- -- SCLK = clk/2 ==> clk < 60MHz because the max SCLK freq for AD7303 is 30MHz -- -- 2007 Javier Valcarce García, javier.valcarce@gmail.com -- 2008-06-06 Faisal Abu-Nimeh: -- Fixed counter for e2-e3 to include the missing 16th bit. -- ---------------------------------------------------------------------------------------------------- -- 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; use work.utils.all; entity ad7303 is port ( reset : in std_logic; clk : in std_logic; wr : in std_logic; XL_wr : in std_logic; XR_wr : in std_logic; XL : in std_logic_vector(7 downto 0); -- A XR : in std_logic_vector(7 downto 0); -- B rdy : out std_logic; int_rdy : out std_logic; sclk : out std_logic; din : out std_logic; sync : out std_logic); end ad7303; architecture Behavioral of ad7303 is constant CTLBYTE_XL : std_logic_vector := "00100011"; constant CTLBYTE_XR : std_logic_vector := "00100111"; signal regWR : std_logic; signal regXL : std_logic_vector(07 downto 0); signal regXR : std_logic_vector(07 downto 0); signal muxout : std_logic_vector(15 downto 0); signal rdy_aux : std_logic; -- edge detector signal int1 : std_logic; signal int2 : std_logic; -- sequencer control signals signal rs : std_logic; signal sel : std_logic; signal ctr_ce : std_logic; signal ctr_tc : std_logic := '0'; signal osr_ce : std_logic; signal osr_ld : std_logic; begin -- i/o registers process (reset, clk) begin -- process if reset = '1' then regWR <= '0'; elsif rising_edge(clk) then if rs = '1' then regWR <= '0'; else if regWR = '0' then regWR <= wr; end if; end if; end if; end process; regXL <= "00000000" when reset = '1' else XL when rising_edge(clk) and XL_wr = '1' and rdy_aux = '1'; regXR <= "00000000" when reset = '1' else XR when rising_edge(clk) and XR_wr = '1' and rdy_aux = '1'; muxout <= (CTLBYTE_XL & regXL) when sel = '0' else (CTLBYTE_XR & regXR); rdy_aux <= not regWR; rdy <= rdy_aux; -- Positive edge detector over signal rdy ---------------------------------------------------------------------------------------------------- int1 <= '1' when reset = '1' else rdy_aux when rising_edge(clk); int2 <= '1' when reset = '1' else int1 when rising_edge(clk); int_rdy <= int1 and not int2; -- 4-bit counter ---------------------------------------------------------------------------------------------------- process (reset, clk) variable count : std_logic_vector(4 downto 0); --variable count : std_logic_vector(3 downto 0); begin if reset = '1' then count := "00000"; elsif rising_edge(clk) then if ctr_ce = '1' then count := count + 1; end if; if count = "10000" then ctr_tc <= '1'; count := "00000"; else ctr_tc <= '0'; end if; end if; end process; -- 16-bit output shift register, signals: muxout, din, osr_ce, osr_ld ---------------------------------------------------------------------------------------------------- process(reset, clk) variable data : std_logic_vector(15 downto 0); begin if reset = '1' then data := (others => '0'); elsif rising_edge(clk) then if osr_ce = '1' then if osr_ld = '1' then data := muxout; else data := data(14 downto 0) & "0"; end if; end if; end if; din <= data(15); end process; -- Control Unit (Finite State Machine) ---------------------------------------------------------------------------------------------------- CTL : block type state_type is (e0, e1, e2, e3, ee, e4, e5, e6, e7); signal state : state_type; signal op : std_logic_vector(6 downto 0); begin -- Graph transitions process (reset, clk) begin if reset = '1' then state <= e0; elsif rising_edge(clk) then case (state) is when e0 => if (regWR = '1') then state <= e1; end if; when e1 => state <= e2; when e2 => state <= e3; when e3 => if (ctr_tc = '0') then state <= e2; else state <= ee; end if; when ee => state <= e4; when e4 => state <= e5; when e5 => state <= e6; when e6 => if (ctr_tc = '0') then state <= e5; else state <= e7; end if; when e7 => state <= e0; end case; end if; end process; ---------------------------------------------------------------------------------------------------- -- control signals for data path process (state) begin case state is -- rs sel sync osr_ce osr_ld ctr_ce sclk when e0 => op <= STRTRIM("0 - 1 0 0 0 0"); when e1 => op <= STRTRIM("0 0 1 1 1 0 0"); when e2 => op <= STRTRIM("0 0 0 0 0 1 0"); when e3 => op <= STRTRIM("0 0 0 1 0 0 1"); when ee => op <= STRTRIM("0 - 1 - - 0 0"); when e4 => op <= STRTRIM("0 1 1 1 1 0 0"); when e5 => op <= STRTRIM("0 1 0 0 0 1 0"); when e6 => op <= STRTRIM("0 1 0 1 0 0 1"); when e7 => op <= STRTRIM("1 - 0 0 0 0 0"); end case; end process; rs <= op(6); sel <= op(5); sync <= op(4); osr_ce <= op(3); osr_ld <= op(2); ctr_ce <= op(1); sclk <= op(0); end block; ---------------------------------------------------------------------------------------------------- end Behavioral;