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

Subversion Repositories thor

[/] [thor/] [trunk/] [FT64v5/] [rtl/] [common/] [FT64_cache.v] - Blame information for rev 57

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

Line No. Rev Author Line
1 48 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
`define BRK         6'd0
30
`define FLT_EXF     9'd497
31
`define FLT_IBE     9'd509
32
 
33
// -----------------------------------------------------------------------------
34
// Small, 64 line cache memory (2kiB) made from distributed RAM. Access is
35
// within a single clock cycle.
36
// -----------------------------------------------------------------------------
37
 
38
module FT64_L1_icache_mem(rst, clk, wr, en, lineno, i, o, ov, invall, invline);
39
parameter pLines = 64;
40 49 robfinch
parameter pLineWidth = 288;
41 48 robfinch
input rst;
42
input clk;
43
input wr;
44 49 robfinch
input [8:0] en;
45 48 robfinch
input [5:0] lineno;
46
input [pLineWidth-1:0] i;
47
output [pLineWidth-1:0] o;
48 49 robfinch
output [8:0] ov;
49 48 robfinch
input invall;
50
input invline;
51
 
52 49 robfinch
(* ram_style="distributed" *)
53 48 robfinch
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
always  @(posedge clk)
65
    if (wr & en[0])  mem[lineno][31:0] <= i[31:0];
66
always  @(posedge clk)
67
    if (wr & en[1])  mem[lineno][63:32] <= i[63:32];
68
always  @(posedge clk)
69
    if (wr & en[2])  mem[lineno][95:64] <= i[95:64];
70
always  @(posedge clk)
71
    if (wr & en[3])  mem[lineno][127:96] <= i[127:96];
72
always  @(posedge clk)
73
    if (wr & en[4])  mem[lineno][159:128] <= i[159:128];
74
always  @(posedge clk)
75
    if (wr & en[5])  mem[lineno][191:160] <= i[191:160];
76
always  @(posedge clk)
77
    if (wr & en[6])  mem[lineno][223:192] <= i[223:192];
78
always  @(posedge clk)
79
    if (wr & en[7])  mem[lineno][255:224] <= i[255:224];
80
always  @(posedge clk)
81
    if (wr & en[8])  mem[lineno][287:256] <= i[287:256];
82
always  @(posedge clk)
83
if (rst) begin
84
     valid0 <= 64'd0;
85
     valid1 <= 64'd0;
86
     valid2 <= 64'd0;
87
     valid3 <= 64'd0;
88
     valid4 <= 64'd0;
89
     valid5 <= 64'd0;
90
     valid6 <= 64'd0;
91
     valid7 <= 64'd0;
92
     valid8 <= 64'd0;
93
end
94
else begin
95
    if (invall) begin
96
        valid0 <= 64'd0;
97
        valid1 <= 64'd0;
98
        valid2 <= 64'd0;
99
        valid3 <= 64'd0;
100
        valid4 <= 64'd0;
101
        valid5 <= 64'd0;
102
        valid6 <= 64'd0;
103
        valid7 <= 64'd0;
104
                        valid8 <= 64'd0;
105
    end
106
    else if (invline) begin
107
        valid0[lineno] <= 1'b0;
108
        valid1[lineno] <= 1'b0;
109
        valid2[lineno] <= 1'b0;
110
        valid3[lineno] <= 1'b0;
111
        valid4[lineno] <= 1'b0;
112
        valid5[lineno] <= 1'b0;
113
        valid6[lineno] <= 1'b0;
114
        valid7[lineno] <= 1'b0;
115
        valid8[lineno] <= 1'b0;
116
        end
117
    else if (wr) begin
118
        if (en[0]) valid0[lineno] <= 1'b1;
119
        if (en[1]) valid1[lineno] <= 1'b1;
120
        if (en[2]) valid2[lineno] <= 1'b1;
121
        if (en[3]) valid3[lineno] <= 1'b1;
122
        if (en[4]) valid4[lineno] <= 1'b1;
123
        if (en[5]) valid5[lineno] <= 1'b1;
124
        if (en[6]) valid6[lineno] <= 1'b1;
125
        if (en[7]) valid7[lineno] <= 1'b1;
126
        if (en[8]) valid8[lineno] <= 1'b1;
127
    end
128
end
129
 
130
assign o = mem[lineno];
131
assign ov[0] = valid0[lineno];
132
assign ov[1] = valid1[lineno];
133
assign ov[2] = valid2[lineno];
134
assign ov[3] = valid3[lineno];
135
assign ov[4] = valid4[lineno];
136
assign ov[5] = valid5[lineno];
137
assign ov[6] = valid6[lineno];
138
assign ov[7] = valid7[lineno];
139
assign ov[8] = valid8[lineno];
140
 
141
endmodule
142
 
143
// -----------------------------------------------------------------------------
144
// Fully associative (64 way) tag memory for L1 icache.
145
//
146
// -----------------------------------------------------------------------------
147
 
148
module FT64_L1_icache_camtag(rst, clk, nxt, wlineno, wr, wadr, adr, hit, lineno);
149
input rst;
150
input clk;
151
input nxt;
152
output [5:0] wlineno;
153
input wr;
154
input [37:0] adr;
155
input [37:0] wadr;
156
output hit;
157
output reg [5:0] lineno;
158
 
159
wire [35:0] wtagi = {9'b0,wadr[37:5]};
160
wire [35:0] tagi = {9'b0,adr[37:5]};
161
wire [63:0] match_addr;
162
 
163
reg [5:0] cntr;
164
always @(posedge clk)
165
if (rst)
166
     cntr <= 6'd0;
167
else begin
168
    if (nxt)  cntr <= cntr + 6'd1;
169
end
170
assign wlineno = cntr;
171
 
172
//wire [21:0] lfsro;
173
//lfsr #(22,22'h0ACE1) u1 (rst, clk, !(wr3|wr2|wr), 1'b0, lfsro);
174
 
175
cam36x64 u01 (rst, clk, wr, cntr[5:0], wtagi, tagi, match_addr);
176
assign hit = |match_addr;
177
 
178
integer n;
179
always @*
180
begin
181
lineno = 0;
182
for (n = 0; n < 64; n = n + 1)
183
    if (match_addr[n]) lineno = n;
184
end
185
 
186
endmodule
187
 
188
 
189
// -----------------------------------------------------------------------------
190
// Four way set associative tag memory for L1 cache.
191
// -----------------------------------------------------------------------------
192
 
193
module FT64_L1_icache_cmptag4way(rst, clk, nxt, wr, adr, lineno, hit);
194
input rst;
195
input clk;
196
input nxt;
197
input wr;
198
input [37:0] adr;
199
output reg [5:0] lineno;
200
output hit;
201
 
202 49 robfinch
(* ram_style="distributed" *)
203 48 robfinch
reg [32:0] mem0 [0:15];
204
reg [32:0] mem1 [0:15];
205
reg [32:0] mem2 [0:15];
206
reg [32:0] mem3 [0:15];
207
reg [37:0] rradr;
208
integer n;
209
initial begin
210
    for (n = 0; n < 16; n = n + 1)
211
    begin
212
        mem0[n] = 0;
213
        mem1[n] = 0;
214
        mem2[n] = 0;
215
        mem3[n] = 0;
216
    end
217
end
218
 
219
wire [21:0] lfsro;
220
lfsr #(22,22'h0ACE3) u1 (rst, clk, nxt, 1'b0, lfsro);
221
reg [5:0] wlineno;
222
always @(posedge clk)
223
if (rst)
224
        wlineno <= 6'h00;
225
else begin
226
        if (wr) begin
227
                case(lfsro[1:0])
228
                2'b00:  begin  mem0[adr[8:5]] <= adr[37:5];  wlineno <= {2'b00,adr[8:5]}; end
229
                2'b01:  begin  mem1[adr[8:5]] <= adr[37:5];  wlineno <= {2'b01,adr[8:5]}; end
230
                2'b10:  begin  mem2[adr[8:5]] <= adr[37:5];  wlineno <= {2'b10,adr[8:5]}; end
231
                2'b11:  begin  mem3[adr[8:5]] <= adr[37:5];  wlineno <= {2'b11,adr[8:5]}; end
232
                endcase
233
        end
234
end
235
 
236
wire hit0 = mem0[adr[8:5]]==adr[37:5];
237
wire hit1 = mem1[adr[8:5]]==adr[37:5];
238
wire hit2 = mem2[adr[8:5]]==adr[37:5];
239
wire hit3 = mem3[adr[8:5]]==adr[37:5];
240
always @*
241
    //if (wr2) lineno = wlineno;
242
    if (hit0)  lineno = {2'b00,adr[8:5]};
243
    else if (hit1)  lineno = {2'b01,adr[8:5]};
244
    else if (hit2)  lineno = {2'b10,adr[8:5]};
245
    else  lineno = {2'b11,adr[8:5]};
246
assign hit = hit0|hit1|hit2|hit3;
247
endmodule
248
 
249
 
250
// -----------------------------------------------------------------------------
251
// 32 way, 16 set associative tag memory for L2 cache
252
// -----------------------------------------------------------------------------
253
 
254
module FT64_L2_icache_camtag(rst, clk, wr, adr, hit, lineno);
255
input rst;
256
input clk;
257
input wr;
258
input [37:0] adr;
259
output hit;
260
output [8:0] lineno;
261
 
262
wire [3:0] set = adr[13:10];
263
wire [35:0] tagi = {7'd0,adr[37:14],adr[9:5]};
264
reg [4:0] encadr;
265
assign lineno[4:0] = encadr;
266
assign lineno[8:5] = adr[13:10];
267
reg [15:0] we;
268
wire [31:0] ma [0:15];
269
always @*
270
begin
271
    we <= 16'h0000;
272
    we[set] <= wr;
273
end
274
 
275
reg wr2;
276
wire [21:0] lfsro;
277
lfsr #(22,22'h0ACE2) u1 (rst, clk, !(wr2|wr), 1'b0, lfsro);
278
 
279
always @(posedge clk)
280
     wr2 <= wr;
281
 
282
genvar g;
283
generate
284
begin
285
for (g = 0; g < 16; g = g + 1)
286
    cam36x32 u01 (clk, we[g], lfsro[4:0], tagi, tagi, ma[g]);
287
end
288
endgenerate
289
wire [31:0] match_addr = ma[set];
290
assign hit = |match_addr;
291
 
292
integer n;
293
always @*
294
begin
295
encadr = 0;
296
for (n = 0; n < 32; n = n + 1)
297
    if (match_addr[n]) encadr = n;
298
end
299
 
300
endmodule
301
 
302
// -----------------------------------------------------------------------------
303
// -----------------------------------------------------------------------------
304
 
305 53 robfinch
module FT64_L1_icache(rst, clk, nxt, wr, wr_ack, en, wadr, adr, i, o, hit, invall, invline);
306 48 robfinch
parameter CAMTAGS = 1'b0;   // 32 way
307
parameter FOURWAY = 1'b1;
308
input rst;
309
input clk;
310
input nxt;
311
input wr;
312 53 robfinch
output wr_ack;
313 49 robfinch
input [8:0] en;
314 48 robfinch
input [37:0] adr;
315
input [37:0] wadr;
316 49 robfinch
input [287:0] i;
317 48 robfinch
output reg [47:0] o;
318
output hit;
319
input invall;
320
input invline;
321
 
322 49 robfinch
wire [287:0] ic;
323
reg [287:0] i1, i2;
324
wire [8:0] lv;                           // line valid
325 48 robfinch
wire [5:0] lineno;
326
wire [5:0] wlineno;
327
wire taghit;
328
reg wr1,wr2;
329 49 robfinch
reg [8:0] en1, en2;
330 48 robfinch
reg invline1, invline2;
331
 
332
// Must update the cache memory on the cycle after a write to the tag memmory.
333
// Otherwise lineno won't be valid. Tag memory takes two clock cycles to update.
334
always @(posedge clk)
335 53 robfinch
        wr1 <= wr;
336 48 robfinch
always @(posedge clk)
337 53 robfinch
        wr2 <= wr1;
338 48 robfinch
always @(posedge clk)
339 49 robfinch
        i1 <= i[287:0];
340 48 robfinch
always @(posedge clk)
341
        i2 <= i1;
342
always @(posedge clk)
343
        en1 <= en;
344
always @(posedge clk)
345
        en2 <= en1;
346
always @(posedge clk)
347
        invline1 <= invline;
348
always @(posedge clk)
349
        invline2 <= invline1;
350
 
351
generate begin : tags
352
if (FOURWAY) begin
353
 
354
FT64_L1_icache_mem u1
355
(
356
    .rst(rst),
357
    .clk(clk),
358
    .wr(wr1),
359
    .en(en1),
360
    .i(i1),
361
    .lineno(lineno),
362
    .o(ic),
363
    .ov(lv),
364
    .invall(invall),
365
    .invline(invline1)
366
);
367
 
368
FT64_L1_icache_cmptag4way u3
369
(
370
        .rst(rst),
371
        .clk(clk),
372
        .nxt(nxt),
373
        .wr(wr),
374
        .adr(adr),
375
        .lineno(lineno),
376
        .hit(taghit)
377
);
378
end
379
else if (CAMTAGS) begin
380
 
381
FT64_L1_icache_mem u1
382
(
383
    .rst(rst),
384
    .clk(clk),
385
    .wr(wr2),
386
    .en(en2),
387
    .i(i2),
388
    .lineno(lineno),
389
    .o(ic),
390
    .ov(lv),
391
    .invall(invall),
392
    .invline(invline2)
393
);
394
 
395
FT64_L1_icache_camtag u2
396
(
397
    .rst(rst),
398
    .clk(clk),
399
    .nxt(nxt),
400
    .wlineno(wlineno),
401
    .wadr(wadr),
402
    .wr(wr),
403
    .adr(adr),
404
    .lineno(lineno),
405
    .hit(taghit)
406
);
407
end
408
end
409
endgenerate
410
 
411 53 robfinch
// Valid if a 64-bit area encompassing a potential 48-bit instruction is valid.
412
assign hit = taghit & lv[adr[4:2]] & lv[adr[4:2]+4'd1];
413 48 robfinch
 
414
//always @(radr or ic0 or ic1)
415
always @(adr or ic)
416
        o <= ic >> {adr[4:1],4'h0};
417 53 robfinch
 
418
assign wr_ack = wr2;
419
 
420 48 robfinch
endmodule
421
 
422
// -----------------------------------------------------------------------------
423
// -----------------------------------------------------------------------------
424
 
425
module FT64_L2_icache_mem(clk, wr, lineno, sel, i, o, ov, invall, invline);
426
input clk;
427
input wr;
428
input [8:0] lineno;
429
input [2:0] sel;
430
input [63:0] i;
431 49 robfinch
output [287:0] o;
432 48 robfinch
output reg ov;
433
input invall;
434
input invline;
435
 
436 49 robfinch
(* ram_style="block" *)
437 48 robfinch
reg [63:0] mem0 [0:511];
438
reg [63:0] mem1 [0:511];
439
reg [63:0] mem2 [0:511];
440
reg [63:0] mem3 [0:511];
441 49 robfinch
reg [31:0] mem4 [0:511];
442 48 robfinch
reg [511:0] valid;
443
reg [8:0] rrcl;
444
 
445
//  instruction parcels per cache line
446
wire [8:0] cache_line;
447
integer n;
448
initial begin
449
    for (n = 0; n < 512; n = n + 1)
450
        valid[n] <= 0;
451
end
452
 
453
always @(posedge clk)
454
    if (invall)  valid <= 512'd0;
455
    else if (invline)  valid[lineno] <= 1'b0;
456
    else if (wr)  valid[lineno] <= 1'b1;
457
 
458
always @(posedge clk)
459
begin
460
    if (wr) begin
461
        case(sel[2:0])
462
        3'd0:    mem0[lineno] <= i;
463
        3'd1:    mem1[lineno] <= i;
464
        3'd2:    mem2[lineno] <= i;
465
        3'd3:    mem3[lineno] <= i;
466 49 robfinch
        3'd4:    mem4[lineno] <= i[31:0];
467 48 robfinch
        endcase
468
    end
469
end
470
 
471
always @(posedge clk)
472
     rrcl <= lineno;
473
 
474
always @(posedge clk)
475
     ov <= valid[lineno];
476
 
477
assign o = {mem4[rrcl],mem3[rrcl],mem2[rrcl],mem1[rrcl],mem0[rrcl]};
478
 
479
endmodule
480
 
481
// -----------------------------------------------------------------------------
482
// Because the line to update is driven by the output of the cam tag memory,
483
// the tag write should occur only during the first half of the line load.
484
// Otherwise the line number would change in the middle of the line. The
485
// first half of the line load is signified by an even hexibyte address (
486
// address bit 4).
487
// -----------------------------------------------------------------------------
488
 
489 53 robfinch
module FT64_L2_icache(rst, clk, nxt, wr, wr_ack, rd_ack, xsel, adr, cnt, exv_i, i, err_i, o, hit, invall, invline);
490 48 robfinch
parameter CAMTAGS = 1'b0;   // 32 way
491
parameter FOURWAY = 1'b1;
492
input rst;
493
input clk;
494
input nxt;
495
input wr;
496 53 robfinch
output wr_ack;
497
output rd_ack;
498 48 robfinch
input xsel;
499
input [37:0] adr;
500
input [2:0] cnt;
501
input exv_i;
502
input [63:0] i;
503
input err_i;
504 49 robfinch
output [287:0] o;
505 48 robfinch
output hit;
506
input invall;
507
input invline;
508
 
509
wire lv;            // line valid
510
wire [8:0] lineno;
511
wire taghit;
512
reg wr1,wr2;
513
reg [2:0] sel1,sel2;
514
reg [63:0] i1,i2;
515 53 robfinch
reg [37:0] last_adr;
516 48 robfinch
 
517
// Must update the cache memory on the cycle after a write to the tag memmory.
518
// Otherwise lineno won't be valid. camTag memory takes two clock cycles to update.
519
always @(posedge clk)
520 53 robfinch
        wr1 <= wr;
521 48 robfinch
always @(posedge clk)
522 53 robfinch
        wr2 <= wr1;
523 48 robfinch
always @(posedge clk)
524 53 robfinch
        sel1 <= {xsel,adr[4:3]};
525 48 robfinch
always @(posedge clk)
526 53 robfinch
        sel2 <= sel1;
527
always @(posedge clk)
528
        last_adr <= adr;
529
 
530
reg [3:0] rdackx;
531
always @(posedge clk)
532
if (rst)
533
        rdackx <= 4'b0;
534
else begin
535
        if (last_adr != adr || wr || wr1 || wr2)
536
                rdackx <= 4'b0;
537
        else
538
                rdackx <= {rdackx,~(wr|wr1|wr2)};
539
end
540
 
541
assign rd_ack = rdackx[3] & ~(last_adr!=adr || wr || wr1 || wr2);
542
 
543 48 robfinch
// An exception is forced to be stored in the event of an error loading the
544
// the instruction line.
545
always @(posedge clk)
546 49 robfinch
     i1 <= err_i ? {2{15'd0,1'b0,`FLT_IBE,2'b00,`BRK}} : exv_i ? {2{15'd0,1'b0,`FLT_EXF,2'b00,`BRK}} : i;
547 48 robfinch
always @(posedge clk)
548
     i2 <= i1;
549
 
550
wire pe_wr;
551
edge_det u3 (.rst(rst), .clk(clk), .ce(1'b1), .i(wr && cnt==3'd0), .pe(pe_wr), .ne(), .ee() );
552
 
553
FT64_L2_icache_mem u1
554
(
555 53 robfinch
        .clk(clk),
556
        .wr(wr2),
557
        .lineno(lineno),
558
        .sel(sel2),
559
        .i(i2),
560
        .o(o),
561
        .ov(lv),
562
        .invall(invall),
563
        .invline(invline)
564 48 robfinch
);
565
 
566
generate
567
begin : tags
568
if (FOURWAY)
569
FT64_L2_icache_cmptag4way u2
570
(
571 53 robfinch
        .rst(rst),
572
        .clk(clk),
573
        .nxt(nxt),
574
        .wr(pe_wr),
575
        .adr(adr),
576
        .lineno(lineno),
577
        .hit(taghit)
578 48 robfinch
);
579
else if (CAMTAGS)
580
FT64_L2_icache_camtag u2
581
(
582 53 robfinch
        .rst(rst),
583
        .clk(clk),
584
        .wr(pe_wr),
585
        .adr(adr),
586
        .lineno(lineno),
587
        .hit(taghit)
588 48 robfinch
);
589
else
590
FT64_L2_icache_cmptag u2
591
(
592 53 robfinch
        .rst(rst),
593
        .clk(clk),
594
        .wr(pe_wr),
595
        .adr(adr),
596
        .lineno(lineno),
597
        .hit(taghit)
598 48 robfinch
);
599
end
600
endgenerate
601
 
602
assign hit = taghit & lv;
603 53 robfinch
assign wr_ack = wr2;
604 48 robfinch
 
605
endmodule
606
 
607
// Four way set associative tag memory
608
module FT64_L2_icache_cmptag4way(rst, clk, nxt, wr, adr, lineno, hit);
609
input rst;
610
input clk;
611
input nxt;
612
input wr;
613
input [37:0] adr;
614
output reg [8:0] lineno;
615
output hit;
616
 
617 49 robfinch
(* ram_style="block" *)
618 48 robfinch
reg [32:0] mem0 [0:127];
619
reg [32:0] mem1 [0:127];
620
reg [32:0] mem2 [0:127];
621
reg [32:0] mem3 [0:127];
622
reg [37:0] rradr;
623
integer n;
624
initial begin
625
    for (n = 0; n < 128; n = n + 1)
626
    begin
627
        mem0[n] = 0;
628
        mem1[n] = 0;
629
        mem2[n] = 0;
630
        mem3[n] = 0;
631
    end
632
end
633
 
634
reg wr2;
635
wire [21:0] lfsro;
636
lfsr #(22,22'h0ACE3) u1 (rst, clk, nxt, 1'b0, lfsro);
637
reg [8:0] wlineno;
638
always @(posedge clk)
639
if (rst)
640
        wlineno <= 9'h000;
641
else begin
642
     wr2 <= wr;
643
        if (wr) begin
644
                case(lfsro[1:0])
645
                2'b00:  begin  mem0[adr[11:5]] <= adr[37:5];  wlineno <= {2'b00,adr[11:5]}; end
646
                2'b01:  begin  mem1[adr[11:5]] <= adr[37:5];  wlineno <= {2'b01,adr[11:5]}; end
647
                2'b10:  begin  mem2[adr[11:5]] <= adr[37:5];  wlineno <= {2'b10,adr[11:5]}; end
648
                2'b11:  begin  mem3[adr[11:5]] <= adr[37:5];  wlineno <= {2'b11,adr[11:5]}; end
649
                endcase
650
        end
651
     rradr <= adr;
652
end
653
 
654
wire hit0 = mem0[rradr[11:5]]==rradr[37:5];
655
wire hit1 = mem1[rradr[11:5]]==rradr[37:5];
656
wire hit2 = mem2[rradr[11:5]]==rradr[37:5];
657
wire hit3 = mem3[rradr[11:5]]==rradr[37:5];
658
always @*
659
    if (wr2) lineno = wlineno;
660
    else if (hit0)  lineno = {2'b00,rradr[11:5]};
661
    else if (hit1)  lineno = {2'b01,rradr[11:5]};
662
    else if (hit2)  lineno = {2'b10,rradr[11:5]};
663
    else  lineno = {2'b11,rradr[11:5]};
664
assign hit = hit0|hit1|hit2|hit3;
665
endmodule
666
 
667
// Simple tag array, 1-way direct mapped
668
module FT64_L2_icache_cmptag(rst, clk, wr, adr, lineno, hit);
669
input rst;
670
input clk;
671
input wr;
672
input [37:0] adr;
673
output reg [8:0] lineno;
674
output hit;
675
 
676
reg [23:0] mem [0:511];
677
reg [37:0] rradr;
678
integer n;
679
initial begin
680
    for (n = 0; n < 512; n = n + 1)
681
    begin
682
        mem[n] = 0;
683
    end
684
end
685
 
686
reg wr2;
687
always @(posedge clk)
688
     wr2 <= wr;
689
reg [8:0] wlineno;
690
always @(posedge clk)
691
begin
692
    if (wr) begin  mem[adr[13:5]] <= adr[37:14];  wlineno <= adr[13:5]; end
693
end
694
always @(posedge clk)
695
     rradr <= adr;
696
wire hit = mem[rradr[13:5]]==rradr[37:14];
697
always @*
698
    if (wr2)  lineno = wlineno;
699
    else  lineno = rradr[13:5];
700
endmodule
701
 
702
// -----------------------------------------------------------------------------
703
// -----------------------------------------------------------------------------
704
 
705
module FT64_dcache_mem(wclk, wr, wadr, i, rclk, radr, o0, o1);
706
input wclk;
707
input wr;
708
input [11:0] wadr;
709
input [63:0] i;
710
input rclk;
711
input [11:0] radr;
712
output [255:0] o0;
713
output [255:0] o1;
714
 
715
reg [11:0] rradr,rradrp8;
716
 
717
always @(posedge rclk)
718
     rradr <= radr;
719
always @(posedge rclk)
720
     rradrp8 <= radr + 14'd8;
721
 
722
genvar n;
723
generate
724
begin
725
for (n = 0; n < 8; n = n + 1)
726
begin : dmem
727
reg [7:0] mem [7:0][0:511];
728
always @(posedge wclk)
729
begin
730
    if (wr && (wadr[2:0]==n))  mem[n][wadr[11:3]] <= i;
731
end
732
assign o0[n*32+31:n*32] = mem[n][rradr[11:3]];
733
assign o1[n*32+31:n*32] = mem[n][rradrp8[11:3]];
734
end
735
end
736
endgenerate
737
 
738
endmodule
739
 
740
// -----------------------------------------------------------------------------
741
// -----------------------------------------------------------------------------
742
 
743 57 robfinch
module FT64_dcache_tag(wclk, wr, wadr, rclk, radr, whit, hit0, hit1);
744 48 robfinch
input wclk;
745
input wr;
746
input [37:0] wadr;
747
input rclk;
748
input [37:0] radr;
749 57 robfinch
output reg whit;
750 48 robfinch
output reg hit0;
751
output reg hit1;
752
 
753
wire [31:0] tago0, tago1;
754 57 robfinch
wire [31:0] wtago;
755 48 robfinch
wire [37:0] radrp8 = radr + 32'd32;
756
 
757
FT64_dcache_tag2 u1 (
758
  .clka(wclk),    // input wire clka
759
  .ena(1'b1),      // input wire ena
760
  .wea(wr),      // input wire [0 : 0] wea
761
  .addra(wadr[13:5]),  // input wire [8 : 0] addra
762
  .dina(wadr[37:14]),    // input wire [31 : 0] dina
763 57 robfinch
  .douta(wtago),
764 48 robfinch
  .clkb(rclk),    // input wire clkb
765
  .web(1'b0),
766
  .dinb(32'd0),
767
  .enb(1'b1),
768
  .addrb(radr[13:5]),  // input wire [8 : 0] addrb
769
  .doutb(tago0)  // output wire [31 : 0] doutb
770
);
771
 
772
FT64_dcache_tag2 u2 (
773
  .clka(wclk),    // input wire clka
774
  .ena(1'b1),      // input wire ena
775
  .wea(wr),      // input wire [0 : 0] wea
776
  .addra(wadr[13:5]),  // input wire [8 : 0] addra
777
  .dina(wadr[37:14]),    // input wire [31 : 0] dina
778
  .clkb(rclk),    // input wire clkb
779
  .web(1'b0),
780
  .dinb(32'd0),
781
  .enb(1'b1),
782
  .addrb(radrp8[13:5]),  // input wire [8 : 0] addrb
783
  .doutb(tago1)  // output wire [31 : 0] doutb
784
);
785
 
786
always @(posedge rclk)
787
     hit0 <= tago0[23:0]==radr[37:14];
788
always @(posedge rclk)
789
     hit1 <= tago1[23:0]==radrp8[37:14];
790 57 robfinch
always @(posedge wclk)
791
                whit <= wtago[23:0]==wadr[37:14];
792 48 robfinch
 
793
endmodule
794
 
795
// -----------------------------------------------------------------------------
796
// -----------------------------------------------------------------------------
797
 
798 57 robfinch
module FT64_dcache(rst, wclk, wr, sel, wadr, whit, i, li, rclk, rdsize, radr, o, lo, hit, hit0, hit1);
799 48 robfinch
input rst;
800
input wclk;
801
input wr;
802
input [7:0] sel;
803
input [37:0] wadr;
804 57 robfinch
output whit;
805 48 robfinch
input [63:0] i;
806
input [255:0] li;                // line input
807
input rclk;
808
input [2:0] rdsize;
809
input [37:0] radr;
810
output reg [63:0] o;
811
output reg [255:0] lo;   // line out
812
output reg hit;
813
output reg hit0;
814
output reg hit1;
815
parameter byt = 3'd0;
816
parameter wyde = 3'd1;
817
parameter tetra = 3'd2;
818
parameter octa = 3'd3;
819
 
820
wire [255:0] dc0, dc1;
821
wire [31:0] v0, v1;
822
wire [13:0] radrp8 = radr + 32'd32;
823
wire hit0a, hit1a;
824
 
825
dcache_mem u1 (
826
  .rst(rst),
827
  .clka(wclk),    // input wire clka
828
  .ena(wr),      // input wire ena
829
  .wea(sel),      // input wire [15 : 0] wea
830
  .addra(wadr[13:0]),  // input wire [9 : 0] addra
831
  .dina(i),    // input wire [127 : 0] dina
832
  .clkb(rclk),    // input wire clkb
833
  .addrb(radr[13:0]),  // input wire [8 : 0] addrb
834
  .doutb(dc0),  // output wire [255 : 0] doutb
835
  .ov(v0)
836
);
837
 
838
dcache_mem u2 (
839
  .rst(rst),
840
  .clka(wclk),    // input wire clka
841
  .ena(wr),      // input wire ena
842
  .wea(sel),      // input wire [15 : 0] wea
843
  .addra(wadr[13:0]),  // input wire [9 : 0] addra
844
  .dina(i),    // input wire [127 : 0] dina
845
  .clkb(rclk),    // input wire clkb
846
  .addrb(radrp8[13:0]),  // input wire [8 : 0] addrb
847
  .doutb(dc1),  // output wire [255 : 0] doutb
848
  .ov(v1)
849
);
850
 
851
FT64_dcache_tag u3
852
(
853
    .wclk(wclk),
854
    .wr(wr),
855
    .wadr(wadr),
856
    .rclk(rclk),
857
    .radr(radr),
858 57 robfinch
    .whit(whit),
859 48 robfinch
    .hit0(hit0a),
860
    .hit1(hit1a)
861
);
862
 
863
wire [7:0] v0a = v0 >> radr[4:0];
864
wire [7:0] v1a = v1 >> radrp8[4:0];
865
always @*
866
case(rdsize)
867
byt:    begin
868
        hit0 = hit0a & v0a[0];
869
        hit1 = `TRUE;
