library ieee; use ieee.std_logic_1164.all; --use ieee.std_logic_arith.all; use ieee.std_logic_unsigned.all; ------------------------------------------------------------------------- entity INTERFACE_SERIAL_DATA is port ( CLK_OUT : out std_logic; RW_ENABLE_OUT : out std_logic; SERIAL_DATA_OUT : out std_logic ); end INTERFACE_SERIAL_DATA; -------------------------------------------------------------------------- architecture BEHAVIOR of INTERFACE_SERIAL_DATA is type STATES is (READY, WRITE_MODE, CTL_REG_A, CTL_REG_B, CTL_REG_C, CTL_REG_D); signal STATE, NEXT_STATE : STATES ; signal DATA_TX : std_logic:= '0'; signal CLK : std_logic; signal RW_ENABLE : std_logic:= '0'; signal RESET : std_logic; signal SIGNAL_RISE : std_logic; signal ENABLE : std_logic := '1'; signal SET_BUTTON : std_logic:= '0'; signal SIGNAL_SYN : std_logic:= '0'; signal CLK_ENABLE : std_logic:= '1'; signal SIGNAL_LAST : std_logic:= '0'; signal SIGNAL_FALL : std_logic:= '0'; signal FLAG_A : std_logic:= '0'; signal FLAG_B : std_logic:= '0'; signal FLAG_C : std_logic:= '0'; signal FLAG_D : std_logic:= '0'; signal default : std_logic:= '0'; constant CONTROL_REG_A : std_logic_vector(14 downto 0):= ("001001011100110"); constant CONTROL_REG_B : std_logic_vector(14 downto 0):= ("010000100111101"); constant CONTROL_REG_C : std_logic_vector(14 downto 0):= ("000100000000000"); constant VADC_REG_D : std_logic_vector(14 downto 0):= ("000010010011010"); begin EDGE_DETECT: process(CLK,RESET) begin if falling_edge(CLK) then if RESET = '1' then SIGNAL_SYN <= '0'; SIGNAL_LAST <= '0'; else SIGNAL_SYN <= SET_BUTTON; SIGNAL_LAST <= SIGNAL_SYN; end if; end if; end process EDGE_DETECT; SIGNAL_RISE <= SIGNAL_SYN and not SIGNAL_LAST; CLK_ENABLE <= SIGNAL_RISE; SIGNAL_FALL <= not SIGNAL_SYN and SIGNAL_LAST; FLAG_A <= SIGNAL_FALL; STATE_INIT : process (RESET, CLK, RW_ENABLE ) begin if CLK_ENABLE = '1' then STATE <= READY; elsif falling_edge (CLK) then if ENABLE = '1' then STATE <= NEXT_STATE; end if; end if; end process STATE_INIT; FSM_DATA_R_W : process (STATE, CLK, RW_ENABLE, FLAG_A, FLAG_B, FLAG_C, FLAG_D) variable i, j, k, l : integer:= 0; begin if falling_edge (CLK) then case STATE is when READY => -- write mode, Button[0] gedrueckt -- activate write mode NEXT_STATE <= WRITE_MODE; when WRITE_MODE => RW_ENABLE <= '0'; if FLAG_A = '1' then -- Flag in REG_A setzen NEXT_STATE <= CTL_REG_A ; elsif FLAG_B = '1' then NEXT_STATE <= CTL_REG_B; elsif FLAG_C = '1' then NEXT_STATE <= CTL_REG_C; elsif FLAG_D = '1' then NEXT_STATE <= CTL_REG_D; else default <= '0'; end if; when CTL_REG_A => RW_ENABLE <= '1'; DATA_TX <= CONTROL_REG_A (i); i := i + 1; if i >= 14 then i := 0; FLAG_B <= '1'; NEXT_STATE <= WRITE_MODE; end if; when CTL_REG_B => RW_ENABLE <= '1'; DATA_TX <= CONTROL_REG_B (j); j := j + 1; if j >= 14 then j:= 0; --RW_ENABLE <= '0'; FLAG_B <= '0'; FLAG_C <= '1'; NEXT_STATE <= WRITE_MODE; end if; when CTL_REG_C => RW_ENABLE <= '1'; DATA_TX <= CONTROL_REG_C (k); k := k + 1; if k >= 14 then k:= 0; FLAG_C <= '0'; FLAG_D <= '1'; NEXT_STATE <= WRITE_MODE; end if; when CTL_REG_D => RW_ENABLE <= '1'; DATA_TX <= VADC_REG_D (l); l := l + 1; if l >= 14 then l:= 0; --RW_ENABLE <= '0'; FLAG_D <= '0'; --FLAG_A <= '1'; NEXT_STATE <= WRITE_MODE; end if; end case; end if; end process FSM_DATA_R_W; SERIAL_DATA_OUT <= DATA_TX; RW_ENABLE_OUT <= RW_ENABLE; CLK_OUT <= CLK; --------------------------------------------------------Testbench--------------------------------------------------------------------------- TAKTGEN: process begin CLK <= '1'; wait for 500 ns; CLK <= '0'; wait for 500 ns; end process TAKTGEN; INIT_BUTTON : process begin SET_BUTTON <= '0','1' after 5 us, '0' after 15 us; wait; end process INIT_BUTTON; INIT_RESET : process begin RESET <= '0'; wait; end process INIT_RESET; end BEHAVIOR;