library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; -- Controller for the PMOD DA3 Digilent Board. -- The controller sends the input 'data' word to the DAC when 'start' is asserted. The 'data' input has -- to be valid only during the period 'start' is asserted, as for the transfer the word is latched -- internally. When the transfer is done, the 'done' signal is asserted for one clock cycle. The 'start' -- and 'done' cycle can be high at the same time, allowing the done signal to be asynchronously connected -- to the 'start' signal to save on latency. entity pmod_da3_ctrl is generic( TRANSFER_CLK_COUNT : integer := 16; DATA_WIDTH : integer := 16 ); port ( sclk : in std_logic; -- PMOD-DA3 reset : in std_logic; start : in std_logic; data : in std_logic_vector(DATA_WIDTH-1 downto 0); cs_n : out std_logic;-- PMOD-DA3 sdata : out std_logic;-- PMOD-DA3 ldac : out std_logic;-- PMOD-DA3 done : out std_logic ); end entity; architecture arch of pmod_da3_ctrl is --*****TYPE DECLARATION***** type STAGE_TYPE is (IDLE, TRANSFER); --*****SIGNAL DECLARATIONS***** signal buf, buf_next : std_logic_vector(DATA_WIDTH-1 downto 0) := (others => '0'); signal stage, stage_next : STAGE_TYPE := IDLE; signal count, count_next : integer range 0 to TRANSFER_CLK_COUNT := 0; -- Output Signals signal cs_n_next : std_logic := '1'; signal sdata_next : std_logic := '0'; signal done_next : std_logic := '0'; begin --LDAC Hardwired to ground ldac <= '0'; state : process(all) begin -- DEFAULT VALUES buf_next <= buf; stage_next <= stage; count_next <= count; done_next <= '0'; cs_n_next <= '1'; sdata_next <= '0'; case stage is when IDLE => if (start = '1') then stage_next <= TRANSFER; cs_n_next <= '0'; count_next <= 1; -- Shift first bit into DAC buf_next <= data(DATA_WIDTH-2 downto 0) & '0'; sdata_next <= data(DATA_WIDTH-1); end if; when TRANSFER => -- Shift Bits into DAC buf_next <= buf(DATA_WIDTH-2 downto 0) & '0'; sdata_next <= buf(DATA_WIDTH-1); cs_n_next <= '0'; if (count = TRANSFER_CLK_COUNT) then cs_n_next <= '1'; stage_next <= IDLE; done_next <= '1'; else count_next <= count + 1; end if; end case; end process; sync : process(sclk, reset) begin if (reset = '1') then -- Internal Signals buf <= (others => '0'); stage <= IDLE; count <= 0; -- Output Signals cs_n <= '1'; sdata <= '0'; done <= '0'; elsif (rising_edge(sclk)) then -- Internal Signals buf <= buf_next; stage <= stage_next; count <= count_next; -- Output Signals cs_n <= cs_n_next; sdata <= sdata_next; done <= done_next; end if; end process; end architecture;