library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; entity omsp_quadcount is port ( mclk : in std_logic; per_addr : in std_logic_vector (7 downto 0); per_din : in std_logic_vector (15 downto 0); -- unused per_en : in std_logic; per_wen : in std_logic_vector (1 downto 0); -- unused puc : in std_logic; -- unused per_irq_acc : in std_logic; -- unused per_irq : out std_logic; -- unused per_dout : out std_logic_vector (15 downto 0); qcount : in std_logic_vector (31 downto 0) ); end omsp_quadcount; -------------------------------------------------------------------------------- architecture behavioral of omsp_quadcount 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 readed. constant QCNTL : std_logic_vector (15 downto 0) := X"0150"; -- qcount lower word logic address constant QCNTH : std_logic_vector (15 downto 0) := X"0152"; -- qcount higher word logic address signal qcntl_sel : boolean; signal qcnth_sel : boolean; signal qcnth_latch : std_logic_vector (15 downto 0) := (others => '0'); signal qcount_prev : std_logic_vector (31 downto 0) := (others => '0'); -------------------------------------------------------------------------------- begin qcntl_sel <= (per_addr = QCNTL(8 downto 1)) and (per_en = '1'); qcnth_sel <= (per_addr = QCNTH(8 downto 1)) and (per_en = '1'); per_dout <= qcount (15 downto 0) when qcntl_sel else qcnth_latch when qcnth_sel else (others => '0'); process (mclk) begin if (rising_edge(mclk) and qcntl_sel) then qcnth_latch <= qcount (31 downto 16); end if; end process; -- Generation of IRQ signal. (changes in lower 2 bits are suppresed) process (mclk) begin if (rising_edge(mclk)) then qcount_prev <= qcount; if (qcntl_sel) then per_irq <= '0'; elsif (qcount_prev (31 downto 2) /= qcount (31 downto 2)) then per_irq <= '1'; end if; end if; end process; end behavioral;