Line 24... |
Line 24... |
//
|
//
|
// ============================================================================
|
// ============================================================================
|
//
|
//
|
`define TRUE 1'b1
|
`define TRUE 1'b1
|
`define FALSE 1'b0
|
`define FALSE 1'b0
|
`define BRK 6'd0
|
|
`define FLT_EXF 9'd497
|
|
`define FLT_IBE 9'd509
|
|
|
|
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
// Small, 64 line cache memory (2kiB) made from distributed RAM. Access is
|
// Small, 64 line cache memory (2kiB) made from distributed RAM. Access is
|
// 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 = 288;
|
parameter pLineWidth = 290;
|
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 [8:0] en;
|
Line 48... |
Line 45... |
output [pLineWidth-1:0] o;
|
output [pLineWidth-1:0] o;
|
output [8:0] ov;
|
output [8:0] ov;
|
input invall;
|
input invall;
|
input invline;
|
input invline;
|
|
|
|
integer n;
|
|
|
(* ram_style="distributed" *)
|
(* ram_style="distributed" *)
|
reg [pLineWidth-1:0] mem [0:pLines-1];
|
reg [pLineWidth-1:0] mem [0:pLines-1];
|
reg [pLines-1:0] valid0;
|
reg [pLines-1:0] valid0;
|
reg [pLines-1:0] valid1;
|
reg [pLines-1:0] valid1;
|
reg [pLines-1:0] valid2;
|
reg [pLines-1:0] valid2;
|
Line 60... |
Line 59... |
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;
|
|
|
|
initial begin
|
|
for (n = 0; n < pLines; n = n + 1)
|
|
mem[n][289:288] <= 2'b00;
|
|
end
|
|
|
always @(posedge clk)
|
always @(posedge clk)
|
if (wr & en[0]) mem[lineno][31:0] <= i[31:0];
|
if (wr & en[0]) mem[lineno][31:0] <= i[31:0];
|
always @(posedge clk)
|
always @(posedge clk)
|
if (wr & en[1]) mem[lineno][63:32] <= i[63:32];
|
if (wr & en[1]) mem[lineno][63:32] <= i[63:32];
|
always @(posedge clk)
|
always @(posedge clk)
|
Line 77... |
Line 81... |
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][287:256] <= i[287:256];
|
if (wr & en[8]) mem[lineno][289:256] <= i[289:256];
|
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 304... |
Line 308... |
endmodule
|
endmodule
|
|
|
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
|
|
module FT64_L1_icache(rst, clk, nxt, wr, wr_ack, en, wadr, adr, i, o, hit, invall, invline);
|
module FT64_L1_icache(rst, clk, nxt, wr, wr_ack, en, wadr, adr, i, o, fault, hit, invall, invline);
|
parameter pSize = 2;
|
parameter pSize = 2;
|
parameter CAMTAGS = 1'b0; // 32 way
|
parameter CAMTAGS = 1'b0; // 32 way
|
parameter FOURWAY = 1'b1;
|
parameter FOURWAY = 1'b1;
|
localparam pLines = pSize==4 ? 128 : 64;
|
localparam pLines = pSize==4 ? 128 : 64;
|
localparam pLNMSB = pSize==4 ? 6 : 5;
|
localparam pLNMSB = pSize==4 ? 6 : 5;
|
Line 318... |
Line 322... |
input wr;
|
input wr;
|
output wr_ack;
|
output wr_ack;
|
input [8:0] en;
|
input [8:0] en;
|
input [37:0] adr;
|
input [37:0] adr;
|
input [37:0] wadr;
|
input [37:0] wadr;
|
input [287:0] i;
|
input [289:0] i;
|
output reg [47:0] o;
|
output reg [47:0] o;
|
|
output reg [1:0] fault;
|
output hit;
|
output hit;
|
input invall;
|
input invall;
|
input invline;
|
input invline;
|
|
|
wire [287:0] ic;
|
wire [289:0] ic;
|
reg [287:0] i1, i2;
|
reg [289:0] i1, i2;
|
wire [8:0] lv; // line valid
|
wire [8: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;
|
Line 341... |
Line 346... |
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[287:0];
|
i1 <= i[289: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 419... |
Line 424... |
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:1],4'h0};
|
o <= ic >> {adr[4:1],4'h0};
|
|
always @*
|
|
fault <= ic[289:288];
|
|
|
assign wr_ack = wr2;
|
assign wr_ack = wr2;
|
|
|
endmodule
|
endmodule
|
|
|
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
|
|
module FT64_L2_icache_mem(clk, wr, lineno, sel, i, o, ov, invall, invline);
|
module FT64_L2_icache_mem(clk, wr, lineno, sel, i, fault, o, ov, invall, invline);
|
input clk;
|
input clk;
|
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;
|
output [287:0] o;
|
input [1:0] fault;
|
|
output [289: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 [31:0] mem4 [0:511];
|
reg [31:0] mem4 [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
|
wire [8:0] cache_line;
|
wire [8:0] cache_line;
|
integer n;
|
integer n;
|
initial begin
|
initial begin
|
for (n = 0; n < 512; n = n + 1)
|
for (n = 0; n < 512; n = n + 1) begin
|
valid[n] <= 0;
|
valid[n] <= 0;
|
|
memf[n] <= 2'b00;
|
|
end
|
end
|
end
|
|
|
always @(posedge clk)
|
always @(posedge clk)
|
if (invall) valid <= 512'd0;
|
if (invall) valid <= 512'd0;
|
else if (invline) valid[lineno] <= 1'b0;
|
else if (invline) valid[lineno] <= 1'b0;
|
Line 464... |
Line 475... |
|
|
always @(posedge clk)
|
always @(posedge clk)
|
begin
|
begin
|
if (wr) begin
|
if (wr) begin
|
case(sel[2:0])
|
case(sel[2:0])
|
3'd0: mem0[lineno] <= i;
|
3'd0: begin mem0[lineno] <= i; memf[lineno] <= fault; end
|
3'd1: mem1[lineno] <= i;
|
3'd1: begin mem1[lineno] <= i; memf[lineno] <= memf[lineno] | fault; end
|
3'd2: mem2[lineno] <= i;
|
3'd2: begin mem2[lineno] <= i; memf[lineno] <= memf[lineno] | fault; end
|
3'd3: mem3[lineno] <= i;
|
3'd3: begin mem3[lineno] <= i; memf[lineno] <= memf[lineno] | fault; end
|
3'd4: mem4[lineno] <= i[31:0];
|
3'd4: begin mem4[lineno] <= i[31:0]; memf[lineno] <= memf[lineno] | fault; end
|
endcase
|
endcase
|
end
|
end
|
end
|
end
|
|
|
always @(posedge clk)
|
always @(posedge clk)
|
rrcl <= lineno;
|
rrcl <= lineno;
|
|
|
always @(posedge clk)
|
always @(posedge clk)
|
ov <= valid[lineno];
|
ov <= valid[lineno];
|
|
|
assign o = {mem4[rrcl],mem3[rrcl],mem2[rrcl],mem1[rrcl],mem0[rrcl]};
|
assign o = {memf[rrcl],mem4[rrcl],mem3[rrcl],mem2[rrcl],mem1[rrcl],mem0[rrcl]};
|
|
|
endmodule
|
endmodule
|
|
|
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
// Because the line to update is driven by the output of the cam tag memory,
|
// Because the line to update is driven by the output of the cam tag memory,
|
Line 506... |
Line 517... |
input [37:0] adr;
|
input [37: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 [287:0] o;
|
output [289:0] o;
|
output hit;
|
output hit;
|
input invall;
|
input invall;
|
input invline;
|
input invline;
|
|
|
wire lv; // line valid
|
wire lv; // line valid
|
wire [8:0] lineno;
|
wire [8:0] lineno;
|
wire taghit;
|
wire taghit;
|
reg wr1,wr2;
|
reg wr1,wr2;
|
reg [2:0] sel1,sel2;
|
reg [2:0] sel1,sel2;
|
reg [63:0] i1,i2;
|
reg [63:0] i1,i2;
|
|
reg [1:0] f1, f2;
|
reg [37:0] last_adr;
|
reg [37:0] last_adr;
|
|
|
// 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. camTag memory takes two clock cycles to update.
|
// Otherwise lineno won't be valid. camTag memory takes two clock cycles to update.
|
always @(posedge clk)
|
always @(posedge clk)
|
Line 531... |
Line 543... |
sel1 <= {xsel,adr[4:3]};
|
sel1 <= {xsel,adr[4:3]};
|
always @(posedge clk)
|
always @(posedge clk)
|
sel2 <= sel1;
|
sel2 <= sel1;
|
always @(posedge clk)
|
always @(posedge clk)
|
last_adr <= adr;
|
last_adr <= adr;
|
|
always @(posedge clk)
|
|
f1 <= {err_i,exv_i};
|
|
always @(posedge clk)
|
|
f2 <= f1;
|
|
|
reg [3:0] rdackx;
|
reg [3:0] rdackx;
|
always @(posedge clk)
|
always @(posedge clk)
|
if (rst)
|
if (rst)
|
rdackx <= 4'b0;
|
rdackx <= 4'b0;
|
Line 545... |
Line 561... |
rdackx <= {rdackx,~(wr|wr1|wr2)};
|
rdackx <= {rdackx,~(wr|wr1|wr2)};
|
end
|
end
|
|
|
assign rd_ack = rdackx[3] & ~(last_adr!=adr || wr || wr1 || wr2);
|
assign rd_ack = rdackx[3] & ~(last_adr!=adr || wr || wr1 || wr2);
|
|
|
// An exception is forced to be stored in the event of an error loading the
|
|
// the instruction line.
|
|
always @(posedge clk)
|
always @(posedge clk)
|
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;
|
i1 <= i;
|
always @(posedge clk)
|
always @(posedge clk)
|
i2 <= i1;
|
i2 <= i1;
|
|
|
wire pe_wr;
|
wire pe_wr;
|
edge_det u3 (.rst(rst), .clk(clk), .ce(1'b1), .i(wr && cnt==3'd0), .pe(pe_wr), .ne(), .ee() );
|
edge_det u3 (.rst(rst), .clk(clk), .ce(1'b1), .i(wr && cnt==3'd0), .pe(pe_wr), .ne(), .ee() );
|
Line 562... |
Line 576... |
.clk(clk),
|
.clk(clk),
|
.wr(wr2),
|
.wr(wr2),
|
.lineno(lineno),
|
.lineno(lineno),
|
.sel(sel2),
|
.sel(sel2),
|
.i(i2),
|
.i(i2),
|
|
.fault(f2),
|
.o(o),
|
.o(o),
|
.ov(lv),
|
.ov(lv),
|
.invall(invall),
|
.invall(invall),
|
.invline(invline)
|
.invline(invline)
|
);
|
);
|