-- -- DSAT EPP Test interface -- library IEEE; use IEEE.STD_LOGIC_1164.all; use IEEE.std_logic_unsigned.all; use IEEE.std_logic_arith.all; library dsat_lib; use dsat_lib.dsat.all; entity epp2 is port ( gclk, grst : in std_logic; --master clock, reset debug_s : out std_logic_vector(3 downto 0); -- EPP port signals epp_din : in std_logic_vector(7 downto 0); --EPP data in epp_dout : out std_logic_vector(7 downto 0); --EPP data out wr, ds, as, rst : in std_logic; --EPP strobes, active low ddir : out std_logic; --EPP buffer direction '1'=out to PC den : out std_logic; --EPP buffer control '0'=enable epp_wait : out std_logic; --EPP busy output -- Local bus signals lb_data_in : in std_logic_vector(7 downto 0); -- data in lb_data_out : out std_logic_vector(7 downto 0); -- data out lb_addr : out std_logic_vector(1 downto 0); -- latched address (low bits) lb_dev : out std_logic_vector(DEV_BITS-1 downto 0); -- latched address (hi bits) lb_byte : out std_logic_vector(1 downto 0); -- byte counter for word access lb_read : out std_logic; -- local bus read enable lb_write : out std_logic); -- local bus write enable end epp2; architecture epp_fsm_arch of epp2 is attribute enum_encoding : string; attribute fsm_encoding : string; -- force binary encoding for fault-tolerance -- type state_t is (idle, rw1, wr1, wr2, rd1, rd2, rd3, wait1, wait2); type state_t is (idle, d1, d2, d3, d4, d5, rw1, wr1, wr2, rd1, rd2, rd3, wait1, wait2); -- attribute enum_encoding of state_t : type is "0000 0001 0010 0011 0100 0101 0110 0111 1000"; signal state : state_t; -- attribute fsm_encoding of state : signal is "user"; signal wait_n, stb_n : std_logic; signal addr_l, data_wr : std_logic_vector(7 downto 0); signal epp_dout_s : std_logic_vector( 7 downto 0); -- output data latch signal epp_din_s : std_logic_vector(7 downto 0); signal byte_num : std_logic_vector(1 downto 0); signal den_s, dir_s : std_logic; signal state_s : std_logic_vector(3 downto 0); signal stbQ_n, wrQ, asQ, dsQ : std_logic; begin -- epp_arch -- state machine decoded outputs with state select wait_n <= -- delay wait going high for 5 clocks '0' when idle | d1 | d2 | d3| d4| d5 | rw1, '1' when others; with state select den_s <= '1' when idle | d1 | d2 | d3| d4| d5, '0' when others; process (gclk, grst) begin if grst = '0' then -- asynchronous reset (active low) state <= idle; elsif gclk'event and gclk = '1' then -- rising clock edge -- synchronize inputs stbQ_n <= stb_n; wrQ <= wr; asQ <= as; dsQ <= ds; epp_din_s <= epp_din; lb_read <= '0'; lb_write <= '0'; case state is when idle => if stbQ_n = '0' then state <= d1; end if; when d1 => if stbQ_n = '0' then state <= d2; else state <= idle; end if; when d2 => if stbQ_n = '0' then state <= d3; else state <= idle; end if; when d3 => if stbQ_n = '0' then state <= d4; else state <= idle; end if; when d4 => if stbQ_n = '0' then state <= d5; else state <= idle; end if; when d5 => if stbQ_n = '0' then state <= rw1; else state <= idle; end if; when rw1 => if stbQ_n = '1' then state <= idle; else if wrQ = '0' then state <= wr1; else state <= rd1; end if; end if; when wr1 => state <= wr2; when wr2 => -- address write if asQ = '0' then addr_l <= epp_din_s; -- capture address byte_num <= "00"; -- reset byte count -- data write else lb_write <= '1'; data_wr <= epp_din_s; end if; state <= wait1; when rd1 => state <= rd2; if asQ = '1' then lb_read <= '1'; --assert lb_read on data read end if; when rd2 => --wait for lb cycle state <= rd3; when rd3 => -- data or address read -- update output data on falling edge of strobe with no write if asQ = '0' then epp_dout_s <= addr_l; else epp_dout_s <= lb_data_in; --and grab data end if; state <= wait1; when wait1 => if dsQ = '0' then byte_num <= byte_num + 1; end if; state <= wait2; when wait2 => if stbQ_n = '1' then state <= idle; end if; when others => state <= idle; end case; end if; end process; -- asynchronous stuff -- debug_s <= state_s; debug_s <= ( den_s & wait_n & stbQ_n & stb_n ); epp_dout <= epp_dout_s; -- epp_dout <= X"78"; lb_data_out <= data_wr; lb_addr <= addr_l(1 downto 0); lb_dev <= addr_l(7 downto 8-DEV_BITS); lb_byte <= byte_num; ddir <= wr; den <= den_s; -- den <= '1'; stb_n <= as and ds; epp_wait <= wait_n; end epp_fsm_arch;