Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/snitch_icache_handler.sv
Original file line number Diff line number Diff line change
Expand Up @@ -315,7 +315,7 @@ module snitch_icache_handler #(
if (hit_valid) begin
out_rsp_ready_o = 0;
in_rsp_data_o = hit_data;
in_rsp_error_o = 0;
in_rsp_error_o = hit_error;
in_rsp_id_o = hit_id;
in_rsp_valid_o = 1;
hit_ready = in_rsp_ready_i;
Expand Down
107 changes: 58 additions & 49 deletions src/snitch_icache_l0.sv
Original file line number Diff line number Diff line change
Expand Up @@ -12,40 +12,41 @@
module snitch_icache_l0
import snitch_icache_pkg::*;
#(
parameter config_t CFG = '0,
parameter int unsigned L0_ID = 0
parameter config_t CFG = '0,
parameter int unsigned L0_ID = 0
) (
input logic clk_i,
input logic rst_ni,
input logic flush_valid_i,

input logic enable_prefetching_i,
input logic enable_branch_pred_i,

output icache_l0_events_t icache_events_o,

input logic [CFG.FETCH_AW-1:0] in_addr_i,
input logic in_valid_i,
output logic [CFG.FETCH_DW-1:0] in_data_o,
output logic in_ready_o,
output logic in_error_o,

output logic [CFG.FETCH_AW-1:0] out_req_addr_o,
output logic [CFG.ID_WIDTH-1:0] out_req_id_o,
output logic out_req_valid_o,
input logic out_req_ready_i,

input logic [CFG.LINE_WIDTH-1:0] out_rsp_data_i,
input logic out_rsp_error_i,
input logic [ CFG.ID_WIDTH-1:0] out_rsp_id_i,
input logic out_rsp_valid_i,
output logic out_rsp_ready_o
input logic clk_i,
input logic rst_ni,
input logic flush_valid_i,

input logic enable_prefetching_i,
input logic enable_branch_pred_i,

output icache_l0_events_t icache_events_o,

input logic [CFG.FETCH_AW-1:0] in_addr_i,
input logic in_valid_i,
output logic [CFG.FETCH_DW-1:0] in_data_o,
output logic in_ready_o,
output logic in_error_o,

output logic [CFG.FETCH_AW-1:0] out_req_addr_o,
output logic [CFG.ID_WIDTH-1:0] out_req_id_o,
output logic out_req_valid_o,
input logic out_req_ready_i,

input logic [CFG.LINE_WIDTH-1:0] out_rsp_data_i,
input logic out_rsp_error_i,
input logic [ CFG.ID_WIDTH-1:0] out_rsp_id_i,
input logic out_rsp_valid_i,
output logic out_rsp_ready_o
);

typedef logic [CFG.FETCH_AW-1:0] addr_t;
typedef struct packed {
logic [CFG.L0_TAG_WIDTH-1:0] tag;
logic vld;
logic err;
} tag_t;

logic [CFG.L0_TAG_WIDTH-1:0] addr_tag, addr_tag_prefetch, addr_tag_prefetch_req;
Expand Down Expand Up @@ -138,18 +139,24 @@ module snitch_icache_l0
assign hit_prefetch_any = |hit_prefetch;
assign miss = ~hit_any & in_valid_i & ~pending_refill_q & ~prefetching_missed_line;

logic clk_inv;
tc_clk_inverter i_clk_inv (
.clk_i(clk_i),
.clk_o(clk_inv)
);
logic [CFG.LINE_WIDTH-1:0] line_in_q;
if (CFG.EARLY_LATCH) begin
always_ff @(posedge clk_i or negedge rst_ni) begin
if (~rst_ni) begin
line_in_q <= '0;
end else begin
line_in_q <= out_rsp_data_i;
end
end
end

for (genvar i = 0; i < CFG.L0_LINE_COUNT; i++) begin : gen_array
// Tag Array
always_ff @(posedge clk_i or negedge rst_ni) begin
if (!rst_ni) begin
tag[i].vld <= 0;
tag[i].tag <= 0;
tag[i].err <= 0;
end else begin
if (evict_strb[i]) begin
tag[i].vld <= 1'b0;
Expand All @@ -158,23 +165,25 @@ module snitch_icache_l0
tag[i].vld <= 1'b0;
end else if (validate_strb[i]) begin
tag[i].vld <= 1'b1;
tag[i].err <= out_rsp_error_i;
end
end
end
if (CFG.EARLY_LATCH) begin : gen_latch

logic clk_vld;
tc_clk_gating i_clk_gate (
.clk_i (clk_inv),
.en_i (validate_strb[i]),
.test_en_i(1'b0),
.clk_o (clk_vld)
.clk_i (clk_i),
.en_i (validate_strb[i]),
.test_en_i(1'b0),
.clk_o (clk_vld)
);
// Data Array
/* verilator lint_off NOLATCH */
/* verilator lint_off COMBDLY */
always_latch begin
if (clk_vld) begin
data[i] <= out_rsp_data_i;
data[i] <= line_in_q;
end
end
/* verilator lint_on COMBDLY */
Expand All @@ -192,9 +201,11 @@ module snitch_icache_l0

logic [CFG.LINE_WIDTH-1:0] ins_data;
always_comb begin : data_muxer
ins_data = '0;
ins_data = '0;
in_error_o = 1'b0;
for (int unsigned i = 0; i < CFG.L0_LINE_COUNT; i++) begin
ins_data |= {CFG.LINE_WIDTH{hit[i]}} & data[i];
in_error_o |= hit[i] & tag[i].err;
end
in_data_o = CFG.FETCH_DW'(
ins_data >> (in_addr_i[CFG.LINE_ALIGN-1:CFG.FETCH_ALIGN] * CFG.FETCH_DW)
Expand All @@ -205,10 +216,10 @@ module snitch_icache_l0
// multiple entries in the tag array)
if (CFG.L0_TAG_WIDTH != CFG.L0_EARLY_TAG_WIDTH) begin : gen_multihit_detection
cc_onehot #(
.Width(CFG.L0_LINE_COUNT)
.Width(CFG.L0_LINE_COUNT)
) i_onehot_hit_early (
.d_i (hit_early),
.is_onehot_o(hit_early_is_onehot)
.d_i (hit_early),
.is_onehot_o(hit_early_is_onehot)
);
end else begin : gen_no_multihit_detection
assign hit_early_is_onehot = 1'b1;
Expand Down Expand Up @@ -296,8 +307,6 @@ module snitch_icache_l0

assign out_rsp_ready_o = 1'b1;

assign in_error_o = '0;

assign out_req_addr_o = out_req.addr;
assign out_req_id_o = CFG.ID_WIDTH'(1'b1 << {L0_ID, out_req.is_prefetch});

Expand Down Expand Up @@ -369,13 +378,13 @@ module snitch_icache_l0
assign ins_idx = 32 * taken_idx;
// Find first taken branch
lzc #(
.WIDTH(FetchPkts),
.MODE (0)
.WIDTH(FetchPkts),
.MODE (0)
) i_lzc_branch (
// look at branches and jals
.in_i (mask & (is_branch_taken | is_jal)),
.cnt_o (taken_idx),
.empty_o(no_prefetch)
// look at branches and jals
.in_i (mask & (is_branch_taken | is_jal)),
.cnt_o (taken_idx),
.empty_o(no_prefetch)
);

addr_t base_addr, offset, uj_imm, sb_imm;
Expand Down