--- /dev/null
+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;
+
--- /dev/null
+library ieee;
+use ieee.std_logic_1164.ALL;
+use ieee.std_logic_arith.ALL;
+
+--------------------------------------------------------------------------------
+
+entity qcounter_mcu16 is
+ port (
+ -- Peripheral bus interface
+ ACK_O : out std_logic;
+ ADR_I : in std_logic;
+ CLK_I : in std_logic;
+ DAT_O : out std_logic_vector (15 downto 0);
+ SEL_I : in std_logic;
+ STB_I : in std_logic;
+ -- QCounter component interface
+ QCOUNT : in std_logic_vector (31 downto 0));
+end qcounter_mcu16;
+
+--------------------------------------------------------------------------------
+
+architecture behavioral of qcounter_mcu16 is
+
+ -- When reading whole 32-bit qcount input, first QCNTL has to be loaded, because
+ -- this event causes QCNTH to latch appropriate value of QCOUNT. This procedure
+ -- ensures that correct value is read.
+
+ -- Register of upper 16 bits of QCOUNT input.
+ signal upper_qcount : std_logic_vector (15 downto 0);
+ signal read_en : std_logic;
+
+--------------------------------------------------------------------------------
+
+begin
+
+ ACK_O <= read_en;
+
+ with ADR_I select
+ DAT_O <=
+ QCOUNT (15 downto 0) when '0',
+ upper_qcount when '1',
+ (others => 'X') when others;
+
+ read_en <= SEL_I and STB_I;
+
+
+ -- Upper qcounter register
+ QCNTH : process (CLK_I)
+ begin
+ if rising_edge(CLK_I) then
+ if read_en = '1' then
+ upper_qcount <= QCOUNT (31 downto 16);
+ end if;
+ end if;
+ end process;
+
+
+end behavioral;
+