OpenCores
URL https://opencores.org/ocsvn/gecko4/gecko4/trunk

Subversion Repositories gecko4

[/] [gecko4/] [trunk/] [GECKO4com/] [spartan200_an/] [vhdl/] [i2c/] [24LC32A_emu-behavior.vhdl] - Blame information for rev 5

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 5 ktt1
--------------------------------------------------------------------------------
2
--            _   _            __   ____                                      --
3
--           / / | |          / _| |  __|                                     --
4
--           | |_| |  _   _  / /   | |_                                       --
5
--           |  _  | | | | | | |   |  _|                                      --
6
--           | | | | | |_| | \ \_  | |__                                      --
7
--           |_| |_| \_____|  \__| |____| microLab                            --
8
--                                                                            --
9
--           Bern University of Applied Sciences (BFH)                        --
10
--           Quellgasse 21                                                    --
11
--           Room HG 4.33                                                     --
12
--           2501 Biel/Bienne                                                 --
13
--           Switzerland                                                      --
14
--                                                                            --
15
--           http://www.microlab.ch                                           --
16
--------------------------------------------------------------------------------
17
--   GECKO4com
18
--  
19
--   2010/2011 Dr. Theo Kluter
20
--  
21
--   This VHDL code is free code: you can redistribute it and/or modify
22
--   it under the terms of the GNU General Public License as published by
23
--   the Free Software Foundation, either version 3 of the License, or
24
--   (at your option) any later version.
25
--  
26
--   This VHDL code is distributed in the hope that it will be useful,
27
--   but WITHOUT ANY WARRANTY; without even the implied warranty of
28
--   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
29
--   GNU General Public License for more details. 
30
--   You should have received a copy of the GNU General Public License
31
--   along with these sources.  If not, see <http://www.gnu.org/licenses/>.
32
--
33
 
34
ARCHITECTURE xilinx OF eeprom_emu IS
35
 
36
   COMPONENT edge_detector
37
      PORT ( clock    : IN  std_logic;
38
             reset    : IN  std_logic;
39
             data_in  : IN  std_logic;
40
             pos_edge : OUT std_logic;
41
             neg_edge : OUT std_logic;
42
             data_out : OUT std_logic );
43
   END COMPONENT;
44
 
45
   COMPONENT spi_if
46
      PORT ( clock            : IN  std_logic;
47
             reset            : IN  std_logic;
48
             read_request     : IN  std_logic;
49
             write_request    : IN  std_logic;
50
             i2c_write_done   : IN  std_logic;
51
             address          : IN  std_logic_vector( 11 DOWNTO 0 );
52
             data_in          : IN  std_logic_vector(  7 DOWNTO 0 );
53
             data_out         : OUT std_logic_vector(  7 DOWNTO 0 );
54
             done             : OUT std_logic;
55
             busy             : OUT std_logic );
56
   END COMPONENT;
57
 
58
   TYPE state_type IS (IDLE,GET_CONTROL,CHECK_CONTROL,SEND_CONTROL_ACK,
59
                       GET_HI_ADDRESS,SEND_HI_ADDR_ACK,GET_LO_ADDRESS,
60
                       SEND_LO_ADDR_ACK,GET_DATA,SEND_DATA_ACK,
61
                       LATCH_DATA_OUT,WRITE_DATA, SAMPLE_DATA_ACK );
62
 
63
   SIGNAL s_scl_neg_edge     : std_logic;
64
   SIGNAL s_scl_pos_edge     : std_logic;
65
   SIGNAL s_scl_value        : std_logic;
66
   SIGNAL s_sda_neg_edge     : std_logic;
67
   SIGNAL s_sda_pos_edge     : std_logic;
68
   SIGNAL s_sda_value        : std_logic;
69
   SIGNAL s_start_condition  : std_logic;
70
   SIGNAL s_stop_condition   : std_logic;
71
   SIGNAL s_shift_reg        : std_logic_vector( 7 DOWNTO 0 );
72
   SIGNAL s_bit_count_reg    : std_logic_vector( 3 DOWNTO 0 );
73
   SIGNAL s_state_reg        : state_type;
74
   SIGNAL s_next_state       : state_type;
75
   SIGNAL s_sda_out_next     : std_logic;
