I2C controller core之Bit controller(05)

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;

 

你可能感兴趣的:(controller)