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

Subversion Repositories i2c

[/] [i2c/] [tags/] [rel_1/] [rtl/] [vhdl/] [i2c_master_byte_ctrl.vhd] - Blame information for rev 69

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 15 rherveille
---------------------------------------------------------------------
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 38 rherveille
--  $Id: i2c_master_byte_ctrl.vhd,v 1.4 2003-08-09 07:01:13 rherveille Exp $
41 15 rherveille
--
42 38 rherveille
--  $Date: 2003-08-09 07:01:13 $
43
--  $Revision: 1.4 $
44 15 rherveille
--  $Author: rherveille $
45
--  $Locker:  $
46
--  $State: Exp $
47
--
48
-- Change History:
49
--               $Log: not supported by cvs2svn $
50 38 rherveille
--               Revision 1.3  2002/12/26 16:05:47  rherveille
51
--               Core is now a Multimaster I2C controller.
52
--
53 31 rherveille
--               Revision 1.2  2002/11/30 22:24:37  rherveille
54
--               Cleaned up code
55
--
56 27 rherveille
--               Revision 1.1  2001/11/05 12:02:33  rherveille
57
--               Split i2c_master_core.vhd into separate files for each entity; same layout as verilog version.
58
--               Code updated, is now up-to-date to doc. rev.0.4.
59
--               Added headers.
60
--
61 15 rherveille
 
62
 
63
 
64
 
65
--
66
------------------------------------------
67
-- Byte controller section
68
------------------------------------------
69
--
70
library ieee;
71
use ieee.std_logic_1164.all;
72
use ieee.std_logic_arith.all;
73
 
74
entity i2c_master_byte_ctrl is
75
        port (
76
                clk    : in std_logic;
77
                rst    : in std_logic; -- synchronous active high reset (WISHBONE compatible)
78
                nReset : in std_logic;  -- asynchornous active low reset (FPGA compatible)
79
                ena    : in std_logic; -- core enable signal
80
 
81 27 rherveille
                clk_cnt : in unsigned(15 downto 0);      -- 4x SCL
82 15 rherveille
 
83
                -- input signals
84
                start,
85
                stop,
86
                read,
87
                write,
88
                ack_in : std_logic;
89
                din    : in std_logic_vector(7 downto 0);
90
 
91
                -- output signals
92 31 rherveille
                cmd_ack  : out std_logic; -- command done
93 15 rherveille
                ack_out  : out std_logic;
94 31 rherveille
                i2c_busy : out std_logic; -- arbitration lost
95
                i2c_al   : out std_logic; -- i2c bus busy
96 15 rherveille
                dout     : out std_logic_vector(7 downto 0);
97
 
98
                -- i2c lines
99
                scl_i   : in std_logic;  -- i2c clock line input
100
                scl_o   : out std_logic; -- i2c clock line output
101
                scl_oen : out std_logic; -- i2c clock line output enable, active low
102
                sda_i   : in std_logic;  -- i2c data line input
103
                sda_o   : out std_logic; -- i2c data line output
104
                sda_oen : out std_logic  -- i2c data line output enable, active low
105
        );
106
end entity i2c_master_byte_ctrl;
107
 
108
architecture structural of i2c_master_byte_ctrl is
109
        component i2c_master_bit_ctrl is
110 27 rherveille
        port (
111
                clk    : in std_logic;
112
                rst    : in std_logic;
113
                nReset : in std_logic;
114
                ena    : in std_logic;                          -- core enable signal
115 15 rherveille
 
116 27 rherveille
                clk_cnt : in unsigned(15 downto 0);              -- clock prescale value
117 15 rherveille
 
118 27 rherveille
                cmd     : in std_logic_vector(3 downto 0);
119 31 rherveille
                cmd_ack : out std_logic; -- command done
120
                busy    : out std_logic; -- i2c bus busy
121
                al      : out std_logic; -- arbitration lost
122 15 rherveille
 
123 27 rherveille
                din  : in std_logic;
124
                dout : out std_logic;
125 15 rherveille
 
126 27 rherveille
                -- i2c lines
127
                scl_i   : in std_logic;  -- i2c clock line input
128
                scl_o   : out std_logic; -- i2c clock line output
129
                scl_oen : out std_logic; -- i2c clock line output enable, active low
130
                sda_i   : in std_logic;  -- i2c data line input
131
                sda_o   : out std_logic; -- i2c data line output
132
                sda_oen : out std_logic  -- i2c data line output enable, active low
133
        );
134 15 rherveille
        end component i2c_master_bit_ctrl;