76
   SIGNAL s_address_reg      : std_logic_vector(11 DOWNTO 0 );
77
   SIGNAL s_shift_next       : std_logic_vector( 7 DOWNTO 0 );
78
   SIGNAL s_spi_busy         : std_logic;
79
   SIGNAL s_i2c_write_done   : std_logic;
80
   SIGNAL s_read_request     : std_logic;
81
   SIGNAL s_write_request    : std_logic;
82
   SIGNAL s_read_request_reg : std_logic;
83
   SIGNAL s_write_request_reg: std_logic;
84
 
85
BEGIN
86
   -- Assign outputs
87
   make_SDA_out : PROCESS( clock , reset , s_sda_out_next , s_scl_neg_edge )
88
      VARIABLE v_enable_reg : std_logic;
89
   BEGIN
90
      IF (clock'event AND (clock = '1')) THEN
91
         IF (reset = '1') THEN SDA_out      <= '1';
92
                               v_enable_reg := '0';
93
                          ELSE
94
            IF (v_enable_reg = '1') THEN SDA_out <= s_sda_out_next;
95
            END IF;
96
            v_enable_reg := s_scl_neg_edge;
97
         END IF;
98
      END IF;
99
   END PROCESS make_SDA_out;
100
 
101
   -- Define control signals
102
   s_read_request    <= '1' WHEN s_start_condition = '1' OR
103
                                 (s_state_reg = LATCH_DATA_OUT AND
104
                                  s_scl_neg_edge = '1') ELSE '0';
105
   s_write_request   <= '1' WHEN (s_state_reg = SEND_DATA_ACK AND
106
                                  s_scl_pos_edge = '1') ELSE '0';
107
   s_i2c_write_done  <= s_start_condition OR s_stop_condition;
108
   s_start_condition <= s_scl_value AND s_sda_neg_edge;
109
   s_stop_condition  <= s_scl_value AND s_sda_pos_edge;
110
   s_sda_out_next    <= '0'
111
                        WHEN s_state_reg = SEND_CONTROL_ACK OR
112
                             s_state_reg = SEND_HI_ADDR_ACK OR
113
                             s_state_reg = SEND_LO_ADDR_ACK OR
114
                             s_state_reg = SEND_DATA_ACK
115
                        ELSE
116
                        s_shift_reg(7) OR NOT(button)
117
                        WHEN s_state_reg = WRITE_DATA
118
                        ELSE '1';
119
 
120
   -- Define processes
121
   make_regs : PROCESS( clock , reset , s_read_request , s_write_request )
122
   BEGIN
123
      IF (clock'event AND (clock = '1')) THEN
124
         IF (reset = '1') THEN s_read_request_reg <= '0';
125
                               s_write_request_reg <= '0';
126
                          ELSE s_read_request_reg <= s_read_request;
127
                               s_write_request_reg <= s_write_request;
128
         END IF;
129
      END IF;
130
   END PROCESS make_regs;
131
 
132
   make_shift_reg : PROCESS( clock , s_state_reg , s_sda_value , s_scl_pos_edge )
133
   BEGIN
134
      IF (clock'event AND (clock = '1')) THEN
135
         IF (s_scl_pos_edge = '1' AND
136
             (s_state_reg = GET_CONTROL OR
137
              s_state_reg = GET_DATA)) THEN
138
            s_shift_reg <= s_shift_reg(6 DOWNTO 0)&s_sda_value;
139
         ELSIF (s_scl_neg_edge = '1' AND
140
                s_state_reg = LATCH_DATA_OUT) THEN
141
            s_shift_reg <= s_shift_next;
142
         ELSIF (s_scl_neg_edge = '1' AND
143
                s_state_reg = WRITE_DATA) THEN
144
            s_shift_reg <= s_shift_reg(6 DOWNTO 0)&"1";
145
         END IF;
146
      END IF;
147
   END PROCESS make_shift_reg;
148
 
149
   make_bit_count_reg : PROCESS( clock , s_state_reg , s_scl_pos_edge ,
150
                                 s_start_condition )
151
   BEGIN
152
      IF (clock'event AND (clock = '1')) THEN
153
         IF (s_state_reg = IDLE OR
154
             s_state_reg = SEND_CONTROL_ACK OR
155
             s_state_reg = SEND_HI_ADDR_ACK OR
156
             s_state_reg = SEND_LO_ADDR_ACK OR
157
             s_state_reg = SEND_DATA_ACK OR
158
             s_start_condition = '1') THEN s_bit_count_reg <= X"0";
159
         ELSIF (s_state_reg = LATCH_DATA_OUT) THEN s_bit_count_reg <= X"1";
160
         ELSIF (((s_state_reg = GET_CONTROL OR
161
                  s_state_reg = GET_HI_ADDRESS OR
162
                  s_state_reg = GET_LO_ADDRESS OR
163
                  s_state_reg = GET_DATA)AND
164
                 s_scl_pos_edge = '1') OR
165
                (s_state_reg = WRITE_DATA AND
166
                 s_scl_neg_edge = '1')) THEN
167
            s_bit_count_reg <= unsigned(s_bit_count_reg) + 1;
168
         END IF;
169
      END IF;
170
   END PROCESS make_bit_count_reg;
171
 
172
   make_address_reg : PROCESS( clock , s_state_reg , s_sda_value ,
173
                               s_scl_pos_edge , reset , s_scl_neg_edge )
174
   BEGIN
175
      IF (clock'event AND (clock = '1')) THEN
176
         IF (reset = '1') THEN s_address_reg <= (OTHERS => '0');
177
         ELSIF (s_scl_pos_edge = '1') THEN
178
            CASE (s_state_reg) IS
179
               WHEN GET_HI_ADDRESS => s_address_reg <=
180
                                      s_address_reg(10 DOWNTO 8)&s_sda_value&
181
                                      s_address_reg( 7 DOWNTO 0);
182
               WHEN GET_LO_ADDRESS => s_address_reg <=
183
                                      s_address_reg(11 DOWNTO 8)&
184
                                      s_address_reg( 6 DOWNTO 0)&s_sda_value;
185
               WHEN OTHERS         => NULL;
186
            END CASE;
187
         ELSIF (s_scl_pos_edge = '1' AND
188
                s_state_reg = SEND_DATA_ACK) OR
189
               (s_scl_neg_edge = '1' AND
190
                s_state_reg = LATCH_DATA_OUT) THEN
191
            s_address_reg <= unsigned(s_address_reg) + 1;
192
         END IF;
193
      END IF;
194
   END PROCESS make_address_reg;
195
 
196
   make_next_state : PROCESS( s_state_reg , s_stop_condition ,
197
                              s_start_condition , s_bit_count_reg , s_shift_reg ,
198
                              s_scl_neg_edge , s_scl_pos_edge , s_spi_busy )
199
   BEGIN
200
      CASE (s_state_reg) IS
201
         WHEN GET_CONTROL        => IF (s_bit_count_reg(3) = '1') THEN
202
                                       s_next_state <= CHECK_CONTROL;
203
                                                                  ELSE
204
                                       s_next_state <= GET_CONTROL;
205
                                    END IF;
206
         WHEN CHECK_CONTROL      => IF (s_shift_reg(7 DOWNTO 1) /= "1010001" OR
207
                                        s_spi_busy = '1') THEN
208
                                       s_next_state <= IDLE;
209
                                    ELSIF (s_scl_neg_edge = '1') THEN
210
                                       s_next_state <= SEND_CONTROL_ACK;
211
                                                                 ELSE
212
                                       s_next_state <= CHECK_CONTROL;
213
                                    END IF;
214
         WHEN SEND_CONTROL_ACK   => IF (s_scl_pos_edge = '1') THEN
215
                                       IF (s_shift_reg(0) = '0') THEN
216
                                          s_next_state <= GET_HI_ADDRESS;
217
                                                                 ELSE
218
                                          s_next_state <= LATCH_DATA_OUT;
219
                                       END IF;
220
                                                                 ELSE
221
                                       s_next_state <= SEND_CONTROL_ACK;
222
                                    END IF;
223
         WHEN GET_HI_ADDRESS     => IF (s_bit_count_reg(3) = '1') THEN
224
                                       s_next_state <= SEND_HI_ADDR_ACK;
225
                                                                  ELSE
226
                                       s_next_state <= GET_HI_ADDRESS;
227
                                    END IF;
228
         WHEN SEND_HI_ADDR_ACK   => IF (s_scl_pos_edge = '1') THEN
229
                                       s_next_state <= GET_LO_ADDRESS;
230
                                                              ELSE
231
                                       s_next_state <= SEND_HI_ADDR_ACK;
232
                                    END IF;
233
         WHEN GET_LO_ADDRESS     => IF (s_bit_count_reg(3) = '1') THEN
234
                                       s_next_state <= SEND_LO_ADDR_ACK;
235
                                                                  ELSE
236
                                       s_next_state <= GET_LO_ADDRESS;
237
                                    END IF;
238
         WHEN SEND_LO_ADDR_ACK   => IF (s_scl_pos_edge = '1') THEN
239
                                       s_next_state <= GET_DATA;
240
                                                              ELSE
241
                                       s_next_state <= SEND_LO_ADDR_ACK;
242
                                    END IF;
243
         WHEN GET_DATA           => IF (s_bit_count_reg(3) = '1') THEN
244
                                       s_next_state <= SEND_DATA_ACK;
245
                                                                  ELSE
246
                                       s_next_state <= GET_DATA;
247
                                    END IF;
248
         WHEN SEND_DATA_ACK      => IF (s_scl_pos_edge = '1') THEN
249
                                       s_next_state <= GET_DATA;
250
                                                              ELSE
251
                                       s_next_state <= SEND_DATA_ACK;
252
                                    END IF;
253
         WHEN LATCH_DATA_OUT     => IF (s_scl_neg_edge = '1') THEN
254
                                       s_next_state <= WRITE_DATA;
255
                                                              ELSE
256
                                       s_next_state <= LATCH_DATA_OUT;
257
                                    END IF;
258
         WHEN WRITE_DATA         => IF (s_bit_count_reg(3) = '1' AND
259
                                        s_scl_pos_edge = '1') THEN
260
                                       s_next_state <= SAMPLE_DATA_ACK;
261
                                                                 ELSE
262
                                       s_next_state <= WRITE_DATA;
263
                                    END IF;
264
         WHEN SAMPLE_DATA_ACK    => IF (s_scl_pos_edge = '1') THEN
265
                                       IF (s_sda_value = '0') THEN
266
                                          s_next_state <= LATCH_DATA_OUT;
267
                                                              ELSE
268
                                          s_next_state <= IDLE;
269
                                       END IF;
270
                                                              ELSE
271
                                          s_next_state <= SAMPLE_DATA_ACK;
272
                                    END IF;
273
         WHEN OTHERS             => s_next_state <= IDLE;
274
      END CASE;
275
   END PROCESS make_next_state;
276
 
277
   make_state_reg : PROCESS( clock , reset , s_stop_condition ,
278
                             s_start_condition , s_next_state )
279
   BEGIN
280
      IF (clock'event AND (clock = '1')) THEN
281
         IF (reset = '1' OR
282
             s_stop_condition = '1') THEN s_state_reg <= IDLE;
283
         ELSIF (s_start_condition = '1') THEN s_state_reg <= GET_CONTROL;
284
                                         ELSE s_state_reg <= s_next_state;
285
         END IF;
286
      END IF;
287
   END PROCESS make_state_reg;
288
 
289
   -- Map components
290
   scl_det : edge_detector
291
             PORT MAP ( clock    => clock,
292
                        reset    => reset,
293
                        data_in  => SCL_in,
294
                        pos_edge => s_scl_pos_edge,
295
                        neg_edge => s_scl_neg_edge,
296
                        data_out => s_scl_value );
297
   sda_det : edge_detector
298
             PORT MAP ( clock    => clock,
299
                        reset    => reset,
300
                        data_in  => SDA_in,
301
                        pos_edge => s_sda_pos_edge,
302
                        neg_edge => s_sda_neg_edge,
303
                        data_out => s_sda_value );
304
   spi : spi_if
305
         PORT MAP ( clock            => clock,
306
                    reset            => reset,
307
                    read_request     => s_read_request_reg,
308
                    write_request    => s_write_request_reg,
309
                    i2c_write_done   => s_i2c_write_done,
310
                    address          => s_address_reg,
311
                    data_in          => s_shift_reg,
312
                    data_out         => s_shift_next,
313
                    done             => OPEN,
314
                    busy             => s_spi_busy );
315
 
316
END xilinx;

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.