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

Subversion Repositories core_arm

[/] [core_arm/] [trunk/] [vhdl/] [mem/] [cache/] [gendc.vhd] - Blame information for rev 6

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

Line No. Rev Author Line
1 2 tarookumic
-- $(help_generic)
2
-- $(help_local)
3
 
4
library ieee;
5
use ieee.std_logic_1164.all;
6
use IEEE.std_logic_unsigned.conv_integer;
7
use IEEE.std_logic_arith.conv_unsigned;
8
use work.config.all;
9
use work.int.all;
10
use work.memdef.all;
11
use work.corelib.all;
12
use work.cache_comp.all;
13
use work.cache_config.all;
14
use work.genic_lib.all;
15
use work.gendc_lib.all;
16
use work.genwb_lib.all;
17
use work.gencmem_lib.all;
18
use work.setrepl_lib.all;
19
use work.arith_cnt_comp.all;
20
use work.bus_comp.all;
21
 
22
entity gendc is
23
  port (
24
    rst     : in  std_logic;
25
    clk     : in  std_logic;
26
    hold : in cli_hold;
27
    i  : in  gendc_type_in;
28
    o  : out gendc_type_out;
29
    ctrl : in gdcl_ctrl;
30
    dcmo : in gencmem_type_dc_out;
31
    dcmi : out gencmem_type_dc_in;
32
    wbi  : out genwb_type_in;
33
    wbo  : in genwb_type_out
34
    );
35
end gendc;
36
 
37
architecture rtl of gendc is
38
 
39
  type gendc_dirty_a is array (natural range <>) of std_logic_vector(GCML_DC_TADDR_BSZ-1 downto 0);
40
 
41
  type gendc_cmaddrsrc is (gdca_no, gdca_in,  gdca_re,  gdca_lo);
42
  type gendc_meaddrsrc is (gdcma_no, gdcma_in, gdcma_re, gdcma_lo );
43
  type gendc_datainsrc is (gdcdi_no, gdcdi_in, gdcdi_re, gdcdi_lo, gdcdi_me );
44
  type gendc_datapisrc is (gdcdp_cm, gdcdp_me, gdcdp_no );
45
  type gendc_dbsrc is (gdcdb_mem, gdcdb_cm );
46
 
47
  type gendc_validsrc is (gdcvalid_old, gdcvalid_clr, gdcvalid_new, gdcvalid_add );
48
  type gendc_dirtysrc is (gdcdirty_old, gdcdirty_clr, gdcdirty_new, gdcdirty_add );
49
 
50
  constant GCML_DC_DLINE_BSZ_X : integer := lin_log2x(CFG_DC_DLINE_SZ);
51
  constant GCML_DC_SETS_X  : integer := lin_log2x(CFG_DC_SETS);
52
 
53
  type gendc_tmp_type is record
54
    hit, valid, dirty  : std_logic;     -- cache line attr 
55
    set, setrep  : integer;                     -- hit set
56
    pos  : integer;                     -- line pos
57
    ehold, req, reqread, reqwrite : std_logic;
58
    sethit  : std_logic_vector(CFG_DC_SETS-1 downto 0);
59
    setvalid   : std_logic_vector(CFG_DC_SETS-1 downto 0);
60
    newvalid, newdirty : std_logic_vector(CFG_DC_TLINE_SZ-1 downto 0);
61
    twrite, dwrite : std_logic;
62
    mexc : std_logic;
63
 
64
    setpos : std_logic_vector(lin_log2x(CFG_DC_SETS)-1 downto 0);
65
 
66
    cmaddr : std_logic_vector(31 downto 0);
67
    datain : std_logic_vector(31 downto 0);
68
    meaddr : std_logic_vector(31 downto 0);
69
    datapi : std_logic_vector(31 downto 0);
70
    tvalid_src : gendc_validsrc;
71
    tdirty_src : gendc_dirtysrc;
72
    cmaddr_src : gendc_cmaddrsrc;
73
    datain_src : gendc_datainsrc;
74
    meaddr_src : gendc_meaddrsrc;
75
    datapi_src : gendc_datapisrc;
76
    db_src : gendc_dbsrc;
77
 
78
    sign, read, lock, burst : std_logic;
79
    size : lmd_memsize;
80
    linepos : std_logic_vector(GCML_DC_TLINE_BSZ-1 downto 0);
81
    linepos_lastbit : std_logic_vector(CFG_DC_TLINE_SZ-1 downto 0);
82
 
83
    cmset : integer;
84
 
85
    si : arith_cnt8_in;
86
    dcmi : gencmem_type_dc_in;
87
    wbi  : genwb_type_in;
88
    o  : gendc_type_out;
89
 
90
    sr_setfree : std_logic_vector(CFG_DC_SETS-1 downto 0);
91
    sr_setlock : std_logic_vector(CFG_DC_SETS-1 downto 0);
92
    sr_useset : std_logic;
93
  end record;
94
  type gendc_state is (gendc_hit,
95
                       gendc_wtwb_readdata,
96
                       gendc_wb_writedata, gendc_wt_writedata,
97
                       gendc_wb_wbline, gendc_wb_fillline,
98
                       gendc_reloadtaddr );
99
  type gendc_reg_type is record
