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

Subversion Repositories i2c

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

powered by: WebSVN 2.1.0

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