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

Subversion Repositories core_arm

[/] [core_arm/] [trunk/] [vhdl/] [sparc/] [mmu_acache.vhd] - Blame information for rev 4

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 tarookumic
----------------------------------------------------------------------------
2
--  This file is a part of the LEON VHDL model
3
--  Copyright (C) 2003  Gaisler Research
4
--
5
--  This library is free software; you can redistribute it and/or
6
--  modify it under the terms of the GNU Lesser General Public
7
--  License as published by the Free Software Foundation; either
8
--  version 2 of the License, or (at your option) any later version.
9
--
10
--  See the file COPYING.LGPL for the full details of the license.
11
 
12
 
13
-----------------------------------------------------------------------------   
14
-- Entity:      mmu_acache
15
-- File:        mmu_acache.vhd
16
-- Author:      Jiri Gaisler - Gaisler Research, Konrad Eisele <eiselekd@web.de>
17
-- Description: Interface module between I/D cache controllers and Amba AHB
18
------------------------------------------------------------------------------  
19
 
20
 
21
library IEEE;
22
use IEEE.std_logic_1164.all;
23
use IEEE.std_logic_unsigned."+";
24
use IEEE.std_logic_arith.conv_unsigned;
25
use work.leon_target.all;
26
use work.leon_config.all;
27
use work.leon_iface.all;
28
use work.amba.all;
29
use work.macro.all;
30
 
31
 
32
entity mmu_acache is
33
  port (
34
    rst    : in  std_logic;
35
    clk    : in  clk_type;
36
    mcii   : in  memory_ic_in_type;
37
    mcio   : out memory_ic_out_type;
38
    mcdi   : in  memory_dc_in_type;
39
    mcdo   : out memory_dc_out_type;
40
    mcmmi  : in  memory_mm_in_type;
41
    mcmmo  : out memory_mm_out_type;
42
    iuo    : in  iu_out_type;
43
    apbi   : in  apb_slv_in_type;
44
    apbo   : out apb_slv_out_type;
45
    ahbi   : in  ahb_mst_in_type;
46
    ahbo   : out ahb_mst_out_type
47
  );
48
end;
49
 
50
architecture rtl of mmu_acache is
51
 
52
-- cache control register type
53
 
54
type cctrltype is record
55
  ib     : std_logic;                           -- icache burst enable
56
  dfrz   : std_logic;                           -- dcache freeze enable
57
  ifrz   : std_logic;                           -- icache freeze enable
58
  dsnoop : std_logic;                           -- data cache snooping
59
  dcs    : std_logic_vector(1 downto 0); -- dcache state
60
  ics    : std_logic_vector(1 downto 0); -- icache state
61
end record;
62
 
63
type astates is (idle, dcache, icache, mmu);
64
type reg_type is record
65
  bg     : std_logic;   -- bus grant
66
  bo     : std_logic_vector(1 downto 0);         -- 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
  astate : astates;
74
end record;
75
 
76
signal r, rin : reg_type;
77
begin
78
 
79
  comb : process(ahbi, r, rst, mcii, mcdi, mcmmi, iuo, apbi)
80
 
81
  variable v : reg_type;
82
  variable haddr   : std_logic_vector(31 downto 0);   -- address bus
83
  variable htrans  : std_logic_vector(1 downto 0);    -- transfer type 
84
  variable hwrite  : std_logic;                       -- read/write
85
  variable hlock   : std_logic;                       -- bus lock
86
  variable hsize   : std_logic_vector(2 downto 0);    -- transfer size
87
  variable hburst  : std_logic_vector(2 downto 0);    -- burst type
88
  variable hwdata  : std_logic_vector(31 downto 0);   -- write data
89
  variable hbusreq : std_logic;   -- bus request
90
  variable iflush, dflush, mmflush : std_logic;
91
  variable iready, dready, mmready : std_logic;
92
  variable igrant, dgrant, mmgrant : std_logic;
93
  variable iretry, dretry, mmretry : std_logic;
94
  variable ihcache, dhcache, mmhcache, hcache : std_logic;
95
  variable imexc, dmexc, mmmexc : std_logic;
96
  variable dreq : std_logic;
97
  variable nbo : std_logic_vector(1 downto 0);
98
  variable su : std_logic;
99
  variable cctrl   : std_logic_vector(31 downto 0);
