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

Subversion Repositories thor

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

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

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

powered by: WebSVN 2.1.0

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