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/] [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:      acache
20
-- File:        acache.vhd
21
-- Author:      Jiri Gaisler - Gaisler Research
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
 
36
entity acache is
37
  generic (
38
    hindex    : integer range 0 to NAHBMST-1  := 0;
39
    ilinesize : integer range 4 to 8 := 4;
40
    cached    : integer := 0;
41
    clk2x     : integer := 0;
42
    scantest  : integer := 0);
43
  port (
44
    rst    : in  std_ulogic;
45
    clk    : in  std_ulogic;
46
    mcii   : in  memory_ic_in_type;
47
    mcio   : out memory_ic_out_type;
48
    mcdi   : in  memory_dc_in_type;
49
    mcdo   : out memory_dc_out_type;
50
    ahbi   : in  ahb_mst_in_type;
51
    ahbo   : out ahb_mst_out_type;
52
    ahbso  : in  ahb_slv_out_vector;
53
    hclken : in std_ulogic
54
  );
55
end;
56
 
57
architecture rtl of acache is
58
 
59
-- cache control register type
60
 
61
type reg_type is record
62
  bg    : std_ulogic;   -- bus grant
63
  bo    : std_ulogic;   -- bus owner
64
  ba    : std_ulogic;   -- bus active
65
  lb    : std_ulogic;   -- last burst cycle
66
  retry : std_ulogic;   -- retry/split pending
67
  werr  : std_ulogic;   -- write error
68
  hlocken : std_ulogic; -- ready to perform locked transaction
69
  lock   : std_ulogic;  -- keep bus locked during SWAP sequence
70
  hcache :  std_ulogic;
71
  nbo    : std_ulogic;
72
  nba    : std_ulogic;
73
end record;
74
 
75
type reg2_type is record
76
  reqmsk  : std_logic_vector(1 downto 0);
77
  hclken2 : std_ulogic;
78
end record;
79
 
80
constant hconfig : ahb_config_type := (
81
 
82
  others => zero32);
83
 
84
constant ctbl : std_logic_vector(15 downto 0) := conv_std_logic_vector(cached, 16);
85
function dec_fixed(scache : std_ulogic;
86
        haddr : std_logic_vector(3 downto 0); cached : integer) return std_ulogic is
87
begin
88
  if (cached /= 0) then return ctbl(conv_integer(haddr(3 downto 0)));
89
  else return(scache); end if;
90
end;
91
 
92
signal r, rin : reg_type;
93
signal r2, r2in : reg2_type;
94
begin
95
 
96
  comb : process(ahbi, r, rst, mcii, mcdi, hclken, ahbso, r2)
97
 
98
  variable v : reg_type;
99
  variable v2 : reg2_type;
100
  variable haddr   : std_logic_vector(31 downto 0);   -- address bus
101
  variable htrans  : std_logic_vector(1 downto 0);    -- transfer type 
102
  variable hwrite  : std_ulogic;                      -- read/write
103
  variable hlock   : std_ulogic;                      -- bus lock
104
  variable hsize   : std_logic_vector(2 downto 0);    -- transfer size
105
  variable hburst  : std_logic_vector(2 downto 0);    -- burst type
106
  variable hwdata  : std_logic_vector(31 downto 0);   -- write data
107
  variable hbusreq : std_ulogic;   -- bus request
108
  variable iready, dready : std_ulogic;
109
  variable igrant, dgrant : std_ulogic;
110
  variable iretry, dretry : std_ulogic;
111
  variable ihcache, dhcache, dec_hcache : std_ulogic;
112
  variable imexc, dmexc, nbo, ireq, dreq : std_ulogic;
113
  variable su, nb : std_ulogic;
114
  variable scanen : std_ulogic;
115
 
116
  begin
117
 
118
-- initialisation
119
 
120
    htrans := HTRANS_IDLE;
121
    v := r; iready := '0'; v.werr := '0'; v2 := r2;
122
    dready := '0'; igrant := '0'; dgrant := '0';
123
    imexc := '0'; dmexc := '0'; hlock := '0'; iretry := '0'; dretry := '0';
124
    ihcache := '0'; dhcache := '0'; su := '0'; --hcache := ahbi.hcache;
125
    if ahbi.hready = '1' then v.lb := '0'; end if;
126
    if scantest = 1 then scanen := ahbi.scanen; else scanen  := '0'; end if;
127
 
128
-- generate AHB signals
129
 
130
    ireq := mcii.req; dreq := mcdi.req;
131
    if (clk2x /= 0) then ireq := ireq and r2.reqmsk(1); dreq := dreq and r2.reqmsk(0); end if;
132
    hbusreq := ireq or dreq;
133
--    if hbusreq = '1' then htrans := HTRANS_NONSEQ; end if;
134
    hwdata := mcdi.data;
135
--    nbo := (dreq and not (r.ba and mcii.req and not r.bo));
136
    nbo := ((not ireq) or (r.ba and mcdi.req and r.bo));
137
 
138
    -- dont change bus master if we have started driving htrans
139
    if r.nba = '1' then
140
      nbo := r.nbo; hbusreq := '1'; htrans := HTRANS_NONSEQ;
141
    end if;
142
    if (r.hlocken or r.retry) = '1' then
143
      nbo := r.nbo;
144
    end if;
145
 
146
    if (nbo and mcdi.lock and not r.hlocken) = '1' then htrans := HTRANS_IDLE; end if;
147
    dec_hcache := ahb_slv_dec_cache(mcdi.address, ahbso, cached);
148
    if nbo = '0' then
149
      if mcii.req = '1' then htrans := HTRANS_NONSEQ; end if;
150
      haddr := mcii.address; hwrite := '0'; hsize := HSIZE_WORD; hlock := '0';
151
      su := mcii.su;
152
      if (ireq and r.ba and not r.bo and not r.retry) = '1' then
153
        htrans := HTRANS_SEQ; haddr(4 downto 2) := haddr(4 downto 2) +1;
154
        if (((ilinesize = 4) and haddr(3 downto 2) = "10")
155
          or ((ilinesize = 8) and haddr(4 downto 2) = "110")) and (ahbi.hready = '1')
156
        then v.lb := '1'; end if;
157
      end if;
158
      if mcii.burst = '1' then
159
        hburst := HBURST_INCR;
160
      else hburst := HBURST_SINGLE; end if;
161
      if (ireq and r.bg and ahbi.hready and not r.retry) = '1'
162
      then igrant := '1'; v.hcache := dec_fixed(ahbi.hcache, haddr(31 downto 28), cached); end if;
163
    else
164
      if mcdi.req = '1' then htrans := HTRANS_NONSEQ; end if;
165
      haddr := mcdi.address; hwrite := not mcdi.read; hsize := '0' & mcdi.size;
166
      hlock := mcdi.lock;
167
      if mcdi.asi /= "1010" then su := '1'; else su := '0'; end if;
168
      if mcdi.burst = '1' then hburst := HBURST_INCR;
169
      else hburst := HBURST_SINGLE; end if;
170
      if (dreq and r.ba and r.bo and not r.retry) = '1' then
171
        htrans := HTRANS_SEQ; haddr(4 downto 2) := haddr(4 downto 2) +1;
172
        hburst := HBURST_INCR;
173
      end if;
174
      if (dreq and r.bg and ahbi.hready and not r.retry) = '1'
175
      then dgrant := not mcdi.lock or r.hlocken; v.hcache := dec_hcache; end if;
176
    end if;
177
 
178
    if (hclken = '1') or (clk2x = 0) then
179
      if (r.ba = '1') and ((ahbi.hresp = HRESP_RETRY) or (ahbi.hresp = HRESP_SPLIT))
180
      then v.retry := not ahbi.hready; else v.retry := '0'; end if;
181
    end if;
182
 
183
    if r.retry = '1' then htrans := HTRANS_IDLE; end if;
184
 
185
    if r.bo = '0' then
186
      if r.ba = '1' then
187
        ihcache := r.hcache;
188
        if ahbi.hready = '1' then
189
          case ahbi.hresp is
190
          when HRESP_OKAY => iready := '1';
191
          when HRESP_RETRY | HRESP_SPLIT=> iretry := '1';
192
          when others => iready := '1'; imexc := '1';
193
          end case;
194
        end if;
195
      end if;
196
    else
197
      if r.ba = '1' then
198
        dhcache := r.hcache;
199
        if ahbi.hready = '1' then
200
          case ahbi.hresp is
201
          when HRESP_OKAY => dready := '1'; v.lock := mcdi.lock and mcdi.read;
202
          when HRESP_RETRY | HRESP_SPLIT=> dretry := '1';
203
          when others => dready := '1'; dmexc := '1'; v.werr := not mcdi.read;
204
          end case;
205
        end if;
206
      end if;
207
    end if;
208
 
209
    if r.lock = '1' then hlock := mcdi.lock; end if;
210
    if (r.lock and nbo) = '1' then v.lock := '0'; end if;
211
 
212
    -- decode cacheability
213
 
214
    if (nbo = '1') and ((hsize = "011") or ((dec_hcache and mcdi.read and mcdi.cache) = '1')) then
215
      hsize := "010"; haddr(1 downto 0) := "00";
216
    end if;
217
 
218
    if ahbi.hready = '1' then
219
      v.bo := nbo; v.bg := ahbi.hgrant(hindex);
220
      if (htrans = HTRANS_NONSEQ) or (htrans = HTRANS_SEQ) then
221
        v.ba := r.bg;
222
      else v.ba := '0'; end if;
223
      v.hlocken := hlock and ahbi.hgrant(hindex);
224
      if (clk2x /= 0) then v.hlocken := v.hlocken and r2.reqmsk(0); end if;
225
    end if;
226
 
227
    if hburst = HBURST_SINGLE then nb := '1'; else nb := '0'; end if;
228
    v.nbo := nbo; v.nba := orv(htrans) and not v.ba;
229
 
230
    if (clk2x /= 0) then
231
      v2.hclken2 := hclken;
232
      if (hclken = '1') then
233
        v2.reqmsk := mcii.req & mcdi.req;
234
        if (clk2x > 8) and (r2.hclken2 = '1') then v2.reqmsk := "11"; end if;
235
      end if;
236
    end if;
237
 
238
 
239
-- reset operation
240
 
241
    if rst = '0' then
242
      v.bg := '0'; v.bo := '0'; v.ba := '0'; v.retry := '0'; v.werr := '0'; v.lb := '0';
243
      v.lock := '0'; v.hlocken := '0'; v2.reqmsk := "00"; v.nba := '0'; v.nbo := '0';
244
    end if;
245
 
246
-- drive ports
247
 
248
    ahbo.haddr   <= haddr ;
249
    ahbo.htrans  <= htrans;
250
    ahbo.hbusreq <= hbusreq and not r.lb and not (((r.bo and r.ba) or nb) and r.bg and nbo);
251
    ahbo.hwdata  <= hwdata;
252
    ahbo.hlock   <= hlock and mcdi.read;
253
    ahbo.hwrite  <= hwrite;
254
    ahbo.hsize   <= hsize;
255
    ahbo.hburst  <= hburst;
256
    ahbo.hprot   <= "11" & su & nbo;
257
    ahbo.hindex  <= hindex;
258
    mcio.grant   <= igrant;
259
    mcio.ready   <= iready;
260
    mcio.mexc    <= imexc;
261
    mcio.retry   <= iretry;
262
    mcio.cache   <= ihcache;
263
    mcdo.grant   <= dgrant;
264
    mcdo.ready   <= dready;
265
    mcdo.mexc    <= dmexc;
266
    mcdo.retry   <= dretry;
267
    mcdo.werr    <= r.werr;
268
    mcdo.cache   <= dhcache;
269
    mcdo.ba      <= r.ba;
270
    mcdo.bg      <= r.bg;
271
    mcio.scanen  <= scanen;
272
    mcdo.scanen  <= scanen;
273
    mcdo.testen  <= ahbi.testen;
274
    mcdo.par     <= (others => '0');
275
    mcio.par     <= (others => '0');
276
 
277
    rin <= v; r2in <= v2;
278
 
279
  end process;
280
 
281
  mcio.data <= ahbi.hrdata; mcdo.data <= ahbi.hrdata;
282
  ahbo.hirq    <= (others => '0');
283
  ahbo.hconfig <= hconfig;
284
 
285
  reg : process(clk)
286
  begin
287
    if rising_edge(clk) then r <= rin; end if;
288
  end process;
289
 
290
  reg2gen : if (clk2x /= 0) generate
291
    reg2 : process(clk)
292
    begin
293
      if rising_edge(clk) then r2 <= r2in; end if;
294
    end process;
295
  end generate;
296
 
297
  noreg2gen : if (clk2x = 0) generate
298
    r2.reqmsk <= "00";
299
  end generate;
300
 
301
end;
302
 

powered by: WebSVN 2.1.0

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