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

Subversion Repositories core_arm

[/] [core_arm/] [trunk/] [vhdl/] [bus/] [apbmst.vhd] - Blame information for rev 4

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 tarookumic
 
2
 
3
 
4
 
5
----------------------------------------------------------------------------
6
--  This file is a part of the LEON VHDL model
7
--  Copyright (C) 1999  European Space Agency (ESA)
8
--
9
--  This library is free software; you can redistribute it and/or
10
--  modify it under the terms of the GNU Lesser General Public
11
--  License as published by the Free Software Foundation; either
12
--  version 2 of the License, or (at your option) any later version.
13
--
14
--  See the file COPYING.LGPL for the full details of the license.
15
 
16
 
17
-----------------------------------------------------------------------------   
18
-- Entity:      apbmst
19
-- File:        apbmst.vhd
20
-- Author:      Jiri Gaisler - ESA/ESTEC
21
-- Description: AMBA AHB/APB bridge
22
------------------------------------------------------------------------------ 
23
 
24
library IEEE;
25
use IEEE.std_logic_1164.all;
26
use IEEE.std_logic_arith.all;
27
use work.leon_target.all;
28
use work.leon_config.all;
29
use work.leon_iface.all;
30
use work.amba.all;
31
 
32
 
33
entity apbmst is
34
  port (
35
    rst     : in  std_logic;
36
    clk     : in  std_logic;
37
    ahbi    : in  ahb_slv_in_type;
38
    ahbo    : out ahb_slv_out_type;
39
    apbi    : out apb_slv_in_vector(0 to APB_SLV_MAX-1);
40
    apbo    : in  apb_slv_out_vector(0 to APB_SLV_MAX-1)
41
  );
42
end;
43
 
44
architecture rtl of apbmst is
45
 
46
-- registers
47
type reg_type is record
48
  haddr   : std_logic_vector(APB_SLV_ADDR_BITS -1 downto 2);   -- address bus
49
  hsel    : std_logic;
50
  hwrite  : std_logic;                       -- read/write
51
  hready  : std_logic;                       -- ready
52
  hready2 : std_logic;                       -- ready
53
  penable : std_logic;
54
end record;
55
 
56
signal r, rin : reg_type;
57
 
58
constant apbmax : integer := APB_SLV_ADDR_BITS -1;
59
begin
60
  comb : process(ahbi, apbo, r, rst)
61
  variable v : reg_type;
62
  variable psel   : std_logic_vector(0 to APB_SLV_MAX-1);
63
  variable prdata : std_logic_vector(31 downto 0);
64
  variable pwdata : std_logic_vector(31 downto 0);
65
  variable apbaddr : std_logic_vector(apbmax downto 2);
66
  variable apbaddr2 : std_logic_vector(31 downto 0);
67
  variable bindex : integer range 0 to APB_SLV_MAX-1;
68
  variable esel : std_logic;
69
  begin
70
 
71
    v := r; v.hready2 := '1';
72
 
73
    -- detect start of cycle
74
    if (ahbi.hready = '1') then
75
      if ((ahbi.htrans = HTRANS_NONSEQ) or (ahbi.htrans = HTRANS_SEQ)) and
76
          (ahbi.hsel = '1')
77
      then
78
        v.hready := '0'; v.hwrite := ahbi.hwrite; v.hsel := '1';
79
        v.hwrite := ahbi.hwrite; v.hready2 := not ahbi.hwrite;
80
        v.haddr(apbmax downto 2)  := ahbi.haddr(apbmax downto 2);
81
      else v.hsel := '0'; end if;
82
    end if;
83
 
84
    -- generate hready and penable
85
    if (r.hsel and r.hready2 and (not r.hready)) = '1' then
86
      v.penable := '1'; v.hready := '1';
87
    else v.penable := '0'; end if;
88
 
89
    -- generate psel and select APB read data
90
    psel := (others => '0'); prdata := (others => '-');
91
    apbaddr := r.haddr(apbmax downto 2);
92
    bindex := 0; esel := '0';
93
 
94
   case apbaddr is
95
   -- memory controller, 0x00 - 0x08
96
   when "00000000" | "00000001" | "00000010" =>
97
     esel := '1'; bindex := 0;
98
   -- AHB status reg.,   0x0C - 0x10
99
   when "00000011" | "00000100" =>
100
     esel := '1'; bindex := 1;
