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/] [icache.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:      icache
20
-- File:        icache.vhd
21
-- Author:      Jiri Gaisler - Gaisler Research
22
-- Modified:    Edvin Catovic - Gaisler Research
23
-- Description: This unit implements the instruction cache controller.
24
------------------------------------------------------------------------------  
25
 
26
library ieee;
27
use ieee.std_logic_1164.all;
28
library grlib;
29
use grlib.amba.all;
30
use grlib.stdlib.all;
31
library gaisler;
32
use gaisler.libiu.all;
33
use gaisler.libcache.all;
34
 
35
entity icache is
36
  generic (
37
    icen      : integer range 0 to 1  := 0;
38
    irepl     : integer range 0 to 2  := 0;
39
    isets     : integer range 1 to 4  := 1;
40
    ilinesize : integer range 4 to 8  := 4;
41
    isetsize  : integer range 1 to 256 := 1;
42
    isetlock  : integer range 0 to 1  := 0;
43
    lram      : integer range 0 to 1 := 0;
44
    lramsize  : integer range 1 to 512 := 1;
45
    lramstart : integer range 0 to 255 := 16#8e#);
46
  port (
47
    rst : in  std_ulogic;
48
    clk : in  std_ulogic;
49
    ici : in  icache_in_type;
50
    ico : out icache_out_type;
51
    dci : in  dcache_in_type;
52
    dco : in  dcache_out_type;
53
    mcii : out memory_ic_in_type;
54
    mcio : in  memory_ic_out_type;
55
    icrami : out icram_in_type;
56
    icramo : in  icram_out_type;
57
    fpuholdn : in  std_ulogic
58
);
59
end;
60
 
61
architecture rtl of icache is
62
 
63
constant ILINE_BITS   : integer := log2(ilinesize);
64
constant IOFFSET_BITS : integer := 8 +log2(isetsize) - ILINE_BITS;
65
constant TAG_LOW      : integer := IOFFSET_BITS + ILINE_BITS + 2;
66
constant OFFSET_HIGH  : integer := TAG_LOW - 1;
67
constant OFFSET_LOW   : integer := ILINE_BITS + 2;
68
constant LINE_HIGH    : integer := OFFSET_LOW - 1;
69
constant LINE_LOW     : integer := 2;
70
constant LRR_BIT      : integer := TAG_HIGH + 1;
71
 
72
constant lline : std_logic_vector((ILINE_BITS -1) downto 0) := (others=>'1');
73
constant fline : std_logic_vector((ILINE_BITS -1) downto 0) := (others=>'0');
74
 
75
constant SETBITS : integer := log2x(ISETS);
76
constant ILRUBITS  : integer := lru_table(ISETS);
77
constant LRAM_START : std_logic_vector(7 downto 0) := conv_std_logic_vector(lramstart, 8);
78
constant LRAM_BITS : integer := log2(lramsize) + 10;
79
constant LRAMCS_EN  : boolean := false;
80
subtype lru_type is std_logic_vector(ILRUBITS-1 downto 0);
81
type lru_array  is array (0 to 2**IOFFSET_BITS-1) of lru_type;  -- lru registers
82
type rdatatype is (itag, idata, memory);        -- sources during cache read
83
 
84
type lru_table_vector_type is array(0 to 3) of std_logic_vector(4 downto 0);
85
type lru_table_type is array (0 to 2**IOFFSET_BITS-1) of lru_table_vector_type;
86
 
87
subtype lock_type is std_logic_vector(0 to ISETS-1);
88
type par_type is array (0 to ISETS-1) of std_logic_vector(1 downto 0);
89
 
90
function lru_set (lru : lru_type; lock : lock_type) return std_logic_vector is
91
variable xlru : std_logic_vector(4 downto 0);
92
variable set  : std_logic_vector(SETBITS-1 downto 0);
93
variable xset : std_logic_vector(1 downto 0);
94
variable unlocked : integer range 0 to ISETS-1;
95
begin
96
 
97
  set := (others => '0'); xlru := (others => '0'); xset := (others => '0');
98
  xlru(ILRUBITS-1 downto 0) := lru;
99
 
100
  if isetlock = 1 then
101
    unlocked := ISETS-1;
102
    for i in ISETS-1 downto 0 loop
103
      if lock(i) = '0' then unlocked := i; end if;
104
    end loop;
105
  end if;
106
 
107
  case ISETS is
108
  when 2 =>
109
    if isetlock = 1 then
110
      if lock(0) = '1' then xset(0) := '1'; else xset(0) := xlru(0); end if;
111
    else xset(0) := xlru(0); end if;
112
  when 3 =>
113
    if isetlock = 1 then
114
      xset := conv_std_logic_vector(lru3_repl_table(conv_integer(xlru)) (unlocked), 2);
115
    else
116
      xset := conv_std_logic_vector(lru3_repl_table(conv_integer(xlru)) (0), 2);
117
    end if;
118
  when 4 =>
119
    if isetlock = 1 then
120
      xset := conv_std_logic_vector(lru4_repl_table(conv_integer(xlru)) (unlocked), 2);
121
    else
122
      xset := conv_std_logic_vector(lru4_repl_table(conv_integer(xlru)) (0), 2);
123
    end if;
124
  when others =>
125
  end case;
126
  set := xset(SETBITS-1 downto 0);
127
  return(set);
128
end;
129
 
130
function lru_calc (lru : lru_type; set : integer) return lru_type is
131
variable new_lru : lru_type;
132
variable xnew_lru: std_logic_vector(4 downto 0);
133
variable xlru : std_logic_vector(4 downto 0);
134
begin
135
  new_lru := (others => '0'); xnew_lru := (others => '0');
136
  xlru := (others => '0'); xlru(ILRUBITS-1 downto 0) := lru;
137
  case ISETS is
138
  when 2 =>
139
    if set = 0 then xnew_lru(0) := '1'; else xnew_lru(0) := '0'; end if;
140
  when 3 =>
141
    xnew_lru(2 downto 0) := lru_3set_table(conv_integer(lru))(set);
142
  when 4 =>
143
    xnew_lru(4 downto 0) := lru_4set_table(conv_integer(lru))(set);
144
  when others =>
145
  end case;
146
  new_lru := xnew_lru(ILRUBITS-1 downto 0);
147
  return(new_lru);
148
end;
149
 
150
type icache_control_type is record                      -- all registers
151
  req, burst, holdn : std_ulogic;
152
  overrun       : std_ulogic;                   -- 
153
  underrun      : std_ulogic;                   -- 
154
  istate        : std_logic_vector(1 downto 0);          -- FSM vector
155
  waddress      : std_logic_vector(31 downto 2); -- write address buffer
156
  valid         : std_logic_vector(ilinesize-1 downto 0); -- valid bits
157
  hit           : std_ulogic;
158
  su            : std_ulogic;
159
  flush         : std_ulogic;                           -- flush in progress
160
  flush2        : std_ulogic;                           -- flush in progress
161
  flush3        : std_ulogic;                           -- flush in progress
162
  faddr         : std_logic_vector(IOFFSET_BITS - 1 downto 0);   -- flush address
163
  diagrdy       : std_ulogic;
164
  rndcnt        : std_logic_vector(log2x(ISETS)-1 downto 0); -- replace counter
165
  lrr           : std_ulogic;
166
  setrepl       : std_logic_vector(log2x(ISETS)-1 downto 0); -- set to replace
167
  diagset       : std_logic_vector(log2x(ISETS)-1 downto 0);
168
  lock          : std_ulogic;
169
end record;
170
 
171
type lru_reg_type is record
172
  write : std_ulogic;
173
  waddr : std_logic_vector(IOFFSET_BITS-1 downto 0);
174
  set   : std_logic_vector(SETBITS-1 downto 0); --integer range 0 to ISETS-1;
175
  lru   : lru_array;
176
end record;
177
 
178
signal r, c : icache_control_type;      -- r is registers, c is combinational
179
signal rl, cl : lru_reg_type;           -- rl is registers, cl is combinational
180
 
181
constant icfg : std_logic_vector(31 downto 0) :=
182
        cache_cfg(irepl, isets, ilinesize, isetsize, isetlock, 0, lram, lramsize, lramstart, 0);
183
 
184
begin
185
 
186
  ictrl : process(rst, r, rl, mcio, ici, dci, dco, icramo, fpuholdn)
187
  variable rdatasel : rdatatype;
188
  variable twrite, diagen, dwrite : std_ulogic;
189
  variable taddr : std_logic_vector(TAG_HIGH  downto LINE_LOW); -- tag address
190
  variable wtag : std_logic_vector(TAG_HIGH downto TAG_LOW); -- write tag value
191
  variable ddatain : std_logic_vector(31 downto 0);
192
  variable rdata : cdatatype;
193
  variable diagdata : std_logic_vector(31 downto 0);
194
  variable vmaskraw, vmask : std_logic_vector((ilinesize -1) downto 0);
195
  variable xaddr_inc : std_logic_vector((ILINE_BITS -1) downto 0);
196
  variable lastline, nlastline, nnlastline : std_ulogic;
197
  variable enable : std_ulogic;
198
  variable error : std_ulogic;
199
  variable whit, hit, valid : std_ulogic;
200
  variable cacheon  : std_ulogic;
201
  variable v : icache_control_type;
202
  variable branch  : std_ulogic;
203
  variable eholdn  : std_ulogic;
204
  variable mds, write  : std_ulogic;
205
  variable memaddr : std_logic_vector(31 downto 2);
206
  variable set     : integer range 0 to MAXSETS-1;
207
  variable setrepl : std_logic_vector(log2x(ISETS)-1 downto 0); -- set to replace
208
  variable ctwrite, cdwrite, validv : std_logic_vector(0 to MAXSETS-1);
209
  variable wlrr : std_ulogic;
210
  variable vl : lru_reg_type;
211
  variable vdiagset, rdiagset : integer range 0 to ISETS-1;
212
  variable lock : std_logic_vector(0 to ISETS-1);
213
  variable wlock, sidle : std_ulogic;
214
  variable tag : cdatatype; --std_logic_vector(31  downto 0);
215
  variable lramacc, ilramwr, lramcs  : std_ulogic;
216
 
217
  begin
218
 
219
-- init local variables
220
 
221
    v := r; vl := rl; vl.write := '0'; vl.set := r.setrepl;
222
    vl.waddr := r.waddress(OFFSET_HIGH downto OFFSET_LOW);
223
 
224
    mds := '1'; dwrite := '0'; twrite := '0'; diagen := '0'; error := '0';
225
    write := mcio.ready; v.diagrdy := '0'; v.holdn := '1';
226
    v.flush3 := r.flush2; sidle := '0';
227
 
228
    if icen /= 0 then
229
      cacheon := dco.icdiag.cctrl.ics(0) and not r.flush;
230
    else cacheon := '0'; end if;
231
    enable := '1'; branch := '0';
232
    eholdn := dco.hold and fpuholdn;
233
 
234
    rdatasel := idata;  -- read data from cache as default
235
    ddatain := mcio.data;       -- load full word from memory
236
    wtag(TAG_HIGH downto TAG_LOW) := r.waddress(TAG_HIGH downto TAG_LOW);
237
    wlrr := r.lrr; wlock := r.lock;
238
 
239
    set := 0; ctwrite := (others => '0'); cdwrite := (others => '0');
240
    vdiagset := 0; rdiagset := 0; lock := (others => '0'); ilramwr := '0';
241
    lramacc := '0'; lramcs := '0';
242
 
243
-- random replacement counter
244
    if ISETS > 1 then
245
      if conv_integer(r.rndcnt) = (ISETS - 1) then v.rndcnt := (others => '0');
246
      else v.rndcnt := r.rndcnt + 1; end if;
247
    end if;
248
 
249
 
250
-- generate lock bits
251
    if isetlock = 1 then
252
      for i in 0 to ISETS-1 loop lock(i) := icramo.tag(i)(CTAG_LOCKPOS); end loop;
253
    end if;
254
 
255
    --local ram access
256
    if (lram = 1) and (ici.fpc(31 downto 24) = LRAM_START) then lramacc := '1'; end if;
257
 
258
-- generate cache hit and valid bits    
259
    hit := '0';
260
    for i in ISETS-1 downto 0 loop
261
      if (icramo.tag(i)(TAG_HIGH downto TAG_LOW) = ici.fpc(TAG_HIGH downto TAG_LOW))
262
      then hit := not r.flush; set := i; end if;
263
      validv(i) := genmux(ici.fpc(LINE_HIGH downto LINE_LOW),
264
                          icramo.tag(i)(ilinesize -1 downto 0));
265
    end loop;
266
 
267
    if (lramacc = '1') and (ISETS > 1) then set := 1; end if;
268
 
269
    if ici.fpc(LINE_HIGH downto LINE_LOW) = lline then lastline := '1';
270
    else lastline := '0'; end if;
271
 
272
    if r.waddress(LINE_HIGH downto LINE_LOW) = lline((ILINE_BITS -1) downto 0) then
273
      nlastline := '1';
274
    else nlastline := '0'; end if;
275
 
276
    if r.waddress(LINE_HIGH downto LINE_LOW+1) = lline((ILINE_BITS -1) downto 1) then
277
      nnlastline := '1';
278
    else nnlastline := '0'; end if;
279
 
280
    valid := validv(set);
281
    xaddr_inc := r.waddress(LINE_HIGH downto LINE_LOW) + 1;
282
 
283
    if mcio.ready = '1' then
284
      v.waddress(LINE_HIGH downto LINE_LOW) := xaddr_inc;
285
    end if;
286
 
287
    taddr := ici.rpc(TAG_HIGH downto LINE_LOW);
288
 
289
-- main state machine
290
 
291
    case r.istate is
292
    when "00" =>        -- main state and cache hit
293
      v.valid := icramo.tag(set)(ilinesize-1 downto 0);
294
      v.hit := hit; v.su := ici.su; sidle := '1';
295
 
296
--      if (ici.inull or eholdn)  = '0' then 
297
      if eholdn  = '0' then
298
        taddr := ici.fpc(TAG_HIGH downto LINE_LOW);
299
      else taddr := ici.rpc(TAG_HIGH downto LINE_LOW); end if;
300
      v.burst := dco.icdiag.cctrl.burst and not lastline;
301
      if (eholdn and not (ici.inull or lramacc)) = '1' then
302
        if not (cacheon and hit and valid) = '1' then
303
          v.istate := "01"; v.req := '1';
304
          v.holdn := '0'; v.overrun := '1';
305
        else
306
          if (ISETS > 1) and (irepl = lru) then vl.write := '1'; end if;
307
        end if;
308
        v.waddress := ici.fpc(31 downto 2);
309
 
310
      end if;
311
      if dco.icdiag.enable = '1' then
312
        diagen := '1';
313
      end if;
314
      ddatain := dci.maddress;
315
      if (ISETS > 1) then
316
        if (irepl = lru) then
317
          vl.set := conv_std_logic_vector(set, SETBITS);
318
          vl.waddr := ici.fpc(OFFSET_HIGH downto OFFSET_LOW);
319
        end if;
320
        v.setrepl := conv_std_logic_vector(set, SETBITS);
321
        if (((not hit) and (not r.flush)) = '1') then
322
          case irepl is
323
          when rnd =>
324
            if isetlock = 1 then
325
              if lock(conv_integer(r.rndcnt)) = '0' then v.setrepl := r.rndcnt;
326
              else
327
                v.setrepl := conv_std_logic_vector(ISETS-1, SETBITS);
328
                for i in ISETS-1 downto 0 loop
329
                  if (lock(i) = '0') and (i>conv_integer(r.rndcnt)) then
330
                    v.setrepl := conv_std_logic_vector(i, SETBITS);
331
                  end if;
332
                end loop;
333
              end if;
334
            else
335
              v.setrepl := r.rndcnt;
336
            end if;
337
          when lru =>
338
            v.setrepl :=  lru_set(rl.lru(conv_integer(ici.fpc(OFFSET_HIGH downto OFFSET_LOW))), lock(0 to ISETS-1));
339
          when lrr =>
340
            v.setrepl := (others => '0');
341
            if isetlock = 1 then
342
              if lock(0) = '1' then v.setrepl(0) := '1';
343
              else
344
                v.setrepl(0) := icramo.tag(0)(CTAG_LRRPOS) xor icramo.tag(1)(CTAG_LRRPOS);
345
              end if;
346
            else
347
              v.setrepl(0) := icramo.tag(0)(CTAG_LRRPOS) xor icramo.tag(1)(CTAG_LRRPOS);
348
            end if;
349
            if v.setrepl(0) = '0' then v.lrr := not icramo.tag(0)(CTAG_LRRPOS);
350
            else v.lrr := icramo.tag(0)(CTAG_LRRPOS); end if;
351
          end case;
352
        end if;
353
        if (isetlock = 1) then
354
          if (hit and lock(set)) = '1' then v.lock := '1';
355
          else v.lock := '0'; end if;
356
        end if;
357
      end if;
358
    when "01" =>                -- streaming: update cache and send data to IU
359
      rdatasel := memory;
360
      taddr(TAG_HIGH downto LINE_LOW) := r.waddress(TAG_HIGH downto LINE_LOW);
361
      branch := (ici.fbranch and r.overrun) or
362
                      (ici.rbranch and (not r.overrun));
363
      v.underrun := r.underrun or
364
        (write and ((ici.inull or not eholdn) and (mcio.ready and not (r.overrun and not r.underrun))));
365
      v.overrun := (r.overrun or (eholdn and not ici.inull)) and
366
                    not (write or r.underrun);
367
      if mcio.ready = '1' then
368
--        mds := not (v.overrun and not r.underrun);
369
        mds := not (r.overrun and not r.underrun);
370
--        v.req := r.burst; 
371
        v.burst := v.req and not (nnlastline and mcio.ready);
372
      end if;
373
      if mcio.grant = '1' then
374
        v.req := dco.icdiag.cctrl.burst and r.burst and
375
                 (not (nnlastline and mcio.ready)) and (dco.icdiag.cctrl.burst or (not branch)) and
376
                 not (v.underrun and not cacheon);
377
        v.burst := v.req and not (nnlastline and mcio.ready);
378
      end if;
379
      v.underrun := (v.underrun or branch) and not v.overrun;
380
      v.holdn := not (v.overrun or v.underrun);
381
      if (mcio.ready = '1') and (r.req = '0') then --(v.burst = '0') then        
382
        v.underrun := '0'; v.overrun := '0';
383
        if (dco.icdiag.cctrl.ics(0) and not r.flush2) = '1' then
384
          v.istate := "10"; v.holdn := '0';
385
        else
386
          v.istate := "00"; v.flush := r.flush2; v.holdn := '1';
387
          if r.overrun = '1' then taddr := ici.fpc(TAG_HIGH downto LINE_LOW);
388
          else taddr := ici.rpc(TAG_HIGH downto LINE_LOW); end if;
389
        end if;
390
      end if;
391
    when "10" =>                -- return to main
392
      taddr := ici.fpc(TAG_HIGH downto LINE_LOW);
393
      v.istate := "00"; v.flush := r.flush2;
394
    when others => v.istate := "00";
395
    end case;
396
 
397
    if mcio.retry = '1' then v.req := '1'; end if;
398
 
399
    if lram = 1 then
400
      if LRAMCS_EN then
401
        if taddr(31 downto 24) = LRAM_START then lramcs := '1'; else lramcs := '0'; end if;
402
      else
403
        lramcs := '1';
404
      end if;
405
    end if;
406
 
407
 
408
-- Generate new valid bits write strobe
409
 
410
    vmaskraw := decode(r.waddress(LINE_HIGH downto LINE_LOW));
411
    twrite := write;
412
    if cacheon = '0' then
413
      twrite := '0'; vmask := (others => '0');
414
    elsif (dco.icdiag.cctrl.ics = "01") then
415
      twrite := twrite and r.hit;
416
      vmask := icramo.tag(set)(ilinesize-1 downto 0) or vmaskraw;
417
    else
418
      if r.hit = '1' then vmask := r.valid or vmaskraw;
419
      else vmask := vmaskraw; end if;
420
    end if;
421
    if (mcio.mexc or not mcio.cache) = '1' then
422
      twrite := '0'; dwrite := '0';
423
    else dwrite := twrite; end if;
424
    if twrite = '1' then
425
      v.valid := vmask; v.hit := '1';
426
      if (ISETS > 1) and (irepl = lru) then vl.write := '1'; end if;
427
    end if;
428
 
429
    if (ISETS > 1) and (irepl = lru) and (rl.write = '1') then
430
      vl.lru(conv_integer(rl.waddr)) :=
431
          lru_calc(rl.lru(conv_integer(rl.waddr)), conv_integer(rl.set));
432
    end if;
433
 
434
-- cache write signals
435
 
436
    if ISETS > 1 then setrepl := r.setrepl; else setrepl := (others => '0'); end if;
437
    if twrite = '1' then ctwrite(conv_integer(setrepl)) := '1'; end if;
438
    if dwrite = '1' then cdwrite(conv_integer(setrepl)) := '1'; end if;
439
 
440
-- diagnostic cache access
441
 
442
    if diagen = '1' then
443
     if (ISETS /= 1) then
444
       if (dco.icdiag.ilramen = '1') and (lram = 1) then
445
         v.diagset := conv_std_logic_vector(1, SETBITS);
446
       else
447
         v.diagset := dco.icdiag.addr(SETBITS -1 + TAG_LOW downto TAG_LOW);
448
       end if;
449
     end if;
450
    end if;
451
 
452
    case ISETS is
453
      when 1 =>
454
        vdiagset := 0; rdiagset := 0;
455
      when 3 =>
456
        if conv_integer(v.diagset) < 3 then vdiagset := conv_integer(v.diagset); end if;
457
        if conv_integer(r.diagset) < 3 then rdiagset := conv_integer(r.diagset); end if;
458
      when others =>
459
        vdiagset := conv_integer(v.diagset);
460
        rdiagset := conv_integer(r.diagset);
461
    end case;
462
 
463
    diagdata := icramo.data(rdiagset);
464
    if diagen = '1' then -- diagnostic or local ram access
465
      taddr(TAG_HIGH downto LINE_LOW) := dco.icdiag.addr(TAG_HIGH downto LINE_LOW);
466
      wtag(TAG_HIGH downto TAG_LOW) := dci.maddress(TAG_HIGH downto TAG_LOW);
467
      wlrr := dci.maddress(CTAG_LRRPOS);
468
      wlock := dci.maddress(CTAG_LOCKPOS);
469
      if (dco.icdiag.ilramen = '1') and (lram = 1) then
470
        ilramwr := not dco.icdiag.read;
471
      elsif dco.icdiag.tag = '1' then
472
        twrite := not dco.icdiag.read; dwrite := '0';
473
        ctwrite := (others => '0'); cdwrite := (others => '0');
474
        ctwrite(vdiagset) := not dco.icdiag.read;
475
        diagdata := icramo.tag(rdiagset);
476
      else
477
        dwrite := not dco.icdiag.read; twrite := '0';
478
        cdwrite := (others => '0'); cdwrite(vdiagset) := not dco.icdiag.read;
479
        ctwrite := (others => '0');
480
      end if;
481
      vmask := dci.maddress(ilinesize -1 downto 0);
482
      v.diagrdy := '1';
483
    end if;
484
 
485
 
486
-- select data to return on read access
487
 
488
    rdata := icramo.data;
489
    case rdatasel is
490
    when memory => rdata(0) := mcio.data; set := 0;
491
    when others =>
492
    end case;
493
 
494
-- cache flush
495
 
496
    if ((ici.flush or dco.icdiag.flush) = '1') and (icen /= 0) then
497
      v.flush := '1'; v.flush2 := '1'; v.faddr := (others => '0');
498
    end if;
499
 
500
    if (r.flush2 = '1') and (icen /= 0) then
501
      twrite := '1'; ctwrite := (others => '1'); vmask := (others => '0');
502
      v.faddr := r.faddr +1; taddr(OFFSET_HIGH downto OFFSET_LOW) := r.faddr;
503
      wlrr := '0'; wlock := '0'; wtag := (others => '0'); v.lrr := '0';
504
      if (r.faddr(IOFFSET_BITS -1) and not v.faddr(IOFFSET_BITS -1)) = '1' then
505
        v.flush2 := '0';
506
      end if;
507
    end if;
508
 
509
-- reset
510
 
511
    if rst = '0' then
512
      v.istate := "00"; v.req := '0'; v.burst := '0'; v.holdn := '1';
513
      v.flush := '0'; v.flush2 := '0'; v.overrun := '0'; v.underrun := '0';
514
      v.rndcnt := (others => '0'); v.lrr := '0'; v.setrepl := (others => '0');
515
      v.diagset := (others => '0'); v.lock := '0'; v.flush3 := '1';
516
      v.waddress := ici.fpc(31 downto 2); v.lrr := '0';
517
    end if;
518
 
519
    if r.flush3 = '1' then
520
      vl.lru := (others => (others => '0'));
521
    end if;
522
 
523
-- Drive signals
524
 
525
    c  <= v;       -- register inputs
526
    cl <= vl;  -- lru register inputs
527
 
528
    -- tag ram inputs
529
    enable := enable and not dco.icdiag.scanen;
530
    for i in 0 to ISETS-1 loop
531
      tag(i) := (others => '0');
532
      tag(i)(ilinesize-1 downto 0) := vmask;
533
      tag(i)(TAG_HIGH downto TAG_LOW) := wtag;
534
      tag(i)(CTAG_LRRPOS) := wlrr;
535
      tag(i)(CTAG_LOCKPOS) := wlock;
536
    end loop;
537
    icrami.tag <= tag;
538
    icrami.tenable   <= enable;
539
    icrami.twrite    <= ctwrite;
540
    icrami.flush    <= r.flush2;
541
    icrami.dpar    <= (others => '0');
542
    icrami.tpar    <= (others => (others => '0'));
543
    icrami.ctx    <= (others => '0');
544
 
545
    -- data ram inputs
546
    icrami.denable  <= enable;
547
    icrami.address  <= taddr(19+LINE_LOW downto LINE_LOW);
548
    icrami.data     <= ddatain;
549
    icrami.dwrite   <= cdwrite;
550
 
551
    -- local ram inputs
552
    icrami.ldramin.enable <= (dco.icdiag.ilramen or lramcs or lramacc) and not dco.icdiag.scanen;
553
    icrami.ldramin.read  <= dco.icdiag.ilramen or lramacc;
554
    icrami.ldramin.write <= ilramwr;
555
 
556
    -- memory controller inputs
557
    mcii.address(31 downto 2)  <= r.waddress(31 downto 2);
558
    mcii.address(1 downto 0)  <= "00";
559
    mcii.su       <= r.su;
560
    mcii.burst    <= r.burst;
561
    mcii.req      <= r.req;
562
    mcii.flush    <= r.flush;
563
 
564
    -- IU data cache inputs
565
    ico.data      <= rdata;
566
    ico.mexc      <= mcio.mexc or error;
567
    ico.hold      <= r.holdn;
568
    ico.mds       <= mds;
569
    ico.flush     <= r.flush;
570
    ico.diagdata  <= diagdata;
571
    ico.diagrdy   <= r.diagrdy;
572
    ico.set       <= conv_std_logic_vector(set, 2);
573
    ico.cfg       <= icfg;
574
    ico.idle      <= sidle;
575
 
576
  end process;
577
 
578
-- Local registers
579
 
580
 
581
  regs1 : process(clk)
582
  begin if rising_edge(clk) then r <= c; end if; end process;
583
 
584
  regs2 : if (ISETS > 1) and (irepl = lru) generate
585
    regs2 : process(clk)
586
    begin if rising_edge(clk) then rl <= cl; end if; end process;
587
  end generate;
588
 
589
  nolru : if (ISETS = 1) or (irepl /= lru) generate
590
    rl.write <= '0'; rl.waddr <= (others => '0');
591
    rl.set <= (others => '0'); rl.lru <= (others => (others => '0'));
592
  end generate;
593
 
594
-- pragma translate_off
595
  chk : process
596
  begin
597
    assert not ((ISETS > 2) and (irepl = lrr)) report
598
        "Wrong instruction cache configuration detected: LRR replacement requires 2 sets"
599
    severity failure;
600
    wait;
601
  end process;
602
-- pragma translate_on
603
 
604
end ;
605
 

powered by: WebSVN 2.1.0

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