100
    setrep : std_logic_vector(lin_log2x(CFG_DC_SETS)-1 downto 0);
101
    state, state_wbline_next : gendc_state;
102
    hit, hold : std_logic;
103
 
104
    p_address : std_logic_vector(31 downto 0);
105
    p_data : std_logic_vector(31 downto 0);
106
    p_sign, p_read, p_lock : std_logic;
107
    p_size : lmd_memsize;
108
 
109
    stored, wbready, wbnext : std_logic;
110
    setrep_locked, setrep_free : std_logic;
111
    o_wr_data : std_logic_vector(31 downto 0);
112
    addrlo : std_logic_vector(1 downto 0);
113
    dirty : std_logic_vector(CFG_DC_TLINE_SZ-1 downto 0);
114
    fill_linepos, linepos : std_logic_vector(GCML_DC_TLINE_BSZ-1 downto 0);
115
    doaddr : std_logic_vector(1 downto 0);
116
    mexc : std_logic;
117
  end record;
118
  type gendc_dbg_type is record
119
     dummy : std_logic;
120
     -- pragma translate_off
121
     cmaddr : std_logic_vector(31 downto 0);
122
     dbg : gendc_tmp_type;
123
     -- pragma translate_on
124
  end record;
125
  signal r, c       : gendc_reg_type;
126
  signal rdbg, cdbg : gendc_dbg_type;
127
 
128
  signal si : arith_cnt8_in;
129
  signal so : arith_cnt8_out;
130
 
131
  signal sr_setfree : std_logic_vector(CFG_DC_SETS-1 downto 0);
132
  signal sr_setlock : std_logic_vector(CFG_DC_SETS-1 downto 0);
133
  signal sr_useset : std_logic;
134
  signal sr_locked : std_logic;
135
  signal sr_free   : std_logic;
136
  signal sr_setrep_free : std_logic_vector(GCML_DC_SETS_X-1 downto 0);
137
  signal sr_setrep_repl : std_logic_vector(GCML_DC_SETS_X-1 downto 0);
138
 
139
begin
140
 
141
  p0: process (clk, rst, r, hold, i, dcmo, wbo, so,
142
               sr_locked, sr_free, sr_setrep_free, sr_setrep_repl )
143
    variable v    : gendc_reg_type;
144
    variable t    : gendc_tmp_type;
145
    variable vdbg : gendc_dbg_type;
146
  begin
147
 
148
    -- todo: locking on atomic load store does not work yet
149
    -- until no multiprocessor system is implemented it's defered to the future
150
 
151
    -- $(init(t:gendc_tmp_type))
152
    v := r;
153
 
154
    t.meaddr := i.addr_in;
155
    t.cmaddr := i.addr_in;
156
    t.datain := i.data_in;
157
 
158
    t.wbi.fifo_write := '0';
159
    v.stored := r.stored or wbo.fifo_stored_v;
160
 
161
    -- write back address
162
    t.si.data := (others => '0');
163
    t.si.data(arith_cnt8_SZ-1 downto arith_cnt8_SZ-CFG_DC_TLINE_SZ) := r.dirty;
164
    t.linepos := so.res(GCML_DC_TLINE_BSZ-1 downto 0);
165
    t.linepos_lastbit := (others => '0');
166
 
167
    t.mexc := '0';
168
 
169
    t.datapi_src := gdcdp_no;
170
    t.db_src := gdcdb_cm;
171
 
172
    t.ehold := hold.ihold;
173
    t.req := (not (t.ehold or i.annul)) and i.addrin_re ;
174
    t.reqread := i.param_r.read and t.req;
175
    t.reqwrite := (not i.param_r.read) and t.req;
176
    t.twrite := '0';
177
    t.dwrite := '0';
178
 
179
    if r.hit = '1' then
180
      t.tvalid_src := gdcvalid_add;
181
      t.tdirty_src := gdcdirty_add;
182
    else
183
      t.tvalid_src := gdcvalid_new;
184
      t.tdirty_src := gdcdirty_new;
185
    end if;
186
 
187
    t.burst := '0';
188
    if (r.hold or t.ehold) = '1' then
189
      t.cmaddr_src := gdca_re;
190
      t.meaddr_src := gdcma_lo;
191
      t.datain_src := gdcdi_lo;
192
      t.sign := r.p_sign;
193
      t.size := r.p_size;
194
      t.read := r.p_read;
195
      t.lock := r.p_lock;
196
    else
197
      t.cmaddr_src := gdca_in;
198
      t.meaddr_src := gdcma_re;
199
      t.datain_src := gdcdi_in;
200
      t.sign := i.param_r.signed;
201
      t.size := i.param_r.size;
202
      t.read := i.param_r.read;
203
      t.lock := i.param_r.lock;
204
    end if;
205
 
206
    if t.read = '1' then
207
      t.size := lmd_word;
208
    end if;
209
 
210
    -- cmp
211
    t.hit := '0';
212
    t.set := 0;
213
    for j in CFG_DC_SETS-1 downto 0 loop
214
      -- (note: multiset does not recognice valid zero tags)
215
      if gdcl_is_taghit(i.addr_re,dcmo.tag_line(j)) then
216
        t.hit := '1';
217
        t.sethit(j) := '1';
218
        t.set := j;
219
      end if;
220
    end loop;
221
 
