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

Subversion Repositories i2c

[/] [i2c/] [tags/] [rel_1/] [rtl/] [vhdl/] [i2c_master_top.vhd] - Blame information for rev 16

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; top level           ----
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 16 rherveille
--  $Id: i2c_master_top.vhd,v 1.2 2001-11-10 10:52:44 rherveille Exp $
41 15 rherveille
--
42 16 rherveille
--  $Date: 2001-11-10 10:52:44 $
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
 
51
 
52
library ieee;
53
use ieee.std_logic_1164.all;
54
use ieee.std_logic_arith.all;
55
 
56
entity i2c_master_top is
57
        generic(
58
                ARST_LVL : std_logic := '0';                  -- asynchronous reset level
59
 
60
                -- Register timing parameters.
61
                -- Last parameters in list for
62
                -- verilog compatibility
63
                Tcq : time := 1 ns                            -- Clock to output delay
64
        );
65
        port (
66
                -- wishbone signals
67
                wb_clk_i  : in  std_logic;                                      -- master clock input
68
                wb_rst_i  : in  std_logic := '0';                                -- synchronous active high reset
69
                arst_i    : in  std_logic := not ARST_LVL;              -- asynchronous reset
70
                wb_adr_i  : in  unsigned(2 downto 0);            -- lower address bits
71
                wb_dat_i  : in  std_logic_vector(7 downto 0);    -- Databus input
72
                wb_dat_o  : out std_logic_vector(7 downto 0);    -- Databus output
73
                wb_we_i   : in  std_logic;                                              -- Write enable input
74
                wb_stb_i  : in  std_logic;                                              -- Strobe signals / core select signal
75
                wb_cyc_i  : in  std_logic;                                              -- Valid bus cycle input
76
                wb_ack_o  : out std_logic;                                      -- Bus cycle acknowledge output
77
                wb_inta_o : out std_logic;                                      -- interrupt request output signal
78
 
79
                -- i2c lines
80
                scl_pad_i     : in  std_logic;                -- i2c clock line input
81
                scl_pad_o     : out std_logic;                -- i2c clock line output
82
                scl_padoen_o  : out std_logic;                -- i2c clock line output enable, active low
83
                sda_pad_i     : in  std_logic;                -- i2c data line input
84
                sda_pad_o     : out std_logic;                -- i2c data line output
85
                sda_padoen_o  : out std_logic                 -- i2c data line output enable, active low
86
        );
87
end entity i2c_master_top;
88
 
89
architecture structural of i2c_master_top is
90
        component i2c_master_byte_ctrl is
91
                generic(
92
                        Tcq : time :=  Tcq
93
                );
94
                port (
95
                        clk    : in std_logic;
96
                        rst    : in std_logic; -- synchronous active high reset (WISHBONE compatible)
97
                        nReset : in std_logic;  -- asynchornous active low reset (FPGA compatible)
98
                        ena    : in std_logic; -- core enable signal
99
 
100
                        clk_cnt : in unsigned(15 downto 0);      -- 4x SCL 
101
 
102
                        -- input signals
103
                        start,
104
                        stop,
105
                        read,
106
                        write,
107
                        ack_in : std_logic;
108
                        din    : in std_logic_vector(7 downto 0);
109
 
110
                        -- output signals
111
                        cmd_ack  : out std_logic;
112
                        ack_out  : out std_logic;
113
                        i2c_busy : out std_logic;
114
                        dout     : out std_logic_vector(7 downto 0);
115
 
116
                        -- i2c lines
117
                        scl_i   : in std_logic;  -- i2c clock line input
118
                        scl_o   : out std_logic; -- i2c clock line output
119
                        scl_oen : out std_logic; -- i2c clock line output enable, active low
120
                        sda_i   : in std_logic;  -- i2c data line input
121
                        sda_o   : out std_logic; -- i2c data line output
122
                        sda_oen : out std_logic  -- i2c data line output enable, active low
123
                );
124
        end component i2c_master_byte_ctrl;
125
 
126
        -- registers
127
        signal prer : unsigned(15 downto 0);                     -- clock prescale register
128
        signal ctr  : std_logic_vector(7 downto 0);       -- control register