100
 
101
  begin
102
 
103
    -- initialisation
104
 
105
    htrans := HTRANS_IDLE;
106
    v := r;  v.werr := '0';
107
    iready := '0'; dready := '0'; mmready := '0';
108
    igrant := '0'; dgrant := '0'; mmgrant := '0';
109
    imexc := '0'; dmexc := '0'; mmmexc := '0'; hlock := '0';
110
    iretry := '0'; dretry := '0'; mmretry := '0';
111
    ihcache := '0'; dhcache := '0'; mmhcache := '0';
112
    iflush := '0'; dflush := '0'; mmflush := '0'; su := '0';
113
 
114
    haddr := (others => '0');
115
    hwrite := '0';
116
    hsize := (others => '0');
117
    hlock := '0';
118
    hburst := (others => '0');
119
 
120
    -- generate AHB signals
121
 
122
    dreq := mcdi.req and not r.pwd;
123
    hwdata := mcdi.data;
124
    hbusreq := '0';
125
 
126
    if (mcii.req = '1') and
127
      not (( ((r.ba and dreq) = '1') and (r.bo = "01")) or
128
           ( ((r.ba and mcmmi.req) = '1') and (r.bo = "10"))) then
129
      nbo := "00";
130
      hbusreq := '1';
131
      htrans := HTRANS_NONSEQ;
132
    elsif (dreq = '1') and
133
      not (( ((r.ba and mcii.req) = '1') and (r.bo = "00")) or
134
           ( ((r.ba and mcmmi.req) = '1') and (r.bo = "10"))) then
135
      nbo := "01";
136
      hbusreq := '1';
137
      htrans := HTRANS_NONSEQ;
138
    elsif (mcmmi.req = '1') and
139
      not (( ((r.ba and mcii.req) = '1') and (r.bo = "00")) or
140
           ( ((r.ba and dreq) = '1') and (r.bo = "01"))) then
141
      nbo := "10";
142
      hbusreq := '1';
143
      htrans := HTRANS_NONSEQ;
144
    else
145
      nbo := "11";
146
    end if;
147
 
148
    if nbo = "10" then
149
      haddr := mcmmi.address; hwrite := not mcmmi.read; hsize := '0' & mcmmi.size;
150
      hlock := mcmmi.lock;
151
--      if mcmmi.burst = '1' then hburst := HBURST_INCR; 
152
--      else hburst := HBURST_SINGLE; end if;
153
--      if ((mcmmi.req and r.ba) = '1')  and (r.bo = "10") and ((not r.retry) = '1') then 
154
--        htrans := HTRANS_SEQ; haddr(4 downto 2) := haddr(4 downto 2) +1;
155
--        hburst := HBURST_INCR; 
156
--      end if;
157
      htrans := HTRANS_NONSEQ; hburst := HBURST_SINGLE;
158
      if (mcmmi.req and r.bg and ahbi.hready and not r.retry) = '1'
159
      then mmgrant := '1'; end if;
160
    elsif nbo = "00" then
161
      haddr := mcii.address; hwrite := '0'; hsize := HSIZE_WORD; hlock := '0';
162
      su := mcii.su;
163
      if mcii.burst = '1' then hburst := HBURST_INCR;
164
      else hburst := HBURST_SINGLE; end if;
165
      if ((mcii.req and r.ba) = '1')  and (r.bo = "00") and ((not r.retry) = '1') then
166
        htrans := HTRANS_SEQ; haddr(4 downto 2) := haddr(4 downto 2) +1;
167
        hburst := HBURST_INCR;
168
      end if;
169
      if (mcii.req and r.bg and ahbi.hready and not r.retry) = '1'
170
      then igrant := '1'; end if;
171
    elsif nbo = "01" then
172
      haddr := mcdi.address; hwrite := not mcdi.read; hsize := '0' & mcdi.size;
173
      hlock := mcdi.lock;
174
      if mcdi.asi /= "1010" then su := '1'; else su := '0'; end if;  --ASI_UDATA
175
      if mcdi.burst = '1' then hburst := HBURST_INCR;
176
      else hburst := HBURST_SINGLE; end if;
177
      if ((dreq and r.ba) = '1') and (r.bo = "01") and ((not r.retry) = '1') then
178
        htrans := HTRANS_SEQ; haddr(4 downto 2) := haddr(4 downto 2) +1;