870
        end
871
wyde:   begin
872
        hit0 = hit0a & &v0a[1:0];
873
        hit1 = radr[2:0]==3'b111 ? hit1a & v1a[0] : `TRUE;
874
        end
875
tetra:  begin
876
        hit0 = hit0a & &v0a[3:0];
877
        case(radr[2:0])
878
        3'd5:      hit1 = hit1a & v1a[0];
879
        3'd6:      hit1 = hit1a & &v1a[1:0];
880
        3'd7:      hit1 = hit1a & &v1a[2:0];
881
        default:   hit1 = `TRUE;
882
        endcase
883
        end
884
octa:   begin
885
        hit0 = hit0a & &v0a[7:0];
886
        case(radr[2:0])
887
        3'd1:      hit1 = hit1a & v1a[0];
888
        3'd2:      hit1 = hit1a & &v1a[1:0];
889
        3'd3:      hit1 = hit1a & &v1a[2:0];
890
        3'd4:      hit1 = hit1a & &v1a[3:0];
891
        3'd5:      hit1 = hit1a & &v1a[4:0];
892
        3'd6:      hit1 = hit1a & &v1a[5:0];
893
        3'd7:      hit1 = hit1a & &v1a[6:0];
894
        default:   hit1 = `TRUE;
895
        endcase
