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

Subversion Repositories thor

[/] [thor/] [trunk/] [FT64v7/] [rtl/] [common/] [FT64_icache.v] - Blame information for rev 60

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

Line No. Rev Author Line
1 60 robfinch
// ============================================================================
2
//        __
3
//   \\__/ o\    (C) 2017-2018  Robert Finch, Waterloo
4
//    \  __ /    All rights reserved.
5
//     \/_//     robfinch<remove>@finitron.ca
6
//       ||
7
//
8
//      FT64_cache.v
9
//              
10
//
11
// This source file is free software: you can redistribute it and/or modify 
12
// it under the terms of the GNU Lesser General Public License as published 
13
// by the Free Software Foundation, either version 3 of the License, or     
14
// (at your option) any later version.                                      
15
//                                                                          
16
// This source file is distributed in the hope that it will be useful,      
17
// but WITHOUT ANY WARRANTY; without even the implied warranty of           
18
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the            
19
// GNU General Public License for more details.                             
20
//                                                                          
21
// You should have received a copy of the GNU General Public License        
22
// along with this program.  If not, see <http://www.gnu.org/licenses/>.    
23
//                                                                          
24
//
25
// ============================================================================
26
//
27
`define TRUE    1'b1
28
`define FALSE   1'b0
29
 
30
// -----------------------------------------------------------------------------
31
// Small, 64 line cache memory (2kiB) made from distributed RAM. Access is
32
// within a single clock cycle.
33
// -----------------------------------------------------------------------------
34
 
35
module FT64_L1_icache_mem(rst, clk, wr, en, lineno, i, o, ov, invall, invline);
36
parameter pLines = 64;
37
parameter pLineWidth = 298;
38
localparam pLNMSB = pLines==128 ? 6 : 5;
39
input rst;
40
input clk;
41
input wr;
42
input [8:0] en;
43
input [pLNMSB:0] lineno;
44
input [pLineWidth-1:0] i;
45
output [pLineWidth-1:0] o;
46
output [8:0] ov;
47
input invall;
48
input invline;
49
 
50
integer n;
51
 
52
(* ram_style="distributed" *)
53
reg [pLineWidth-1:0] mem [0:pLines-1];
54
reg [pLines-1:0] valid0;
55
reg [pLines-1:0] valid1;
56
reg [pLines-1:0] valid2;
57
reg [pLines-1:0] valid3;
58
reg [pLines-1:0] valid4;
59
reg [pLines-1:0] valid5;
60
reg [pLines-1:0] valid6;
61
reg [pLines-1:0] valid7;
62
reg [pLines-1:0] valid8;
63
 
64
initial begin
65
        for (n = 0; n < pLines; n = n + 1)
66
                mem[n] <= 2'b00;
67
end
68
 
69
always  @(posedge clk)
70
    if (wr & en[0])  mem[lineno][31:0] <= i[31:0];
71
always  @(posedge clk)
72
    if (wr & en[1])  mem[lineno][63:32] <= i[63:32];
73
always  @(posedge clk)
74
    if (wr & en[2])  mem[lineno][95:64] <= i[95:64];
75
always  @(posedge clk)
76
    if (wr & en[3])  mem[lineno][127:96] <= i[127:96];
77
always  @(posedge clk)
78
    if (wr & en[4])  mem[lineno][159:128] <= i[159:128];
79
always  @(posedge clk)
80
    if (wr & en[5])  mem[lineno][191:160] <= i[191:160];
81
always  @(posedge clk)
82
    if (wr & en[6])  mem[lineno][223:192] <= i[223:192];
83
always  @(posedge clk)
84
    if (wr & en[7])  mem[lineno][255:224] <= i[255:224];
85
always  @(posedge clk)
86
    if (wr & en[8])  mem[lineno][297:256] <= i[297:256];
87
always  @(posedge clk)
88
if (rst) begin
89
     valid0 <= 64'd0;
90
     valid1 <= 64'd0;
91
     valid2 <= 64'd0;
