First shot at happy path
This commit is contained in:
192
src/application_wrapper/cache/application_wrapper_cache_miss_handler.sv
vendored
Normal file
192
src/application_wrapper/cache/application_wrapper_cache_miss_handler.sv
vendored
Normal file
@@ -0,0 +1,192 @@
|
|||||||
|
module application_wrapper_cache_miss_handler #(
|
||||||
|
parameter NUM_WAYS = 4,
|
||||||
|
parameter NUM_SETS = 64,
|
||||||
|
|
||||||
|
localparam CPU_W = 8,
|
||||||
|
localparam DATA_W = 64*8,
|
||||||
|
localparam OFFSET_W = 6,
|
||||||
|
localparam INDEX_W = $clog2(NUM_SETS),
|
||||||
|
localparam TAG_W = 32 - INDEX_W - OFFSET_W,
|
||||||
|
localparam LRU_W = NUM_WAYS-1
|
||||||
|
|
||||||
|
localparam META_W = TAG_W + 2
|
||||||
|
) (
|
||||||
|
input logic i_clk,
|
||||||
|
input logic i_rst,
|
||||||
|
|
||||||
|
// NOTE: tag is physical tag, expected 1 cycle after the index and the offset
|
||||||
|
input logic [TAG_W-1:0] i_cpu_tag,
|
||||||
|
input logic [INDEX_W-1:0] i_cpu_index,
|
||||||
|
input logic [OFFSET_W-1:0] i_cpu_offset,
|
||||||
|
|
||||||
|
input logic i_rdy,
|
||||||
|
output logic o_rdy,
|
||||||
|
|
||||||
|
input logic i_cpu_we,
|
||||||
|
|
||||||
|
input logic [CPU_W-1:0] i_cpu_data,
|
||||||
|
output logic [CPU_W-1:0] o_cpu_data,
|
||||||
|
|
||||||
|
output logic [INDEX_W-1:0] o_read_index,
|
||||||
|
output logic o_read_valid,
|
||||||
|
|
||||||
|
input logic [DATA_W-1:0] i_read_data [NUM_WAYS],
|
||||||
|
input logic [META_W-1:0] i_read_meta [NUM_WAYS],
|
||||||
|
|
||||||
|
output logic [INDEX_W-1:0] o_write_index,
|
||||||
|
output logic [NUM_WAYS-1:0] o_write_valid,
|
||||||
|
|
||||||
|
output logic [DATA_W-1:0] o_write_data,
|
||||||
|
output logic [META_W-1:0] o_write_meta,
|
||||||
|
|
||||||
|
output logic [INDEX_W-1:0] o_lru_read_index,
|
||||||
|
output logic o_lru_read_valid,
|
||||||
|
input logic [LRU_W-1:0]] i_lru_read_data,
|
||||||
|
|
||||||
|
output logic [INDEX_W-1:0] o_lru_write_index,
|
||||||
|
output logic o_lru_write_valid,
|
||||||
|
output logic [LRU_W-1:0]] o_lru_write_data,
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
enum logic [3:0] {
|
||||||
|
IDLE,
|
||||||
|
CHECK_VICTIM,
|
||||||
|
WRITEBACK,
|
||||||
|
WAIT_WRITEBACK_ACK,
|
||||||
|
REQUEST_MEMORY,
|
||||||
|
WAIT_MEMORY,
|
||||||
|
INSTALL_LINE,
|
||||||
|
UPDATE_LRU,
|
||||||
|
REQUEST_OWNERSHIP
|
||||||
|
} state, state_next;
|
||||||
|
|
||||||
|
logic cpu_we_d1;
|
||||||
|
logic cpu_i_data_d1;
|
||||||
|
|
||||||
|
logic [INDEX_W-1:0] cpu_index_d1;
|
||||||
|
logic [OFFSET_W-1:0] cpu_offset_d1;
|
||||||
|
|
||||||
|
logic way_match_found;
|
||||||
|
logic [NUM_WAYS-1:0] way_select_mask;
|
||||||
|
mesi_e mesi;
|
||||||
|
logic [TAG_W-1:0] tag;
|
||||||
|
|
||||||
|
always_ff @(posedge i_clk) begin
|
||||||
|
if (i_rst) begin
|
||||||
|
state <= IDLE;
|
||||||
|
end else begin
|
||||||
|
state <= state_next;
|
||||||
|
end
|
||||||
|
|
||||||
|
cpu_we_d1 <= i_cpu_we;
|
||||||
|
cpu_i_data_d1 <= i_cpu_data
|
||||||
|
cpu_index_d1 <= i_cpu_index;
|
||||||
|
cpu_offset_d1 <= i_cpu_offset;
|
||||||
|
end
|
||||||
|
|
||||||
|
always_comb begin
|
||||||
|
o_rdy = '0;
|
||||||
|
o_cpu_data = '0;
|
||||||
|
|
||||||
|
o_read_valid = '0;
|
||||||
|
o_read_index = '0;
|
||||||
|
|
||||||
|
o_write_valid = '0;
|
||||||
|
o_write_index = '0;
|
||||||
|
o_write_data = '0;
|
||||||
|
o_write_meta = '0;
|
||||||
|
|
||||||
|
o_lru_read_valid = '0;
|
||||||
|
o_lru_read_index = '0;
|
||||||
|
o_lru_write_valid = '0;
|
||||||
|
o_lru_write_index = '0;
|
||||||
|
o_lru_write_data = '0;
|
||||||
|
|
||||||
|
|
||||||
|
state_next = state;
|
||||||
|
|
||||||
|
|
||||||
|
case (state)
|
||||||
|
IDLE: begin
|
||||||
|
// by default, o_rdy is 1 unless something is wrong
|
||||||
|
o_rdy = '1;
|
||||||
|
|
||||||
|
// Read from arrays
|
||||||
|
o_read_index = i_cpu_index;
|
||||||
|
o_read_valid = i_rdy;
|
||||||
|
|
||||||
|
o_lru_read_index = i_cpu_index;
|
||||||
|
o_lru_read_valid = i_rdy;
|
||||||
|
|
||||||
|
// data from previous cycle that was read from arrays
|
||||||
|
way_match_found = '0;
|
||||||
|
way_select_mask = '0;
|
||||||
|
for (int i; i < NUM_WAYS; i++) begin
|
||||||
|
{mesi, tag} = i_read_meta[i];
|
||||||
|
if (tag == i_cpu_tag && mesi != MESI_INVALID) begin
|
||||||
|
way_match_found = '1;
|
||||||
|
way_select_mask[i] = '1;
|
||||||
|
break;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
// We have a match, so either read or write data
|
||||||
|
if (way_match_found) begin
|
||||||
|
if (cpu_we_d1) begin
|
||||||
|
// write data back to the cache array
|
||||||
|
// check if we are in the M or E states before we write.
|
||||||
|
// If we are in S then we need to request ownership before
|
||||||
|
// we can modify it.
|
||||||
|
if (mesi == MESI_MODIFIED || mesi == MESI_EXCLUSIVE) begin
|
||||||
|
o_write_data = i_read_data;
|
||||||
|
o_write_data[cpu_offset_d1 +: 8] = cpu_i_data_d1;
|
||||||
|
o_write_meta = {MESI_MODIFIED, i_cpu_tag};
|
||||||
|
o_write_valid = way_select_mask;
|
||||||
|
o_write_index = cpu_index_d1;
|
||||||
|
|
||||||
|
end else begin
|
||||||
|
o_rdy = '0;
|
||||||
|
state_next = REQUEST_OWNERSHIP;
|
||||||
|
end
|
||||||
|
end else begin
|
||||||
|
// Send the data to the CPU
|
||||||
|
o_cpu_data = i_read_data[cpu_offset_d1 +: 8];
|
||||||
|
end
|
||||||
|
|
||||||
|
// update lru
|
||||||
|
// start by copying the read data, then change the bits
|
||||||
|
// based on what we matched.
|
||||||
|
o_lru_write_index = cpu_index_d1;
|
||||||
|
o_lru_write_data = i_lru_read_data;
|
||||||
|
o_lru_write_valid = '1;
|
||||||
|
|
||||||
|
case (way_select_mask)
|
||||||
|
4'b0001: begin
|
||||||
|
o_lru_write_data[0] = '1;
|
||||||
|
o_lru_write_data[1] = '1;
|
||||||
|
end
|
||||||
|
|
||||||
|
4'b0010: begin
|
||||||
|
o_lru_write_data[0] = '1;
|
||||||
|
o_lru_write_data[1] = '0;
|
||||||
|
end
|
||||||
|
|
||||||
|
4'b0100: begin
|
||||||
|
o_lru_write_data[0] = '0;
|
||||||
|
o_lru_write_data[2] = '1;
|
||||||
|
end
|
||||||
|
|
||||||
|
4'b1000: begin
|
||||||
|
o_lru_write_data[0] = '0;
|
||||||
|
o_lru_write_data[2] = '0;
|
||||||
|
end
|
||||||
|
endcase
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
default: begin
|
||||||
|
end
|
||||||
|
|
||||||
|
endcase
|
||||||
|
end
|
||||||
@@ -19,10 +19,10 @@ package application_wrapper_cache_pkg;
|
|||||||
} cache_cmd_e;
|
} cache_cmd_e;
|
||||||
|
|
||||||
typedef enum logic [1:0] {
|
typedef enum logic [1:0] {
|
||||||
MODIFIED,
|
MESI_MODIFIED,
|
||||||
EXCLUSIVE,
|
MESI_EXCLUSIVE,
|
||||||
SHARED,
|
MESI_SHARED,
|
||||||
INVALID
|
MESI_INVALID
|
||||||
} mesi_e;
|
} mesi_e;
|
||||||
|
|
||||||
endpackage
|
endpackage
|
||||||
Reference in New Issue
Block a user