222
    t.sr_setfree := (others => '0');
223
    for j in CFG_DC_SETS-1 downto 0 loop
224
      if gdcl_is_free(dcmo.tag_line(j)) then
225
        t.sr_setfree(j) := '1';
226
      end if;
227
    end loop;
228
 
229
    t.sr_setlock := (others => '0');
230
    for j in CFG_DC_SETS-1 downto 0 loop
231
      t.sr_setlock(j) := dcmo.tag_line(j).lock;
232
    end loop;
233
 
234
    t.sr_useset := '0';
235
 
236
    t.valid := '0';
237
    if gdcl_is_linevalid(i.addr_re,dcmo.tag_line(t.set)) then
238
      t.valid := '1';
239
    end if;
240
 
241
    t.dirty := '0';
242
    t.setrep := lin_convint(sr_setrep_repl);
243
    if (sr_free = '1') or (sr_locked = '1') then
244
      t.dirty := '0';
245
      if (sr_free = '1') then
246
        t.setrep := lin_convint(sr_setrep_free);
247
      end if;
248
    else
249
      if gdcl_is_linedirty(i.addr_re,dcmo.tag_line(t.setrep)) then
250
        t.dirty := '1';
251
      end if;
252
    end if;
253
 
254
    -- $(del)
255
    --                read                               write                                                
256
    --   Writeback     |   Writethrough     Writeback     |   Writethrough                                        
257
    --        +--------+--------+                +--------+--------+                                                  
258
    --    hit | miss        hit | miss       hit | miss        hit | miss                                      
259
    --   +----+----+       +----+----+      +----+----+       +----+----+                               
260
    --   |     free|dirty  |         |      |     free|dirty  |         |                   
261
    --   O1     +--+--+    O1        O3    O5      +--+--+   O4/O6     O6                              
262
    --          |     |              |             |     |                                            
263
    --          O3<---O2             O4            O5<---O2                                            
264
    --          |                                                                                                     
265
    --          O4                                                                                     
266
    --                                                                                                        
267
    --  O1: cacheread                                                                                                  
268
    --  O2: writeback line                                                                                              
269
    --  O3: memload                                                                                                     
270
    --  O4: cachewrite clean                                                                                              
271
    --  O5: cachewrite dirty                                                                                             
272
    --  O6: writeback single                                                                                            
273
    -- $(/del)
274
 
275
 
276
    case r.state is
277
 
278
      when gendc_hit =>
279
 
280
        if t.hit = '1' then
281
          t.tvalid_src := gdcvalid_add;
282
          t.tdirty_src := gdcdirty_add;
283
        else
284
          t.tvalid_src := gdcvalid_new;
285
          t.tdirty_src := gdcdirty_new;
286
        end if;
287
 
288
        v.mexc := '0';
289
        v.wbready := '0';
290
        v.wbnext := '0';
291
        v.stored := wbo.fifo_stored_v;
292
        v.hold := '0';
293
 
294
        v.setrep_locked := sr_locked;
295
        v.setrep_free := sr_free;
296
 
297
        v.hit := t.hit;
298
 
299
        v.p_address := i.addr_re;
300
        v.p_data := i.data_in;
301
        v.p_sign := i.param_r.signed;
302
        v.p_size := i.param_r.size;
303
        v.p_read := i.param_r.read;
304
        v.p_lock := i.param_r.lock;
305
 
306
        if t.req = '1' then
307
 
308
          t.sr_useset := '1';
309
 
310
          if i.param_r.read = '1' then
311
            if ctrl.writeback = '0' then
312
              if (not (t.hit and t.valid)) = '1' or (i.forceread = '1') then
313
 
314
                -- $(del)
315
                --                read               
316
                --   Writeback     |   Writethrough  
317
                --        +--------+--------+        
318
                --    hit | miss        hit |<MISS>                   
319
                --   +----+----+       +----+----+   
320
                --   |     free|dirty  |         |   
321
                --   O1     +--+--+    O1        O3  
322
                --          |     |              |   
323
                --          O3<---O2             O4  
324
                --          |                        
325
                --          O4
326
                -- $(/del)
327
 
328
                -- $(del)
329
                -- $(/del)
330
                t.cmaddr_src := gdca_re;
331
 
332
                v.hold := '1';
333
 
334
                t.wbi.fifo_write := '1';
335
                v.state := gendc_wtwb_readdata;
336
 
337
              else
338
 
339
                -- $(del)
340
                --                read               
341
                --   Writeback     |   Writethrough  
342
                --        +--------+--------+        
343
                --    hit | miss       <HIT>| miss                   
344
                --   +----+----+       +----+----+   
345
                --   |     free|dirty  |         |   
346
                --   O1     +--+--+    O1        O3  
347
                --          |     |              |   
348
                --          O3<---O2             O4  
349
                --          |                        
350
                --          O4
351
                -- $(/del)
352
 
353
                t.setrep := t.set;
354
                t.datapi_src := gdcdp_cm;
355
 
356
              end if;
357
 
358
            else
359
              if (not (t.hit and t.valid)) = '1' or (i.forceread = '1') then
360
 
361
                -- $(del)
362
                --                read               
363
                --   Writeback     |   Writethrough  
364
                --        +--------+--------+        
365
                --    hit |<MISS>       hit | miss                   
