--- /dev/null
+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;
+