135
 
136
        -- commands for bit_controller block
137
        constant I2C_CMD_NOP    : std_logic_vector(3 downto 0) := "0000";
138
        constant I2C_CMD_START  : std_logic_vector(3 downto 0) := "0001";
139
        constant I2C_CMD_STOP    : std_logic_vector(3 downto 0) := "0010";
140
        constant I2C_CMD_READ    : std_logic_vector(3 downto 0) := "0100";
141
        constant I2C_CMD_WRITE  : std_logic_vector(3 downto 0) := "1000";
142
 
143
        -- signals for bit_controller
144
        signal core_cmd : std_logic_vector(3 downto 0);
145
        signal core_ack, core_txd, core_rxd : std_logic;
146 31 rherveille
        signal al : std_logic;
147 15 rherveille
 
148
        -- signals for shift register
149
        signal sr : std_logic_vector(7 downto 0); -- 8bit shift register
150
        signal shift, ld : std_logic;
151
 
152
        -- signals for state machine
153
        signal go, host_ack : std_logic;
154
        signal dcnt : unsigned(2 downto 0); -- data counter
155
        signal cnt_done : std_logic;
156
 
157
begin
158
        -- hookup bit_controller
159 31 rherveille
        bit_ctrl: i2c_master_bit_ctrl port map(
160 15 rherveille
                clk     => clk,
161
                rst     => rst,
162
                nReset  => nReset,
163
                ena     => ena,
164
                clk_cnt => clk_cnt,
165
                cmd     => core_cmd,
166
                cmd_ack => core_ack,
167
                busy    => i2c_busy,
168 31 rherveille
                al      => al,
169 15 rherveille
                din     => core_txd,
170
                dout    => core_rxd,
171
                scl_i   => scl_i,
172
                scl_o   => scl_o,
173
                scl_oen => scl_oen,
174
                sda_i   => sda_i,
175
                sda_o   => sda_o,
176
                sda_oen => sda_oen
177
        );
178 31 rherveille
        i2c_al <= al;
179 15 rherveille
 
180
        -- generate host-command-acknowledge
181
        cmd_ack <= host_ack;
182 27 rherveille
 
183 15 rherveille
        -- generate go-signal
184
        go <= (read or write or stop) and not host_ack;
185
 
186
        -- assign Dout output to shift-register
187
        dout <= sr;
188
 
189
        -- generate shift register
190
        shift_register: process(clk, nReset)
191
        begin
192 27 rherveille
            if (nReset = '0') then
193
              sr <= (others => '0');
