From a57211e91dfe1060381b1283052c084b8d67fec6 Mon Sep 17 00:00:00 2001 From: Luca Rufer Date: Mon, 30 Jun 2025 14:47:37 +0200 Subject: [PATCH 1/4] Hook up error signals --- src/snitch_icache_handler.sv | 2 +- src/snitch_icache_l0.sv | 7 +++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/snitch_icache_handler.sv b/src/snitch_icache_handler.sv index 3e9ee0b..e09ff48 100644 --- a/src/snitch_icache_handler.sv +++ b/src/snitch_icache_handler.sv @@ -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; diff --git a/src/snitch_icache_l0.sv b/src/snitch_icache_l0.sv index d4460f6..66dd308 100644 --- a/src/snitch_icache_l0.sv +++ b/src/snitch_icache_l0.sv @@ -46,6 +46,7 @@ module snitch_icache_l0 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; @@ -150,6 +151,7 @@ module snitch_icache_l0 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; @@ -158,6 +160,7 @@ 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 @@ -193,8 +196,10 @@ module snitch_icache_l0 logic [CFG.LINE_WIDTH-1:0] ins_data; always_comb begin : data_muxer 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) @@ -296,8 +301,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}); From 7dc228d22e2d4ffd04313bdf49b5e8aafa5c88ea Mon Sep 17 00:00:00 2001 From: moritz Date: Wed, 27 Aug 2025 18:08:55 +0200 Subject: [PATCH 2/4] Fix latch memory implementation --- src/snitch_icache_l0.sv | 28 +++++++++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/src/snitch_icache_l0.sv b/src/snitch_icache_l0.sv index 66dd308..1ffb1b9 100644 --- a/src/snitch_icache_l0.sv +++ b/src/snitch_icache_l0.sv @@ -145,6 +145,17 @@ module snitch_icache_l0 .clk_o(clk_inv) ); + if (CFG.EARLY_LATCH) begin + logic [CFG.LINE_WIDTH-1:0] line_in_q; + always_ff @(posedge clk_i, 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 @@ -165,10 +176,21 @@ module snitch_icache_l0 end end if (CFG.EARLY_LATCH) begin : gen_latch + + logic validate_strb_q; + + always_ff @(posedge clk_i, negedge rst_ni) begin + if (!rst_ni) begin + validate_strb_q <= '0; + end else begin + validate_strb_q <= validate_strb[i]; + end + end + logic clk_vld; tc_clk_gating i_clk_gate ( - .clk_i (clk_inv), - .en_i (validate_strb[i]), + .clk_i (clk_i), + .en_i (validate_strb_q), .test_en_i(1'b0), .clk_o (clk_vld) ); @@ -177,7 +199,7 @@ module snitch_icache_l0 /* 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 */ From 90cab61dae355dfae4bf1550b7ce1a8de6891527 Mon Sep 17 00:00:00 2001 From: moritz Date: Wed, 27 Aug 2025 19:08:17 +0200 Subject: [PATCH 3/4] Fixup --- src/snitch_icache_l0.sv | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/src/snitch_icache_l0.sv b/src/snitch_icache_l0.sv index 1ffb1b9..bb8d3bd 100644 --- a/src/snitch_icache_l0.sv +++ b/src/snitch_icache_l0.sv @@ -139,14 +139,8 @@ 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 - logic [CFG.LINE_WIDTH-1:0] line_in_q; always_ff @(posedge clk_i, negedge rst_ni) begin if (!rst_ni) begin line_in_q <= '0; From 89026f5746cb33ae4520e49d4b5b8fb73c8b524e Mon Sep 17 00:00:00 2001 From: moritz Date: Wed, 27 Aug 2025 21:26:26 +0200 Subject: [PATCH 4/4] Fix mismatching clk gate enable cycle --- src/snitch_icache_l0.sv | 106 ++++++++++++++++++---------------------- 1 file changed, 48 insertions(+), 58 deletions(-) diff --git a/src/snitch_icache_l0.sv b/src/snitch_icache_l0.sv index bb8d3bd..447b704 100644 --- a/src/snitch_icache_l0.sv +++ b/src/snitch_icache_l0.sv @@ -12,34 +12,34 @@ 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; @@ -141,13 +141,13 @@ module snitch_icache_l0 logic [CFG.LINE_WIDTH-1:0] line_in_q; if (CFG.EARLY_LATCH) begin - always_ff @(posedge clk_i, negedge rst_ni) begin - if (!rst_ni) begin - line_in_q <= '0; - end else begin - line_in_q <= out_rsp_data_i; - end - end + 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 @@ -171,22 +171,12 @@ module snitch_icache_l0 end if (CFG.EARLY_LATCH) begin : gen_latch - logic validate_strb_q; - - always_ff @(posedge clk_i, negedge rst_ni) begin - if (!rst_ni) begin - validate_strb_q <= '0; - end else begin - validate_strb_q <= validate_strb[i]; - end - end - logic clk_vld; tc_clk_gating i_clk_gate ( - .clk_i (clk_i), - .en_i (validate_strb_q), - .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 */ @@ -211,7 +201,7 @@ 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]; @@ -226,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; @@ -388,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;