92
     valid3 <= 64'd0;
93
     valid4 <= 64'd0;
94
     valid5 <= 64'd0;
95
     valid6 <= 64'd0;
96
     valid7 <= 64'd0;
97
     valid8 <= 64'd0;
98
end
99
else begin
100
    if (invall) begin
101
        valid0 <= 64'd0;
102
        valid1 <= 64'd0;
103
        valid2 <= 64'd0;
104
        valid3 <= 64'd0;
105
        valid4 <= 64'd0;
106
        valid5 <= 64'd0;
107
        valid6 <= 64'd0;
108
        valid7 <= 64'd0;
109
                        valid8 <= 64'd0;
110
    end
111
    else if (invline) begin
112
        valid0[lineno] <= 1'b0;
113
        valid1[lineno] <= 1'b0;
114
        valid2[lineno] <= 1'b0;
115
        valid3[lineno] <= 1'b0;
116
        valid4[lineno] <= 1'b0;
117
        valid5[lineno] <= 1'b0;
118
        valid6[lineno] <= 1'b0;
119
        valid7[lineno] <= 1'b0;
120
        valid8[lineno] <= 1'b0;
121
        end
122
    else if (wr) begin
123
        if (en[0]) valid0[lineno] <= 1'b1;
124
        if (en[1]) valid1[lineno] <= 1'b1;
125
        if (en[2]) valid2[lineno] <= 1'b1;
126
        if (en[3]) valid3[lineno] <= 1'b1;
127
        if (en[4]) valid4[lineno] <= 1'b1;
128
        if (en[5]) valid5[lineno] <= 1'b1;
129
        if (en[6]) valid6[lineno] <= 1'b1;
130
        if (en[7]) valid7[lineno] <= 1'b1;
131
        if (en[8]) valid8[lineno] <= 1'b1;
132
    end
133
end
134
 
135
assign o = mem[lineno];
136
assign ov[0] = valid0[lineno];
137
assign ov[1] = valid1[lineno];
138
assign ov[2] = valid2[lineno];
139
assign ov[3] = valid3[lineno];
140
assign ov[4] = valid4[lineno];
141
assign ov[5] = valid5[lineno];
142
assign ov[6] = valid6[lineno];
143
assign ov[7] = valid7[lineno];
144
assign ov[8] = valid8[lineno];
145
 
146
endmodule
147
 
148
// -----------------------------------------------------------------------------
149
// Fully associative (64 way) tag memory for L1 icache.
150
//
151
// -----------------------------------------------------------------------------
152
 
153
module FT64_L1_icache_camtag(rst, clk, nxt, wlineno, wr, wadr, adr, hit, lineno);
154
input rst;
155
input clk;
156
input nxt;
157
output [5:0] wlineno;
158
input wr;
159
input [37:0] adr;
160
input [37:0] wadr;
161
output hit;
162
output reg [5:0] lineno;
163
 
