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

Subversion Repositories mips_enhanced

[/] [mips_enhanced/] [trunk/] [grlib-gpl-1.0.19-b3188/] [lib/] [gaisler/] [misc/] [i2cmst.vhd] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 dimamali
------------------------------------------------------------------------------
2
--  This file is a part of the GRLIB VHDL IP LIBRARY
3
--  Copyright (C) 2003, Gaisler Research
4
--
5
--  This program is free software; you can redistribute it and/or modify
6
--  it under the terms of the GNU General Public License as published by
7
--  the Free Software Foundation; either version 2 of the License, or
8
--  (at your option) any later version.
9
--
10
--  This program is distributed in the hope that it will be useful,
11
--  but WITHOUT ANY WARRANTY; without even the implied warranty of
12
--  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
--  GNU General Public License for more details.
14
--
15
--  You should have received a copy of the GNU General Public License
16
--  along with this program; if not, write to the Free Software
17
--  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
18
-------------------------------------------------------------------------------
19
-- Entity: i2cmst
20
-- File:   i2cmst.vhd
21
-- Author: Jan Andersson - Gaisler Research
22
--         jan@gaisler.com
23
--
24
-- Description:
25
--
26
--         APB interface to OpenCores I2C-master. This is an GRLIB AMBA wrapper
27
--         that instantiates the byte- and bit-controller of the OpenCores I2C
28
--         master (OC core developed by Richard Herveille, richard@asics.ws). 
29
--         The OC byte- and bit-controller are located under lib/opencores/i2c
30
--
31
--         The original master had a WISHBONE interface with registers
32
--         aligned at byte boundaries. This wrapper has a slighly different
33
--         alignment of the registers:
34
--
35
--         +------------+--------------------------------------+
36
--         |  Offset    |            Bits in word              |
37
--         |            |---------+---------+---------+--------+
38
--         |            | 31 - 24 | 23 - 16 | 15 - 8  | 7 - 0  |
39
--         +------------+---------+---------+---------+--------+
40
--         |   0x00     |  0x00   |   0x00  | PRERhi  | PRERlo |
41
--         |   0x04     |  0x00   |   0x00  |  0x00   |  CTR   |
42
--         |   0x08     |  0x00   |   0x00  |  0x00   |  TXR   |
43
--         |   0x08     |  0x00   |   0x00  |  0x00   |  RXR   |
44
--         |   0x0C     |  0x00   |   0x00  |  0x00   |  CR    |
45
--         |   0x0C     |  0x00   |   0x00  |  0x00   |  SR    |
46
--         +------------+---------+---------+---------+--------+
47
 
48
library ieee;
49
use ieee.std_logic_1164.all;
50
use ieee.numeric_std.all;
51
 
52
library grlib;
53
use grlib.amba.all;
54
use grlib.devices.all;
55
use grlib.stdlib.all;
56
 
57
library gaisler;
58
use gaisler.misc.all;
59
 
60
library opencores;
61
use opencores.i2coc.all;
62
 
63
entity i2cmst is
64
  generic (
65
    -- APB generics
66
    pindex  : integer := 0;                -- slave bus index
67
    paddr   : integer := 0;
68
    pmask   : integer := 16#fff#;
69
    pirq    : integer := 0;                -- interrupt index
70
    oepol   : integer range 0 to 1 := 0);  -- output enable polarity
71
  port (
72
    rstn : in std_ulogic;
73
    clk  : in std_ulogic;
74
 
75
    -- APB signals
76
    apbi  : in apb_slv_in_type;
77
    apbo  : out apb_slv_out_type;
78
 
79
    -- I2C signals
80
    i2ci    : in  i2c_in_type;
81
    i2co    : out i2c_out_type
82
    );
83
end entity i2cmst;
84
 
85
architecture rtl of i2cmst is
86
  -----------------------------------------------------------------------------
87
  -- Constants
88
  -----------------------------------------------------------------------------
89
 
90
  constant PCONFIG : apb_config_type := (
91
 
92
  1 => apb_iobar(paddr, pmask));
93
 