366
                --   +----+----+       +----+----+   
367
                --   |     free|dirty  |         |   
368
                --   O1     +--+--+    O1        O3  
369
                --          |     |              |   
370
                --          O3<---O2             O4  
371
                --          |                        
372
                --          O4
373
                -- $(/del)
374
 
375
                v.hold := '1';
376
 
377
                if t.dirty = '1' then
378
                  v.state := gendc_wb_wbline;
379
                  v.state_wbline_next := gendc_wtwb_readdata;
380
                else
381
 
382
                  t.wbi.fifo_write := '1';
383
                  v.state := gendc_wtwb_readdata;
384
 
385
                end if;
386
 
387
 
388
              else
389
 
390
                -- $(del)
391
                --                read               
392
                --   Writeback     |   Writethrough  
393
                --        +--------+--------+        
394
                --   <HIT>| miss        hit | miss                   
395
                --   +----+----+       +----+----+   
396
                --   |     free|dirty  |         |   
397
                --   O1     +--+--+    O1        O3  
398
                --          |     |              |   
399
                --          O3<---O2             O4  
400
                --          |                        
401
                --          O4
402
                -- $(/del)
403
 
404
                t.setrep := t.set;
405
                t.datapi_src := gdcdp_cm;
406
 
407
              end if;
408
 
409
            end if;
410
 
411
 
412
          else
413
 
414
            if ctrl.writeback = '0' then
415
              if (not (t.hit and t.valid)) = '1' then
416
                -- $(del)
417
                --               write                                                
418
                --    writeback    |   Writethrough                                  
419
                --        +--------+--------+
420
                --    hit | miss        hit |<MISS>                                      
421
                --   +----+----+       +----+----+                               
422
                --   |     free|dirty  |         |                   
423
                --  O5      +--+--+   O4/O6     O6                              
424
                --          |     |                                            
425
                --          O5<---O2                                        
426
                -- $(/del)
427
 
428
                if ctrl.allocateonstore = '1' then
429
                  t.twrite := '1';
430
                  t.dwrite := '1';
431
                end if;
432
 
433
              else
434
                -- $(del)
435
                --               write                                                
436
                --    writeback    |   writethrough                                    
437
                --        +--------+--------+                                          
438
                --    hit | miss       <HIT>| miss                                     
439
                --   +----+----+       +----+----+                               
440
                --   |     free|dirty  |         |                   
441
                --  O5      +--+--+   O4/O6     O6                              
442
                --          |     |                                            
443
                --          O5<---O2                                            
444
                -- $(/del)
445
 
446
                t.setrep := t.set;
447
                t.twrite := '1';
448
                t.dwrite := '1';
449
              end if;
450
 
451
              v.state := gendc_wt_writedata;
452
              t.wbi.fifo_write := '1';
453
 
454
 
455
              t.cmaddr_src := gdca_re;
456
              t.meaddr_src := gdcma_re;  -- addr cycle 1
457
              t.datain_src := gdcdi_in;  -- data cycle 2
458
 
459
            else
460
              if (not (t.hit and t.valid)) = '1' then
461
                -- $(del)
462
                --               write                                                
463
                --    writeback    |   writethrough                                  
464
                --        +--------+--------+
465
                --    hit |<MISS>       hit | miss                                      
466
                --   +----+----+       +----+----+                               
467
                --   |     free|dirty  |         |                   
468
                --  O5      +--+--+   O4/O6     O6                              
469
                --          |     |                                            
470
                --          O5<---O2
471
                -- $(/del)
472
                -- 
473
                if ctrl.allocateonstore = '0' then
474
                  v.hold := '1';
475
                  v.setrep_locked := '1';
476
                  v.state := gendc_wb_writedata;
477
                  t.wbi.fifo_write := '1';
478
                else
479
 
480
                  if t.dirty = '1' then
481
                    v.hold := '1';
482
                    v.state := gendc_wb_wbline;
483
                    v.state_wbline_next := gendc_wb_writedata;
484
                  else
485
 
486
                    if (sr_locked = '1') then
487
                      v.hold := '1';
488
                      v.state := gendc_wb_writedata;
489
                      t.wbi.fifo_write := '1';
490
 
491
                    else
492
 
493
                      if i.param_r.size = lmd_word then
494
 
495
                        -- note : store is 2 cycle (no reload needed)
496
                        t.twrite := '1';
497
                        t.dwrite := '1';
498
 
499
                      else
500
 
501
                        v.hold := '1';
502
                        v.state := gendc_wb_writedata;
503
 
504
                      end if;
505
                    end if;
506
                  end if;
507
                end if;
508
              else
509
                -- $(del)
510
                --               write                                                
511
                --    writeback    |   writethrough                                  
512
                --        +--------+--------+                                  
513
                --   <HIT>| miss        hit | miss                                      
514
                --   +----+----+       +----+----+                               
515
                --   |     free|dirty  |         |                   
516
                --  O5      +--+--+   O4/O6     O6                              
517
                --          |     |                                            
518
                --          O5<---O2                                            
519
                -- $(/del)
520
 
521
                t.setrep := t.set;
522
                t.twrite := '1';
523
                t.dwrite := '1';
524
 
525
                t.tvalid_src := gdcvalid_old;
526
                t.tdirty_src := gdcdirty_add;