179
        hburst := HBURST_INCR;
180
      end if;
181
      if (dreq and r.bg and ahbi.hready and not r.retry) = '1'
182
      then dgrant := '1'; end if;
183
    end if;
184
 
185
    if mcii.req = '0' then hlock := mcdi.lock; end if;
186
 
187
    if (r.ba = '1') and
188
       ((ahbi.hresp = HRESP_RETRY) or (ahbi.hresp = HRESP_SPLIT))
189
    then v.retry := not ahbi.hready; else v.retry := '0'; end if;
190
 
191
    if r.retry = '1' then htrans := HTRANS_IDLE; end if;
192
 
193
    if r.bo = "10" then
194
      hwdata := mcmmi.data;
195
      if r.ba = '1' then
196
        mmhcache := r.hcache;
197
        if ahbi.hready = '1' then
198
          case ahbi.hresp is
199
          when HRESP_OKAY => mmready := '1';
200
          when HRESP_RETRY | HRESP_SPLIT=> mmretry := '1';
201
          when others => mmready := '1'; mmmexc := '1'; v.werr := not mcmmi.read;
202
          end case;
203
        end if;
204
      end if;
205
    elsif r.bo = "00" then
206
      if r.ba = '1' then
207
        ihcache := r.hcache;
208
        if ahbi.hready = '1' then
209
          case ahbi.hresp is
210
          when HRESP_OKAY => iready := '1';
211
          when HRESP_RETRY | HRESP_SPLIT=> iretry := '1';
212
          when others => iready := '1'; imexc := '1';
213
          end case;
214
        end if;
215
      end if;
216
    elsif r.bo = "01" then
217
      --hwdata := mcdi.data;
218
      if r.ba = '1' then
219
        dhcache := r.hcache;
220
        if ahbi.hready = '1' then
221
          case ahbi.hresp is
222
          when HRESP_OKAY => dready := '1';
223
          when HRESP_RETRY | HRESP_SPLIT=> dretry := '1';
224
          when others => dready := '1'; dmexc := '1'; v.werr := not mcdi.read;
225
          end case;
226
        end if;
227
      end if;
228
      hlock := mcdi.lock;
229
    end if;
230
 
231
    -- decode cacheability
232
 
233
    hcache := is_cacheable(haddr(31 downto 24));
234
 
235
    if nbo = "01" and ((hsize = "011") or ((hcache and mcdi.read) = '1')) then
236
      hsize := "010";
237
    end if;
238
 
239
    if ahbi.hready = '1' then
240
      v.hcache := hcache; v.bo := nbo; v.bg := ahbi.hgrant;
241
      if (htrans = HTRANS_NONSEQ) or (htrans = HTRANS_SEQ) then
242
        v.ba := r.bg;
243
      else v.ba := '0'; end if;
244
    end if;
245
 
246
    -- cache freeze operation
247
 
248
    if (r.cctrl.ifrz and iuo.intack and r.cctrl.ics(0)) = '1' then
249
      v.cctrl.ics := "01";
250
    end if;
251
    if (r.cctrl.dfrz and iuo.intack and r.cctrl.dcs(0)) = '1' then
252
      v.cctrl.dcs := "01";
253
    end if;
254
 
255
    if (apbi.psel and apbi.penable and apbi.pwrite) = '1' then
256
      case apbi.paddr(2 downto 2) is
257
      when "1" =>
258
 
259
        v.cctrl.dsnoop := apbi.pwdata(23);
260
        dflush       := apbi.pwdata(22);
261
        iflush       := apbi.pwdata(21);
262
        v.cctrl.ib   := apbi.pwdata(16);
263
        v.cctrl.dfrz := apbi.pwdata(5);
264
        v.cctrl.ifrz := apbi.pwdata(4);
265
        v.cctrl.dcs  := apbi.pwdata(3 downto 2);
266
        v.cctrl.ics  := apbi.pwdata(1 downto 0);
267
      when others =>
268
        v.pwd := '1';
269
      end case;
270
    end if;
271
 
272
    cctrl := (others => '0');
273
 
274
    if DSNOOP then cctrl(23) := r.cctrl.dsnoop; end if;
275
    cctrl(16 downto 14) := r.cctrl.ib & mcii.flush  &  mcdi.flush;
