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

Subversion Repositories i2c

[/] [i2c/] [trunk/] [rtl/] [vhdl/] [i2c_master_byte_ctrl.vhd] - Blame information for rev 27

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

powered by: WebSVN 2.1.0

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