129
        signal txr  : std_logic_vector(7 downto 0);              -- transmit register
130
        signal rxr  : std_logic_vector(7 downto 0);              -- receive register
131
        signal cr   : std_logic_vector(7 downto 0);       -- command register
132
        signal sr   : std_logic_vector(7 downto 0);              -- status register
133
 
134
        -- internal reset signal
135
        signal rst_i : std_logic;
136
 
137
        -- done signal: command completed, clear command register
138
        signal done : std_logic;
139
 
140
        -- command register signals
141
        signal sta, sto, rd, wr, ack, iack : std_logic;
142
 
143
        -- core enable signal
144
        signal core_en : std_logic;
145
        signal ien : std_logic;
146
 
147
        -- status register signals
148
        signal irxack, rxack : std_logic;                       -- received aknowledge from slave
149
        signal tip : std_logic;                                         -- transfer in progress
150
        signal irq_flag : std_logic;                            -- interrupt pending flag
151
        signal i2c_busy : std_logic;                            -- bus busy (start signal detected)
152
 
153
begin
154
        -- generate internal reset signal
155
        rst_i <= arst_i xor ARST_LVL;
156
 
157
        -- generate acknowledge output signal
158
        wb_ack_o <= wb_cyc_i and wb_stb_i;        -- because timing is always honored 
159
 
160
        -- assign wb_dat_o
161
        assign_dato : process(wb_adr_i, prer, ctr, txr, cr, rxr, sr)
162
        begin
163
                case wb_adr_i is
164
                        when "000" =>
165
                                wb_dat_o <= std_logic_vector(prer( 7 downto 0));
166
 
167
                        when "001" =>
168
                                wb_dat_o <= std_logic_vector(prer(15 downto 8));
169
 
170
                        when "010" =>
171
                                wb_dat_o <= ctr;
172
 
173
                        when "011" =>
174
                                wb_dat_o <= rxr; -- write is transmit register TxR
175
 
176
                        when "100" =>
177
                                wb_dat_o <= sr; -- write is command register CR
178
 
179
                        -- Debugging registers:
180
                        -- These registers are not documented.
181
                        -- Functionality could change in future releases
182
 
183
                        when "101" =>
184
                                wb_dat_o <= txr;
185
 
186
                        when "110" =>
187
                                wb_dat_o <= cr;
188
 
189
                        when "111" =>
190
                                wb_dat_o <= (others => '0');
191
 
192
                        when others =>
193
                                wb_dat_o <= (others => 'X');    -- for simulation only
194
 
195
                end case;
196
        end process assign_dato;
197
 
198
 
199
        -- registers block
200
        regs_block: process(rst_i, wb_clk_i)
201
        begin
202
                if (rst_i = '0') then
203 16 rherveille
                        prer <= (others => '1') after Tcq;
204 15 rherveille
                        ctr  <= (others => '0') after Tcq;
205
                        txr  <= (others => '0') after Tcq;
206
                        cr   <= (others => '0') after Tcq;
