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

60 lines
2.0 KiB
Systemverilog

`include "wally-config.vh"
module ICacheMem #(parameter NUMLINES=512, parameter BLOCKLEN = 256)
(
// Pipeline stuff
input logic clk,
input logic reset,
// If flush is high, invalidate the entire cache
input logic flush,
input logic [`PA_BITS-1:0] PCTagF, // physical address
input logic [`PA_BITS-1:0] PCNextIndexF, // virtual address
input logic WriteEnable,
input logic [BLOCKLEN-1:0] WriteLine,
output logic [BLOCKLEN-1:0] ReadLineF,
output logic HitF
);
// divide the address bus into sections; tag, index, and offset
localparam BLOCKBYTELEN = BLOCKLEN/8;
localparam OFFSETLEN = $clog2(BLOCKBYTELEN);
localparam INDEXLEN = $clog2(NUMLINES);
// *** BUG. `XLEN needs to be replaced with the virtual address width, S32, S39, or S48
localparam TAGLEN = `PA_BITS - OFFSETLEN - INDEXLEN;
logic [TAGLEN-1:0] LookupTag;
logic [NUMLINES-1:0] ValidOut;
logic DataValidBit;
// Depth is number of bits in one "word" of the memory, width is number of such words
sram1rw #(.DEPTH(BLOCKLEN), .WIDTH(NUMLINES))
cachemem (.*,
.Addr(PCNextIndexF[INDEXLEN+OFFSETLEN-1:OFFSETLEN]),
.ReadData(ReadLineF),
.WriteData(WriteLine)
);
sram1rw #(.DEPTH(TAGLEN), .WIDTH(NUMLINES))
cachetags (.*,
.Addr(PCNextIndexF[INDEXLEN+OFFSETLEN-1:OFFSETLEN]),
.ReadData(LookupTag),
.WriteData(PCTagF[`PA_BITS-1:INDEXLEN+OFFSETLEN])
);
// 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
ValidOut[PCNextIndexF[INDEXLEN+OFFSETLEN-1:OFFSETLEN]] <= 1;
end
end
DataValidBit <= ValidOut[PCNextIndexF[INDEXLEN+OFFSETLEN-1:OFFSETLEN]];
end
assign HitF = DataValidBit && (LookupTag == PCTagF[`PA_BITS-1:INDEXLEN+OFFSETLEN]);
endmodule