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

Subversion Repositories thor

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

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

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

powered by: WebSVN 2.1.0

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