101
   -- cache controller,  0x14 - 0x18
102
   when "00000101" | "00000110" =>
103
     esel := '1'; bindex := 2;
104
   -- write protection,  0x1C - 0x20
105
   when "00000111" | "00001000" =>
106
     if WPROTEN then esel := '1'; bindex := 3; end if;
107
   -- config register,   0x24 - 0x24
108
   when "00001001" =>
109
     if CFGREG then esel := '1'; bindex := 4; end if;
110
   -- timers,            0x40 - 0x6C
111
   when "00010000" | "00010001" | "00010010" | "00010011" |
112
        "00010100" | "00010101" | "00010110" | "00010111" |
113
        "00011000" | "00011001" | "00011010" | "00011011" =>
114
     esel := '1'; bindex := 5;
115
   -- uart1,             0x70 - 0x7C
116
   when "00011100" | "00011101" | "00011110" | "00011111" =>
117
     esel := '1'; bindex := 6;
118
   -- uart2,             0x80 - 0x8C
119
   when "00100000" | "00100001" | "00100010" | "00100011" =>
120
     esel := '1'; bindex := 7;
121
   -- interrupt ctrl     0x90 - 0x9C
122
   when "00100100" | "00100101" | "00100110" | "00100111" =>
123
     esel := '1'; bindex := 8;
124
   -- I/O port           0xA0 - 0xAC
125
   when "00101000" | "00101001" | "00101010" | "00101011" =>
126
     esel := '1'; bindex := 9;
127
   -- 2nd interrupt ctrl 0xB0 - 0xBC
128
   when "00101100" | "00101101" | "00101110" | "00101111" =>
129
     if IRQ2EN then esel := '1'; bindex := 10; end if;
130
   -- DSU uart           0xC0 - 0xCC
131
   when "00110000" | "00110001" | "00110010" | "00110011" =>
132
     if DEBUG_UNIT then esel := '1'; bindex := 11; end if;
133
   when others =>
134
     if PCIEN and ( r.haddr(apbmax downto apbmax-1) = "01") then
135
       esel := '1'; bindex := 12;
136
     end if;
137
     if PCIARBEN and ( r.haddr(apbmax downto apbmax-1) = "10") then
138
       esel := '1'; bindex := 13;
139
     end if;
140
   end case;
141
 
142
   prdata := apbo(bindex).prdata; psel(bindex) := esel;
143
--    for i in APB_TABLE'range loop     --'
144
--      if  APB_TABLE(i).enable and
145
--       (apbaddr >= APB_TABLE(i).firstaddr(apbmax downto 2)) and
146
--         (apbaddr <= APB_TABLE(i).lastaddr(apbmax downto 2)) 
147
--      then 
148
--      prdata := apbo(APB_TABLE(i).index).prdata; 
149
--      psel(APB_TABLE(i).index) := '1';
150
--      end if;
151
--    end loop;
152
 
153
    -- AHB respons
154
    ahbo.hresp  <= HRESP_OKAY;
155
    ahbo.hready <= r.hready;
156
    ahbo.hrdata <= prdata;
157
    ahbo.hsplit <= (others => '0');
158
 
159
    if rst = '0' then
160
      v.penable := '0'; v.hready := '1'; v.hsel := '0';
161
-- pragma translate_off
162
      v.haddr := (others => '0');
163
-- pragma translate_on
164
    end if;
165
 
166
    rin <= v;
167
 
168
    -- tie write data to zero if not used to save power (not testable)
169
    if r.hsel = '1' then pwdata := ahbi.hwdata;
170
    else pwdata := (others => '0'); end if;
171
 
172
    -- drive APB bus
173
    apbaddr2 := (others => '0');
174
    apbaddr2(apbmax downto 2)    := r.haddr(apbmax downto 2);
175
    for i in 0 to APB_SLV_MAX-1 loop
176
      apbi(i).paddr   <= apbaddr2;
177
      apbi(i).pwdata  <= pwdata;
178
      apbi(i).pwrite  <= r.hwrite;
179
      apbi(i).penable <= r.penable;
180
      apbi(i).psel    <= psel(i) and r.hsel and r.hready2;
181
    end loop;
182
 
183
  end process;
184
 
185
 
186
  reg : process(clk)
187
  begin if rising_edge(clk) then r <= rin; end if; end process;
188
 
189
 
190
end;
191
 

powered by: WebSVN 2.1.0

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