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

Subversion Repositories thor

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

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

powered by: WebSVN 2.1.0

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