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

Subversion Repositories core_arm

[/] [core_arm/] [trunk/] [vhdl/] [sparc/] [acache.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:      acache
19
-- File:        acache.vhd
20
-- Author:      Jiri Gaisler - Gaisler Research
21
-- Description: Interface module between I/D cache controllers and Amba AHB
22
------------------------------------------------------------------------------  
23
 
24
library IEEE;
25
use IEEE.std_logic_1164.all;
26
use IEEE.std_logic_unsigned."+";
27
use IEEE.std_logic_arith.conv_unsigned;
28
use work.leon_target.all;
29
use work.leon_config.all;
30
use work.leon_iface.all;
31
use work.amba.all;
32
use work.macro.all;
33
 
34
 
35
entity acache is
36
  port (
37
    rst    : in  std_logic;
38
    clk    : in  clk_type;
39
    mcii   : in  memory_ic_in_type;
40
    mcio   : out memory_ic_out_type;
41
    mcdi   : in  memory_dc_in_type;
42
    mcdo   : out memory_dc_out_type;
43
    iuo    : in  iu_out_type;
44
    apbi   : in  apb_slv_in_type;
45
    apbo   : out apb_slv_out_type;
46
    ahbi   : in  ahb_mst_in_type;
47
    ahbo   : out ahb_mst_out_type
48
  );
49
end;
50
 
51
architecture rtl of acache is
52
 
53
-- cache control register type
54
 
55
type cctrltype is record
56
  ib     : std_logic;                           -- icache burst enable
57
  dfrz   : std_logic;                           -- dcache freeze enable
58
  ifrz   : std_logic;                           -- icache freeze enable
59
  dsnoop : std_logic;                           -- data cache snooping
60
  dcs    : std_logic_vector(1 downto 0); -- dcache state
61
  ics    : std_logic_vector(1 downto 0); -- icache state
62
end record;
63
 
64
type reg_type is record
65
  bg    : std_logic;    -- bus grant
66
  bo    : std_logic;    -- bus owner
67
  ba    : std_logic;    -- bus active
68
  retry : std_logic;    -- retry/split pending
69
  werr  : std_logic;    -- write error
70
  cctrl            : cctrltype;
71
  pwd   : std_logic;    -- power-down
72
  hcache: std_logic;    -- cacheable access
73
end record;
74
 
75
 
76
 
77
signal r, rin : reg_type;
78
begin
79
 
80
  comb : process(ahbi, r, rst, mcii, mcdi, iuo, apbi)
81
 
82
  variable v : reg_type;
83
  variable haddr   : std_logic_vector(31 downto 0);   -- address bus
84
  variable htrans  : std_logic_vector(1 downto 0);    -- transfer type 
85
  variable hwrite  : std_logic;                       -- read/write
86
  variable hlock   : std_logic;                       -- bus lock
87
  variable hsize   : std_logic_vector(2 downto 0);    -- transfer size
88
  variable hburst  : std_logic_vector(2 downto 0);    -- burst type
89
  variable hwdata  : std_logic_vector(31 downto 0);   -- write data
90
  variable hbusreq : std_logic;   -- bus request
91
  variable iflush, dflush : std_logic;
92
  variable iready, dready : std_logic;
93
  variable igrant, dgrant : std_logic;
94
  variable iretry, dretry : std_logic;
95
  variable ihcache, dhcache, hcache : std_logic;
96
  variable imexc, dmexc, nbo, dreq : std_logic;
97
  variable su : std_logic;
98
  variable cctrl   : std_logic_vector(31 downto 0);
99
 
100
  begin
101
 
102
-- initialisation
103
 
104
    htrans := HTRANS_IDLE;
105
    v := r; iready := '0'; v.werr := '0';
106
    dready := '0'; igrant := '0'; dgrant := '0';
107
    imexc := '0'; dmexc := '0'; hlock := '0'; iretry := '0'; dretry := '0';
108
    ihcache := '0'; dhcache := '0';
109
    iflush := '0'; dflush := '0'; su := '0';
110
 
111
 
112
-- generate AHB signals
113
 
114
    dreq := mcdi.req and not r.pwd;
115
    hbusreq := mcii.req or dreq;
116
    if hbusreq = '1' then htrans := HTRANS_NONSEQ; end if;
117
    hwdata := mcdi.data;
118
    nbo := (dreq and not (r.ba and mcii.req and not r.bo));
119
 
120
    if nbo = '0' then
121
      haddr := mcii.address; hwrite := '0'; hsize := HSIZE_WORD; hlock := '0';
122
      su := mcii.su;
123
      if mcii.burst = '1' then hburst := HBURST_INCR;
124
      else hburst := HBURST_SINGLE; end if;
125
      if (mcii.req and r.ba and not r.bo and not r.retry) = '1' then
126
        htrans := HTRANS_SEQ; haddr(4 downto 2) := haddr(4 downto 2) +1;
127
        hburst := HBURST_INCR;
128
      end if;
129
      if (mcii.req and r.bg and ahbi.hready and not r.retry) = '1'
130
      then igrant := '1'; end if;
131
    else
132
      haddr := mcdi.address; hwrite := not mcdi.read; hsize := '0' & mcdi.size;
133
      hlock := mcdi.lock;
134
      if mcdi.asi /= "1010" then su := '1'; else su := '0'; end if;
135
      if mcdi.burst = '1' then hburst := HBURST_INCR;
136
      else hburst := HBURST_SINGLE; end if;
137
      if (dreq and r.ba and r.bo and not r.retry) = '1' then
138
        htrans := HTRANS_SEQ; haddr(4 downto 2) := haddr(4 downto 2) +1;
139
        hburst := HBURST_INCR;
140
      end if;
141
      if (dreq and r.bg and ahbi.hready and not r.retry) = '1'
142
      then dgrant := '1'; end if;
143
    end if;
144
    if mcii.req = '0' then hlock := mcdi.lock; end if;
145
 
146
    if (r.ba = '1') and
147
       ((ahbi.hresp = HRESP_RETRY) or (ahbi.hresp = HRESP_SPLIT))
148
    then v.retry := not ahbi.hready; else v.retry := '0'; end if;
149
 
150
    if r.retry = '1' then htrans := HTRANS_IDLE; end if;
151
 
152
    if r.bo = '0' then
153
      if r.ba = '1' then
154
        ihcache := r.hcache;
155
        if ahbi.hready = '1' then
156
          case ahbi.hresp is
157
          when HRESP_OKAY => iready := '1';
158
          when HRESP_RETRY | HRESP_SPLIT=> iretry := '1';
159
          when others => iready := '1'; imexc := '1';
160
          end case;
161
        end if;
162
      end if;
163
    else
164
      if r.ba = '1' then
165
        dhcache := r.hcache;
166
        if ahbi.hready = '1' then
167
          case ahbi.hresp is
168
          when HRESP_OKAY => dready := '1';
169
          when HRESP_RETRY | HRESP_SPLIT=> dretry := '1';
170
          when others => dready := '1'; dmexc := '1'; v.werr := not mcdi.read;
171
          end case;
172
        end if;
173
      end if;
174
      hlock := mcdi.lock;
175
    end if;
176
 
177
    -- decode cacheability
178
 
179
--    hcache := not orv (haddr(31) & (haddr(30 downto 28) xor "001"));
180
--    hcache := '0';
181
--    for i in PROC_CACHETABLE'range loop       --'
182
--      if (haddr(31 downto 32-PROC_CACHE_ADDR_MSB) >= PROC_CACHETABLE(i).firstaddr) and
183
--         (haddr(31 downto 32-PROC_CACHE_ADDR_MSB) < PROC_CACHETABLE(i).lastaddr) 
184
--      then hcache := '1';  end if;
185
--    end loop;
186
      hcache := is_cacheable(haddr(31 downto 24));
187
 
188
    if nbo = '1' and ((hsize = "011") or ((hcache and mcdi.read) = '1')) then
189
      hsize := "010"; haddr(1 downto 0) := "00";
190
    end if;
191
 
192
    if ahbi.hready = '1' then
193
      v.hcache := hcache; v.bo := nbo; v.bg := ahbi.hgrant;
194
      if (htrans = HTRANS_NONSEQ) or (htrans = HTRANS_SEQ) then
195
        v.ba := r.bg;
196
      else v.ba := '0'; end if;
197
    end if;
198
 
199
-- cache control and power-down handling
200
 
201
    -- cache freeze operation
202
    if (r.cctrl.ifrz and iuo.intack and r.cctrl.ics(0)) = '1' then
203
      v.cctrl.ics := "01";
204
    end if;
205
    if (r.cctrl.dfrz and iuo.intack and r.cctrl.dcs(0)) = '1' then
206
      v.cctrl.dcs := "01";
207
    end if;
208
 
209
    if (apbi.psel and apbi.penable and apbi.pwrite) = '1' then
210
      case apbi.paddr(2 downto 2) is
211
      when "1" =>
212
 
213
        v.cctrl.dsnoop := apbi.pwdata(23);
214
        dflush       := apbi.pwdata(22);
215
        iflush       := apbi.pwdata(21);
216
        v.cctrl.ib   := apbi.pwdata(16);
217
        v.cctrl.dfrz := apbi.pwdata(5);
218
        v.cctrl.ifrz := apbi.pwdata(4);
219
        v.cctrl.dcs  := apbi.pwdata(3 downto 2);
220
        v.cctrl.ics  := apbi.pwdata(1 downto 0);
221
      when others =>
222
        v.pwd := '1';
223
      end case;
224
    end if;
225
 
226
    cctrl := (others => '0');
227
 
228
    if DSNOOP then cctrl(23) := r.cctrl.dsnoop; end if;
229
    cctrl(16 downto 14) := r.cctrl.ib & mcii.flush  &  mcdi.flush;
230
    cctrl(5 downto 0)   := r.cctrl.dfrz & r.cctrl.ifrz & r.cctrl.dcs & r.cctrl.ics;
231
    cctrl(25 downto 24) := std_logic_vector(conv_unsigned(DSETS-1,2));
232
    cctrl(27 downto 26) := std_logic_vector(conv_unsigned(ISETS-1,2));
233
    if ISETS /= 1 then
234
      if ICREPLACE = rnd then cctrl(29 downto 28) := "01"; end if;
235
      if ICREPLACE = lrr then cctrl(29 downto 28) := "10"; end if;
236
      if ICREPLACE = lru then cctrl(29 downto 28) := "11"; end if;
237
    end if;
238
    if DSETS /= 1 then
239
      if DCREPLACE = rnd then cctrl(31 downto 30) := "01"; end if;
240
      if DCREPLACE = lrr then cctrl(31 downto 30) := "10"; end if;
241
      if DCREPLACE = lru then cctrl(31 downto 30) := "11"; end if;
242
    end if;
243
 
244
    -- exit power-down in DSU debug mode
245
    if DEBUG_UNIT then
246
      v.pwd := v.pwd and (not iuo.ipend) and not iuo.debug.dbreak;
247
    else v.pwd := v.pwd and not iuo.ipend; end if;
248
 
249
 
250
-- reset operation
251
 
252
    if rst = '0' then
253
      v.bg := '0'; v.bo := '0'; v.ba := '0'; v.retry := '0'; v.werr := '0';
254
      v.cctrl.dcs := "00"; v.cctrl.ics := "00"; v.hcache := '0';
255
      v.cctrl.ib := '0'; v.pwd := '0'; v.cctrl.dsnoop := '0';
256
    end if;
257
 
258
-- drive ports
259
 
260
    ahbo.haddr   <= haddr ;
261
    ahbo.htrans  <= htrans;
262
    ahbo.hbusreq <= hbusreq;
263
    ahbo.hwdata  <= hwdata;
264
    ahbo.hlock   <= hlock;
265
    ahbo.hwrite  <= hwrite;
266
    ahbo.hsize   <= hsize;
267
    ahbo.hburst  <= hburst;
268
    ahbo.hprot   <= hcache & hcache & su & nbo;
269
    mcio.grant   <= igrant;
270
    mcio.ready   <= iready;
271
    mcio.mexc    <= imexc;
272
    mcio.retry   <= iretry;
273
    mcio.cache   <= ihcache;
274
    mcdo.grant   <= dgrant;
275
    mcdo.ready   <= dready;
276
    mcdo.mexc    <= dmexc;
277
    mcdo.retry   <= dretry;
278
    mcdo.werr    <= r.werr;
279
    mcdo.cache   <= dhcache;
280
    mcdo.iflush  <= iflush;
281
    mcdo.dflush  <= dflush;
282
    mcdo.ba      <= r.ba;
283
    mcdo.bg      <= r.bg;
284
    mcdo.dsnoop  <= r.cctrl.dsnoop;
285
    apbo.prdata  <= cctrl;
286
 
287
 
288
    rin <= v;
289
 
290
  end process;
291
 
292
  mcio.data <= ahbi.hrdata; mcdo.data <= ahbi.hrdata;
293
 
294
  mcio.ics <= r.cctrl.ics; mcdo.dcs <= r.cctrl.dcs;
295
  mcio.burst <= r.cctrl.ib;
296
 
297
  reg : process(clk)
298
  begin if rising_edge(clk) then r <= rin; end if; end process;
299
 
300
 
301
end;
302
 

powered by: WebSVN 2.1.0

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