4  generate clock and control signals

 1 -- architecture
 2 signal iscl_oen, isda_oen   : std_logic;             -- internal I2C lines
 3 signal sda_chk              : std_logic;             -- check SDA status (multi-master arbitration)
 4 signal dscl_oen             : std_logic;             -- delayed scl_oen signals
 5 signal sSCL, sSDA           : std_logic;             -- synchronized SCL and SDA inputs
 6 signal dSCL, dSDA           : std_logic;             -- delayed versions ofsSCL and sSDA
 7 signal clk_en               : std_logic;             -- statemachine clock enable
 8 signal scl_sync, slave_wait : std_logic;             -- clock generation signals
 9 signal ial                  : std_logic;             -- internal arbitration lost signal
10 signal cnt                  : unsigned(15 downto 0); -- clock divider counter (synthesis)
11 
12 -- whenever the slave is not ready it can delay the cycle by pulling SCL low
13 -- delay scl_oen
14 process (clk, nRst)
15 begin
16     if (nRst = '0') then
17         dscl_oen <= '0';
18     elsif (clk'event and clk = '1') then
19         dscl_oen <= iscl_oen;
20     end if;
21 end process;
22 
23 -- slave_wait is asserted when master wants to drive SCL high, but the slave pulls it low
24 -- slave_wait remains asserted until the slave releases SCL
25 process (clk, nRst)
26 begin
27     if (nRst = '0') then
28         slave_wait <= '0';
29     elsif (clk'event and clk = '1') then
30         slave_wait <= (iscl_oen and not dscl_oen and not sSCL) or (slave_wait and not sSCL);
31     end if;
32 end process;
33 
34 -- master drives SCL high, but another master pulls it low
35 -- master start counting down its low cycle now (clock synchronization)
36 scl_sync <= dSCL and not sSCL and iscl_oen;
37 
38 -- generate clk enable signal
39 gen_clken: process(clk, nRst)
40 begin
41     if (nRst = '0') then
42         cnt    <= (others => '0');
43         clk_en <= '1';
44     elsif (clk'event and clk = '1') then
45            if ((rst = '1') or (cnt = 0) or (ena = '0') or (scl_sync = '1')) then
46                cnt    <= clk_cnt;
47                clk_en <= '1';
48            elsif (slave_wait = '1') then
49                cnt    <= cnt;
50                clk_en <= '0';
51            else
52                cnt    <= cnt -1;
53                clk_en <= '0';
54            end if;
55     end if;
56 end process gen_clken;

 

posted on 2015-05-07 08:00  mengdie  阅读(368)  评论(0)    收藏  举报