527
 
528
                if i.forcewrite = '1' then
529
                  v.setrep_locked := '1';
530
                  v.hold := '1';
531
                  v.state := gendc_wb_writedata;
532
                  t.wbi.fifo_write := '1';
533
                end if;
534
              end if;
535
            end if;
536
          end if;
537
        end if;
538
 
539
        v.setrep := std_logic_vector(conv_unsigned(t.setrep, lin_log2x(CFG_IC_SETS)));
540
        v.dirty := dcmo.tag_line(t.set).dirty;
541
 
542
-------------------------------------------------------------------------------
543
 
544
      when gendc_wtwb_readdata =>
545
 
546
        -- writethrough and writeback read, load and allocate
547
        -- $(del)
548
        --                read               
549
        --   Writeback     |   Writethrough  
550
        --        +--------+--------+        
551
        --    hit |<MISS>       hit |<MISS>                   
552
        --   +----+----+       +----+----+   
553
        --   |   <free>|<dirty>|         |   
554
        --   O1     +--+--+    O1        O3  
555
        --          |     |              |   
556
        --          O3<---O2             O4  
557
        --          |                        
558
        --          O4
559
        -- $(/del)
560
 
561
        t.datain_src := gdcdi_me;
562
        t.datapi_src := gdcdp_me;
563
        t.cmaddr_src := gdca_lo;
564
 
565
        if r.stored = '0' then
566
          t.wbi.fifo_write := '1';
567
        else
568
          if wbo.read_finish_v = '1' then
569
 
570
            t.mexc := wbo.read_mexc;
571
            --t.mexc := '1';
572
 
573
            if r.setrep_locked = '0' then
574
              t.twrite := '1';
575
              t.dwrite := '1';
576
            end if;
577
 
578
            if i.addrin_re = '1' then
579
              v.state := gendc_reloadtaddr;
580
            else
581
              v.state := gendc_hit;
582
              v.hold := '0';
583
            end if;
584
          end if;
585
        end if;
586
 
587
-------------------------------------------------------------------------------
588
 
589
      when gendc_wb_writedata =>
590
 
591
        -- writeback-write, allocate, allocate word on subword write
592
        -- $(del)
593
        --               write                                                
594
        --    writeback    |   Writethrough                                  
595
        --        +--------+--------+
596
        --    hit | miss        hit | miss                                       
597
        --   +----+----+       +----+----+                               
598
        --   |   <FREE>|<DIRTY>|         |                   
599
        --  O5      +--+--+   O4/O6     O6                              
600
        --          |     |                                            
601
        --          O5<---O2
602
        -- $(/del)
603
 
604
        -- todo: check for lock on all sets
605
 
606
        if r.setrep_locked = '1' then
607
          t.wbi.fifo_write := '1';
608
          if wbo.fifo_stored_v = '1' then
609
            v.hold := '0';
610
            v.state := gendc_hit;
611
          end if;
612
        else
613
          t.twrite := '1';
614
 
615
          -- load word of subword allocate
616
          if (t.size /= lmd_word) then
617
            t.twrite := '0';
618
 
619
            t.datain_src := gdcdi_me;
620
            t.cmaddr_src := gdca_lo;
621
 
622
            if r.stored = '0' then
623
 
624
              t.wbi.fifo_write := '1';
625
              t.size := lmd_word;
626
              t.read := '1';
627
              t.lock := '0';
628
 
629
              t.datain_src := gdcdi_me;
630
              t.datapi_src := gdcdp_me;
631
              t.cmaddr_src := gdca_lo;
632
 
633
            else
634
 
635
              if wbo.read_finish_v = '1' then
636
                t.mexc := wbo.read_mexc;
637
 
638
                t.twrite := '1';
639
                t.db_src := gdcdb_mem;
640
              end if;
641
            end if;
642
          end if;
643
 
644
          if (t.twrite = '1') then
645
            t.cmaddr_src := gdca_lo;
646
            t.datain_src := gdcdi_lo;
647
            t.meaddr_src := gdcma_lo;
648
            t.twrite := '1';
649
            t.dwrite := '1';
650
            v.hold := '0';
651
            if i.addrin_re = '1' then
652
              v.state := gendc_reloadtaddr;
653
            else
654
              v.state := gendc_hit;
655
              v.hold := '0';
656
            end if;
657
          end if;
658
        end if;
659
 
660
-------------------------------------------------------------------------------
661
 
662
      when gendc_wt_writedata =>
663
 
664
        -- writethrough-write, no allocate
665
        -- $(del)
666
        --               write                                                
667
        --    writeback    |   Writethrough                                  
668
        --        +--------+--------+
669
        --    hit | miss       <HIT>|<MISS>                                      
670
        --   +----+----+       +----+----+                               
671
        --   |     free|dirty  |         |                   
672
        --  O5      +--+--+   O4/O6     O6                              
673
        --          |     |                                            
674
        --          O5<---O2                                        
675
        -- $(/del)
676
 
677
        t.datain_src := gdcdi_lo;
678
        t.meaddr_src := gdcma_lo;
679
 
680
        if r.stored = '0'  then
681
          v.hold := '1';
682
          t.wbi.fifo_write := '1';
683
        end if;
684
        if v.stored = '1' then
