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

Subversion Repositories mytwoqcache

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

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

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

powered by: WebSVN 2.1.0

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