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

Subversion Repositories thor

[/] [thor/] [trunk/] [FT64/] [rtl/] [common/] [FT64_cache.v] - Blame information for rev 43

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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