RVSCC/rtl/cache_controller.sv
Mario Romero 24a5622103
Some checks are pending
continuous-integration/drone/push Build is pending
Add 5 stage pipeline test and move timescale to include
2023-02-27 23:22:34 -03:00

93 lines
2.2 KiB
Systemverilog

`include "timescale.sv"
module cache_controller #(
parameter int ADDR_SIZE = 32,
parameter int NUM_SETS = 16,
parameter int NUM_WAYS = 4,
parameter int BLOCK_SIZE = 32
) (
input logic clk,
input logic [ADDR_SIZE - 1:0] addr,
input logic write_enable,
input logic replace_way,
input logic [NUM_WAYS - 1:0] hits,
input logic [NUM_WAYS - 1:0] valid_flags,
output logic [SetSize - 1:0] set,
output logic [TagSize - 1:0] tag,
output logic [WaySize - 1:0] way,
output logic hit,
output logic cru_enable
);
localparam int NumBlockBytes = BLOCK_SIZE / 4;
localparam int ByteOffsetSize = $clog2(NumBlockBytes);
localparam int SetSize = $clog2(NUM_SETS);
localparam int TagSize = ADDR_SIZE - SetSize - ByteOffsetSize;
localparam int WaySize = $clog2(NUM_WAYS);
typedef struct packed {
logic [ByteOffsetSize - 1:0] byte_offset;
logic [SetSize - 1:0] set;
logic [TagSize - 1:0] tag;
} cache_addr_t;
typedef enum logic [1:0] {
READ = 'b00,
WRITE_UNVALID = 'b10,
REPLACE = 'b11
} cache_state_t;
cache_addr packed_addr;
cache_state_t state;
logic [WaySize - 1:0] valid_encode, next_unvalid_way;
PriorityEncoder #(
.N(WaySize)
) valid_flags_encoder (
.data_in(valid_flags),
.data_out(valid_encode),
.valid(valid_flags_encoder_valid)
);
PriorityEncoder #(
.N(WaySize)
) read_way_encoder (
.data_in(hits),
.data_out(read_way),
.valid(read_way_encoder_valid)
);
logic valid;
always_comb begin
packed_addr = cache_addr'(addr);
set = packed_addr.set;
tag = packed_addr.tag;
hit = |hits;
valid = &valid_flags;
state = cache_state_t'{write_enable, valid};
case (state)
READ: begin
cru_enable = 0;
if (read_way_encoder_valid) way = read_way;
else way = 'd0;
end
WRITE_UNVALID: begin
cru_enable = 0;
way = next_unvalid_way;
end
REPLACE: begin
cru_enable = 1;
way = replace_way;
end
default: begin
cru_enable = 0;
way = 'dx;
end
endcase
if (valid_flags_encoder_valid) next_unvalid_way = valid_encode + 'd1;
else next_unvalid_way = 'd0;
end
endmodule