Line 1... |
Line 1... |
// ============================================================================
|
// ============================================================================
|
// __
|
// __
|
// \\__/ o\ (C) 2017-2018 Robert Finch, Waterloo
|
// \\__/ o\ (C) 2017-2019 Robert Finch, Waterloo
|
// \ __ / All rights reserved.
|
// \ __ / All rights reserved.
|
// \/_// robfinch<remove>@finitron.ca
|
// \/_// robfinch<remove>@finitron.ca
|
// ||
|
// ||
|
//
|
//
|
// FT64_cache.v
|
// FT64_cache.v
|
Line 32... |
Line 32... |
// within a single clock cycle.
|
// within a single clock cycle.
|
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
|
|
module FT64_L1_icache_mem(rst, clk, wr, en, lineno, i, o, ov, invall, invline);
|
module FT64_L1_icache_mem(rst, clk, wr, en, lineno, i, o, ov, invall, invline);
|
parameter pLines = 64;
|
parameter pLines = 64;
|
parameter pLineWidth = 298;
|
parameter pLineWidth = 306;
|
localparam pLNMSB = pLines==128 ? 6 : 5;
|
localparam pLNMSB = pLines==128 ? 6 : 5;
|
input rst;
|
input rst;
|
input clk;
|
input clk;
|
input wr;
|
input wr;
|
input [8:0] en;
|
input [9:0] en;
|
input [pLNMSB:0] lineno;
|
input [pLNMSB:0] lineno;
|
input [pLineWidth-1:0] i;
|
input [pLineWidth-1:0] i;
|
output [pLineWidth-1:0] o;
|
output [pLineWidth-1:0] o;
|
output [8:0] ov;
|
output [9:0] ov;
|
input invall;
|
input invall;
|
input invline;
|
input invline;
|
|
|
integer n;
|
integer n;
|
|
|
Line 58... |
Line 58... |
reg [pLines-1:0] valid4;
|
reg [pLines-1:0] valid4;
|
reg [pLines-1:0] valid5;
|
reg [pLines-1:0] valid5;
|
reg [pLines-1:0] valid6;
|
reg [pLines-1:0] valid6;
|
reg [pLines-1:0] valid7;
|
reg [pLines-1:0] valid7;
|
reg [pLines-1:0] valid8;
|
reg [pLines-1:0] valid8;
|
|
reg [pLines-1:0] valid9;
|
|
|
initial begin
|
initial begin
|
for (n = 0; n < pLines; n = n + 1)
|
for (n = 0; n < pLines; n = n + 1)
|
mem[n] <= 2'b00;
|
mem[n] <= 2'b00;
|
end
|
end
|
Line 81... |
Line 82... |
always @(posedge clk)
|
always @(posedge clk)
|
if (wr & en[6]) mem[lineno][223:192] <= i[223:192];
|
if (wr & en[6]) mem[lineno][223:192] <= i[223:192];
|
always @(posedge clk)
|
always @(posedge clk)
|
if (wr & en[7]) mem[lineno][255:224] <= i[255:224];
|
if (wr & en[7]) mem[lineno][255:224] <= i[255:224];
|
always @(posedge clk)
|
always @(posedge clk)
|
if (wr & en[8]) mem[lineno][297:256] <= i[297:256];
|
if (wr & en[8]) mem[lineno][287:256] <= i[287:256];
|
|
always @(posedge clk)
|
|
if (wr & en[9]) mem[lineno][305:288] <= i[305:288];
|
always @(posedge clk)
|
always @(posedge clk)
|
if (rst) begin
|
if (rst) begin
|
valid0 <= 64'd0;
|
valid0 <= 64'd0;
|
valid1 <= 64'd0;
|
valid1 <= 64'd0;
|
valid2 <= 64'd0;
|
valid2 <= 64'd0;
|
Line 93... |
Line 96... |
valid4 <= 64'd0;
|
valid4 <= 64'd0;
|
valid5 <= 64'd0;
|
valid5 <= 64'd0;
|
valid6 <= 64'd0;
|
valid6 <= 64'd0;
|
valid7 <= 64'd0;
|
valid7 <= 64'd0;
|
valid8 <= 64'd0;
|
valid8 <= 64'd0;
|
|
valid9 <= 64'd0;
|
end
|
end
|
else begin
|
else begin
|
if (invall) begin
|
if (invall) begin
|
valid0 <= 64'd0;
|
valid0 <= 64'd0;
|
valid1 <= 64'd0;
|
valid1 <= 64'd0;
|
Line 105... |
Line 109... |
valid4 <= 64'd0;
|
valid4 <= 64'd0;
|
valid5 <= 64'd0;
|
valid5 <= 64'd0;
|
valid6 <= 64'd0;
|
valid6 <= 64'd0;
|
valid7 <= 64'd0;
|
valid7 <= 64'd0;
|
valid8 <= 64'd0;
|
valid8 <= 64'd0;
|
|
valid9 <= 64'd0;
|
end
|
end
|
else if (invline) begin
|
else if (invline) begin
|
valid0[lineno] <= 1'b0;
|
valid0[lineno] <= 1'b0;
|
valid1[lineno] <= 1'b0;
|
valid1[lineno] <= 1'b0;
|
valid2[lineno] <= 1'b0;
|
valid2[lineno] <= 1'b0;
|
Line 116... |
Line 121... |
valid4[lineno] <= 1'b0;
|
valid4[lineno] <= 1'b0;
|
valid5[lineno] <= 1'b0;
|
valid5[lineno] <= 1'b0;
|
valid6[lineno] <= 1'b0;
|
valid6[lineno] <= 1'b0;
|
valid7[lineno] <= 1'b0;
|
valid7[lineno] <= 1'b0;
|
valid8[lineno] <= 1'b0;
|
valid8[lineno] <= 1'b0;
|
|
valid9[lineno] <= 1'b0;
|
end
|
end
|
else if (wr) begin
|
else if (wr) begin
|
if (en[0]) valid0[lineno] <= 1'b1;
|
if (en[0]) valid0[lineno] <= 1'b1;
|
if (en[1]) valid1[lineno] <= 1'b1;
|
if (en[1]) valid1[lineno] <= 1'b1;
|
if (en[2]) valid2[lineno] <= 1'b1;
|
if (en[2]) valid2[lineno] <= 1'b1;
|
Line 127... |
Line 133... |
if (en[4]) valid4[lineno] <= 1'b1;
|
if (en[4]) valid4[lineno] <= 1'b1;
|
if (en[5]) valid5[lineno] <= 1'b1;
|
if (en[5]) valid5[lineno] <= 1'b1;
|
if (en[6]) valid6[lineno] <= 1'b1;
|
if (en[6]) valid6[lineno] <= 1'b1;
|
if (en[7]) valid7[lineno] <= 1'b1;
|
if (en[7]) valid7[lineno] <= 1'b1;
|
if (en[8]) valid8[lineno] <= 1'b1;
|
if (en[8]) valid8[lineno] <= 1'b1;
|
|
if (en[9]) valid9[lineno] <= 1'b1;
|
end
|
end
|
end
|
end
|
|
|
assign o = mem[lineno];
|
assign o = mem[lineno];
|
assign ov[0] = valid0[lineno];
|
assign ov[0] = valid0[lineno];
|
Line 140... |
Line 147... |
assign ov[4] = valid4[lineno];
|
assign ov[4] = valid4[lineno];
|
assign ov[5] = valid5[lineno];
|
assign ov[5] = valid5[lineno];
|
assign ov[6] = valid6[lineno];
|
assign ov[6] = valid6[lineno];
|
assign ov[7] = valid7[lineno];
|
assign ov[7] = valid7[lineno];
|
assign ov[8] = valid8[lineno];
|
assign ov[8] = valid8[lineno];
|
|
assign ov[9] = valid9[lineno];
|
|
|
endmodule
|
endmodule
|
|
|
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
// Fully associative (64 way) tag memory for L1 icache.
|
// Fully associative (64 way) tag memory for L1 icache.
|
Line 212... |
Line 220... |
reg [AMSB+8-5:0] mem0 [0:pLines/4-1];
|
reg [AMSB+8-5:0] mem0 [0:pLines/4-1];
|
reg [AMSB+8-5:0] mem1 [0:pLines/4-1];
|
reg [AMSB+8-5:0] mem1 [0:pLines/4-1];
|
reg [AMSB+8-5:0] mem2 [0:pLines/4-1];
|
reg [AMSB+8-5:0] mem2 [0:pLines/4-1];
|
reg [AMSB+8-5:0] mem3 [0:pLines/4-1];
|
reg [AMSB+8-5:0] mem3 [0:pLines/4-1];
|
reg [AMSB+8:0] rradr;
|
reg [AMSB+8:0] rradr;
|
|
reg [pLines/4-1:0] mem0v;
|
|
reg [pLines/4-1:0] mem1v;
|
|
reg [pLines/4-1:0] mem2v;
|
|
reg [pLines/4-1:0] mem3v;
|
integer n;
|
integer n;
|
initial begin
|
initial begin
|
for (n = 0; n < pLines/4; n = n + 1)
|
for (n = 0; n < pLines/4; n = n + 1)
|
begin
|
begin
|
mem0[n] = 0;
|
mem0[n] = 0;
|
Line 240... |
Line 252... |
2'b11: begin mem3[adr[pMSB:5]] <= adr[AMSB+8:5]; wlineno <= {2'b11,adr[pMSB:5]}; end
|
2'b11: begin mem3[adr[pMSB:5]] <= adr[AMSB+8:5]; wlineno <= {2'b11,adr[pMSB:5]}; end
|
endcase
|
endcase
|
end
|
end
|
end
|
end
|
|
|
wire hit0 = mem0[adr[pMSB:5]]==adr[AMSB+8:5];
|
always @(posedge clk)
|
wire hit1 = mem1[adr[pMSB:5]]==adr[AMSB+8:5];
|
if (rst) begin
|
wire hit2 = mem2[adr[pMSB:5]]==adr[AMSB+8:5];
|
mem0v <= 1'd0;
|
wire hit3 = mem3[adr[pMSB:5]]==adr[AMSB+8:5];
|
mem1v <= 1'd0;
|
|
mem2v <= 1'd0;
|
|
mem3v <= 1'd0;
|
|
end
|
|
else begin
|
|
if (wr) begin
|
|
case(lfsro[1:0])
|
|
2'b00: begin mem0v[adr[pMSB:5]] <= 1'b1; end
|
|
2'b01: begin mem1v[adr[pMSB:5]] <= 1'b1; end
|
|
2'b10: begin mem2v[adr[pMSB:5]] <= 1'b1; end
|
|
2'b11: begin mem3v[adr[pMSB:5]] <= 1'b1; end
|
|
endcase
|
|
end
|
|
end
|
|
|
|
|
|
wire hit0 = mem0[adr[pMSB:5]]==adr[AMSB+8:5] & mem0v[adr[pMSB:5]];
|
|
wire hit1 = mem1[adr[pMSB:5]]==adr[AMSB+8:5] & mem1v[adr[pMSB:5]];
|
|
wire hit2 = mem2[adr[pMSB:5]]==adr[AMSB+8:5] & mem2v[adr[pMSB:5]];
|
|
wire hit3 = mem3[adr[pMSB:5]]==adr[AMSB+8:5] & mem3v[adr[pMSB:5]];
|
always @*
|
always @*
|
//if (wr2) lineno = wlineno;
|
//if (wr2) lineno = wlineno;
|
if (hit0) lineno = {2'b00,adr[pMSB:5]};
|
if (hit0) lineno = {2'b00,adr[pMSB:5]};
|
else if (hit1) lineno = {2'b01,adr[pMSB:5]};
|
else if (hit1) lineno = {2'b01,adr[pMSB:5]};
|
else if (hit2) lineno = {2'b10,adr[pMSB:5]};
|
else if (hit2) lineno = {2'b10,adr[pMSB:5]};
|
Line 322... |
Line 353... |
input rst;
|
input rst;
|
input clk;
|
input clk;
|
input nxt;
|
input nxt;
|
input wr;
|
input wr;
|
output wr_ack;
|
output wr_ack;
|
input [8:0] en;
|
input [9:0] en;
|
input [AMSB+8:0] adr;
|
input [AMSB+8:0] adr;
|
input [AMSB+8:0] wadr;
|
input [AMSB+8:0] wadr;
|
input [297:0] i;
|
input [305:0] i;
|
output reg [55:0] o;
|
output reg [55:0] o;
|
output reg [1:0] fault;
|
output reg [1:0] fault;
|
output hit;
|
output hit;
|
input invall;
|
input invall;
|
input invline;
|
input invline;
|
|
|
wire [297:0] ic;
|
wire [305:0] ic;
|
reg [297:0] i1, i2;
|
reg [305:0] i1, i2;
|
wire [8:0] lv; // line valid
|
wire [9:0] lv; // line valid
|
wire [pLNMSB:0] lineno;
|
wire [pLNMSB:0] lineno;
|
wire [pLNMSB:0] wlineno;
|
wire [pLNMSB:0] wlineno;
|
wire taghit;
|
wire taghit;
|
reg wr1,wr2;
|
reg wr1,wr2;
|
reg [8:0] en1, en2;
|
reg [9:0] en1, en2;
|
reg invline1, invline2;
|
reg invline1, invline2;
|
|
|
// Must update the cache memory on the cycle after a write to the tag memmory.
|
// Must update the cache memory on the cycle after a write to the tag memmory.
|
// Otherwise lineno won't be valid. Tag memory takes two clock cycles to update.
|
// Otherwise lineno won't be valid. Tag memory takes two clock cycles to update.
|
always @(posedge clk)
|
always @(posedge clk)
|
wr1 <= wr;
|
wr1 <= wr;
|
always @(posedge clk)
|
always @(posedge clk)
|
wr2 <= wr1;
|
wr2 <= wr1;
|
always @(posedge clk)
|
always @(posedge clk)
|
i1 <= i[297:0];
|
i1 <= i[305:0];
|
always @(posedge clk)
|
always @(posedge clk)
|
i2 <= i1;
|
i2 <= i1;
|
always @(posedge clk)
|
always @(posedge clk)
|
en1 <= en;
|
en1 <= en;
|
always @(posedge clk)
|
always @(posedge clk)
|
Line 422... |
Line 453... |
end
|
end
|
end
|
end
|
endgenerate
|
endgenerate
|
|
|
// Valid if a 64-bit area encompassing a potential 48-bit instruction is valid.
|
// Valid if a 64-bit area encompassing a potential 48-bit instruction is valid.
|
assign hit = taghit & lv[adr[4:2]] & lv[adr[4:2]+4'd1];
|
assign hit = taghit & |lv;//[adr[4:2]];// & lv[adr[4:2]+4'd1];
|
|
|
//always @(radr or ic0 or ic1)
|
//always @(radr or ic0 or ic1)
|
always @(adr or ic)
|
always @(adr or ic)
|
o <= ic >> {adr[4:0],3'h0};
|
o <= ic >> {adr[4:0],3'h0};
|
always @*
|
always @*
|
fault <= ic[297:296];
|
fault <= ic[305:304];
|
|
|
assign wr_ack = wr2;
|
assign wr_ack = wr2;
|
|
|
endmodule
|
endmodule
|
|
|
Line 444... |
Line 475... |
input wr;
|
input wr;
|
input [8:0] lineno;
|
input [8:0] lineno;
|
input [2:0] sel;
|
input [2:0] sel;
|
input [63:0] i;
|
input [63:0] i;
|
input [1:0] fault;
|
input [1:0] fault;
|
output [297:0] o;
|
output [305:0] o;
|
output reg ov;
|
output reg ov;
|
input invall;
|
input invall;
|
input invline;
|
input invline;
|
|
|
(* ram_style="block" *)
|
(* ram_style="block" *)
|
reg [63:0] mem0 [0:511];
|
reg [63:0] mem0 [0:511];
|
reg [63:0] mem1 [0:511];
|
reg [63:0] mem1 [0:511];
|
reg [63:0] mem2 [0:511];
|
reg [63:0] mem2 [0:511];
|
reg [63:0] mem3 [0:511];
|
reg [63:0] mem3 [0:511];
|
reg [39:0] mem4 [0:511];
|
reg [47:0] mem4 [0:511];
|
reg [1:0] memf [0:511];
|
reg [1:0] memf [0:511];
|
reg [511:0] valid;
|
reg [511:0] valid;
|
reg [8:0] rrcl;
|
reg [8:0] rrcl;
|
|
|
// instruction parcels per cache line
|
// instruction parcels per cache line
|
Line 482... |
Line 513... |
case(sel[2:0])
|
case(sel[2:0])
|
3'd0: begin mem0[lineno] <= i; memf[lineno] <= fault; end
|
3'd0: begin mem0[lineno] <= i; memf[lineno] <= fault; end
|
3'd1: begin mem1[lineno] <= i; memf[lineno] <= memf[lineno] | fault; end
|
3'd1: begin mem1[lineno] <= i; memf[lineno] <= memf[lineno] | fault; end
|
3'd2: begin mem2[lineno] <= i; memf[lineno] <= memf[lineno] | fault; end
|
3'd2: begin mem2[lineno] <= i; memf[lineno] <= memf[lineno] | fault; end
|
3'd3: begin mem3[lineno] <= i; memf[lineno] <= memf[lineno] | fault; end
|
3'd3: begin mem3[lineno] <= i; memf[lineno] <= memf[lineno] | fault; end
|
3'd4: begin mem4[lineno] <= i[39:0]; memf[lineno] <= memf[lineno] | fault; end
|
3'd4: begin mem4[lineno] <= i[47:0]; memf[lineno] <= memf[lineno] | fault; end
|
endcase
|
endcase
|
end
|
end
|
end
|
end
|
|
|
always @(posedge clk)
|
always @(posedge clk)
|
Line 521... |
Line 552... |
input [AMSB+8:0] adr;
|
input [AMSB+8:0] adr;
|
input [2:0] cnt;
|
input [2:0] cnt;
|
input exv_i;
|
input exv_i;
|
input [63:0] i;
|
input [63:0] i;
|
input err_i;
|
input err_i;
|
output [297:0] o;
|
output [305:0] o;
|
output hit;
|
output hit;
|
input invall;
|
input invall;
|
input invline;
|
input invline;
|
|
|
wire lv; // line valid
|
wire lv; // line valid
|