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/] [leon3/] [mmu_acache.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:      mmu_acache
20
-- File:        mmu_acache.vhd
21
-- Author:      Jiri Gaisler - Gaisler Research, Konrad Eisele <eiselekd@web.de>
22
-- Description: Interface module between I/D cache controllers and Amba AHB
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
use grlib.devices.all;
31
library gaisler;
32
use gaisler.libiu.all;
33
use gaisler.libcache.all;
34
use gaisler.leon3.all;
35
use gaisler.mmuconfig.all;
36
use gaisler.mmuiface.all;
37
 
38
 
39
entity mmu_acache is
40
  generic (
41
    hindex    : integer range 0 to NAHBMST-1  := 0;
42
    ilinesize : integer range 4 to 8 := 4;
43
    cached    : integer := 0;
44
    clk2x     : integer := 0;
45
    scantest  : integer := 0);
46
  port (
47
    rst    : in  std_logic;
48
    clk    : in  std_logic;
49
    mcii   : in  memory_ic_in_type;
50
    mcio   : out memory_ic_out_type;
51
    mcdi   : in  memory_dc_in_type;
52
    mcdo   : out memory_dc_out_type;
53
    mcmmi  : in  memory_mm_in_type;
54
    mcmmo  : out memory_mm_out_type;
55
    ahbi   : in  ahb_mst_in_type;
56
    ahbo   : out ahb_mst_out_type;
57
    ahbso  : in  ahb_slv_out_vector;
58
    hclken : in  std_ulogic
59
  );
60
end;
61
 
62
architecture rtl of mmu_acache is
63
 
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
  lb    : std_ulogic;   -- last burst cycle
69
  retry  : std_logic;   -- retry/split pending
70
  retry2 : std_ulogic;  -- retry/split pending
71
  werr   : std_logic;   -- write error
72
  hlocken : std_ulogic; -- ready to perform locked transaction
73
  lock   : std_ulogic;  -- keep bus locked during SWAP sequence
74
  hcache : std_logic;   -- cacheable access
75
  nba    :  std_ulogic;
76
  nbo    : std_logic_vector(1 downto 0);       -- bus owner
77
end record;
78
 
79
type reg2_type is record
80
  reqmsk  : std_logic_vector(2 downto 0);
81
  hclken2 : std_ulogic;
82
end record;
83
 
84
constant hconfig : ahb_config_type := (
85
 
86
  others => zero32);
87
 
88
constant ctbl : std_logic_vector(15 downto 0) := conv_std_logic_vector(cached, 16);
89
function dec_fixed(scache : std_ulogic;
90
        haddr : std_logic_vector(3 downto 0); cached : integer) return std_ulogic is
91
begin
92
  if (cached /= 0) then return ctbl(conv_integer(haddr(3 downto 0)));
93
  else return(scache); end if;
94
end;
95
 
96
signal r, rin : reg_type;
97
signal r2, r2in : reg2_type;
98
begin
99
 
100
  comb : process(ahbi, r, rst, mcii, mcdi, mcmmi, ahbso, hclken, r2)
101
 
102
  variable v : reg_type;
103
  variable v2 : reg2_type;
104
  variable haddr   : std_logic_vector(31 downto 0);   -- address bus
105
  variable htrans  : std_logic_vector(1 downto 0);    -- transfer type 
106
  variable hwrite  : std_logic;                       -- read/write
107
  variable hlock   : std_logic;                       -- bus lock
108
  variable hsize   : std_logic_vector(2 downto 0);    -- transfer size
109
  variable hburst  : std_logic_vector(2 downto 0);    -- burst type
110
  variable hwdata  : std_logic_vector(31 downto 0);   -- write data
111
  variable hbusreq : std_logic;   -- bus request
112
  variable iready, dready, mmready : std_logic;
113
  variable igrant, dgrant, mmgrant : std_logic;
114
  variable iretry, dretry, mmretry : std_logic;
115
  variable ihcache, dhcache, mmhcache, dec_hcache : std_logic;
116
  variable imexc, dmexc, mmmexc : std_logic;
117
  variable dreq : std_logic;
118
  variable nbo : std_logic_vector(1 downto 0);
119
  variable su, nb, bo_icache : std_logic;
120
  variable scanen : std_ulogic;
121
 
122
  begin
123
 
124
    -- initialisation
125
 
126
    htrans := HTRANS_IDLE;
127
    v := r;  v.werr := '0'; v2 := r2;
128
    iready := '0'; dready := '0'; mmready := '0';
129
    igrant := '0'; dgrant := '0'; mmgrant := '0';
130
    imexc := '0'; dmexc := '0'; mmmexc := '0'; hlock := '0';
131
    iretry := '0'; dretry := '0'; mmretry := '0';
132
    ihcache := '0'; dhcache := '0'; mmhcache := '0'; su := '0';
133
    if (r.bo = "00") then bo_icache := '1'; else bo_icache := '0'; end if;
134
 
135
    haddr := (others => '0');
136
    hwrite := '0';
137
    hsize := (others => '0');
138
    hlock := '0';
139
    hburst := (others => '0');
140
    if ahbi.hready = '1' then v.lb := '0'; end if;
141
    if scantest = 1 then scanen := ahbi.scanen; else scanen  := '0'; end if;
142
    v.retry2 := (r.retry or r.retry2) and not (r.ba and not r.retry);
143
 
144
    -- generate AHB signals
145
 
146
    dreq := mcdi.req;
147
    hwdata := mcdi.data;
148
    hbusreq := '0';
149
 
150
    if (mcii.req = '1') and ((clk2x = 0) or (r2.reqmsk(2) = '1')) and (r.hlocken = '0') and
151
      not (( ((r.ba and dreq) = '1') and (r.bo = "01")) or
152
           ( ((r.ba and mcmmi.req) = '1') and (r.bo = "10"))) then
153
      nbo := "00";
154
      hbusreq := '1';
155
      htrans := HTRANS_NONSEQ;
156
    elsif (dreq = '1') and ((clk2x = 0) or (r2.reqmsk(1) = '1')) and
157
      not (( ((r.ba and mcii.req) = '1') and (r.bo = "00")) or
158
           ( ((r.ba and mcmmi.req) = '1') and (r.bo = "10"))) then
159
      nbo := "01";
160
      hbusreq := '1';
161
      if (not mcdi.lock or r.hlocken) = '1' then htrans := HTRANS_NONSEQ; end if;
162
    elsif (mcmmi.req = '1') and ((clk2x = 0) or (r2.reqmsk(0) = '1')) and
163
      not (( ((r.ba and mcii.req) = '1') and (r.bo = "00")) or
164
           ( ((r.ba and dreq) = '1') and (r.bo = "01"))) then
165
      nbo := "10";
166
      hbusreq := '1';
167
      htrans := HTRANS_NONSEQ;
168
    else
169
      nbo := "11";
170
    end if;
171
 
172
    -- dont change bus master if we have started driving htrans
173
    if r.nba = '1' then
174
      nbo := r.nbo; hbusreq := '1'; htrans := HTRANS_NONSEQ;
175
    end if;
176
 
177
    -- dont change bus master on retry
178
    if (r.retry2 and not r.ba) = '1' then
179
      nbo := r.bo; hbusreq := '1'; htrans := HTRANS_NONSEQ;
180
    end if;
181
 
182
    dec_hcache := ahb_slv_dec_cache(mcdi.address, ahbso, cached);
183
 
184
    if nbo = "10" then
185
      haddr := mcmmi.address; hwrite := not mcmmi.read; hsize := '0' & mcmmi.size;
186
      hlock := mcmmi.lock;
187
      htrans := HTRANS_NONSEQ; hburst := HBURST_SINGLE;
188
      if (mcmmi.req and r.bg and ahbi.hready and not r.retry) = '1'
189
      then mmgrant := '1'; v.hcache := dec_fixed(ahbi.hcache, haddr(31 downto 28), cached); end if;
190
    elsif nbo = "00" then
191
      haddr := mcii.address; hwrite := '0'; hsize := HSIZE_WORD; hlock := '0';
192
      su := mcii.su;
193
      if ((mcii.req and r.ba) = '1')  and (r.bo = "00") and ((not r.retry) = '1') then
194
        htrans := HTRANS_SEQ; haddr(4 downto 2) := haddr(4 downto 2) +1;
195
        if (((ilinesize = 4) and haddr(3 downto 2) = "10")
196
          or ((ilinesize = 8) and haddr(4 downto 2) = "110")) and (ahbi.hready = '1')
197
        then v.lb := '1'; end if;
198
      end if;
199
      if mcii.burst = '1' then hburst := HBURST_INCR;
200
      else hburst := HBURST_SINGLE; end if;
201
      if (mcii.req and r.bg and ahbi.hready and not r.retry) = '1'
202
      then igrant := '1'; v.hcache := dec_fixed(ahbi.hcache, haddr(31 downto 28), cached); end if;
203
    elsif nbo = "01" then
204
      haddr := mcdi.address; hwrite := not mcdi.read; hsize := '0' & mcdi.size;
205
      hlock := mcdi.lock;
206
      if mcdi.asi /= "1010" then su := '1'; else su := '0'; end if;  --ASI_UDATA
207
      if mcdi.burst = '1' then hburst := HBURST_INCR;
208
      else hburst := HBURST_SINGLE; end if;
209
      if ((dreq and r.ba) = '1') and (r.bo = "01") and ((not r.retry) = '1') then
210
        htrans := HTRANS_SEQ; haddr(4 downto 2) := haddr(4 downto 2) +1;
211
        hburst := HBURST_INCR;
212
      end if;
213
      if (dreq and r.bg and ahbi.hready and not r.retry) = '1'
214
      then dgrant := not mcdi.lock or r.hlocken; v.hcache := dec_hcache; end if;
215
    end if;
216
 
217
    if (hclken = '1') or (clk2x = 0) then
218
      if (r.ba = '1') and ((ahbi.hresp = HRESP_RETRY) or (ahbi.hresp = HRESP_SPLIT))
219
      then v.retry := not ahbi.hready; else v.retry := '0'; end if;
220
    end if;
221
 
222
    if r.retry = '1' then htrans := HTRANS_IDLE; end if;
223
 
224
    if r.bo = "10" then
225
      hwdata := mcmmi.data;
226
      if r.ba = '1' then
227
        mmhcache := r.hcache;
228
        if ahbi.hready = '1' then
229
          case ahbi.hresp is
230
          when HRESP_OKAY => mmready := '1';
231
          when HRESP_RETRY | HRESP_SPLIT=> mmretry := '1';
232
          when others => mmready := '1'; mmmexc := '1'; v.werr := not mcmmi.read;
233
          end case;
234
        end if;
235
      end if;
236
    elsif r.bo = "00" then
237
      if r.ba = '1' then
238
        ihcache := r.hcache;
239
        if ahbi.hready = '1' then
240
          case ahbi.hresp is
241
          when HRESP_OKAY => iready := '1';
242
          when HRESP_RETRY | HRESP_SPLIT=> iretry := '1';
243
          when others => iready := '1'; imexc := '1';
244
          end case;
245
        end if;
246
      end if;
247
    elsif r.bo = "01" then
248
      if r.ba = '1' then
249
        dhcache := r.hcache;
250
        if ahbi.hready = '1' then
251
          case ahbi.hresp is
252
          when HRESP_OKAY => dready := '1'; v.lock := mcdi.lock and mcdi.read;
253
          when HRESP_RETRY | HRESP_SPLIT=> dretry := '1';
254
          when others => dready := '1'; dmexc := '1'; v.werr := not mcdi.read;
255
          end case;
256
        end if;
257
      end if;
258
      hlock := mcdi.lock;
259
    end if;
260
 
261
    if r.lock = '1' then hlock := mcdi.lock; end if;
262
    if (r.lock = '1') and (nbo = "01") then v.lock := '0'; end if;
263
 
264
 
265
    if (nbo = "01") and ((hsize = "011") or ((dec_hcache and mcdi.read and mcdi.cache) = '1')) then
266
      hsize := "010"; haddr(1 downto 0) := "00";
267
    end if;
268
 
269
    if ahbi.hready = '1' then
270
      if r.retry = '0' then v.bo := nbo; end if;
271
      v.bg := ahbi.hgrant(hindex);
272
      if (htrans = HTRANS_NONSEQ) or (htrans = HTRANS_SEQ) then
273
        v.ba := r.bg;
274
      else v.ba := '0'; end if;
275
      v.hlocken := hlock and ahbi.hgrant(hindex);
276
      if (clk2x /= 0) then v.hlocken := v.hlocken and r2.reqmsk(1); end if;
277
    end if;
278
 
279
    if hburst = HBURST_SINGLE then nb := '1'; else nb := '0'; end if;
280
 
281
    v.nbo := nbo; v.nba := orv(htrans) and not v.ba;
282
 
283
    if (clk2x /= 0) then
284
      v2.hclken2 := hclken;
285
      if hclken = '1' then
286
        v2.reqmsk := mcii.req & mcdi.req & mcmmi.req;
287
        if (clk2x > 8) and (r2.hclken2 = '1') then v2.reqmsk := "111"; end if;
288
      end if;
289
    end if;
290
 
291
 
292
    -- reset operation
293
 
294
    if rst = '0' then
295
      v.bg := '0'; v.bo := "00"; v.ba := '0'; v.retry := '0'; v.werr := '0'; v.lb := '0';
296
      v.hcache := '0'; v.lock := '0'; v.hlocken := '0'; v.nba := '0'; v.nbo := "00";
297
      v.retry2 := '0';
298
    end if;
299
 
300
    -- drive ports
301
 
302
    ahbo.haddr   <= haddr ;
303
    ahbo.htrans  <= htrans;
304
    ahbo.hbusreq <= hbusreq and not r.lb and not ((((not bo_icache) and r.ba) or nb) and r.bg);
305
    ahbo.hwdata  <= hwdata;
306
    ahbo.hlock   <= hlock and mcdi.read;
307
    ahbo.hwrite  <= hwrite;
308
    ahbo.hsize   <= hsize;
309
    ahbo.hburst  <= hburst;
310
    ahbo.hindex  <= hindex;
311
    if nbo = "00" then ahbo.hprot   <= "11" & su & '0';
312
    else ahbo.hprot   <= "11" & su & (nbo(1) xor nbo(0)); end if;
313
 
314
    mcio.grant   <= igrant;
315
    mcio.ready   <= iready;
316
    mcio.mexc    <= imexc;
317
    mcio.retry   <= iretry;
318
    mcio.cache   <= ihcache;
319
    mcdo.grant   <= dgrant;
320
    mcdo.ready   <= dready;
321
    mcdo.mexc    <= dmexc;
322
    mcdo.retry   <= dretry;
323
    mcdo.werr    <= r.werr;
324
    mcdo.cache   <= dhcache;
325
    mcdo.ba      <= r.ba;
326
    mcdo.bg      <= r.bg;
327
 
328
    mcmmo.grant   <= mmgrant;
329
    mcmmo.ready   <= mmready;
330
    mcmmo.mexc    <= mmmexc;
331
    mcmmo.retry   <= mmretry;
332
    mcmmo.werr    <= r.werr;
333
    mcmmo.cache   <= mmhcache;
334
 
335
    mcio.scanen  <= scanen;
336
    mcdo.scanen  <= scanen;
337
    mcdo.testen  <= ahbi.testen;
338
 
339
    rin <= v; r2in <= v2;
340
 
341
  end process;
342
 
343
  mcio.data  <= ahbi.hrdata;
344
  mcdo.data  <= ahbi.hrdata;
345
  mcmmo.data <= ahbi.hrdata;
346
  ahbo.hirq    <= (others => '0');
347
  ahbo.hconfig <= hconfig;
348
 
349
  reg : process(clk)
350
  begin
351
    if rising_edge(clk) then r <= rin; end if;
352
  end process;
353
 
354
  reg2gen : if (clk2x /= 0) generate
355
    reg2 : process(clk)
356
    begin
357
      if rising_edge(clk) then r2 <= r2in; end if;
358
    end process;
359
  end generate;
360
 
361
  noreg2gen : if (clk2x = 0) generate
362
    r2.reqmsk <= "000";
363
  end generate;
364
 
365
end;
366
 
367
 
368
 
369
 
370
 
371
 
372
 
373
 
374
 
375
 
376
 
377
 
378
 
379
 

powered by: WebSVN 2.1.0

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