685
          v.hold := '0';
686
          v.state := gendc_hit;
687
        end if;
688
 
689
-------------------------------------------------------------------------------
690
 
691
        -- writeback, allocte full line
692
        -- $(del)                                                        
693
        --                read                              write               
694
        --   Writeback     |   Writethrough      writeback    |   writethrough  
695
        --        +--------+--------+                +--------+--------+        
696
        --    hit |<MISS>       hit | miss       hit |<MISS>       hit | miss                   
697
        --   +----+----+       +----+----+      +----+----+       +----+----+   
698
        --   |   <free>|<dirty>|         |      |   <free>|<dirty>|         |   
699
        --   O1     +--+--+    O1        O3    O5      +--+--+   O4/O6     O6   
700
        --          |     |              |             |     |                  
701
        --          O3<---O2             O4            O5<---O2                 
702
        --          |                                                    
703
        --          O4
704
        -- $(/del)
705
 
706
      when gendc_wb_fillline =>
707
 
708
        t.cmaddr_src := gdca_no;
709
        t.meaddr_src := gdcma_no;
710
        t.datain_src := gdcdi_me;
711
 
712
        t.cmaddr := r.p_address;
713
        t.cmaddr(GDCL_TLINE_U downto GDCL_TLINE_D) := r.fill_linepos;
714
        t.meaddr := (others => '0');
715
        t.meaddr(GDCL_TTAG_U downto GDCL_TTAG_D) := dcmo.tag_line(lin_convint(r.setrep)).tag;
716
        t.meaddr(GDCL_TLINE_U downto GDCL_TLINE_D) := r.linepos;
717
        t.linepos := so.res(GCML_DC_TLINE_BSZ-1 downto 0);
718
 
719
        if r.fill_linepos = GDCL_ZERO_C then
720
          t.tvalid_src := gdcvalid_new;
721
          t.tdirty_src := gdcdirty_new;
722
        else
723
          t.tvalid_src := gdcvalid_add;
724
          t.tdirty_src := gdcdirty_add;
725
        end if;
726
 
727
        t.size := lmd_word;
728
        t.read := '1';
729
        t.lock := '0';
730
        t.burst := '1';
731
        if r.linepos = GDCL_LAST_C then
732
          t.burst := '0';
733
        end if;
734
 
735
        if r.stored = '0' then
736
          t.wbi.fifo_write := '1';
737
          v.fill_linepos := r.linepos;
738
        else
739
 
740
          if r.wbnext = '0' then
741
            v.wbnext := '1';
742
            lin_incdec(r.linepos,v.linepos,'1','1');
743
          end if;
744
 
745
          if wbo.read_finish_v = '1' then
746
 
747
            t.mexc := wbo.read_mexc;
748
 
749
            v.stored := '0';
750
            v.wbnext := '0';
751
 
752
            -- return data (on load)
753
            if t.cmaddr(GDCL_TLINE_U downto GDCL_TLINE_D) = r.p_address(GDCL_TLINE_U downto GDCL_TLINE_D) then
754
              t.datapi_src := gdcdp_me;
755
            end if;
756
 
757
            t.twrite := '1';
758
            t.dwrite := '1';
759
 
760
            if (r.linepos = GDCL_ZERO_C) then
761
              v.state := gendc_hit;
762
            end if;
763
          end if;
764
        end if;
765
 
766
-------------------------------------------------------------------------------
767
 
768
        -- writeback, line flush
769
        -- $(del)                                                        
770
        --                read                              write               
771
        --   Writeback     |   Writethrough      writeback    |   writethrough  
772
        --        +--------+--------+                +--------+--------+        
773
        --    hit |<MISS>       hit | miss       hit |<MISS>       hit | miss                   
774
        --   +----+----+       +----+----+      +----+----+       +----+----+   
775
        --   |     free|<dirty>|         |      |     free|<dirty>|         |   
776
        --   O1     +--+--+    O1        O3    O5      +--+--+   O4/O6     O6   
777
        --          |     |              |             |     |                  
778
        --          O3<---O2             O4            O5<---O2                 
779
        --          |                                                    
780
        --          O4
781
        -- $(/del)
782
 
783
      when gendc_wb_wbline =>
784
 
785
        t.cmaddr_src := gdca_no;
786
        t.meaddr_src := gdcma_no;
787
        t.datain_src := gdcdi_no;
788
        t.datapi_src := gdcdp_no;
789
 
790
        t.linepos := so.res(GCML_DC_TLINE_BSZ-1 downto 0);
791
 
792
        t.cmaddr := r.p_address;
793
        t.cmaddr(GDCL_TLINE_U downto GDCL_TLINE_D) := t.linepos;
794
        t.meaddr := (others => '0');
795
        t.meaddr(GDCL_TTAG_U downto GDCL_TTAG_D) := dcmo.tag_line(lin_convint(r.setrep)).tag;
796
        t.meaddr(GDCL_TLINE_U downto GDCL_TLINE_D) := r.linepos;
797
        t.datain := r.o_wr_data;
798
 
799
        t.size := lmd_word;
800
        t.read := '0';
801
        t.lock := '0';
802
        t.burst := '0';
803
 
804
        if r.wbready = '0' then         --calculating first address
805
 
806
          v.wbready := '1';