94
  constant PRER_addr : std_logic_vector(7 downto 2) := "000000";
95
  constant CTR_addr  : std_logic_vector(7 downto 2) := "000001";
96
  constant TXR_addr  : std_logic_vector(7 downto 2) := "000010";
97
  constant RXR_addr  : std_logic_vector(7 downto 2) := "000010";
98
  constant CR_addr   : std_logic_vector(7 downto 2) := "000011";
99
  constant SR_addr   : std_logic_vector(7 downto 2) := "000011";
100
 
101
  -----------------------------------------------------------------------------
102
  -- Types 
103
  -----------------------------------------------------------------------------
104
  -- Register interface
105
  type ctrl_reg_type is record          -- Control register
106
      en  : std_ulogic;
107
      ien : std_ulogic;
108
  end record;
109
 
110
  type cmd_reg_type is record           -- Command register
111
      sta : std_ulogic;
112
      sto : std_ulogic;
113
      rd  : std_ulogic;
114
      wr  : std_ulogic;
115
      ack : std_ulogic;
116
  end record;
117
 
118
  type sts_reg_type is record           -- Status register
119
      rxack : std_ulogic;
120
      busy  : std_ulogic;
121
      al    : std_ulogic;
122
      tip   : std_ulogic;
123
      ifl   : std_ulogic;
124
  end record;
125
 
126
  -- Core registers
127
  type i2c_reg_type is record
128
       -- i2c registers
129
       prer : std_logic_vector(15 downto 0);     -- clock prescale register
130
       ctrl : ctrl_reg_type;                     -- control register
131
       txr  : std_logic_vector(7 downto 0);      -- transmit register
132
       cmd  : cmd_reg_type;                      -- command register
133
       sts  : sts_reg_type;                      -- status register
134
       --
135
       irq  : std_ulogic;
136
 end record;
137
 
138
  -- Signals to and from byte controller block
139
  signal rxr       : std_logic_vector(7 downto 0); -- Receive register
140
  signal done      : std_logic;         -- Signals completion of command
141
  signal rxack     : std_logic;         -- Received acknowledge
142
  signal busy      : std_logic;         -- I2C core busy
143
  signal al        : std_logic;         -- Aribitration lost
144
  signal irst      : std_ulogic;        -- Internal, negated reset signal
145
  signal iscloen   : std_ulogic;        -- Internal SCL output enable
146
  signal isdaoen   : std_ulogic;        -- Internal SDA output enable
147
 
148
  -- Register interface
149
  signal r, rin : i2c_reg_type;
150
  signal vcc : std_logic;
151
begin
152
  -- Byte Controller from OpenCores I2C master,
153
  -- by Richard Herveille (richard@asics.ws). The asynchronous
154
  -- reset is tied to '1'. Only the synchronous reset is used.
155
 
156
  vcc <= '1';
157
  byte_ctrl: i2c_master_byte_ctrl
158
    port map (clk, irst, vcc, r.ctrl.en, r.prer, r.cmd.sta,
159
              r.cmd.sto, r.cmd.rd, r.cmd.wr, r.cmd.ack, r.txr, done,
160
              rxack, busy, al, rxr, i2ci.scl, i2co.scl, iscloen,
161
              i2ci.sda, i2co.sda, isdaoen);
162
 
163
  -- OC I2C logic has active high reset.
164
  irst <= not rstn;
165
 
166
  -- Fix output enable polarity
167
  soepol0: if oepol = 0 generate
168
    i2co.scloen <= iscloen;
169
    i2co.sdaoen <= isdaoen;
170
  end generate soepol0;
171
  soepol1: if oepol /= 0 generate
172
    i2co.scloen <= not iscloen;
173
    i2co.sdaoen <= not isdaoen;
174
  end generate soepol1;
175
 
176
  comb: process (r, rstn, rxr, rxack, busy, al, done, apbi)
177
    variable v : i2c_reg_type;
178
    variable irq : std_logic_vector((NAHBIRQ-1) downto 0);
179
    variable apbaddr : std_logic_vector(7 downto 2);
180
    variable apbout : std_logic_vector(31 downto 0);
