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/] [grlib/] [amba/] [apbctrl.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:      apbctrl
20
-- File:        apbctrl.vhd
21
-- Author:      Jiri Gaisler - Gaisler Research
22
-- Description: AMBA AHB/APB bridge with plug&play support
23
------------------------------------------------------------------------------ 
24
 
25
library ieee;
26
use ieee.std_logic_1164.all;
27
library grlib;
28
use grlib.amba.all;
29
use grlib.stdlib.all;
30
-- pragma translate_off
31
use grlib.devices.all;
32
use std.textio.all;
33
-- pragma translate_on
34
 
35
entity apbctrl is
36
  generic (
37
    hindex      : integer := 0;
38
    haddr       : integer := 0;
39
    hmask       : integer := 16#fff#;
40
    nslaves     : integer range 1 to NAPBSLV := NAPBSLV;
41
    debug       : integer range 0 to 2 := 2;
42
    icheck      : integer range 0 to 1 := 1;
43
    enbusmon    : integer range 0 to 1 := 0;
44
    asserterr   : integer range 0 to 1 := 0;
45
    assertwarn  : integer range 0 to 1 := 0;
46
    pslvdisable : integer := 0);
47
  port (
48
    rst     : in  std_ulogic;
49
    clk     : in  std_ulogic;
50
    ahbi    : in  ahb_slv_in_type;
51
    ahbo    : out ahb_slv_out_type;
52
    apbi    : out apb_slv_in_type;
53
    apbo    : in  apb_slv_out_vector
54
  );
55
end;
56
 
57
architecture rtl of apbctrl is
58
 
59
constant apbmax : integer := 19;
60
 
61
constant VERSION   : amba_version_type := 0;
62
 
63
constant hconfig : ahb_config_type := (
64
 
65
  4 => ahb_membar(haddr, '0', '0', hmask),
66
  others => zero32);
67
 
68
constant IOAREA : std_logic_vector(11 downto 0) :=
69
        conv_std_logic_vector(haddr, 12);
70
constant IOMSK  : std_logic_vector(11 downto 0) :=
71
        conv_std_logic_vector(hmask, 12);
72
 
73
type reg_type is record
74
  haddr   : std_logic_vector(apbmax downto 0);   -- address bus
75
  hwrite  : std_logic;                       -- read/write
76
  hready  : std_logic;                       -- ready
77
  penable : std_logic;
78
  psel    : std_logic;
79
  prdata  : std_logic_vector(31 downto 0);   -- read data
80
  pwdata  : std_logic_vector(31 downto 0);   -- write data
81
  state   : std_logic_vector(1 downto 0);   -- state
82
  cfgsel  : std_ulogic;
83
end record;
84
 
85
signal r, rin : reg_type;
86
--pragma translate_off
87
signal lapbi  : apb_slv_in_type;
88
--pragma translate_on
89
 
90
begin
91
  comb : process(ahbi, apbo, r, rst)
92
  variable v : reg_type;
93
  variable psel   : std_logic_vector(0 to 31);
94
  variable pwdata : std_logic_vector(31 downto 0);
95
  variable apbaddr : std_logic_vector(apbmax downto 0);
96
  variable apbaddr2 : std_logic_vector(31 downto 0);
97
  variable hirq, pirq : std_logic_vector(NAHBIRQ-1 downto 0);
98
  variable nslave : integer range 0 to nslaves-1;
99
  variable bnslave : std_logic_vector(3 downto 0);
100
  begin
101
 
102
    v := r; v.psel := '0'; v.penable := '0'; psel := (others => '0');
103
    hirq := (others => '0');  pirq := (others => '0');
104
 
105
    -- detect start of cycle
106
    if (ahbi.hready = '1') then
107
      if ((ahbi.htrans = HTRANS_NONSEQ) or (ahbi.htrans = HTRANS_SEQ)) and
108
          (ahbi.hsel(hindex) = '1')
109
      then
110
        v.hready := '0'; v.hwrite := ahbi.hwrite;
111
        v.haddr(apbmax downto 0) := ahbi.haddr(apbmax downto 0);
112
        v.state := "01"; v.psel := not ahbi.hwrite;
113
      end if;
114
    end if;
115
 
116
    case r.state is
117
    when "00" => null;          -- idle
118
    when "01" =>
119
      if r.hwrite = '0' then v.penable := '1';
120
      else v.pwdata := ahbi.hwdata; end if;
121
      v.psel := '1'; v.state := "10";
122
    when others =>
123
      if r.penable = '0' then v.psel := '1'; v.penable := '1'; end if;
124
      v.state := "00"; v.hready := '1';
125
    end case;
126
 
127
    psel := (others => '0');
128
 
129
    for i in 0 to nslaves-1 loop
130
      if ((apbo(i).pconfig(1)(1 downto 0) = "01") and
131
        ((apbo(i).pconfig(1)(31 downto 20) and apbo(i).pconfig(1)(15 downto 4)) =
132
        (r.haddr(19 downto  8) and apbo(i).pconfig(1)(15 downto 4))))
133
      then psel(i) := '1'; end if;
134
    end loop;
135
 
136
    bnslave(0) := psel(1) or psel(3) or psel(5) or psel(7) or
137
                  psel(9) or psel(11) or psel(13) or psel(15);
138
    bnslave(1) := psel(2) or psel(3) or psel(6) or psel(7) or
139
                  psel(10) or psel(11) or psel(14) or psel(15);
140
    bnslave(2) := psel(4) or psel(5) or psel(6) or psel(7) or
141
                  psel(12) or psel(13) or psel(14) or psel(15);
142
    bnslave(3) := psel(8) or psel(9) or psel(10) or psel(11) or
143
                  psel(12) or psel(13) or psel(14) or psel(15);
144
    nslave := conv_integer(bnslave);
145
 
146
    if (r.haddr(19 downto  12) = "11111111") then
147
     v.cfgsel := '1'; psel := (others => '0'); v.penable := '0';
148
    else v.cfgsel := '0'; end if;
149
 
150
    v.prdata := apbo(nslave).prdata;
151
 
152
    if r.cfgsel = '1' then
153
      v.prdata := apbo(conv_integer(r.haddr(log2x(nslaves)+2 downto 3))).pconfig(conv_integer(r.haddr(2 downto 2)));
154
    end if;
155
 
156
    for i in 0 to nslaves-1 loop pirq := pirq or apbo(i).pirq; end loop;
157
 
158
    -- AHB respons
159
    ahbo.hready <= r.hready;
160
    ahbo.hrdata <= r.prdata;
161
    ahbo.hirq   <= pirq;
162
 
163
    if rst = '0' then
164
      v.penable := '0'; v.hready := '1'; v.psel := '0'; v.state := "00";
165
      v.hwrite := '0';
166
-- pragma translate_off
167
      v.haddr := (others => '0');
168
-- pragma translate_on
169
    end if;
170
 
171
    rin <= v;
172
 
173
    -- drive APB bus
174
    apbaddr2 := (others => '0');
175
    apbaddr2(apbmax downto 0) := r.haddr(apbmax downto 0);
176
    apbi.paddr   <= apbaddr2;
177
    apbi.pwdata  <= r.pwdata;
178
    apbi.pwrite  <= r.hwrite;
179
    apbi.penable <= r.penable;
180
    apbi.pirq    <= ahbi.hirq;
181
    apbi.testen  <= ahbi.testen;
182
    apbi.testoen <= ahbi.testoen;
183
    apbi.scanen <= ahbi.scanen;
184
    apbi.testrst <= ahbi.testrst;
185
 
186
    for i in 0 to nslaves-1 loop apbi.psel(i) <= psel(i) and r.psel; end loop;
187
 
188
--pragma translate_off
189
    lapbi.paddr   <= apbaddr2;
190
    lapbi.pwdata  <= r.pwdata;
191
    lapbi.pwrite  <= r.hwrite;
192
    lapbi.penable <= r.penable;
193
    lapbi.pirq    <= ahbi.hirq;
194
 
195
    for i in 0 to nslaves-1 loop lapbi.psel(i) <= psel(i) and r.psel; end loop;
196
--pragma translate_on
197
 
198
  end process;
199
 
200
  ahbo.hindex <= hindex;
201
  ahbo.hconfig <= hconfig;
202
  ahbo.hcache <= '0';
203
  ahbo.hsplit <= (others => '0');
204
  ahbo.hresp  <= HRESP_OKAY;
205
 
206
  reg : process(clk)
207
  begin if rising_edge(clk) then r <= rin; end if; end process;
208
 
209
-- pragma translate_off
210
 
211
  mon0 : if enbusmon /= 0 generate
212
    mon :  apbmon
213
      generic map(
214
        asserterr   => asserterr,
215
        assertwarn  => assertwarn,
216
        pslvdisable => pslvdisable,
217
        napb        => nslaves)
218
      port map(
219
        rst         => rst,
220
        clk         => clk,
221
        apbi        => lapbi,
222
        apbo        => apbo,
223
        err         => open);
224
  end generate;
225
 
226
  diag : process
227
  variable k : integer;
228
  variable mask : std_logic_vector(11 downto 0);
229
  variable device : std_logic_vector(11 downto 0);
230
  variable devicei : integer;
231
  variable vendor : std_logic_vector( 7 downto 0);
232
  variable vendori : integer;
233
  variable iosize : integer;
234
  variable iounit : string(1 to 5) := "byte ";
235
  variable memstart : std_logic_vector(11 downto 0) := IOAREA and IOMSK;
236
  variable L1 : line := new string'("");
237
  begin
238
    wait for 3 ns;
239
    if debug = 0 then wait; end if;
240
    print("apbctrl: APB Bridge at " & tost(memstart) & "00000 rev 1");
241
    if debug = 1 then wait; end if;
242
    for i in 0 to nslaves-1 loop
243
      vendor := apbo(i).pconfig(0)(31 downto 24);
244
      vendori := conv_integer(vendor);
245
      if vendori /= 0 then
246
        device := apbo(i).pconfig(0)(23 downto 12);
247
        devicei := conv_integer(device);
248
        std.textio.write(L1, "apbctrl: slv" & tost(i) & ": " &
249
        iptable(vendori).vendordesc  & iptable(vendori).device_table(devicei));
250
        std.textio.writeline(OUTPUT, L1);
251
        mask := apbo(i).pconfig(1)(15 downto 4);
252
        k := 0;
253
        while (k<15) and (mask(k) = '0') loop k := k+1; end loop;
254
        iosize := 256 * 2**k; iounit := "byte ";
255
        if (iosize > 1023) then iosize := iosize/1024; iounit := "kbyte"; end if;
256
        print("apbctrl:       I/O ports at " &
257
          tost(memstart & (apbo(i).pconfig(1)(31 downto 20) and apbo(i).pconfig(1)(15 downto 4))) &
258
                "00, size " & tost(iosize) & " " & iounit);
259
        assert (apbo(i).pindex = i) or (icheck = 0)
260
        report "APB slave index error on slave " & tost(i) severity failure;
261
      end if;
262
    end loop;
263
    wait;
264
  end process;
265
-- pragma translate_on
266
 
267
end;
268
 

powered by: WebSVN 2.1.0

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