807
          v.dirty(lin_convint(t.linepos)) := '0';
808
          v.linepos := t.linepos;
809
 
810
        else
811
 
812
          t.wbi.fifo_write := '1';
813
 
814
          -- burst calc
815
          t.linepos_lastbit := lin_decode(r.linepos);
816
          t.linepos_lastbit := t.linepos_lastbit(CFG_DC_TLINE_SZ-2 downto 0) & "0";
817
          if (r.dirty and t.linepos_lastbit) /= GDCL_ZERO_C then
818
            t.burst := '1';
819
          end if;
820
 
821
          -- buffer cm out
822
          if r.wbnext = '0' then
823
            v.wbnext := '1';
824
            v.o_wr_data := dcmo.dat_line(lin_convint(r.setrep)).data(t.pos);
825
            t.datain := v.o_wr_data;
826
          end if;
827
 
828
          -- next pos
829
          if wbo.fifo_stored_v = '1' then
830
            v.wbnext := '0';
831
            v.dirty(lin_convint(t.linepos)) := '0';
832
            v.linepos := t.linepos;
833
            if r.dirty = GDCL_ZERO_C then
834
              v.state := r.state_wbline_next;
835
            end if;
836
          end if;
837
        end if;
838
 
839
        v.stored := '0';
840
 
841
-------------------------------------------------------------------------------
842
 
843
      when gendc_reloadtaddr =>
844
 
845
        t.cmaddr_src := gdca_re;
846
        v.state := gendc_hit;
847
        v.hold := '0';
848
 
849
-------------------------------------------------------------------------------
850
 
851
      when others =>
852
 
853
    end case;
854
 
855
    if t.mexc = '1' then
856
      t.twrite := '0';
857
      t.dwrite := '0';
858
      v.mexc := '1';
859
    end if;
860
 
861
    -- cm read/write address 
862
    case t.cmaddr_src is
863
      when gdca_no =>
864
      when gdca_in => t.cmaddr := i.addr_in;
865
      when gdca_re => t.cmaddr := i.addr_re;
866
      when gdca_lo => t.cmaddr := r.p_address;
867
      when others => null;
868
    end case;
869
 
870
    -- mem load/store address (wb input)
871
    case t.meaddr_src is
872
      when gdcma_no =>
873
      when gdcma_in => t.meaddr := i.addr_in;
874
      when gdcma_re => t.meaddr := i.addr_re;
875
      when gdcma_lo => t.meaddr := r.p_address;
876
      when others => null;
877
    end case;
878
 
879
    t.setpos := std_logic_vector(conv_unsigned(t.setrep, lin_log2x(CFG_IC_SETS)));
880
    if r.hold = '1' then
881
      t.setpos := r.setrep;
882
    end if;
883
 
884
    -- data pipeline: read data output [cm|mem]->pipeline
885
    t.pos := gdcl_getpos(t.meaddr(GDCL_TLINE_U downto GDCL_TLINE_D));
886
    case t.datapi_src is
887
      when gdcdp_no =>
888
      when gdcdp_me => v.o_wr_data := wbo.read_data;
889
      when gdcdp_cm => v.o_wr_data := dcmo.dat_line(lin_convint(t.setpos)).data(t.pos);
890
      when others =>
891
    end case;
892
    v.doaddr(1 downto 0) := t.meaddr(1 downto 0);
893
    t.o.wr_data := gdcl_readdata ( r.doaddr, r.o_wr_data, CFG_BO_BUS, r.p_sign, r.p_size );
894
 
895
    -- write data input (from (pipeline or mem) to (cmem or mem))
896
    case t.datain_src is
897
      when gdcdi_no =>
898
      when gdcdi_in => t.datain := i.data_in;
899
      when gdcdi_re => t.datain := i.data_re;
900
      when gdcdi_lo => t.datain := r.p_data;
901
      when gdcdi_me => t.datain := wbo.read_data;
902
      when others => null;
903
    end case;
904
 
905
    -- input tag/data line
906
    -- $(del)
907
    --               read                               write                                                
908
    --   Writeback     |   Writethrough     Writeback     |   Writethrough                                        
909
    --        +--------+--------+                +--------+--------+                                                  
910
    --    hit | miss        hit | miss       hit | miss        hit | miss                                      
911
    --   +----+----+       +----+----+      +----+----+       +----+----+                               
912
    --   |     free|dirty  |         |      |     free|dirty  |         |                   
913
    --   O1     +--+--+    O1        O3   <O5>     +--+--+  <O4>/O6     O6                              
914
    --          |     |              |             |     |                                            
915
    --          O3<---O2            <O4>         <O5><---O2                                            
916
    --          |                                                                                                     
917
    --         <O4>                                                                                     
918
    -- $(/del)
919
 
920
    -- assemble input tag line    
921
    t.dcmi.addr := t.cmaddr;
922
    t.dcmi.tag_line := dcmo.tag_line(lin_convint(t.setpos));
923
    t.newvalid := (others => '0');
924
    t.newvalid := lin_decode(t.cmaddr(GDCL_TLINE_U downto GDCL_TLINE_D));
925
    case t.tvalid_src is
926
      when gdcvalid_old =>
927
      when gdcvalid_clr => t.dcmi.tag_line.valid := (others => '0');
