cvw/wally-pipelined/src/cache/ICacheMem.sv

105 lines
3.6 KiB
Systemverilog
Raw Normal View History

`include "wally-config.vh"
2021-06-04 17:41:02 +00:00
module ICacheMem #(parameter NUMLINES=512, parameter BLOCKLEN = 256) (
// Pipeline stuff
2021-05-03 19:36:09 +00:00
input logic clk,
input logic reset,
// If flush is high, invalidate the entire cache
2021-05-03 19:36:09 +00:00
input logic flush,
// Select which address to read (broken for efficiency's sake)
2021-05-03 19:36:09 +00:00
input logic [`XLEN-1:0] PCTagF, // physical tag address
input logic [`XLEN-1:0] PCNextIndexF,
// Write new data to the cache
2021-05-03 19:36:09 +00:00
input logic WriteEnable,
2021-06-04 17:41:02 +00:00
input logic [BLOCKLEN-1:0] WriteLine,
// Output the word, as well as if it is valid
2021-06-04 17:41:02 +00:00
output logic [31:0] DataWord, // *** was `XLEN-1
2021-05-03 19:36:09 +00:00
output logic DataValid
);
// Various compile-time constants
2021-06-04 17:41:02 +00:00
localparam integer WORDWIDTH = $clog2(`XLEN/8);
localparam integer OFFSETWIDTH = $clog2(BLOCKLEN/`XLEN);
localparam integer SETWIDTH = $clog2(NUMLINES);
localparam integer TAGWIDTH = `XLEN - OFFSETWIDTH - SETWIDTH - WORDWIDTH;
localparam integer OFFSETBEGIN = WORDWIDTH;
localparam integer OFFSETEND = OFFSETBEGIN+OFFSETWIDTH-1;
localparam integer SETBEGIN = OFFSETEND+1;
localparam integer SETEND = SETBEGIN + SETWIDTH - 1;
localparam integer TAGBEGIN = SETEND + 1;
localparam integer TAGEND = TAGBEGIN + TAGWIDTH - 1;
// Machinery to read from and write to the correct addresses in memory
2021-06-04 17:41:02 +00:00
logic [BLOCKLEN-1:0] ReadLine;
logic [BLOCKLEN/`XLEN-1:0][`XLEN-1:0] ReadLineTransformed;
// Machinery to check if a given read is valid and is the desired value
logic [TAGWIDTH-1:0] DataTag;
logic [NUMLINES-1:0] ValidOut;
logic DataValidBit;
// Depth is number of bits in one "word" of the memory, width is number of such words
2021-06-04 17:41:02 +00:00
sram1rw #(.DEPTH(BLOCKLEN), .WIDTH(NUMLINES)) cachemem (
.*,
2021-05-03 19:36:09 +00:00
.Addr(PCNextIndexF[SETEND:SETBEGIN]),
.ReadData(ReadLine),
.WriteData(WriteLine)
);
2021-05-03 19:36:09 +00:00
sram1rw #(.DEPTH(TAGWIDTH), .WIDTH(NUMLINES)) cachetags (
.*,
2021-05-03 19:36:09 +00:00
.Addr(PCNextIndexF[SETEND:SETBEGIN]),
.ReadData(DataTag),
2021-05-03 19:36:09 +00:00
.WriteData(PCTagF[TAGEND:TAGBEGIN])
);
// Pick the right bits coming out the read line
//assign DataWord = ReadLineTransformed[ReadOffset];
//logic [31:0] tempRD;
always_comb begin
2021-05-03 19:36:09 +00:00
case (PCTagF[4:1])
0: DataWord = ReadLine[31:0];
1: DataWord = ReadLine[47:16];
2: DataWord = ReadLine[63:32];
3: DataWord = ReadLine[79:48];
4: DataWord = ReadLine[95:64];
5: DataWord = ReadLine[111:80];
6: DataWord = ReadLine[127:96];
7: DataWord = ReadLine[143:112];
8: DataWord = ReadLine[159:128];
9: DataWord = ReadLine[175:144];
10: DataWord = ReadLine[191:160];
11: DataWord = ReadLine[207:176];
12: DataWord = ReadLine[223:192];
13: DataWord = ReadLine[239:208];
14: DataWord = ReadLine[255:224];
15: DataWord = {16'b0, ReadLine[255:240]};
endcase
end
genvar i;
generate
2021-06-04 17:41:02 +00:00
for (i=0; i < BLOCKLEN/`XLEN; i++) begin
assign ReadLineTransformed[i] = ReadLine[(i+1)*`XLEN-1:i*`XLEN];
end
endgenerate
// Correctly handle the valid bits
always_ff @(posedge clk, posedge reset) begin
if (reset) begin
ValidOut <= {NUMLINES{1'b0}};
end else if (flush) begin
ValidOut <= {NUMLINES{1'b0}};
end else begin
if (WriteEnable) begin
2021-05-03 19:36:09 +00:00
ValidOut[PCNextIndexF[SETEND:SETBEGIN]] <= 1;
end
end
2021-05-03 19:36:09 +00:00
DataValidBit <= ValidOut[PCNextIndexF[SETEND:SETBEGIN]];
end
2021-05-03 19:36:09 +00:00
assign DataValid = DataValidBit && (DataTag == PCTagF[TAGEND:TAGBEGIN]);
endmodule