]> rtime.felk.cvut.cz Git - fpga/virtex2/uart.git/blob - omsp_quadcount.vhd
+ README
[fpga/virtex2/uart.git] / omsp_quadcount.vhd
1 library IEEE;
2 use IEEE.STD_LOGIC_1164.ALL;
3 use IEEE.STD_LOGIC_ARITH.ALL;
4 use IEEE.STD_LOGIC_UNSIGNED.ALL;
5
6 entity omsp_quadcount is
7   generic (
8     ADDR : std_logic_vector (15 downto 0) := X"0150");
9   port (
10     -- MCU peripheral interface
11     mclk     : in  std_logic;
12     puc      : in  std_logic;
13     per_addr : in  std_logic_vector (7 downto 0);
14     per_en   : in  std_logic;
15     per_irq  : out std_logic;
16     per_dout : out std_logic_vector (15 downto 0);
17     -- QCounter component interface
18     qclk     : in  std_logic;
19     qreset   : in  std_logic;
20     a0, b0   : in  std_logic;
21     qcount   : out std_logic_vector (31 downto 0));
22 end omsp_quadcount;
23
24 --------------------------------------------------------------------------------
25
26 architecture behavioral of omsp_quadcount is
27
28   -- When reading whole 32-bit qcount input, first QCNTL has to be loaded, because
29   -- this event causes QCNTH to latch appropriate value of qcount. This procedure
30   -- ensures that correct value is readed.
31
32     -- qcount lower word logic address
33   constant QCNTL : std_logic_vector (15 downto 0) := ADDR;
34     -- qcount higher word logic address
35   constant QCNTH : std_logic_vector (15 downto 0) := ADDR + 2;
36
37   -- Address read decoder
38   signal qcntl_sel : boolean;
39   signal qcnth_sel : boolean;
40
41   -- Latch of high work of qcounter component
42   signal qcnth_latch : std_logic_vector (15 downto 0);
43
44   signal qcount_out : std_logic_vector (31 downto 0);
45   -- AB error of qcounter component (lead in peripheral irq)
46   signal ab_error : std_logic;
47   
48
49   component qcounter is
50     port (
51       clock    : in  std_logic;
52       reset    : in  std_logic;
53       a0, b0   : in  std_logic;
54       qcount   : out std_logic_vector (31 downto 0);
55       a_rise   : out std_logic;
56       a_fall   : out std_logic;
57       b_rise   : out std_logic;
58       b_fall   : out std_logic;
59       ab_event : out std_logic;
60       ab_error : out std_logic);
61   end component qcounter;
62   
63 --------------------------------------------------------------------------------
64
65 begin
66
67   qcounter_1: qcounter
68     port map (
69       clock    => qclk,
70       reset    => qreset,
71       a0       => a0,
72       b0       => b0,
73       qcount   => qcount_out,
74       a_rise   => open,
75       a_fall   => open,
76       b_rise   => open,
77       b_fall   => open,
78       ab_event => open,
79       ab_error => ab_error);
80
81   
82   qcntl_sel <= (per_addr = QCNTL(8 downto 1)) and (per_en = '1');
83   qcnth_sel <= (per_addr = QCNTH(8 downto 1)) and (per_en = '1');
84
85   per_dout <= qcount_out (15 downto 0) when qcntl_sel else
86               qcnth_latch              when qcnth_sel else
87               (others => '0');
88
89   qcount <= qcount_out;
90   
91   
92   -- QCNTL latch.
93   process (mclk, puc)
94   begin
95     if (puc = '1') then
96       qcnth_latch <= (others => '0');
97       
98     elsif (rising_edge(mclk) and qcntl_sel) then
99       qcnth_latch <= qcount_out (31 downto 16);
100       
101     end if;
102   end process;
103
104   -- Generation of IRQ signal. IRQ is cleared by QCNTL read operation.
105   process (mclk, puc)
106   begin
107     if (puc = '1') then
108       per_irq <= '0';
109
110     elsif (rising_edge(mclk)) then
111       if (ab_error = '1') then
112         per_irq <= '1';
113         
114       elsif (qcntl_sel) then
115         per_irq <= '0';
116         
117       end if;
118     end if;
119   end process;
120
121 end behavioral;
122