6 generate statemachine  

  1 -- port
  2   cmd_ack : out std_logic;    -- command completed
  3   
  4 -- architecture
  5  type states is (idle, start_a, start_b, start_c, start_d, start_e, stop_a, stop_b,    
  6                  stop_c, stop_d, rd_a, rd_b, rd_c, rd_d, wr_a, wr_b, wr_c, wr_d);
  7  signal c_state : states;
  8  signal iscl_oen, isda_oen  : std_logic;   -- internal I2C lines
  9  signal sda_chk  : std_logic;  -- check SDA status (multi-master arbitration)
 10 
 11 -- statemachine
 12 nxt_state_decoder : process (clk, nRst)
 13 begin
 14     if (nRst = '0') then
 15         c_state  <= idle;
 16         cmd_ack  <= '0';
 17         iscl_oen <= '1';
 18         isda_oen <= '1';
 19         sda_chk  <= '0';
 20     elsif (clk'event and clk = '1') then
 21            if (rst = '1' or ial = '1') then
 22                c_state  <= idle;
 23                cmd_ack  <= '0';
 24                iscl_oen <= '1';
 25                isda_oen <= '1';
 26                sda_chk  <= '0';
 27            else
 28                cmd_ack <= '0'; -- default no acknowledge
 29 
 30                if (clk_en = '1') then
 31                    case (c_state) is
 32                          -- idle
 33                          when idle =>
 34                              case cmd is
 35                                  when I2C_CMD_START => c_state <= start_a;
 36                                  when I2C_CMD_STOP  => c_state <= stop_a;
 37                                  when I2C_CMD_WRITE => c_state <= wr_a;
 38                                  when I2C_CMD_READ  => c_state <= rd_a;
 39                                  when others        => c_state <= idle; -- NOP command
 40                              end case;
 41 
 42                              iscl_oen <= iscl_oen; -- keep SCL in same state
 43                              isda_oen <= isda_oen; -- keep SDA in same state
 44                              sda_chk  <= '0';      -- don't check SDA
 45 
 46                          -- start
 47                          when start_a =>
 48                              c_state  <= start_b;
 49                              iscl_oen <= iscl_oen; -- keep SCL in same state (for repeated start)
 50                              isda_oen <= '1';      -- set SDA high
 51                              sda_chk  <= '0';      -- don't check SDA
 52 
 53                          when start_b =>
 54                              c_state  <= start_c;
 55                              iscl_oen <= '1'; -- set SCL high
 56                              isda_oen <= '1'; -- keep SDA high
 57                              sda_chk  <= '0'; -- don't check SDA
 58 
 59                          when start_c =>
 60                              c_state  <= start_d;
 61                              iscl_oen <= '1'; -- keep SCL high
 62                              isda_oen <= '0'; -- set SDA low
 63                              sda_chk  <= '0'; -- don't check SDA
 64 
 65                          when start_d =>
 66                              c_state  <= start_e;
 67                              iscl_oen <= '1'; -- keep SCL high
 68                              isda_oen <= '0'; -- keep SDA low
 69                              sda_chk  <= '0'; -- don't check SDA
 70 
 71                          when start_e =>
 72                              c_state  <= idle;
 73                              cmd_ack  <= '1'; -- command completed
 74                              iscl_oen <= '0'; -- set SCL low
 75                              isda_oen <= '0'; -- keep SDA low
 76                              sda_chk  <= '0'; -- don't check SDA
 77 
 78                          -- stop
 79                         when stop_a =>
 80                             c_state  <= stop_b;
 81                             iscl_oen <= '0'; -- keep SCL low
 82                             isda_oen <= '0'; -- set SDA low
 83                             sda_chk  <= '0'; -- don't check SDA
 84 
 85                         when stop_b =>
 86                             c_state  <= stop_c;
 87                             iscl_oen <= '1'; -- set SCL high
 88                             isda_oen <= '0'; -- keep SDA low
 89                             sda_chk  <= '0'; -- don't check SDA
 90 
 91                         when stop_c =>
 92                             c_state  <= stop_d;
 93                             iscl_oen <= '1'; -- keep SCL high
 94                             isda_oen <= '0'; -- keep SDA low
 95                             sda_chk  <= '0'; -- don't check SDA
 96 
 97                         when stop_d =>
 98                             c_state  <= idle;
 99                             cmd_ack  <= '1'; -- command completed
100                             iscl_oen <= '1'; -- keep SCL high
101                             isda_oen <= '1'; -- set SDA high
102                             sda_chk  <= '0'; -- don't check SDA
103 
104                         -- read
105                         when rd_a =>
106                             c_state  <= rd_b;
107                             iscl_oen <= '0'; -- keep SCL low
108                             isda_oen <= '1'; -- tri-state SDA
109                             sda_chk  <= '0'; -- don't check SDA
110 
111                         when rd_b =>
112                             c_state  <= rd_c;
113                             iscl_oen <= '1'; -- set SCL high
114                             isda_oen <= '1'; -- tri-state SDA
115                             sda_chk  <= '0'; -- don't check SDA
116 
117                         when rd_c =>
118                             c_state  <= rd_d;
119                             iscl_oen <= '1'; -- keep SCL high
120                             isda_oen <= '1'; -- tri-state SDA
121                             sda_chk  <= '0'; -- don't check SDA
122 
123                         when rd_d =>
124                             c_state  <= idle;
125                             cmd_ack  <= '1'; -- command completed
126                             iscl_oen <= '0'; -- set SCL low
127                             isda_oen <= '1'; -- tri-state SDA
128                             sda_chk  <= '0'; -- don't check SDA
129 
130                         -- write
131                         when wr_a =>
132                             c_state  <= wr_b;
133                             iscl_oen <= '0'; -- keep SCL low
134                             isda_oen <= din; -- set SDA
135                             sda_chk  <= '0'; -- don't check SDA (SCL low)
136 
137                         when wr_b =>
138                             c_state  <= wr_c;
139                             iscl_oen <= '1'; -- set SCL high
140                             isda_oen <= din; -- keep SDA
141                             sda_chk  <= '0'; -- don't check SDA yet
142                                              -- Allow some more time for SDA and SCL to settle
143 
144                         when wr_c =>
145                             c_state  <= wr_d;
146                             iscl_oen <= '1'; -- keep SCL high
147                             isda_oen <= din; -- keep SDA
148                             sda_chk  <= '1'; -- check SDA
149 
150                         when wr_d =>
151                             c_state  <= idle;
152                             cmd_ack  <= '1'; -- command completed
153                             iscl_oen <= '0'; -- set SCL low
154                             isda_oen <= din; -- keep SDA
155                             sda_chk  <= '0'; -- don't check SDA (SCL low)
156 
157                         when others =>
158 
159                    end case;
160                end if;
161            end if;
162     end if;
163 end process nxt_state_decoder;

 

posted on 2015-05-07 10:09  mengdie  阅读(215)  评论(0)    收藏  举报