194
            elsif (clk'event and clk = '1') then
195
              if (rst = '1') then
196
                sr <= (others => '0');
197
              elsif (ld = '1') then
198
                sr <= din;
199
              elsif (shift = '1') then
200
                sr <= (sr(6 downto 0) & core_rxd);
201
              end if;
202
            end if;
203 15 rherveille
        end process shift_register;
204
 
205
        -- generate data-counter
206
        data_cnt: process(clk, nReset)
207
        begin
208 27 rherveille
            if (nReset = '0') then
209
              dcnt <= (others => '0');
210
            elsif (clk'event and clk = '1') then
211
              if (rst = '1') then
212
                dcnt <= (others => '0');
213
              elsif (ld = '1') then
214
                dcnt <= (others => '1');  -- load counter with 7
215
              elsif (shift = '1') then
216
                dcnt <= dcnt -1;
217
              end if;
218
            end if;
219 15 rherveille
        end process data_cnt;
220
 
221
        cnt_done <= '1' when (dcnt = 0) else '0';
222
 
223
        --
224
        -- state machine
225
        --
226
        statemachine : block
227 27 rherveille
            type states is (st_idle, st_start, st_read, st_write, st_ack, st_stop);
228
            signal c_state : states;
229 15 rherveille
        begin
230 27 rherveille
            --
231
            -- command interpreter, translate complex commands into simpler I2C commands
232
            --
233
            nxt_state_decoder: process(clk, nReset)
234
            begin
235
                if (nReset = '0') then
236
                  core_cmd <= I2C_CMD_NOP;
237
                  core_txd <= '0';
238
                  shift    <= '0';
239
                  ld       <= '0';
240
                  host_ack <= '0';
241
                  c_state  <= st_idle;
242
                  ack_out  <= '0';
243
                elsif (clk'event and clk = '1') then
244 31 rherveille
                  if (rst = '1' or al = '1') then
245 27 rherveille
                    core_cmd <= I2C_CMD_NOP;
246
                    core_txd <= '0';
247
                    shift    <= '0';
248
                    ld       <= '0';
249
                    host_ack <= '0';
250
                    c_state  <= st_idle;
251
                    ack_out  <= '0';
252
                  else
253
                    -- initialy reset all signal
254
                    core_txd <= sr(7);
255
                    shift    <= '0';
256
                    ld       <= '0';
257
                    host_ack <= '0';
258 15 rherveille
 
259 27 rherveille
                    case c_state is
260
                      when st_idle =>
261
                         if (go = '1') then
262
                           if (start = '1') then
263
                             c_state  <= st_start;
264
                             core_cmd <= I2C_CMD_START;
265
                           elsif (read = '1') then
266
                             c_state  <= st_read;
267
                             core_cmd <= I2C_CMD_READ;
268
                           elsif (write = '1') then
269
                             c_state  <= st_write;
270
                             core_cmd <= I2C_CMD_WRITE;
271
                           else -- stop
272
                             c_state  <= st_stop;
273
                             core_cmd <= I2C_CMD_STOP;
274
                             host_ack <= '1'; -- generate acknowledge signal
275
                           end if;
276 15 rherveille
 
277 27 rherveille
                           ld <= '1';
278
                         end if;
279 15 rherveille
 
280 27 rherveille
                      when st_start =>
281
                         if (core_ack = '1') then
282
                           if (read = '1') then
283
                             c_state  <= st_read;
284
                             core_cmd <= I2C_CMD_READ;
285
                           else
286
                             c_state  <= st_write;
287
                             core_cmd <= I2C_CMD_WRITE;
288
                           end if;
289 15 rherveille
 
290 27 rherveille
                           ld <= '1';
291
                         end if;
292 15 rherveille
 
293 27 rherveille
                      when st_write =>
294
                         if (core_ack = '1') then
295
                           if (cnt_done = '1') then
296
                             c_state  <= st_ack;
297
                             core_cmd <= I2C_CMD_READ;
298
                           else
299
                             c_state  <= st_write;       -- stay in same state
300
                             core_cmd <= I2C_CMD_WRITE;  -- write next bit
301
                             shift    <= '1';
302
                           end if;
303
                         end if;
304 15 rherveille
 
305 27 rherveille
                      when st_read =>
306
                         if (core_ack = '1') then
307
                           if (cnt_done = '1') then
308
                             c_state  <= st_ack;
309
                             core_cmd <= I2C_CMD_WRITE;
310
                           else
311
                             c_state  <= st_read;      -- stay in same state
312
                             core_cmd <= I2C_CMD_READ; -- read next bit
313
                           end if;
314 15 rherveille
 
315 27 rherveille
                           shift    <= '1';
316
                           core_txd <= ack_in;
317
                         end if;
318 15 rherveille
 
319 27 rherveille
                      when st_ack =>
320
                         if (core_ack = '1') then
321
                           -- check for stop; Should a STOP command be generated ?
322
                           if (stop = '1') then
323
                             c_state  <= st_stop;
324
                             core_cmd <= I2C_CMD_STOP;
325
                           else
326
                             c_state  <= st_idle;
327
                             core_cmd <= I2C_CMD_NOP;
328 38 rherveille
 
329
                             -- generate command acknowledge signal
330
                             host_ack <= '1';
331 27 rherveille
                           end if;
332 15 rherveille
 
333 27 rherveille
                           -- assign ack_out output to core_rxd (contains last received bit)
334
                           ack_out  <= core_rxd;
335 15 rherveille
 
336 27 rherveille
                           core_txd <= '1';
337
                         else
338
                           core_txd <= ack_in;
339
                         end if;
340 15 rherveille
 
341 27 rherveille
                      when st_stop =>
342
                         if (core_ack = '1') then
343
                           c_state  <= st_idle;
344
                           core_cmd <= I2C_CMD_NOP;
345 38 rherveille
 
346
                           -- generate command acknowledge signal
347
                           host_ack <= '1';
348 27 rherveille
                         end if;
349 15 rherveille
 
350 27 rherveille
                      when others => -- illegal states
351
                         c_state  <= st_idle;
352
                         core_cmd <= I2C_CMD_NOP;
353
                         report ("Byte controller entered illegal state.");
354 15 rherveille
 
355 27 rherveille
                    end case;
356 15 rherveille
 
357 27 rherveille
                  end if;
358
                end if;
359
            end process nxt_state_decoder;
360 15 rherveille
 
361
        end block statemachine;
362
 
363
end architecture structural;
364
 

powered by: WebSVN 2.1.0

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