276
    cctrl(5 downto 0)   := r.cctrl.dfrz & r.cctrl.ifrz & r.cctrl.dcs & r.cctrl.ics;
277
    cctrl(25 downto 24) := std_logic_vector(conv_unsigned(DSETS-1,2));
278
    cctrl(27 downto 26) := std_logic_vector(conv_unsigned(ISETS-1,2));
279
    if ISETS /= 1 then
280
      if ICREPLACE = rnd then cctrl(29 downto 28) := "01"; end if;
281
      if ICREPLACE = lrr then cctrl(29 downto 28) := "10"; end if;
282
      if ICREPLACE = lru then cctrl(29 downto 28) := "11"; end if;
283
    end if;
284
    if DSETS /= 1 then
285
      if DCREPLACE = rnd then cctrl(31 downto 30) := "01"; end if;
286
      if DCREPLACE = lrr then cctrl(31 downto 30) := "10"; end if;
287
      if DCREPLACE = lru then cctrl(31 downto 30) := "11"; end if;
288
    end if;
289
 
290
 
291
    -- exit power-down in DSU debug mode
292
 
293
    if DEBUG_UNIT then
294
      v.pwd := v.pwd and (not iuo.ipend) and not iuo.debug.dbreak;
295
    else v.pwd := v.pwd and not iuo.ipend; end if;
296
 
297
 
298
    -- reset operation
299
 
300
    if rst = '0' then
301
      v.bg := '0'; v.bo := "00"; v.ba := '0'; v.retry := '0'; v.werr := '0';
302
      v.cctrl.dcs := "00"; v.cctrl.ics := "00"; v.hcache := '0';
303
      v.cctrl.ib := '0'; v.pwd := '0'; v.cctrl.dsnoop := '0';
304
      v.astate := idle;
305
    end if;
306
 
307
    -- drive ports
308
 
309
    ahbo.haddr   <= haddr ;
310
    ahbo.htrans  <= htrans;
311
    ahbo.hbusreq <= hbusreq;
312
    ahbo.hwdata  <= hwdata;
313
    ahbo.hlock   <= hlock;
314
    ahbo.hwrite  <= hwrite;
315
    ahbo.hsize   <= hsize;
316
    ahbo.hburst  <= hburst;
317
 
318
    if nbo = "00" then ahbo.hprot   <= hcache & hcache & su & '0';
319
    else ahbo.hprot   <= hcache & hcache & su & '1'; end if;
320
    mcio.grant   <= igrant;
321
    mcio.ready   <= iready;
322
    mcio.mexc    <= imexc;
323
    mcio.retry   <= iretry;
324
    mcio.cache   <= ihcache;
325
    mcdo.grant   <= dgrant;
326
    mcdo.ready   <= dready;
327
    mcdo.mexc    <= dmexc;
328
    mcdo.retry   <= dretry;
329
    mcdo.werr    <= r.werr;
330
    mcdo.cache   <= dhcache;
331
    mcdo.iflush  <= iflush;
332
    mcdo.dflush  <= dflush;
333
    mcdo.ba      <= r.ba;
334
    mcdo.bg      <= r.bg;
335
    mcdo.dsnoop  <= r.cctrl.dsnoop;
336
    apbo.prdata  <= cctrl;
337
 
338
    mcmmo.grant   <= mmgrant;
339
    mcmmo.ready   <= mmready;
340
    mcmmo.mexc    <= mmmexc;
341
    mcmmo.retry   <= mmretry;
342
    mcmmo.werr    <= r.werr;
343
    mcmmo.cache   <= mmhcache;
344
 
345
    rin <= v;
346
 
347
  end process;
348
 
349
  mcio.data  <= ahbi.hrdata;
350
  mcdo.data  <= ahbi.hrdata;
351
  mcmmo.data <= ahbi.hrdata;
352
 
353
  mcio.ics <= r.cctrl.ics; mcdo.dcs <= r.cctrl.dcs;
354
  mcio.burst <= r.cctrl.ib;
355
 
356
  reg : process(clk)
357
  begin if rising_edge(clk) then r <= rin; end if; end process;
358
 
359
 
360
end;
361
 
362
 
363
 
364
 
365
 
366
 
367
 
368
 
369
 
370
 
371
 
372
 
373
 
374
 

powered by: WebSVN 2.1.0

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