library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_arith.all; -------------------------------------------------------------------------------- entity gpio is generic ( W : integer := 8); -- GPIO port width (pin count) port ( -- Peripheral bus interface ACK_O : out std_logic; ADR_I : in std_logic_vector (1 downto 0); CLK_I : in std_logic; DAT_I : in std_logic_vector (W-1 downto 0); DAT_O : out std_logic_vector (W-1 downto 0); RST_I : in std_logic; SEL_I : in std_logic; STB_I : in std_logic; WE_I : in std_logic; -- GPIO port pins GPIO_I : in std_logic_vector (W-1 downto 0); GPIO_O : out std_logic_vector (W-1 downto 0)); end gpio; -------------------------------------------------------------------------------- architecture behavioral of gpio is signal gpio_output : std_logic_vector (W-1 downto 0) := (others => '0'); signal gpio_output_new : std_logic_vector (W-1 downto 0); signal write_en : std_logic; begin ACK_O <= SEL_I and STB_I; with ADR_I select DAT_O <= GPIO_I when "00", gpio_output when "01", (others => '-') when others; with ADR_I select gpio_output_new <= DAT_I when "01", gpio_output or DAT_I when "10", gpio_output and not DAT_I when "11", gpio_output when others; write_en <= SEL_I and STB_I and WE_I; process (CLK_I, RST_I) is begin if rising_edge(CLK_I) then if RST_I = '1' then gpio_output <= (others => '0'); else if write_en = '1' then gpio_output <= gpio_output_new; end if; end if; end if; end process; end behavioral;