164
wire [35:0] wtagi = {9'b0,wadr[37:5]};
165
wire [35:0] tagi = {9'b0,adr[37:5]};
166
wire [63:0] match_addr;
167
 
168
reg [5:0] cntr;
169
always @(posedge clk)
170
if (rst)
171
     cntr <= 6'd0;
172
else begin
173
    if (nxt)  cntr <= cntr + 6'd1;
174
end
175
assign wlineno = cntr;
176
 
177
//wire [21:0] lfsro;
178
//lfsr #(22,22'h0ACE1) u1 (rst, clk, !(wr3|wr2|wr), 1'b0, lfsro);
179
 
180
cam36x64 u01 (rst, clk, wr, cntr[5:0], wtagi, tagi, match_addr);
181
assign hit = |match_addr;
182
 
183
integer n;
184
always @*
185
begin
186
lineno = 0;
187
for (n = 0; n < 64; n = n + 1)
188
    if (match_addr[n]) lineno = n;
189
end
190
 
191
endmodule
192
 
193
 
194
// -----------------------------------------------------------------------------
195
// Four way set associative tag memory for L1 cache.
196
// -----------------------------------------------------------------------------
197
 
198
module FT64_L1_icache_cmptag4way(rst, clk, nxt, wr, adr, lineno, hit);
199
parameter pLines = 64;
200
parameter AMSB = 63;
201
localparam pLNMSB = pLines==128 ? 6 : 5;
202
localparam pMSB = pLines==128 ? 9 : 8;
203
input rst;
204
input clk;
205
input nxt;
206
input wr;
207
input [AMSB+8:0] adr;
208
output reg [pLNMSB:0] lineno;
209
output hit;
210
 
211
(* ram_style="distributed" *)
212
reg [AMSB+8-5:0] mem0 [0:pLines/4-1];
213
reg [AMSB+8-5:0] mem1 [0:pLines/4-1];
214
reg [AMSB+8-5:0] mem2 [0:pLines/4-1];
215
reg [AMSB+8-5:0] mem3 [0:pLines/4-1];
216
reg [AMSB+8:0] rradr;
217
integer n;
218
initial begin
219
  for (n = 0; n < pLines/4; n = n + 1)
220
  begin
221
    mem0[n] = 0;
222
    mem1[n] = 0;
223
    mem2[n] = 0;
224
    mem3[n] = 0;
225
  end
226
end
227
 
228
wire [21:0] lfsro;
229
lfsr #(22,22'h0ACE3) u1 (rst, clk, nxt, 1'b0, lfsro);
230
reg [pLNMSB:0] wlineno;
231
always @(posedge clk)
232
if (rst)
233
        wlineno <= 6'h00;
234
else begin
235
        if (wr) begin
236
                case(lfsro[1:0])
237
                2'b00:  begin  mem0[adr[pMSB:5]] <= adr[AMSB+8:5];  wlineno <= {2'b00,adr[pMSB:5]}; end
238
                2'b01:  begin  mem1[adr[pMSB:5]] <= adr[AMSB+8:5];  wlineno <= {2'b01,adr[pMSB:5]}; end
239
                2'b10:  begin  mem2[adr[pMSB:5]] <= adr[AMSB+8:5];  wlineno <= {2'b10,adr[pMSB:5]}; end
240
                2'b11:  begin  mem3[adr[pMSB:5]] <= adr[AMSB+8:5];  wlineno <= {2'b11,adr[pMSB:5]}; end
241
                endcase
242
        end
243
end
244
 
245
wire hit0 = mem0[adr[pMSB:5]]==adr[AMSB+8:5];
246
wire hit1 = mem1[adr[pMSB:5]]==adr[AMSB+8:5];
247
wire hit2 = mem2[adr[pMSB:5]]==adr[AMSB+8:5];
248
wire hit3 = mem3[adr[pMSB:5]]==adr[AMSB+8:5];
249
always @*
250
    //if (wr2) lineno = wlineno;