207
                elsif (wb_clk_i'event and wb_clk_i = '1') then
208
                        if (wb_rst_i = '1') then
209 16 rherveille
                                prer <= (others => '1') after Tcq;
210 15 rherveille
                                ctr  <= (others => '0') after Tcq;
211
                                txr  <= (others => '0') after Tcq;
212
                                cr   <= (others => '0') after Tcq;
213
                        else
214
                                if (wb_cyc_i = '1' and wb_stb_i = '1' and wb_we_i = '1') then
215
                                        if (wb_adr_i(2) = '0') then
216
                                                case wb_adr_i(1 downto 0) is
217
                                                        when "00" => prer( 7 downto 0) <= unsigned(wb_dat_i) after Tcq;
218
                                                        when "01" => prer(15 downto 8) <= unsigned(wb_dat_i) after Tcq;
219
                                                        when "10" => ctr               <= wb_dat_i after Tcq;
220
                                                        when "11" => txr               <= wb_dat_i after Tcq;
221
 
222
                                                        -- illegal cases, for simulation only
223
                                                        when others =>
224
                                                                report ("Illegal write address, setting all registers to unknown.");
225
                                                                prer <= (others => 'X');
226
                                                                ctr  <= (others => 'X');
227
                                                                txr  <= (others => 'X');
228
                                                end case;
229
                                        elsif ( (core_en = '1') and (wb_adr_i(1 downto 0) = 0) ) then
230
                                                -- only take new commands when i2c ore enabled
231
                                                -- pending commands are finished
232
                                                cr <= wb_dat_i after Tcq;
233
                                        end if;
234
                                else
235
                                        -- clear command bits when done
236
                                        if (done = '1') then
237
                                                cr(7 downto 4) <= (others => '0') after Tcq;
238
                                        end if;
239
 
240
                                        -- reserved bits
241
                                        cr(2 downto 1) <= (others => '0') after Tcq;
242
 
243
                                        -- clear iack when irq_flag cleared
244
                                        cr(0) <= cr(0) and irq_flag;
245
                                end if;
246
                        end if;
247
                end if;
248
        end process regs_block;
249
 
250
        -- decode command register
251
        sta  <= cr(7);
252
        sto  <= cr(6);
253
        rd   <= cr(5);
254
        wr   <= cr(4);
255
        ack  <= cr(3);
256
        iack <= cr(0);
257
 
258
        -- decode control register
259
        core_en <= ctr(7);
260
        ien     <= ctr(6);
261
 
262
        -- hookup byte controller block
263
        u1: i2c_master_byte_ctrl port map (
264
                clk      => wb_clk_i,
265
                rst      => wb_rst_i,
266
                nReset   => rst_i,
267
                ena      => core_en,
268
                clk_cnt  => prer,
269
                start    => sta,
270
                stop     => sto,
271
                read     => rd,
272
                write    => wr,
273
                ack_in   => ack,
274
                i2c_busy => i2c_busy,
275
                din      => txr,
276
                cmd_ack  => done,
277
                ack_out  => irxack,
278
                dout     => rxr,
279
                scl_i    => scl_pad_i,
280
                scl_o    => scl_pad_o,
281
                scl_oen  => scl_padoen_o,
282
                sda_i    => sda_pad_i,
283
                sda_o    => sda_pad_o,
284
                sda_oen  => sda_padoen_o
285
        );
286
 
287
 
288
        -- status register block + interrupt request signal
289
        st_irq_block : block
290
        begin
291
                -- generate status register bits
292
                gen_sr_bits: process (wb_clk_i, rst_i)
293
                begin
294
                        if (rst_i = '0') then
295
                                rxack    <= '0' after Tcq;
296
                                tip      <= '0' after Tcq;
297
                                irq_flag <= '0' after Tcq;
298
                        elsif (wb_clk_i'event and wb_clk_i = '1') then
299
                                if (wb_rst_i = '1') then
300
                                        rxack    <= '0' after Tcq;
301
                                        tip      <= '0' after Tcq;
302
                                        irq_flag <= '0' after Tcq;
303
                                else
304
                                        rxack    <= irxack after Tcq;
305
                                        tip      <= (rd or wr) after Tcq;
306
 
307
                                        -- interrupt request flag is always generated
308
                                        irq_flag <= (done or irq_flag) and not iack after Tcq;
309
                                end if;
310
                        end if;
311
                end process gen_sr_bits;
312
 
313
                -- generate interrupt request signals
314
                gen_irq: process (wb_clk_i, rst_i)
315
                begin
316
                        if (rst_i = '0') then
317
                                wb_inta_o <= '0' after Tcq;
318
                        elsif (wb_clk_i'event and wb_clk_i = '1') then
319
                                if (wb_rst_i = '1') then
320
                                        wb_inta_o <= '0' after Tcq;
321
                                else
322
                                        -- interrupt signal is only generated when IEN (interrupt enable bit) is set
323
                                        wb_inta_o <= irq_flag and ien after Tcq;
324
                                end if;
325
                        end if;
326
                end process gen_irq;
327
 
328
                -- assign status register bits
329
                sr(7)          <= rxack;
330
                sr(6)          <= i2c_busy;
331
                sr(5 downto 2) <= (others => '0'); -- reserved
332
                sr(1)          <= tip;
333
                sr(0)          <= irq_flag;
334
        end block;
335
 
336
end architecture structural;
337
 

powered by: WebSVN 2.1.0

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