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

Subversion Repositories mips_enhanced

[/] [mips_enhanced/] [trunk/] [grlib-gpl-1.0.19-b3188/] [lib/] [opencores/] [i2c/] [i2c_master_byte_ctrl.vhd] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 dimamali
---------------------------------------------------------------------
2
----                                                             ----
3
----  WISHBONE revB2 compl. I2C Master Core; byte-controller     ----
4
----                                                             ----
5
----                                                             ----
6
----  Author: Richard Herveille                                  ----
7
----          richard@asics.ws                                   ----
8
----          www.asics.ws                                       ----
9
----                                                             ----
10
----  Downloaded from: http://www.opencores.org/projects/i2c/    ----
11
----                                                             ----
12
---------------------------------------------------------------------
13
----                                                             ----
14
---- Copyright (C) 2000 Richard Herveille                        ----
15
----                    richard@asics.ws                         ----
16
----                                                             ----
17
---- This source file may be used and distributed without        ----
18
---- restriction provided that this copyright statement is not   ----
19
---- removed from the file and that any derivative work contains ----
20
---- the original copyright notice and the associated disclaimer.----
21
----                                                             ----
22
----     THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY     ----
23
---- EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED   ----
24
---- TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS   ----
25
---- FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR      ----
26
---- OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,         ----
27
---- INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES    ----
28
---- (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE   ----
29
---- GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR        ----
30
---- BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF  ----
31
---- LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT  ----
32
---- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT  ----
33
---- OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE         ----
34
---- POSSIBILITY OF SUCH DAMAGE.                                 ----
35
----                                                             ----
36
---------------------------------------------------------------------
37
 
38
--  CVS Log
39
--
40
--  $Id: i2c_master_byte_ctrl.vhd,v 1.5 2004/02/18 11:41:48 rherveille Exp $
41
--
42
--  $Date: 2004/02/18 11:41:48 $
43
--  $Revision: 1.5 $
44
--  $Author: rherveille $
45
--  $Locker:  $
46
--  $State: Exp $
47
--
48
-- Change History:
49
--               $Log: i2c_master_byte_ctrl.vhd,v $
50
--               Revision 1.5  2004/02/18 11:41:48  rherveille
51
--               Fixed a potential bug in the statemachine. During a 'stop' 2 cmd_ack signals were generated. Possibly canceling a new start command.
52
--
53
--               Revision 1.4  2003/08/09 07:01:13  rherveille
54
--               Fixed a bug in the Arbitration Lost generation caused by delay on the (external) sda line.
55
--               Fixed a potential bug in the byte controller's host-acknowledge generation.
56
--
57
--               Revision 1.3  2002/12/26 16:05:47  rherveille
58
--               Core is now a Multimaster I2C controller.
59
--
60
--               Revision 1.2  2002/11/30 22:24:37  rherveille
61
--               Cleaned up code
62
--
63
--               Revision 1.1  2001/11/05 12:02:33  rherveille
64
--               Split i2c_master_core.vhd into separate files for each entity; same layout as verilog version.
65
--               Code updated, is now up-to-date to doc. rev.0.4.
66
--               Added headers.
67
--
68
 
69
-- Modified by Jan Andersson (jan@gaisler.com). Changed std_logic_arith to numeric_std.
70
 
71
 
72
--
73
------------------------------------------
74
-- Byte controller section
75
------------------------------------------
76
--
77
library ieee;
78
use ieee.std_logic_1164.all;
79
library grlib;
80
use grlib.stdlib.all;
81
 
82
entity i2c_master_byte_ctrl is
83
        port (
84
                clk    : in std_logic;
85
                rst    : in std_logic; -- synchronous active high reset (WISHBONE compatible)
86
                nReset : in std_logic;  -- asynchornous active low reset (FPGA compatible)
87
                ena    : in std_logic; -- core enable signal
88
 
89
                clk_cnt : in std_logic_vector(15 downto 0);      -- 4x SCL
90
 
91
                -- input signals
92
                start,
93
                stop,
94
                read,
95
                write,
96
                ack_in : std_logic;
97
                din    : in std_logic_vector(7 downto 0);
98
 
99
                -- output signals
100
                cmd_ack  : out std_logic; -- command done
101
                ack_out  : out std_logic;
102
                i2c_busy : out std_logic; -- arbitration lost
103
                i2c_al   : out std_logic; -- i2c bus busy
104
                dout     : out std_logic_vector(7 downto 0);
105
 
106
                -- i2c lines
107
                scl_i   : in std_logic;  -- i2c clock line input
108
                scl_o   : out std_logic; -- i2c clock line output
109
                scl_oen : out std_logic; -- i2c clock line output enable, active low
110
                sda_i   : in std_logic;  -- i2c data line input
111
                sda_o   : out std_logic; -- i2c data line output
112
                sda_oen : out std_logic  -- i2c data line output enable, active low
113
        );
114
end entity i2c_master_byte_ctrl;
115
 
116
architecture structural of i2c_master_byte_ctrl is
117
        component i2c_master_bit_ctrl is
118
        port (
119
                clk    : in std_logic;
120
                rst    : in std_logic;
121
                nReset : in std_logic;
122
                ena    : in std_logic;                          -- core enable signal
123
 
124
                clk_cnt : in std_logic_vector(15 downto 0);              -- clock prescale value
125
 
126
                cmd     : in std_logic_vector(3 downto 0);
127
                cmd_ack : out std_logic; -- command done
128
                busy    : out std_logic; -- i2c bus busy
129
                al      : out std_logic; -- arbitration lost
130
 
131
                din  : in std_logic;
132
                dout : out std_logic;
133
 
134
                -- i2c lines
135
                scl_i   : in std_logic;  -- i2c clock line input
136
                scl_o   : out std_logic; -- i2c clock line output
137
                scl_oen : out std_logic; -- i2c clock line output enable, active low
138
                sda_i   : in std_logic;  -- i2c data line input
139
                sda_o   : out std_logic; -- i2c data line output
140
                sda_oen : out std_logic  -- i2c data line output enable, active low
141
        );
142
        end component i2c_master_bit_ctrl;
143
 
144
        -- commands for bit_controller block
145
        constant I2C_CMD_NOP    : std_logic_vector(3 downto 0) := "0000";
146
        constant I2C_CMD_START  : std_logic_vector(3 downto 0) := "0001";
147
        constant I2C_CMD_STOP    : std_logic_vector(3 downto 0) := "0010";
148
        constant I2C_CMD_READ    : std_logic_vector(3 downto 0) := "0100";
149
        constant I2C_CMD_WRITE  : std_logic_vector(3 downto 0) := "1000";
150
 
151
        -- signals for bit_controller
152
        signal core_cmd : std_logic_vector(3 downto 0);
153
        signal core_ack, core_txd, core_rxd : std_logic;
154
        signal al : std_logic;
155
 
156
        -- signals for shift register
157
        signal sr : std_logic_vector(7 downto 0); -- 8bit shift register
158
        signal shift, ld : std_logic;
159
 
160
        -- signals for state machine
161
        signal go, host_ack : std_logic;
162
        -- Added init value to dcnt to prevent simulation meta-value
163
        -- - jan@gaisler.com
164
        signal dcnt : std_logic_vector(2 downto 0) := (others => '0'); -- data counter
165
        signal cnt_done : std_logic;
166
 
167
begin
168
        -- hookup bit_controller
169
        bit_ctrl: i2c_master_bit_ctrl port map(
170
                clk     => clk,
171
                rst     => rst,
172
                nReset  => nReset,
173
                ena     => ena,
174
                clk_cnt => clk_cnt,
175
                cmd     => core_cmd,
176
                cmd_ack => core_ack,
177
                busy    => i2c_busy,
178
                al      => al,
179
                din     => core_txd,
180
                dout    => core_rxd,
181
                scl_i   => scl_i,
182
                scl_o   => scl_o,
183
                scl_oen => scl_oen,
184
                sda_i   => sda_i,
185
                sda_o   => sda_o,
186
                sda_oen => sda_oen
187
        );
188
        i2c_al <= al;
189
 
190
        -- generate host-command-acknowledge
191
        cmd_ack <= host_ack;
192
 
193
        -- generate go-signal
194
        go <= (read or write or stop) and not host_ack;
195
 
196
        -- assign Dout output to shift-register
197
        dout <= sr;
198
 
199
        -- generate shift register
200
        shift_register: process(clk, nReset)
201
        begin
202
            if (nReset = '0') then
203
              sr <= (others => '0');
204
            elsif (clk'event and clk = '1') then
205
              if (rst = '1') then
206
                sr <= (others => '0');
207
              elsif (ld = '1') then
208
                sr <= din;
209
              elsif (shift = '1') then
210
                sr <= (sr(6 downto 0) & core_rxd);
211
              end if;
212
            end if;
213
        end process shift_register;
214
 
215
        -- generate data-counter
216
        data_cnt: process(clk, nReset)
217
        begin
218
            if (nReset = '0') then
219
              dcnt <= (others => '0');
220
            elsif (clk'event and clk = '1') then
221
              if (rst = '1') then
222
                dcnt <= (others => '0');
223
              elsif (ld = '1') then
224
                dcnt <= (others => '1');  -- load counter with 7
225
              elsif (shift = '1') then
226
                dcnt <= dcnt -1;
227
              end if;
228
            end if;
229
        end process data_cnt;
230
 
231
        cnt_done <= '1' when (dcnt = "000") else '0';
232
 
233
        --
234
        -- state machine
235
        --
236
        statemachine : block
237
            type states is (st_idle, st_start, st_read, st_write, st_ack, st_stop);
238
            signal c_state : states;
239
        begin
240
            --
241
            -- command interpreter, translate complex commands into simpler I2C commands
242
            --
243
            nxt_state_decoder: process(clk, nReset)
244
            begin
245
                if (nReset = '0') then
246
                  core_cmd <= I2C_CMD_NOP;
247
                  core_txd <= '0';
248
                  shift    <= '0';
249
                  ld       <= '0';
250
                  host_ack <= '0';
251
                  c_state  <= st_idle;
252
                  ack_out  <= '0';
253
                elsif (clk'event and clk = '1') then
254
                  if (rst = '1' or al = '1') then
255
                    core_cmd <= I2C_CMD_NOP;
256
                    core_txd <= '0';
257
                    shift    <= '0';
258
                    ld       <= '0';
259
                    host_ack <= '0';
260
                    c_state  <= st_idle;
261
                    ack_out  <= '0';
262
                  else
263
                    -- initialy reset all signal
264
                    core_txd <= sr(7);
265
                    shift    <= '0';
266
                    ld       <= '0';
267
                    host_ack <= '0';
268
 
269
                    case c_state is
270
                      when st_idle =>
271
                         if (go = '1') then
272
                           if (start = '1') then
273
                             c_state  <= st_start;
274
                             core_cmd <= I2C_CMD_START;
275
                           elsif (read = '1') then
276
                             c_state  <= st_read;
277
                             core_cmd <= I2C_CMD_READ;
278
                           elsif (write = '1') then
279
                             c_state  <= st_write;
280
                             core_cmd <= I2C_CMD_WRITE;
281
                           else -- stop
282
                             c_state  <= st_stop;
283
                             core_cmd <= I2C_CMD_STOP;
284
                           end if;
285
 
286
                           ld <= '1';
287
                         end if;
288
 
289
                      when st_start =>
290
                         if (core_ack = '1') then
291
                           if (read = '1') then
292
                             c_state  <= st_read;
293
                             core_cmd <= I2C_CMD_READ;
294
                           else
295
                             c_state  <= st_write;
296
                             core_cmd <= I2C_CMD_WRITE;
297
                           end if;
298
 
299
                           ld <= '1';
300
                         end if;
301
 
302
                      when st_write =>
303
                         if (core_ack = '1') then
304
                           if (cnt_done = '1') then
305
                             c_state  <= st_ack;
306
                             core_cmd <= I2C_CMD_READ;
307
                           else
308
                             c_state  <= st_write;       -- stay in same state
309
                             core_cmd <= I2C_CMD_WRITE;  -- write next bit
310
                             shift    <= '1';
311
                           end if;
312
                         end if;
313
 
314
                      when st_read =>
315
                         if (core_ack = '1') then
316
                           if (cnt_done = '1') then
317
                             c_state  <= st_ack;
318
                             core_cmd <= I2C_CMD_WRITE;
319
                           else
320
                             c_state  <= st_read;      -- stay in same state
321
                             core_cmd <= I2C_CMD_READ; -- read next bit
322
                           end if;
323
 
324
                           shift    <= '1';
325
                           core_txd <= ack_in;
326
                         end if;
327
 
328
                      when st_ack =>
329
                         if (core_ack = '1') then
330
                           -- check for stop; Should a STOP command be generated ?
331
                           if (stop = '1') then
332
                             c_state  <= st_stop;
333
                             core_cmd <= I2C_CMD_STOP;
334
                           else
335
                             c_state  <= st_idle;
336
                             core_cmd <= I2C_CMD_NOP;
337
 
338
                             -- generate command acknowledge signal
339
                             host_ack <= '1';
340
                           end if;
341
 
342
                           -- assign ack_out output to core_rxd (contains last received bit)
343
                           ack_out  <= core_rxd;
344
 
345
                           core_txd <= '1';
346
                         else
347
                           core_txd <= ack_in;
348
                         end if;
349
 
350
                      when st_stop =>
351
                         if (core_ack = '1') then
352
                           c_state  <= st_idle;
353
                           core_cmd <= I2C_CMD_NOP;
354
 
355
                           -- generate command acknowledge signal
356
                           host_ack <= '1';
357
                         end if;
358
 
359
                      when others => -- illegal states
360
                         c_state  <= st_idle;
361
                         core_cmd <= I2C_CMD_NOP;
362
                         report ("Byte controller entered illegal state.");
363
 
364
                    end case;
365
 
366
                  end if;
367
                end if;
368
            end process nxt_state_decoder;
369
 
370
        end block statemachine;
371
 
372
end architecture structural;
373
 

powered by: WebSVN 2.1.0

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