896
        end
897
default:    begin
898
            hit0 = 1'b0;
899
            hit1 = 1'b0;
900
            end
901
endcase
902
 
903
// hit0, hit1 are also delayed by a clock already
904
always @(posedge rclk)
905
        lo <= dc0;
906
always @(posedge rclk)
907
     o <= dc0 >> {radr[4:3],6'b0};
908
//     o <= {dc1,dc0} >> (radr[4:0] * 8);
909
 
910
always @*
911
    if (hit0 & hit1)
912
        hit = `TRUE;
913
/*
914
    else if (hit0) begin
915
        case(rdsize)
916
        wyde:   hit = radr[4:0] <= 5'h1E;
917
        tetra:  hit = radr[4:0] <= 5'h1C;
918
        penta:  hit = radr[4:0] <= 5'h1B;
919
        deci:   hit = radr[4:0] <= 5'h16;
920
        default:    hit = `TRUE;    // byte
921
        endcase
922
    end
923
*/
924
    else
925
        hit = `FALSE;
926
 
927
endmodule
928
 
929
module dcache_mem(rst, clka, ena, wea, addra, dina, clkb, addrb, doutb, ov);
930
input rst;
931
input clka;
932
input ena;
933
input [7:0] wea;
934
input [13:0] addra;
935
input [63:0] dina;
936
input clkb;
937
input [13:0] addrb;
938
output reg [255:0] doutb;
939
output reg [31:0] ov;
940
 
941
reg [255:0] mem [0:511];
942
reg [31:0] valid [0:511];
943
reg [255:0] doutb1;
944
reg [31:0] ov1;
945
 
946
integer n;
947
 
948
initial begin
949
    for (n = 0; n < 512; n = n + 1)
950
        valid[n] = 32'h00;
951
end
952
 
953
genvar g;
954
generate begin
955
for (g = 0; g < 4; g = g + 1)
956
always @(posedge clka)
957
begin
958
    if (ena & wea[0] & addra[4:3]==g)  mem[addra[13:5]][g*64+7:g*64] <= dina[7:0];
959
    if (ena & wea[1] & addra[4:3]==g)  mem[addra[13:5]][g*64+15:g*64+8] <= dina[15:8];
960
    if (ena & wea[2] & addra[4:3]==g)  mem[addra[13:5]][g*64+23:g*64+16] <= dina[23:16];
961
    if (ena & wea[3] & addra[4:3]==g)  mem[addra[13:5]][g*64+31:g*64+24] <= dina[31:24];
962
    if (ena & wea[4] & addra[4:3]==g)  mem[addra[13:5]][g*64+39:g*64+32] <= dina[39:32];
963
    if (ena & wea[5] & addra[4:3]==g)  mem[addra[13:5]][g*64+47:g*64+40] <= dina[47:40];
964
    if (ena & wea[6] & addra[4:3]==g)  mem[addra[13:5]][g*64+55:g*64+48] <= dina[55:48];
965
    if (ena & wea[7] & addra[4:3]==g)  mem[addra[13:5]][g*64+63:g*64+56] <= dina[63:56];
966
    if (ena & wea[0] & addra[4:3]==g)  valid[addra[13:5]][g*8] <= 1'b1;
967
    if (ena & wea[1] & addra[4:3]==g)  valid[addra[13:5]][g*8+1] <= 1'b1;
968
    if (ena & wea[2] & addra[4:3]==g)  valid[addra[13:5]][g*8+2] <= 1'b1;
969
    if (ena & wea[3] & addra[4:3]==g)  valid[addra[13:5]][g*8+3] <= 1'b1;
970
    if (ena & wea[4] & addra[4:3]==g)  valid[addra[13:5]][g*8+4] <= 1'b1;
971
    if (ena & wea[5] & addra[4:3]==g)  valid[addra[13:5]][g*8+5] <= 1'b1;
972
    if (ena & wea[6] & addra[4:3]==g)  valid[addra[13:5]][g*8+6] <= 1'b1;
973
    if (ena & wea[7] & addra[4:3]==g)  valid[addra[13:5]][g*8+7] <= 1'b1;
974
end
975
end
976
endgenerate
977
always @(posedge clkb)
978
     doutb1 <= mem[addrb[13:5]];
979
always @(posedge clkb)
980
     doutb <= doutb1;
981
always @(posedge clkb)
982
     ov1 <= valid[addrb[13:5]];
983
always @(posedge clkb)
984
     ov <= ov1;
985
endmodule
986
 
987
// -----------------------------------------------------------------------------
988
// Branch target buffer.
989
// -----------------------------------------------------------------------------
990
/*
991
module FT64_BTB(rst, wclk, wr, wadr, wdat, valid, rclk, pcA, btgtA, pcB, btgtB, pcC, btgtC, pcD, btgtD);
992
parameter RSTPC = 32'hFFFC0100;
993
input rst;
994
input wclk;
995
input wr;
996
input [31:0] wadr;
997
input [31:0] wdat;
998
input valid;
999
input rclk;
1000
input [31:0] pcA;
1001
output [31:0] btgtA;
1002
input [31:0] pcB;
1003
output [31:0] btgtB;
1004
input [31:0] pcC;
1005
output [31:0] btgtC;
1006
input [31:0] pcD;
1007
output [31:0] btgtD;
1008
 
1009
integer n;
1010
reg [60:0] mem [0:1023];
1011
reg [9:0] radrA, radrB, radrC, radrD;
1012
initial begin
1013
    for (n = 0; n < 1024; n = n + 1)
1014
        mem[n] <= RSTPC[31:2];
1015
end
1016
always @(posedge wclk)
1017
//if (rst) begin
1018
//    // Zero out valid bit
1019
//    for (n = 0; n < 1024; n = n + 1)
1020
//        mem[n] <= RSTPC[31:2];
1021
//end
1022
//else
1023
begin
1024
    if (wr) mem[wadr[11:2]][29:0] <= wdat[31:2];
1025
    if (wr) mem[wadr[11:2]][59:30] <= wadr[31:2];
1026
    if (wr) mem[wadr[11:2]][60] <= valid;
1027
end
1028
always @(posedge rclk)
1029
    radrA <= pcA[11:2];
1030
always @(posedge rclk)
1031
    radrB <= pcB[11:2];
1032
always @(posedge rclk)
1033
    radrC <= pcC[11:2];
1034
always @(posedge rclk)
1035
    radrD <= pcD[11:2];
1036
wire hitA = mem[radrA][59:30]==pcA[31:2] && mem[radrA][60];
1037
wire hitB = mem[radrB][59:30]==pcB[31:2] && mem[radrB][60];
1038
wire hitC = mem[radrC][59:30]==pcC[31:2] && mem[radrC][60];
1039
wire hitD = mem[radrD][59:30]==pcD[31:2] && mem[radrD][60];
1040
assign btgtA = hitA ? {mem[radrA][29:0],2'b00} : {pcA + 32'd4};
1041
assign btgtB = hitB ? {mem[radrB][29:0],2'b00} : {pcB + 32'd4};
1042
assign btgtC = hitC ? {mem[radrC][29:0],2'b00} : {pcC + 32'd4};
1043
assign btgtD = hitD ? {mem[radrD][29:0],2'b00} : {pcD + 32'd4};
1044
 
1045
endmodule
1046
*/

powered by: WebSVN 2.1.0

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