X-Git-Url: https://rtime.felk.cvut.cz/gitweb/fpga/virtex2/uart.git/blobdiff_plain/67981366db36c2e7679ccffb8ab879a6825cbd51..HEAD:/omsp_quadcount.vhd diff --git a/omsp_quadcount.vhd b/omsp_quadcount.vhd index 5c84577..c58c5ed 100644 --- a/omsp_quadcount.vhd +++ b/omsp_quadcount.vhd @@ -4,19 +4,21 @@ use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; entity omsp_quadcount is + 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; -------------------------------------------------------------------------------- @@ -26,45 +28,92 @@ 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 + -- qcount lower word logic address + constant QCNTL : std_logic_vector (15 downto 0) := ADDR; + -- 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;