181
  begin  -- process comb
182
    v := r;  v.irq := '0'; irq := (others=>'0'); irq(pirq) := r.irq;
183
    apbaddr := apbi.paddr(7 downto 2); apbout := (others => '0');
184
 
185
    -- Command done or arbitration lost, clear command register
186
    if (done or al) = '1' then
187
      v.cmd := ('0', '0', '0', '0', '0');
188
    end if;
189
 
190
    -- Update status register
191
    v.sts := (rxack => rxack,
192
              busy  => busy,
193
              al    => al or (r.sts.al and not r.cmd.sta),
194
              tip   => r.cmd.rd or r.cmd.wr,
195
              ifl   => done or al or r.sts.ifl);
196
    v.irq := (done or al) and r.ctrl.ien;
197
 
198
    -- read registers
199
    if (apbi.psel(pindex) and apbi.penable and (not apbi.pwrite)) = '1' then
200
      case apbaddr is
201
        when PRER_addr =>
202
          apbout(15 downto 0) := r.prer;
203
        when CTR_addr  =>
204
          apbout(7 downto 6) := r.ctrl.en & r.ctrl.ien;
205
        when RXR_addr  =>
206
          apbout(7 downto 0) := rxr;
207
        when SR_Addr   =>
208
          apbout(7 downto 5) := r.sts.rxack & r.sts.busy & r.sts.al;
209
          apbout(1 downto 0) := r.sts.tip & r.sts.ifl;
210
        when others => null;
211
      end case;
212
    end if;
213
 
214
    -- write registers
215
    if (apbi.psel(pindex) and apbi.penable and apbi.pwrite) = '1' then
216
      case apbaddr is
217
        when PRER_addr => v.prer := apbi.pwdata(15 downto 0);
218
        when CTR_addr  => v.ctrl.en := apbi.pwdata(7);
219
                          v.ctrl.ien := apbi.pwdata(6);
220
        when TXR_addr  => v.txr  := apbi.pwdata(7 downto 0);
221
        when CR_addr   =>
222
          -- Check that core is enabled and that WR and RD has been cleared
223
          -- before accepting new command.
224
          if (r.ctrl.en and not (r.cmd.wr or r.cmd.rd)) = '1' then
225
            v.cmd.sta := apbi.pwdata(7);
226
            v.cmd.sto := apbi.pwdata(6);
227
            v.cmd.rd  := apbi.pwdata(5);
228
            v.cmd.wr  := apbi.pwdata(4);
229
            v.cmd.ack := apbi.pwdata(3);
230
          end if;
231
          -- Bit 0 of CR is interrupt acknowledge. The core will only pulse one
232
          -- interrupt per irq event. Software does not have to clear the
233
          -- interrupt flag... 
234
          if apbi.pwdata(0) = '1' then
235
            v.sts.ifl := '0';
236
          end if;
237
        when others => null;
238
      end case;
239
    end if;
240
 
241
    if rstn = '0' then
242
      v.prer := (others => '1');
243
      v.ctrl := ('0', '0');
244
      v.txr  := (others => '0');
245
      v.cmd  := ('0','0','0','0', '0');
246
      v.sts   := ('0','0','0','0', '0');
247
    end if;
248
 
249
    -- Update registers
250
    rin <= v;
251
 
252
    -- Update outputs
253
    apbo.prdata <= apbout;
254
    apbo.pirq <= irq;
255
    apbo.pconfig <= PCONFIG;
256
    apbo.pindex <= pindex;
257
 
258
  end process comb;
259
 
260
  reg: process (clk)
261
  begin  -- process reg
262
    if rising_edge(clk) then
263
      r <= rin;
264
    end if;
265
  end process reg;
266
 
267
  -- Boot message
268
  -- pragma translate_off
269
  bootmsg : report_version
270
    generic map (
271
      "i2cmst" & tost(pindex) & ": AMBA Wrapper for OC I2C-master rev " &
272
      tost(0) & ", irq " & tost(pirq));
273
  -- pragma translate_on
274
 
275
end architecture rtl;

powered by: WebSVN 2.1.0

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