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

Subversion Repositories thor

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

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

powered by: WebSVN 2.1.0

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