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

Subversion Repositories i2c

[/] [i2c/] [trunk/] [rtl/] [vhdl/] [i2c_master_top.vhd] - Blame information for rev 68

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

powered by: WebSVN 2.1.0

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