251
    if (hit0)  lineno = {2'b00,adr[pMSB:5]};
252
    else if (hit1)  lineno = {2'b01,adr[pMSB:5]};
253
    else if (hit2)  lineno = {2'b10,adr[pMSB:5]};
254
    else  lineno = {2'b11,adr[pMSB:5]};
255
assign hit = hit0|hit1|hit2|hit3;
256
endmodule
257
 
258
 
259
// -----------------------------------------------------------------------------
260
// 32 way, 16 set associative tag memory for L2 cache
261
// -----------------------------------------------------------------------------
262
 
263
module FT64_L2_icache_camtag(rst, clk, wr, adr, hit, lineno);
264
parameter AMSB=63;
265
input rst;
266
input clk;
267
input wr;
268
input [AMSB+8:0] adr;
269
output hit;
270
output [8:0] lineno;
271
 
272
wire [3:0] set = adr[13:10];
273
wire [AMSB+8-5:0] tagi = {7'd0,adr[AMSB+8:14],adr[9:5]};
274
reg [4:0] encadr;
275
assign lineno[4:0] = encadr;
276
assign lineno[8:5] = adr[13:10];
277
reg [15:0] we;
278
wire [31:0] ma [0:15];
279
always @*
280
begin
281
    we <= 16'h0000;
282
    we[set] <= wr;
283
end
284
 
285
reg wr2;
286
wire [21:0] lfsro;
287
lfsr #(22,22'h0ACE2) u1 (rst, clk, !(wr2|wr), 1'b0, lfsro);
288
 
289
always @(posedge clk)
290
     wr2 <= wr;
291
 
292
genvar g;
293
generate
294
begin
295
for (g = 0; g < 16; g = g + 1)
296
    cam36x32 u01 (clk, we[g], lfsro[4:0], tagi, tagi, ma[g]);
297
end
298
endgenerate
299
wire [31:0] match_addr = ma[set];
300
assign hit = |match_addr;
301
 
302
integer n;
303
always @*
304
begin
305
encadr = 0;
306
for (n = 0; n < 32; n = n + 1)
307
    if (match_addr[n]) encadr = n;
308
end
309
 
310
endmodule
311
 
312
// -----------------------------------------------------------------------------
313
// -----------------------------------------------------------------------------
314
 
315
module FT64_L1_icache(rst, clk, nxt, wr, wr_ack, en, wadr, adr, i, o, fault, hit, invall, invline);
316
parameter pSize = 2;
317
parameter CAMTAGS = 1'b0;   // 32 way
318
parameter FOURWAY = 1'b1;
319
parameter AMSB = 63;
320
localparam pLines = pSize==4 ? 128 : 64;
321
localparam pLNMSB = pSize==4 ? 6 : 5;
322
input rst;
323
input clk;
324
input nxt;
325
input wr;
326
output wr_ack;
327
input [8:0] en;
328
input [AMSB+8:0] adr;
329
input [AMSB+8:0] wadr;
330
input [297:0] i;
331
output reg [55:0] o;
332
output reg [1:0] fault;
333
output hit;
334
input invall;
335
input invline;
336
 
337
wire [297:0] ic;
338
reg [297:0] i1, i2;
339
wire [8:0] lv;                           // line valid
340
wire [pLNMSB:0] lineno;
341
wire [pLNMSB:0] wlineno;
342
wire taghit;
343
reg wr1,wr2;
344
reg [8:0] en1, en2;
345
reg invline1, invline2;
346
 
347
// Must update the cache memory on the cycle after a write to the tag memmory.
348
// Otherwise lineno won't be valid. Tag memory takes two clock cycles to update.
349
always @(posedge clk)
350
        wr1 <= wr;
351
always @(posedge clk)
352
        wr2 <= wr1;
353
always @(posedge clk)
354
        i1 <= i[297:0];
355
always @(posedge clk)
356
        i2 <= i1;
357
always @(posedge clk)
358
        en1 <= en;
359
always @(posedge clk)
360
        en2 <= en1;
361
always @(posedge clk)
362
        invline1 <= invline;
363
always @(posedge clk)
364
        invline2 <= invline1;
365
 
366
generate begin : tags
367
if (FOURWAY) begin
368
 
369
FT64_L1_icache_mem #(.pLines(pLines)) u1
370
(
371
    .rst(rst),
372
    .clk(clk),
373
    .wr(wr1),
374
    .en(en1),
375
    .i(i1),
376
    .lineno(lineno),
377
    .o(ic),
378
    .ov(lv),
379
    .invall(invall),
380
    .invline(invline1)
381
);
382
 
383
FT64_L1_icache_cmptag4way #(.pLines(pLines)) u3
384
(
385
        .rst(rst),
386
        .clk(clk),
387
        .nxt(nxt),
388
        .wr(wr),
389
        .adr(adr),
390
        .lineno(lineno),
391
        .hit(taghit)
392
);
393
end
394
else if (CAMTAGS) begin
395
 
396
FT64_L1_icache_mem u1
397
(
398
    .rst(rst),
399
    .clk(clk),
400
    .wr(wr2),
401
    .en(en2),
402
    .i(i2),
403
    .lineno(lineno),
404
    .o(ic),
405
    .ov(lv),
406
    .invall(invall),
407
    .invline(invline2)
408
);
409
 
410
FT64_L1_icache_camtag u2
411
(
412
    .rst(rst),
413
    .clk(clk),
414
    .nxt(nxt),
415
    .wlineno(wlineno),
416
    .wadr(wadr),
417
    .wr(wr),
418
    .adr(adr),
419
    .lineno(lineno),
420
    .hit(taghit)
421
);
422
end
423
end
424
endgenerate
425
 
426
// Valid if a 64-bit area encompassing a potential 48-bit instruction is valid.
427
assign hit = taghit & lv[adr[4:2]] & lv[adr[4:2]+4'd1];
428
 
429
//always @(radr or ic0 or ic1)
430
always @(adr or ic)
431
        o <= ic >> {adr[4:0],3'h0};
432
always @*
433
        fault <= ic[297:296];
434
 
435
assign wr_ack = wr2;
436
 
437
endmodule
438
 
439
// -----------------------------------------------------------------------------
440
// -----------------------------------------------------------------------------
441
 
442
module FT64_L2_icache_mem(clk, wr, lineno, sel, i, fault, o, ov, invall, invline);
443
input clk;
444
input wr;
445
input [8:0] lineno;
446
input [2:0] sel;
447
input [63:0] i;
448
input [1:0] fault;
449
output [297:0] o;
450
output reg ov;
451
input invall;
452
input invline;
453
 
454
(* ram_style="block" *)
455
reg [63:0] mem0 [0:511];
456
reg [63:0] mem1 [0:511];
457
reg [63:0] mem2 [0:511];
458
reg [63:0] mem3 [0:511];
459
reg [39:0] mem4 [0:511];
460
reg [1:0] memf [0:511];
461
reg [511:0] valid;
462
reg [8:0] rrcl;
463
 
464
//  instruction parcels per cache line
465
wire [8:0] cache_line;
466
integer n;
467
initial begin
468
    for (n = 0; n < 512; n = n + 1) begin
469
        valid[n] <= 0;
470
        memf[n] <= 2'b00;
471
    end
472
end
473
 
474
always @(posedge clk)
475
    if (invall)  valid <= 512'd0;
476
    else if (invline)  valid[lineno] <= 1'b0;
477
    else if (wr)  valid[lineno] <= 1'b1;
478
 
479
always @(posedge clk)
480
begin
481
    if (wr) begin
482
        case(sel[2:0])
483
        3'd0:    begin mem0[lineno] <= i; memf[lineno] <= fault; end
484
        3'd1:    begin mem1[lineno] <= i; memf[lineno] <= memf[lineno] | fault; end
485
        3'd2:    begin mem2[lineno] <= i; memf[lineno] <= memf[lineno] | fault; end
486
        3'd3:    begin mem3[lineno] <= i; memf[lineno] <= memf[lineno] | fault; end
487
        3'd4:    begin mem4[lineno] <= i[39:0]; memf[lineno] <= memf[lineno] | fault; end
488
        endcase
489
    end
490
end
491
 
492
always @(posedge clk)
493
     rrcl <= lineno;
494
 
495
always @(posedge clk)
496
     ov <= valid[lineno];
497
 
498
assign o = {memf[rrcl],mem4[rrcl],mem3[rrcl],mem2[rrcl],mem1[rrcl],mem0[rrcl]};
499
 
500
endmodule
501
 
502
// -----------------------------------------------------------------------------
503
// Because the line to update is driven by the output of the cam tag memory,
504
// the tag write should occur only during the first half of the line load.
505
// Otherwise the line number would change in the middle of the line. The
506
// first half of the line load is signified by an even hexibyte address (
507
// address bit 4).
508
// -----------------------------------------------------------------------------
509
 
510
module FT64_L2_icache(rst, clk, nxt, wr, wr_ack, rd_ack, xsel, adr, cnt, exv_i, i, err_i, o, hit, invall, invline);
511
parameter CAMTAGS = 1'b0;   // 32 way
512
parameter FOURWAY = 1'b1;
513
parameter AMSB = 63;
514
input rst;
515
input clk;
516
input nxt;
517
input wr;
518
output wr_ack;
519
output rd_ack;
520
input xsel;
521
input [AMSB+8:0] adr;
522
input [2:0] cnt;
523
input exv_i;
524
input [63:0] i;
525
input err_i;
526
output [297:0] o;
527
output hit;
528
input invall;
529
input invline;
530
 
531
wire lv;            // line valid
532
wire [8:0] lineno;
533
wire taghit;
534
reg wr1,wr2;
535
reg [2:0] sel1,sel2;
536
reg [63:0] i1,i2;
537
reg [1:0] f1, f2;
538
reg [AMSB+8:0] last_adr;
539
 
540
// Must update the cache memory on the cycle after a write to the tag memmory.
541
// Otherwise lineno won't be valid. camTag memory takes two clock cycles to update.
542
always @(posedge clk)
543
        wr1 <= wr;
544
always @(posedge clk)
545
        wr2 <= wr1;
546
always @(posedge clk)
547
        sel1 <= {xsel,adr[4:3]};
548
always @(posedge clk)
549
        sel2 <= sel1;
550
always @(posedge clk)
551
        last_adr <= adr;
552
always @(posedge clk)
553
        f1 <= {err_i,exv_i};
554
always @(posedge clk)
555
        f2 <= f1;
556
 
557
reg [3:0] rdackx;
558
always @(posedge clk)
559
if (rst)
560
        rdackx <= 4'b0;
561
else begin
562
        if (last_adr != adr || wr || wr1 || wr2)
563
                rdackx <= 4'b0;
564
        else
565
                rdackx <= {rdackx,~(wr|wr1|wr2)};
566
end
567
 
568
assign rd_ack = rdackx[3] & ~(last_adr!=adr || wr || wr1 || wr2);
569
 
570
always @(posedge clk)
571
     i1 <= i;
572
always @(posedge clk)
573
     i2 <= i1;
574
 
575
wire pe_wr;
576
edge_det u3 (.rst(rst), .clk(clk), .ce(1'b1), .i(wr && cnt==3'd0), .pe(pe_wr), .ne(), .ee() );
577
 
578
FT64_L2_icache_mem u1
579
(
580
        .clk(clk),
581
        .wr(wr2),
582
        .lineno(lineno),
583
        .sel(sel2),
584
        .i(i2),
585
        .fault(f2),
586
        .o(o),
587
        .ov(lv),
588
        .invall(invall),
589
        .invline(invline)
590
);
591
 
592
generate
593
begin : tags
594
if (FOURWAY)
595
FT64_L2_icache_cmptag4way u2
596
(
597
        .rst(rst),
598
        .clk(clk),
599
        .nxt(nxt),
600
        .wr(pe_wr),
601
        .adr(adr),
602
        .lineno(lineno),
603
        .hit(taghit)
604
);
605
else if (CAMTAGS)
606
FT64_L2_icache_camtag u2
607
(
608
        .rst(rst),
609
        .clk(clk),
610
        .wr(pe_wr),
611
        .adr(adr),
612
        .lineno(lineno),
613
        .hit(taghit)
614
);
615
else
616
FT64_L2_icache_cmptag u2
617
(
618
        .rst(rst),
619
        .clk(clk),
620
        .wr(pe_wr),
621
        .adr(adr),
622
        .lineno(lineno),
623
        .hit(taghit)
624
);
625
end
626
endgenerate
627
 
628
assign hit = taghit & lv;
629
assign wr_ack = wr2;
630
 
631
endmodule
632
 
633
// Four way set associative tag memory
634
module FT64_L2_icache_cmptag4way(rst, clk, nxt, wr, adr, lineno, hit);
635
parameter AMSB = 63;
636
input rst;
637
input clk;
638
input nxt;
639
input wr;
640
input [AMSB+8:0] adr;
641
output reg [8:0] lineno;
642
output hit;
643
 
644
(* ram_style="block" *)
645
reg [AMSB+8-5:0] mem0 [0:127];
646
reg [AMSB+8-5:0] mem1 [0:127];
647
reg [AMSB+8-5:0] mem2 [0:127];
648
reg [AMSB+8-5:0] mem3 [0:127];
649
reg [AMSB+8:0] rradr;
650
integer n;
651
initial begin
652
  for (n = 0; n < 128; n = n + 1)
653
  begin
654
    mem0[n] = 0;
655
    mem1[n] = 0;
656
    mem2[n] = 0;
657
    mem3[n] = 0;
658
  end
659
end
660
 
661
reg wr2;
662
wire [21:0] lfsro;
663
lfsr #(22,22'h0ACE3) u1 (rst, clk, nxt, 1'b0, lfsro);
664
reg [8:0] wlineno;
665
always @(posedge clk)
666
if (rst)
667
        wlineno <= 9'h000;
668
else begin
669
     wr2 <= wr;
670
        if (wr) begin
671
                case(lfsro[1:0])
672
                2'b00:  begin  mem0[adr[11:5]] <= adr[AMSB+8:5];  wlineno <= {2'b00,adr[11:5]}; end
673
                2'b01:  begin  mem1[adr[11:5]] <= adr[AMSB+8:5];  wlineno <= {2'b01,adr[11:5]}; end
674
                2'b10:  begin  mem2[adr[11:5]] <= adr[AMSB+8:5];  wlineno <= {2'b10,adr[11:5]}; end
675
                2'b11:  begin  mem3[adr[11:5]] <= adr[AMSB+8:5];  wlineno <= {2'b11,adr[11:5]}; end
676
                endcase
677
        end
678
     rradr <= adr;
679
end
680
 
681
wire hit0 = mem0[rradr[11:5]]==rradr[AMSB+8:5];
682
wire hit1 = mem1[rradr[11:5]]==rradr[AMSB+8:5];
683
wire hit2 = mem2[rradr[11:5]]==rradr[AMSB+8:5];
684
wire hit3 = mem3[rradr[11:5]]==rradr[AMSB+8:5];
685
always @*
686
    if (wr2) lineno = wlineno;
687
    else if (hit0)  lineno = {2'b00,rradr[11:5]};
688
    else if (hit1)  lineno = {2'b01,rradr[11:5]};
689
    else if (hit2)  lineno = {2'b10,rradr[11:5]};
690
    else  lineno = {2'b11,rradr[11:5]};
691
assign hit = hit0|hit1|hit2|hit3;
692
endmodule
693
 
694
// Simple tag array, 1-way direct mapped
695
module FT64_L2_icache_cmptag(rst, clk, wr, adr, lineno, hit);
696
parameter AMSB = 63;
697
input rst;
698
input clk;
699
input wr;
700
input [AMSB+8:0] adr;
701
output reg [8:0] lineno;
702
output hit;
703
 
704
reg [AMSB+8-14:0] mem [0:511];
705
reg [AMSB+8:0] rradr;
706
integer n;
707
initial begin
708
    for (n = 0; n < 512; n = n + 1)
709
    begin
710
        mem[n] = 0;
711
    end
712
end
713
 
714
reg wr2;
715
always @(posedge clk)
716
     wr2 <= wr;
717
reg [8:0] wlineno;
718
always @(posedge clk)
719
begin
720
    if (wr) begin  mem[adr[13:5]] <= adr[AMSB+8:14];  wlineno <= adr[13:5]; end
721
end
722
always @(posedge clk)
723
     rradr <= adr;
724
wire hit = mem[rradr[13:5]]==rradr[AMSB+8:14];
725
always @*
726
    if (wr2)  lineno = wlineno;
727
    else  lineno = rradr[13:5];
728
endmodule
729
 

powered by: WebSVN 2.1.0

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