928
      when gdcvalid_new => t.dcmi.tag_line.valid := t.newvalid;
929
      when gdcvalid_add => t.dcmi.tag_line.valid := t.dcmi.tag_line.valid or t.newvalid;
930
    end case;
931
    t.newdirty := (others => '0');
932
    t.newdirty := lin_decode(t.cmaddr(GDCL_TLINE_U downto GDCL_TLINE_D));
933
    case t.tdirty_src is
934
      when gdcdirty_old =>
935
      when gdcdirty_clr => t.dcmi.tag_line.dirty := (others => '0');
936
      when gdcdirty_new => t.dcmi.tag_line.dirty := t.newdirty;
937
      when gdcdirty_add => t.dcmi.tag_line.dirty := t.dcmi.tag_line.dirty or t.newdirty;
938
    end case;
939
    t.dcmi.tag_line.tag := t.cmaddr(GDCL_TTAG_U downto GDCL_TTAG_D);
940
    t.dcmi.tag_write := (others => '0');
941
    t.dcmi.tag_write(lin_convint(t.setpos)) := t.twrite;
942
 
943
    -- assemble input data line [mem->cache]
944
    t.dcmi.dat_line := dcmo.dat_line(lin_convint(t.setpos));
945
    case t.db_src is
946
      when gdcdb_mem => t.dcmi.dat_line.data(t.pos) := wbo.read_data;  -- on allocate subword
947
      when others =>
948
    end case;
949
    t.dcmi.dat_line.data(t.pos) := gdcl_writedata(t.cmaddr(1 downto 0),t.dcmi.dat_line.data(t.pos),t.datain,CFG_BO_BUS,t.size);
950
    t.dcmi.dat_write := (others => '0');
951
    t.dcmi.dat_write(lin_convint(t.setpos)) := t.dwrite;
952
 
953
    -- write buffer in 
954
    -- $(del)
955
    --               read                               write                                                
956
    --   Writeback     |   Writethrough     Writeback     |   Writethrough                                        
957
    --        +--------+--------+                +--------+--------+                                                  
958
    --    hit | miss        hit | miss       hit | miss        hit | miss                                      
959
    --   +----+----+       +----+----+      +----+----+       +----+----+                               
960
    --   |     free|dirty  |         |      |     free|dirty  |         |                   
961
    --   O1     +--+--+    O1        O3    O5      +--+--+   O4/<O6>   <O6>                              
962
    --          |     |              |             |     |                                            
963
    --          O3<---<O2>           O4           O5 <---<O2>                                            
964
    --          |                                                                                                     
965
    --          O4                                                                                     
966
    -- $(/del)
967
 
968
    t.o.me_mexc := t.mexc;
969
    t.o.wr_mexc := r.mexc;
970
 
971
    t.wbi.fifo_entry.data := t.datain;
972
    t.wbi.fifo_entry.addr := t.meaddr;
973
    t.wbi.fifo_entry.size := t.size;
974
    t.wbi.fifo_entry.read := t.read;
975
    t.wbi.fifo_entry.lock := t.lock;
976
    t.wbi.fifo_entry.burst := t.burst;
977
    case t.wbi.fifo_entry.size is
978
      when lmd_word => t.wbi.fifo_entry.addr(1 downto 0) := (others => '0');
979
      when lmd_half => t.wbi.fifo_entry.addr(0) := '0';
980
      when others =>
981
    end case;
982
 
983
    -- reset
984
    if ( rst = '0' ) then
985
      v.hold := '0';
986
    end if;
987
 
988
    t.o.hold := r.hold;
989
 
990
    c <= v;
991
 
992
    o <= t.o;
993
    si <= t.si;
994
    dcmi <= t.dcmi;
995
    wbi <= t.wbi;
996
 
997
    sr_setfree <= t.sr_setfree;
998
    sr_setlock <= t.sr_setlock;
999
    sr_useset <= t.sr_useset;
1000
 
1001
    -- pragma translate_off
1002
    vdbg := rdbg;
1003
    vdbg.cmaddr := t.cmaddr;
1004
    vdbg.dbg := t;
1005
    cdbg <= vdbg;
1006
    -- pragma translate_on  end process p0;
1007
 
1008
  end process p0;
1009
 
1010
  pregs : process (clk, c)
1011
  begin
1012
    if rising_edge(clk) then
1013
      r <= c;
1014
      -- pragma translate_off
1015
      rdbg <= cdbg;
1016
      -- pragma translate_on
1017
    end if;
1018
  end process;
1019
 
1020
  cnt0: arith_cnt8 port map (rst, clk, si, so);
1021
 
1022
  sr0: setrepl generic map ( SETSIZE => CFG_DC_SETS,SETSIZE_logx => GCML_DC_SETS_X )
1023
    port map (rst, clk, sr_setfree, sr_setlock, sr_useset, sr_locked, sr_free, sr_setrep_free, sr_setrep_repl);
1024
 
1025
  -- pragma translate_off
1026
  check0 : process (rst)
1027
  begin
1028
    assert (CFG_DC_TLINE_SZ <= 8) report "Error: current arith_cntxx component can only count up to 8 positions. Replace with a larger one." severity failure;
1029
  end process;
1030
  -- pragma translate_on
1031
 
1032
end rtl;

powered by: WebSVN 2.1.0

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