generic (
ADDR : std_logic_vector (15 downto 0) := X"0150");
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;
- per_dout : out std_logic_vector (15 downto 0);
-
- qcount : in std_logic_vector (31 downto 0)
- );
+ -- MCU peripheral interface
+ mclk : in std_logic;
+ puc : in std_logic;
+ per_addr : in std_logic_vector (7 downto 0);
+ per_en : in std_logic;
+ per_irq : out std_logic;
+ per_dout : out std_logic_vector (15 downto 0);
+ -- QCounter component interface
+ qclk : in std_logic;
+ qreset : in std_logic;
+ a0, b0 : in std_logic;
+ qcount : out std_logic_vector (31 downto 0));
end omsp_quadcount;
--------------------------------------------------------------------------------
-- qcount higher word logic address
constant QCNTH : std_logic_vector (15 downto 0) := ADDR + 2;
+ -- Address read decoder
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');
-
+ -- Latch of high work of qcounter component
+ signal qcnth_latch : std_logic_vector (15 downto 0);
+
+ signal qcount_out : std_logic_vector (31 downto 0);
+ -- AB error of qcounter component (lead in peripheral irq)
+ signal ab_error : std_logic;
+
+
+ component qcounter is
+ port (
+ clock : in std_logic;
+ reset : in std_logic;
+ a0, b0 : in std_logic;
+ qcount : out std_logic_vector (31 downto 0);
+ a_rise : out std_logic;
+ a_fall : out std_logic;
+ b_rise : out std_logic;
+ b_fall : out std_logic;
+ ab_event : out std_logic;
+ ab_error : out std_logic);
+ end component qcounter;
+
--------------------------------------------------------------------------------
begin
+ qcounter_1: qcounter
+ port map (
+ clock => qclk,
+ reset => qreset,
+ a0 => a0,
+ b0 => b0,
+ qcount => qcount_out,
+ a_rise => open,
+ a_fall => open,
+ b_rise => open,
+ b_fall => open,
+ ab_event => open,
+ ab_error => ab_error);
+
+
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
+ per_dout <= qcount_out (15 downto 0) when qcntl_sel else
+ qcnth_latch when qcnth_sel else
(others => '0');
-
- process (mclk)
+ qcount <= qcount_out;
+
+
+ -- QCNTL latch.
+ process (mclk, puc)
begin
- if (rising_edge(mclk) and qcntl_sel) then
- qcnth_latch <= qcount (31 downto 16);
+ if (puc = '1') then
+ qcnth_latch <= (others => '0');
+
+ elsif (rising_edge(mclk) and qcntl_sel) then
+ qcnth_latch <= qcount_out (31 downto 16);
+
end if;
end process;
- -- Generation of IRQ signal. (changes in lower 2 bits are suppresed)
- process (mclk)
+ -- Generation of IRQ signal. IRQ is cleared by QCNTL read operation.
+ process (mclk, puc)
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
+ if (puc = '1') then
+ per_irq <= '0';
+
+ elsif (rising_edge(mclk)) then
+ if (ab_error = '1') then
per_irq <= '1';
+
+ elsif (qcntl_sel) then
+ per_irq <= '0';
+
end if;
end if;
end process;