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

Subversion Repositories mytwoqcache

[/] [mytwoqcache/] [trunk/] [2QCache.vhd] - Blame information for rev 14

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 11 gerhardhoh
----------------------------------------------------------------------------------
2
-- Company: 
3
-- Engineer: 
4
-- 
5
-- Create Date:    07:41:47 12/14/2010 
6
-- Design Name: 
7
-- Module Name:    Cache - Rtl 
8
-- Project Name: 
9
-- Target Devices: 
10
-- Tool versions: 
11
-- Description: 
12
--
13
-- Dependencies: 
14
--
15
-- Revision: 
16
-- Revision 0.01 - File Created
17
-- Additional Comments: 
18
--
19
----------------------------------------------------------------------------------
20
library IEEE, work;
21
use IEEE.std_logic_1164.all;
22
use IEEE.std_logic_arith.all;
23
use work.global.all;
24
 
25
---- Uncomment the following library declaration if instantiating
26
---- any Xilinx primitives in this code.
27
--library UNISIM;
28
--use UNISIM.VComponents.all;
29
 
30
entity Cache is
31
  generic( constant blocksizeld: integer := 11;
32
                          constant ldways: integer := 1;
33
                          constant ldCachedWords: integer := 2);
34
  port( nReset: in std_ulogic;                                          -- System reset active low
35
        Clock: in std_ulogic;                                           -- System Clock
36 10 gerhardhoh
                  AddressIn: in std_ulogic_vector(RAMrange'high + 1 downto 0);    -- Address of memory fetch
37 11 gerhardhoh
                  DataIn: in std_ulogic_vector( 31 downto 0);                     -- Data to write
38
             IOCode: in std_ulogic_vector(2 downto 0);                                           -- operation
39 10 gerhardhoh
                                                                                  -- Bit
40
                                                                                                                                                                                                --  2    0 read
41
                                                                                                                                                                                                --       1 write
42
                                                                                                                                                                                                -- 1 0   11 word
43
                                                                                                                                                                                                --       10 halfword
44
                                                                                                                                                                                                --       01 single byte
45 11 gerhardhoh
                                                                                                                                                                                                --       00 no operation
46
                  DataOut: out std_ulogic_vector( 31 downto 0);                   -- Data read
47 10 gerhardhoh
                  done: out std_ulogic;
48 11 gerhardhoh
                  -- memory interface
49
                  AddressOut: out std_ulogic_vector(RAMrange'high downto 0);        -- memory address
50
                  DataBlockIn: in std_ulogic_vector( 2 ** ldCachedWords * 32 - 1 downto 0);   -- data from memory
51
                  reads: out std_ulogic;                                                      -- read memory
52
                  DataBlockOut: out std_ulogic_vector( 2 ** ldCachedWords * 32 - 1 downto 0); -- data to memory
53
                  Mask: out std_ulogic_vector( 2 ** ldCachedWords * 4 - 1 downto 0);          -- enables for each byte active low
54 10 gerhardhoh
                  writes: out std_ulogic;                                                     -- write memory
55 11 gerhardhoh
                  ack: in std_ulogic                                                          -- acknowledge from memory
56
                );
57
end Cache;
58
 
59 10 gerhardhoh
architecture Rtl of Cache is
60
constant ways: integer := 2 ** ldways;
61
constant ldram: integer := blocksizeld + ldways - 1;
62
constant ldqueuelength: integer := ldram;
63
 
64 11 gerhardhoh
type IOType is ( Start, busy);
65
type tType is ( inittag, startt, startt1, tagtest, tagwait, stateget, stateget1, finish, finished);
66 10 gerhardhoh
type rType is ( raminit, ramstart, ramstart1, ramcheck, ramcheck1, ramcheck2, ramread, ramread1, ramupdate,
67 11 gerhardhoh
                ramupdate1, ramupdate2, ramupdate3, ramflush, ramflush1, ramwait, ramwait1, ramclean, ramclean1);
68
type fType is ( queuestart, queuewait, queuewaitAm1, queuewaitAm2, queuewaitA11, queuewaitA12, queueelim);
69
subtype myint is natural range 15 downto 0;
70
type TagRAMType is record
71
  cacheAddr: std_ulogic_vector( ldram - 1 downto 0);
72
  cacheValid: std_ulogic;
73
  Tag: std_ulogic_vector( RAMrange'high downto 2 + ldCachedWords + blocksizeld);
74
  TagValid: std_ulogic;
75 10 gerhardhoh
end record;
76
type WordType is record
77 11 gerhardhoh
  Word: std_ulogic_vector(31 downto 0);
78 10 gerhardhoh
  Modified: std_ulogic_vector( 3 downto 0);
79
end record;
80 11 gerhardhoh
type WordArray is array ( 2 ** ldCachedWords - 1 downto 0) of WordType;
81
type CacheType is record
82 10 gerhardhoh
  Words: WordArray;
83
  FiFoaddr: std_ulogic_vector( ldqueuelength - 1 downto 0);
84 11 gerhardhoh
  Am: std_ulogic;                                                        -- redifined and renamed
85
end record;
86 10 gerhardhoh
type FiFoType is record
87
  Word: std_ulogic_vector( blocksizeld - 1 downto 0);
88
  way: std_ulogic_vector( ldways downto 0);
89
  valid: std_ulogic;
90
end record;
91
 
92
type TagRAMarray is array ( ways - 1 downto 0) of TagRAMType;
93
type TagBuffer is array ( ways - 1 downto 0) of std_ulogic_vector( RAMrange'high - ldCachedWords - blocksizeld - 2 + ldram + 2 downto 0);
94
type TagFile is array ( 2 ** blocksizeld - 1 downto 0) of std_ulogic_vector( RAMrange'high - ldCachedWords - blocksizeld - 2 + ldram + 2 downto 0);
95
type TagFiles is array ( ways - 1 downto 0) of TagFile;
96
 
97
type RAMFile is array ( 2 ** ldram - 1 downto 0) of std_ulogic_vector( 35 downto 0);
98
type RAMFiles is array ( 2 ** ldCachedWords - 1 downto 0) of RAMFile;
99
type RAMBuffer is array ( 2 ** ldCachedWords - 1 downto 0) of std_ulogic_vector( 35 downto 0);
100 11 gerhardhoh
type AFile is array ( 2 ** ldram - 1 downto 0) of std_ulogic_vector( ldqueuelength downto 0); -- redimensioned
101 10 gerhardhoh
 
102
type myarrayf is array ( 2 ** ldram - 1 downto 0) of std_ulogic_vector( ldram - 1 downto 0);
103
type myarrayA is array ( 2 ** ldram - 1 downto 0) of std_ulogic_vector( blocksizeld + ldways + 1 downto 0);
104
 
105
signal RAMs: RAMFiles;
106
signal Ax: AFile;
107 11 gerhardhoh
signal tagRAM: TagFiles;
108 10 gerhardhoh
signal tagdummy, tagBuff, TagRAMIn, TagRAMOut: TagRAMarray;
109
signal RecBuff, CacheIn, CacheOut: CacheType;
110
signal blockIn, blockOut: WordArray;
111
signal DataInh: std_ulogic_vector( 31 downto 0);
112
signal A1In, A1Out, AmIn, AmOut: FiFoType;
113
signal putA1, removeA1, getA1, emptyA1, fullA1: std_ulogic;
114
signal putAm, removeAm, getAm, emptyAm, fullAm: std_ulogic;
115
signal A1Inaddr, A1Outaddr, AmInaddr, AmOutaddr: std_ulogic_vector( ldqueuelength - 1 downto 0);
116
signal emptyf, getf, putf: std_ulogic;
117 11 gerhardhoh
signal cindex, FreeOut, FreeIn: std_ulogic_vector( ldram - 1 downto 0);
118
signal ramf: myarrayf;
119
signal counterf: unsigned( ldram downto 0);
120 10 gerhardhoh
signal firstf, lastf: unsigned( ldram - 1 downto 0);
121
signal newFiFoAddr: std_ulogic_vector( ldqueuelength - 1 downto 0);
122 11 gerhardhoh
signal newAm: std_ulogic;  -- redifined and renamed
123 10 gerhardhoh
signal initcount: unsigned( blocksizeld - 1 downto 0);
124
signal initcount1: unsigned( ldram - 1 downto 0);
125 11 gerhardhoh
signal ramA1: myarrayA;
126
signal counterA1: unsigned( ldqueuelength downto 0);
127
signal firstA1, lastA1: unsigned( ldqueuelength - 1 downto 0);
128
signal ramAm: myarrayA;
129
signal counterAm: unsigned( ldqueuelength downto 0);
130
signal firstAm, lastAm: unsigned( ldqueuelength - 1 downto 0);
131 10 gerhardhoh
 
132
signal AddressInh: std_ulogic_vector( AddressIn'high -1 downto 0);
133 11 gerhardhoh
signal IOCodeh: std_ulogic_vector( IOCode'range);
134
signal toFlush, AddressInt: std_ulogic_vector( 2 + ldCachedWords + blocksizeld - 1 downto 2 + ldCachedWords);
135
signal found, free, elim, del: myint;
136 10 gerhardhoh
signal stateIO: IOType;
137
signal statetag: tType;
138
signal stateram: rType;
139
signal statequeue: fType;
140
signal enableram, enablequeue, queuedone, readsh, writesh, doneh, preempted,
141 13 gerhardhoh
       interrupt, readb, writeb, writec, writet, accdone, accqueue, accinterrupt, serviced, oldint: std_ulogic;
142 11 gerhardhoh
 
143
begin
144 10 gerhardhoh
 
145 11 gerhardhoh
 
146
 
147 10 gerhardhoh
  blockIO: process( nReset, Clock, readb, writeb) is
148
  variable s: std_ulogic;
149
  begin
150
    if nReset /= '1' then
151
           writesh <= '0';
152
                readsh <= '0';
153
                stateIO <= start;
154
    elsif rising_edge(Clock) then
155
           case stateIO is
156
                when start =>
157
                  if readb = '1' then
158
                         Mask <= ( others => '1');
159
                         readsh <= '1';
160
                    stateIO <= busy;
161
                  elsif writeb = '1' then
162
                    s := '0';
163
 
164
                    for i in blockOut'range loop
165
                      DataBlockOut( ( i + 1) * 32 - 1 downto i * 32) <= blockOut( i).word;
166
                           Mask( ( i + 1) * 4 - 1 downto i * 4) <= not blockOut( i).Modified;
167
                                s := s or blockOut( i).Modified(0) or blockOut( i).Modified(1) or
168
                                          blockOut( i).Modified(2) or blockOut( i).Modified(3);
169
                         end loop;
170
 
171
                         writesh <= s;
172
 
173
                         if s = '1' then
174
                      stateIO <= busy;
175
                         end if;
176
                  end if;
177
                when busy =>
178
                  if ack = '1' then
179
                    stateIO <= start;
180
 
181
                    if readsh = '1' then
182
                           for i in blockIn'range loop
183
                        blockIn( i).word <= DataBlockIn( ( i + 1) * 32 - 1 downto i * 32);
184
                                  blockIn( i).Modified <= ( others => '0');
185
                                end loop;
186
                    end if;
187
 
188
                    readsh <= '0';
189
                    writesh <= '0';
190
                  end if;
191
                end case;
192
         end if;
193
  end process blockIO;
194
 
195
  writes <= writesh;
196
  reads <= readsh;
197
 
198
  tagrams: process ( nReset, Clock) is
199
  variable a, b, d: myint;
200 11 gerhardhoh
  variable DataInTag, DataOutTag: TagBuffer;
201 10 gerhardhoh
  begin
202
  if rising_edge(Clock) then
203
    if nReset /= '1' then
204
           statetag <= inittag;
205
                writet <= '0';
206
                enableram <= '0';
207 13 gerhardhoh
           oldint <= '0';
208 10 gerhardhoh
                found <= 15;
209
                free <= 15;
210
                done <= '0'; -- NEW
211
                initcount <= ( others => '0');
212
                AddressInt <= ( others => '0');
213
                IOCodeh <= ( others => '0');
214
                AddressInh <= ( others => '0');
215
         else
216
 
217 13 gerhardhoh
         oldint <= interrupt;
218 10 gerhardhoh
           case statetag is
219
                  when inittag =>
220
                    for i in tagRAMIn'range loop
221
                           tagRAMIn(i).tagValid <= '0';
222
                           tagRAMIn(i).tag <= ( others => '0');
223
                           tagRAMIn(i).cacheValid <= '0';
224
                           tagRAMIn(i).cacheAddr <= ( others => '0');
225
                         end loop;
226
                         AddressInt <= std_ulogic_vector(initcount);
227
                         initcount <= initcount + 1;
228
                         if unsigned( not AddressInt) = 0 then
229
                      statetag <= startt;
230
                           writet <= '0';
231
                         else
232
                           writet <= '1';
233
                         end if;
234
                  when startt =>
235
                    if IOCode( 1 downto 0) /= "00" and AddressIn( AddressIn'high) = '0' then
236
                      -- request encountered
237
                                AddressInh <= AddressIn(AddressInh'range);
238 11 gerhardhoh
                                IOCodeh <= IOCode;
239 10 gerhardhoh
                      AddressInt <= AddressIn( AddressInt'range);
240
                                DataInh <= DataIn;
241
                      statetag <= startt1;
242
                    end if;
243
                  when startt1 =>
244
                    statetag <= tagtest;
245
                  when tagtest =>
246 11 gerhardhoh
          a := 15;
247 10 gerhardhoh
                    b := 15;
248 11 gerhardhoh
 
249
               for i in 0 to TagRAMarray'high loop
250
                      if tagRAMOut( i).tagValid = '1' then
251
                   if AddressInh(tagRAMout( i).tag'range) = tagRAMout( i).tag then
252 10 gerhardhoh
                          a := i; -- present
253 11 gerhardhoh
                                  end if;
254
                      else
255
                             b := i; -- free entry
256
                      end if;
257
               end loop;
258 10 gerhardhoh
 
259 11 gerhardhoh
                    found <= a;
260
                    free <= b;
261
 
262 10 gerhardhoh
                    if stateram = ramstart then
263
                      enableram <= '1';
264
                      statetag <= tagwait;
265
                         end if;
266
                  when tagwait =>
267
                    writet <= '0';
268
 
269 13 gerhardhoh
                    if interrupt = '1' and oldint = '0' then
270 10 gerhardhoh
                      enableram <= '0';
271
                           AddressInt <= toFlush;
272
                                statetag <= stateget;
273
                         elsif queuedone = '1' then
274
                      enableram <= '0';
275
                           statetag <= finish;
276
                         end if;
277
                  when stateget =>
278
                         statetag <= stateget1;
279
                  when stateget1 =>
280
                    enableram <= '1';
281
                         tagDummy <= tagRAMOut;
282
 
283
                         for i in tagRAMIn'range loop
284
                           if del = i then
285
                        tagRAMIn( i).tagvalid <= '0';
286
                             tagRAMIn( i).cacheValid <= '0';
287
                             tagRAMIn( i).tag <= ( others => '0');
288
                             tagRAMIn( i).cacheAddr <= ( others => '0');
289
                                  writet <= '1';
290
                           else
291
                             tagRAMIn( i) <= tagRAMOut( i);
292
                           end if;
293
                         end loop;
294
 
295
                         statetag <= tagwait;
296
                  when finish =>
297
                    if doneh = '1' then
298
                           tagRAMIn <= tagBuff;
299
                                writet <= '1';
300
                      AddressInt <= AddressInh( AddressInt'range);
301
                                done <= '1';
302
                      statetag <= finished;
303
                    end if;
304
                  when finished => -- NEW
305
                    writet <= '0';
306
                    done <= '0';
307
                    statetag <= startt;
308
                end case;
309
 
310
         for i in tagRAM'range loop
311
      DataInTag( i) := TagRAMIn( i).TagValid & TagRAMIn( i).Tag & TagRAMIn( i).cacheValid & TagRAMIn( i).cacheAddr;
312
 
313
           if writet = '1' then
314
                  tagRAM(i)(to_integer( AddressInt)) <= DataInTag( i);
315
                else
316
                  DataOutTag( i) := tagRAM(i)(to_integer( AddressInt));
317
 
318
             TagRAMOut( i).cacheAddr <= DataOutTag( i)( ldram - 1 downto 0);
319
             TagRAMOut( i).cacheValid <= DataOutTag( i)( ldram);
320
             TagRAMOut( i).Tag <= DataOutTag( i)( DataOutTag( 0)'high - 1 downto ldram + 1);
321
             TagRAMOut( i).TagValid <= DataOutTag( i)( DataOutTag( 0)'high);
322
                end if;
323
         end loop;
324
         end if;
325
  end if;
326
  end Process tagrams;
327
 
328
  dataram: process (nReset, Clock, enableram) is
329
  variable en, acc, hi: std_ulogic;
330
  variable f, g: std_ulogic_vector( CacheIn.FiFoAddr'length downto 0);
331
  variable a, b: RAMBuffer;
332
  variable index, index1: integer;
333
 
334 11 gerhardhoh
  variable address: std_ulogic_vector( ldram - 1 downto 0);
335
  variable uaddress: unsigned( ldram - 1 downto 0);
336 10 gerhardhoh
  variable datum:  std_ulogic_vector( FreeIn'range);
337 11 gerhardhoh
  variable w: std_ulogic;
338 10 gerhardhoh
  begin
339
  if rising_edge(Clock) then
340
    if nReset /= '1' then
341
           enablequeue <= '0';
342
           stateram <= raminit;
343
                writec <= '0';
344
                writeb <= '0';
345
                readb <= '0';
346
                getf <= '0';
347
                putf <= '0'; -- NEW inserted
348
                doneh <= '0';
349
                elim <= 15;
350
                accinterrupt <= '0';
351
                accqueue <= '0';
352
                initcount1 <= ( others => '0');
353
                FreeIn <= ( others => '0');
354 11 gerhardhoh
                firstf <= ( others => '0');
355
                lastf <= ( others => '0');
356
                counterf <= ( others => '0');
357 10 gerhardhoh
         else
358 13 gerhardhoh
           hi := accinterrupt or (interrupt and not oldint);
359 10 gerhardhoh
                acc := accqueue or queuedone;
360 13 gerhardhoh
                en := enablequeue and not acc;
361 10 gerhardhoh
 
362
                if ldCachedWords = 0 then
363
                  index := 0;
364
                else
365
                  index := to_integer( AddressInh( ldCachedWords + 1 downto 2));
366
                end if;
367
 
368
           case stateram is
369
                  when raminit =>
370
                         FreeIn <= std_ulogic_vector( initcount1);
371
          initcount1    <= initcount1 + 1;
372
 
373
                         if unsigned( not FreeIn) = 0 then
374
                           stateram <= ramstart;
375
                           putf <= '0';
376
                         else
377
                           putf <= '1';
378
                         end if;
379
                  when ramstart =>
380
                    if enableram = '1' then -- UPDATE
381
                           tagBuff <= tagRAMOut;
382
                                elim <= 15;
383
                                stateram <= ramstart1;
384 11 gerhardhoh
                         end if;
385 10 gerhardhoh
                  when ramstart1 =>
386
                    if enableram = '1' then
387
                                if found /= 15 then
388
                                  cindex <= tagBuff( found).cacheAddr;
389
                                  stateram <= ramupdate;
390
                                elsif free /= 15 then
391
                                  en := '1';
392
                                  stateram <= ramwait;
393
                                else
394
                                  elim <= 0;
395
                                  stateram <= ramcheck;
396
                                end if;
397
                         end if;
398
                  when ramcheck =>
399
                         cindex <= tagBuff( elim).cacheAddr;
400
                    stateram <= ramcheck1;
401
                  when ramcheck1 =>
402
                    stateram <= ramcheck2;
403
                  when ramcheck2 =>
404
                    if cacheOut.Am = '0' or elim = ways - 1 then
405
                           RecBuff <= cacheOut;
406
                                en := '1';
407
                      stateram <= ramwait;
408
                         else
409
                           elim <= elim + 1;
410
                      stateram <= ramcheck;
411
                         end if;
412
                  when ramupdate =>
413
                    stateram <= ramupdate1;
414
                  when ramupdate1 =>
415
                    cacheIn <= cacheOut;
416
                         blockOut <= cacheOut.Words;
417
                         RecBuff <= cacheOut;
418
                         en := '1';
419
                         stateram <= ramwait;
420
                  when ramwait =>
421
                         doneh <= '0';
422
 
423
                    if hi = '1' then
424
                                stateram <= ramwait1;
425
                         elsif acc = '1' then
426
                           if found /= 15 then
427
                                  cindex <= tagBuff( found).cacheAddr;
428
                                  cacheIn <= RecBuff;
429
                                  blockOut <= RecBuff.Words;
430
                                  stateram <= ramupdate2;
431
                                elsif free /= 15 then
432
                                  cindex <= FreeOut;
433
                                  tagBuff( free).cacheAddr <= FreeOut;
434
                                  tagBuff( free).cacheValid <= '1';
435
                                  tagBuff( free).tag <= AddressInh( tagBuff( free).tag'range);
436
                                  tagBuff( free).tagValid <= '1';
437
                                  getf <= '1';
438
                                  if IOCodeh = "111" and ldCachedWords = 0 then
439
                                    stateram <= ramupdate2;
440
                                  else
441
                                    readb <= '1';
442
                               AddressOut <= AddressInh( AddressOut'range);
443
                                    stateram <= ramread;
444
                                  end if;
445
                                else
446
                                  cindex <= tagBuff( elim).cacheAddr;
447
                                  cacheIn <= RecBuff;
448
                                  blockOut <= RecBuff.Words;
449
                                  AddressOut <= tagBuff( elim).tag & AddressInh( AddressInt'range) & ( ldCachedWords + 1 downto 0 => '0');
450
                        writeb <= '1';
451
                                  stateram <= ramflush;
452
                                end if;
453
                         end if;
454
                  when ramwait1 =>
455
                         if del /= 15 and enableram = '1' then
456 11 gerhardhoh
                           if toflush = AddressInh( toflush'range) then -- inserted, tagline could match flushing tagline !!!!
457 10 gerhardhoh
                        tagBuff( del).tagvalid <= '0';
458
                             tagBuff( del).cacheValid <= '0';
459
                             tagBuff( del).tag <= ( others => '0');
460
                             tagBuff( del).cacheAddr <= ( others => '0');
461
                                end if;
462
                           cindex <= tagdummy( del).cacheAddr;
463
                                FreeIn <= tagdummy( del).cacheAddr;
464
                                putf <= tagdummy( del).cacheValid;
465
                           stateram <= ramclean;
466
                         end if;
467
                  when ramread =>
468
                    readb <= '0';
469
                         getf <= '0';
470
                    stateram <= ramread1;
471
                  when ramread1 =>
472
                    if readsh = '0' then
473
                           for i in blockIn'range loop
474
                                  cacheIn.Words( i) <= blockIn( i);
475
                                end loop;
476
                      stateram <= ramupdate2;
477
                         end if;
478
                  when ramupdate2 =>
479
                    if IOCodeh(2) = '1' then
480
                           if IOCodeh(1) = '1' then
481
                                  If IOCodeh(0) = '1' then
482
                                    cacheIn.Words( index).Word <= DataInh;
483
                                         cacheIn.Words( index).Modified <= "1111";
484
                                  elsif AddressInh(1) = '1' then
485
                                    cacheIn.Words( index).Word( 31 downto 16) <= DataInh( 15 downto 0);
486
                                         cacheIn.Words( index).Modified( 3 downto 2) <= "11";
487
                                  else
488
                                    cacheIn.Words( index).Word( 15 downto 0) <= DataInh( 15 downto 0);
489
                                         cacheIn.Words( index).Modified( 1 downto 0) <= "11";
490
                                  end if;
491
                                else
492
                                  if AddressInh(1) = '0' then
493
                                    if AddressInh(0) = '0' then
494
                                           cacheIn.Words( index).Word( 7 downto 0) <= DataInh( 7 downto 0);
495
                                                cacheIn.Words( index).Modified(0) <= '1';
496
                                    else
497
                                           cacheIn.Words( index).Word( 15 downto 8) <= DataInh( 7 downto 0);
498
                                                cacheIn.Words( index).Modified(1) <= '1';
499
                                         end if;
500
                                  else
501
                                    if AddressInh(0) = '0' then
502
                                           cacheIn.Words( index).Word( 23 downto 16) <= DataInh( 7 downto 0);
503
                                                cacheIn.Words( index).Modified(2) <= '1';
504
                                    else
505
                                           cacheIn.Words( index).Word( 31 downto 24) <= DataInh( 7 downto 0);
506
                                                cacheIn.Words( index).Modified(3) <= '1';
507
                                         end if;
508
                                  end if;
509
                                end if;
510
                         else
511
                           DataOut <= cacheIn.Words( index).Word;
512
                         end if;
513
 
514
                         cacheIn.FiFoAddr <= newFiFoAddr;
515
                         cacheIn.Am <= newAm;
516
 
517
                         getf <= '0';
518
                         writec <= '1';
519
                         doneh <= '1';
520
 
521
                         stateram <= ramupdate3;
522
                  when ramupdate3 =>
523
                    hi := '0';
524
                         acc := '0';
525
                         en := '0';
526
                         writec <= '0';
527
                    doneh <= '0';
528
                         stateram <= ramstart;
529
                  when ramclean =>
530
                    putf <= '0';
531
                    stateram <= ramclean1;
532
                  when ramclean1 =>
533
                         if del /= 15 then
534
                           blockOut <= cacheOut.words;
535
                                writeb <= tagdummy( del).tagValid;
536
                                AddressOut <= tagdummy( del).tag & toFlush & ( ldCachedWords + 1 downto 0 => '0');
537
                           stateram <= ramflush;
538
                         end if;
539
                  when ramflush =>
540
                    writeb <= '0';
541
                         for i in blockIn'range loop
542
                      cacheIn.Words( i).Word <= ( others => '0');
543
                           cacheIn.Words( i).Modified <= ( others => '0');
544
                         end loop;
545
 
546
                         stateram <= ramflush1;
547
                  when ramflush1 =>
548
                         if writesh = '0' then
549
                           if del /= 15 and hi = '1' then
550
                                  hi := '0';
551
                             stateram <= ramwait;
552
                                else
553
                                  tagBuff( elim).tag <= AddressInh( tagBuff( elim).tag'range);
554
                                  tagBuff( elim).tagValid <= '1';
555
                                  if IOCodeh = "111" and ldCachedWords = 0 then
556
                                    stateram <= ramupdate2;
557
                                  else
558
                                    readb <= '1';
559
                                    AddressOut <= AddressInh( AddressOut'range);
560
                                    stateram <= ramread;
561
                                  end if;
562
                                end if;
563
                         end if;
564
                end case;
565
 
566
                accinterrupt <= hi;
567
                enablequeue <= en;
568
                accqueue <= acc;
569
 
570
         f := CacheIn.Am & CacheIn.FiFoAddr;
571
         if writec = '1' then
572
           Ax( to_integer( cindex)) <= f;
573
         else
574
           g := Ax( to_integer( cindex));
575
                CacheOut.FiFoAddr <= g( g'high - 1 downto g'low);
576
                CacheOut.Am <= g( g'high);
577
         end if;
578
 
579
         for i in RAMBuffer'range loop
580
           a( i) := CacheIn.Words( i).Modified & CacheIn.Words( i).Word;
581
                if writec = '1' then
582
                  RAMs( i)( to_integer( cindex)) <= a( i);
583
                else
584
                  b( i) := RAMs( i)( to_integer( cindex));
585
                  CacheOut.Words( i).Word <= b( i)( 31 downto 0);
586
                  CacheOut.Words( i).Modified <= b( i)( 35 downto 32);
587
                end if;
588
         end loop;
589
 
590 11 gerhardhoh
         if putf = '1' then
591
           address := std_ulogic_vector( firstf);
592
                datum := FreeIn;
593
                firstf <= firstf + 1;
594
                counterf <= counterf + 1;
595 10 gerhardhoh
                w := '1';
596
         else
597 11 gerhardhoh
           uaddress := lastf;
598
           if getf = '1' and counterf /= 0 then
599 10 gerhardhoh
             counterf <= counterf - 1;
600 11 gerhardhoh
                  uaddress := uaddress + 1;
601 10 gerhardhoh
           end if;
602 11 gerhardhoh
                lastf <= uaddress;
603 10 gerhardhoh
                address := std_ulogic_vector( uaddress);
604 11 gerhardhoh
                w := '0';
605
         end if;
606 10 gerhardhoh
 
607
         if w = '1' then
608 11 gerhardhoh
           ramf( to_integer( address)) <= datum;
609 10 gerhardhoh
         else
610 11 gerhardhoh
           FreeOut <= ramf( to_integer( address));
611
         end if;
612 10 gerhardhoh
 
613
         end if;
614
  end if;
615
  end process dataram;
616
 
617
  emptyf <= '1' when counterf = 0 else '0';
618
 
619
  queues: process( nReset, Clock, enablequeue) is
620
  variable acc, hi: std_ulogic;
621
  variable A1OutBuff, AmOutBuff: std_ulogic_vector( blocksizeld + ldways + 1 downto 0);
622 11 gerhardhoh
  variable addressA1: std_ulogic_vector( ldqueuelength - 1 downto 0);
623
  variable diff, uaddressA1: unsigned( ldqueuelength - 1 downto 0);
624 10 gerhardhoh
  variable datumA1:  std_ulogic_vector( A1OutBuff'range);
625 11 gerhardhoh
  variable wA1: std_ulogic;
626
  variable addressAm: std_ulogic_vector( ldqueuelength - 1 downto 0);
627
  variable uaddressAm: unsigned( ldqueuelength - 1 downto 0);
628 10 gerhardhoh
  variable datumAm:  std_ulogic_vector( AmOutBuff'range);
629 11 gerhardhoh
  variable wAm: std_ulogic;
630 10 gerhardhoh
  begin
631
  if rising_edge(Clock) then
632
    if nReset /= '1' then
633
                del <= 15;
634
           statequeue <= queuestart;
635
           queuedone <= '0';
636
                interrupt <= '0';
637
                accdone <= '0';
638
                preempted <= '0';
639 11 gerhardhoh
                firstA1 <= ( others => '0');
640
                A1Outaddr <= ( others => '0');
641
                lastA1 <= ( others => '0');
642 10 gerhardhoh
                counterA1 <= ( others => '0');
643 11 gerhardhoh
                firstAm <= ( others => '0');
644
                AmOutaddr <= ( others => '0');
645
                lastAm <= ( others => '0');
646 10 gerhardhoh
                counterAm <= ( others => '0');
647
                getA1 <= '0'; -- NEW
648
                getAm <= '0'; -- NEW
649
                removeA1 <= '0'; -- NEW
650
                removeAm <= '0'; -- NEW
651
                putA1 <= '0'; -- NEW
652 11 gerhardhoh
                putAm <= '0'; -- NEW
653 13 gerhardhoh
           serviced <= '0';
654 10 gerhardhoh
         else
655 13 gerhardhoh
           hi := interrupt;
656 10 gerhardhoh
                acc := accdone or doneh;
657
 
658
                diff := firstA1 - unsigned( RecBuff.FiFoAddr);
659
 
660
           case statequeue is
661
                  when queuestart =>
662
                         getA1 <= '0';
663
 
664
                    if enablequeue = '1' then
665
                           if found /= 15 then
666
                                  if RecBuff.Am = '1' or                                -- in Am
667
                                    ( RecBuff.Am = '0' and diff( diff'high) = '0') then -- in lower half of A1
668
                                    queuedone <= '1';
669
                                         newFiFoAddr <= RecBuff.FiFoAddr;
670
                                         newAm <= RecBuff.Am;
671
                               statequeue <= queuewait;
672
                                  elsif fullAm = '1' then
673
                                    -- Am full
674
                                         if AmOut.valid = '1' then
675
                                           del <= to_integer( AmOut.way);
676
                                                toFlush <= AmOut.word;
677
                                                getAm <= '1';
678
                                           hi := '1';
679
                                           statequeue <= queuewait;
680
                                         end if;
681
                                  else
682
                                    AmIn.word <= AddressInh( 2 + ldCachedWords + blocksizeld - 1 downto 2 + ldCachedWords);
683
                                         AmIn.way <= std_ulogic_vector(to_unsigned( found, ldways + 1));
684
                                         AmIn.valid <= '1';
685
                                         putAm <= '1';
686
                                         A1Inaddr <= RecBuff.FiFoAddr;
687
                                         removeA1 <= '1';
688
                                         statequeue <= queuewaitAm1;
689
                                  end if;
690
                                elsif free /= 15 then
691 13 gerhardhoh
                                  if fullA1 = '1' or (emptyf = '1' and emptyA1 = '0' and serviced = '0') then
692 10 gerhardhoh
                                    -- remove last entry from A1
693
                                         if A1Out.valid = '1' then
694
                                           del <= to_integer( A1Out.way);
695
                                           toFlush <= A1Out.word;
696
                                           getA1 <= '1';
697
                                           hi := '1';
698 13 gerhardhoh
                              serviced <= '1';
699 10 gerhardhoh
                                           statequeue <= queuewait;
700
                                         end if;
701 13 gerhardhoh
                                  elsif fullAm = '1' and emptyf = '1' and serviced = '0' then
702 10 gerhardhoh
                                    -- remove last entry from Am
703
                                         if AmOut.valid = '1' then
704
                                           del <= to_integer( AmOut.way);
705
                                           toFlush <= AmOut.word;
706
                                           getAm <= '1';
707
                                           hi := '1';
708 13 gerhardhoh
                              serviced <= '1';
709 10 gerhardhoh
                                           statequeue <= queuewait;
710
                                         end if;
711
                                  else
712
                                    A1In.word <= AddressInh( 2 + ldCachedWords + blocksizeld - 1 downto 2 + ldCachedWords);
713
                                         A1In.way <= std_ulogic_vector(to_unsigned( free, ldways + 1));
714
                                         A1In.valid <= '1';
715
                                         putA1 <= '1';
716 13 gerhardhoh
                            serviced <= '0';
717 10 gerhardhoh
                                         statequeue <= queuewaitA11;
718
                                  end if;
719
                                elsif elim /= 15 then
720
                                  if fullA1 = '1' then
721
                                    if A1Out.valid = '1' then
722
                                           if not ( to_integer( A1Out.way) = elim and
723
                                                        A1Out.word = AddressInh( 2 + ldCachedWords + blocksizeld - 1 downto 2 + ldCachedWords)) then
724
                                             del <= to_integer( A1Out.way);
725
                                             toFlush <= A1Out.word;
726
                                             statequeue <= queueelim;
727
                                           end if;
728
 
729
                                           getA1 <= '1';
730
                                         end if;
731
                                  else
732 12 gerhardhoh
                            if getA1 = '1' then
733
                              preempted <= '1';
734
                            end if;
735 10 gerhardhoh
                                         getA1 <= '0'; -- NEW, inserted the only bug!!!!!!!!!!!!!!
736
                                    A1In.word <= AddressInh( 2 + ldCachedWords + blocksizeld - 1 downto 2 + ldCachedWords);
737
                                         A1In.way <= std_ulogic_vector(to_unsigned( elim, ldways + 1));
738
                                         A1In.valid <= '1';
739
                                         putA1 <= '1';
740
                                         statequeue <= queueelim;
741
                                  end if;
742
                                end if;
743
                         end if;
744
                  when queuewait =>
745
                         removeA1 <= '0';
746
                         removeAm <= '0';
747
                    getAm <= '0';
748
                    getA1 <= '0';
749 14 gerhardhoh
                         queuedone <= '0';
750 10 gerhardhoh
 
751 13 gerhardhoh
             if hi = '1' then
752
                   hi := '0';
753
                           statequeue <= queuestart;
754
               elsif acc = '1' then
755 10 gerhardhoh
                           acc := '0';
756
                                del <= 15;
757
                           statequeue <= queuestart;
758
                         end if;
759
                  when queuewaitAm1 =>
760
                    putAm <= '0';
761
                         removeA1 <= '0';
762
                         statequeue <= queuewaitAm2;
763
                  when queuewaitAm2 =>
764
                         newFiFoAddr <= AmOutAddr;
765
                         newAm <= '1';
766
                         queuedone <= '1';
767
                         statequeue <= queuewait;
768
                  when queuewaitA11 =>
769
                    putA1 <= '0';
770
                         statequeue <= queuewaitA12;
771
                  when queuewaitA12 =>
772
                         newFiFoAddr <= A1OutAddr;
773
                         newAm <= '0';
774
                         removeA1 <= '0';
775
                         removeAm <= '0';
776
                         queuedone <= '1';
777
                    preempted <= '0';
778
                         statequeue <= queuewait;
779
                  when queueelim =>
780
                    putA1 <= '0';
781
                         getA1 <= '0';
782
 
783
                         if RecBuff.Am = '1' and preempted = '0' then
784
                           AmInAddr <= RecBuff.FiFoAddr;
785
                           removeAm <= '1';
786
                         elsif preempted = '0' then
787
                           A1InAddr <= RecBuff.FiFoAddr;
788
                           removeA1 <= '1';
789
                         end if;
790
 
791
                         if getA1 = '1' then
792
                           hi := '1';
793
                                preempted <= '1';
794
                           statequeue <= queuewait;
795
                         else
796
                           statequeue <= queuewaitA12;
797
                         end if;
798
                end case;
799
 
800
                interrupt <= hi;
801
                accdone <= acc;
802
 
803 11 gerhardhoh
         if putA1 = '1' or removeA1 = '1' then
804
           if removeA1 = '0' then
805
             addressA1 := std_ulogic_vector( firstA1);
806 10 gerhardhoh
                  datumA1 := A1In.valid & A1In.way & A1In.Word;
807 11 gerhardhoh
                  firstA1 <= firstA1 + 1;
808
                  counterA1 <= counterA1 + 1;
809
                  A1Outaddr <= std_ulogic_vector( firstA1);
810
                else
811
                  addressA1 := A1Inaddr( addressA1'range);
812
                  datumA1 := ( others => '0');
813 10 gerhardhoh
                end if;
814 11 gerhardhoh
                wA1 := '1';
815
         else
816
           uaddressA1 := lastA1;
817
           if (getA1 = '1' or A1Out.valid = '0') and counterA1 /= 0 then
818
             counterA1 <= counterA1 - 1;
819
             uaddressA1 := uaddressA1 + 1;
820 10 gerhardhoh
           end if;
821
           lastA1 <= uaddressA1;
822
           addressA1 := std_ulogic_vector( uaddressA1);
823 11 gerhardhoh
           wA1 := '0';
824 10 gerhardhoh
         end if;
825
 
826
         if wA1 = '1' then
827 11 gerhardhoh
           ramA1( to_integer( addressA1)) <= datumA1;
828 10 gerhardhoh
         else
829 11 gerhardhoh
           A1OutBuff := ramA1( to_integer( addressA1));
830 10 gerhardhoh
 
831
      A1Out.Word <= A1OutBuff( blocksizeld - 1 downto 0);
832
      A1Out.way <= A1OutBuff( blocksizeld + ldways downto blocksizeld);
833
                A1Out.valid <= A1OutBuff( blocksizeld + ldways + 1);
834 11 gerhardhoh
         end if;
835 10 gerhardhoh
 
836 11 gerhardhoh
         if putAm = '1' or removeAm = '1' then
837
           if removeAm = '0' then
838
             addressAm := std_ulogic_vector( firstAm);
839 10 gerhardhoh
                  datumAm := AmIn.valid & AmIn.way & AmIn.Word;
840 11 gerhardhoh
                  firstAm <= firstAm + 1;
841
                  counterAm <= counterAm + 1;
842
                  AmOutaddr <= std_ulogic_vector( firstAm);
843
                else
844
                  addressAm := AmInaddr( addressAm'range);
845
                  datumAm := ( others => '0');
846 10 gerhardhoh
                end if;
847 11 gerhardhoh
                wAm := '1';
848
         else
849
           uaddressAm := lastAm;
850
           if (getAm = '1' or AmOut.valid = '0') and counterAm /= 0 then
851
             counterAm <= counterAm - 1;
852
             uaddressAm := uaddressAm + 1;
853 10 gerhardhoh
           end if;
854
           lastAm <= uaddressAm;
855
           addressAm := std_ulogic_vector( uaddressAm);
856 11 gerhardhoh
           wAm := '0';
857 10 gerhardhoh
         end if;
858 11 gerhardhoh
 
859 10 gerhardhoh
         if wAm = '1' then
860 11 gerhardhoh
           ramAm( to_integer( addressAm)) <= datumAm;
861 10 gerhardhoh
         else
862
           AmOutBuff := ramAm( to_integer( addressAm));
863 11 gerhardhoh
 
864 10 gerhardhoh
      AmOut.Word <= AmOutBuff( blocksizeld - 1 downto 0);
865
      AmOut.way <= AmOutBuff( blocksizeld + ldways downto blocksizeld);
866
                AmOut.valid <= AmOutBuff( blocksizeld + ldways + 1);
867
         end if;
868 11 gerhardhoh
         end if;
869 10 gerhardhoh
  end if;
870
  end process queues;
871
 
872
  fullA1 <= counterA1( counterA1'high);
873 11 gerhardhoh
  emptyA1 <= '1' when counterA1 = 0 else '0';
874 10 gerhardhoh
 
875
  fullAm <= counterAm( counterAm'high);
876 11 gerhardhoh
  emptyAm <= '1' when counterAm = 0 else '0';
877 10 gerhardhoh
 
878 11 gerhardhoh
end Rtl;
879
 

powered by: WebSVN 2.1.0

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