Skip to content
Merged
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
68 changes: 50 additions & 18 deletions rtl/ibex_icache.sv
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,6 @@ module ibex_icache import ibex_pkg::*; #(

// Cache pipeline IC1 signals
logic [TagSizeECC-1:0] tag_rdata_ic1 [IC_NUM_WAYS];
logic [LineSizeECC-1:0] data_rdata_ic1 [IC_NUM_WAYS];
logic [LineSizeECC-1:0] hit_data_ecc_ic1;
logic [IC_LINE_SIZE-1:0] hit_data_ic1;
logic lookup_valid_ic1;
Expand Down Expand Up @@ -324,15 +323,15 @@ module ibex_icache import ibex_pkg::*; #(
// Determine the full address used for the outgoing data bank request. Apply '0, wich
// effectively disabled the tweak infection, when (a) invalidating the cache and (b)
// when there is already an ECC error (we have already raised a minor alert).
logic [ADDR_W-1:0] data_address_ic0;
logic [ADDR_W-1:0] data_tweak_ic0;
logic [ADDR_W-1:0] data_address_ic0;
logic [ADDR_W-IC_LINE_W-1:0] data_tweak_ic0;
assign data_address_ic0 = inval_write_req ? '0 :
ecc_write_req ? '0 :
fill_grant_ic0 ? fill_ram_req_addr :
lookup_addr_ic0;

// Mask the IC_LINE_W LSBs to remove the offset within a cache line.
assign data_tweak_ic0 = {data_address_ic0[ADDR_W-1:IC_LINE_W], {IC_LINE_W{1'b0}}};
assign data_tweak_ic0 = data_address_ic0[ADDR_W-1:IC_LINE_W];

// Tie off the unused LSBs.
logic unused_data_address_ic0;
Expand All @@ -343,25 +342,45 @@ module ibex_icache import ibex_pkg::*; #(
always_comb begin
data_tweak_lw_ic0 = '0;
for (int i = 0; i < IC_LINE_BEATS; i++) begin
data_tweak_lw_ic0 |= (LineSizeECC'({data_tweak_ic0}) <<
data_tweak_lw_ic0 |= (LineSizeECC'({data_tweak_ic0, {IC_LINE_W{1'b0}}}) <<
(i * (ADDR_W + IC_DATA_ECC_SIZE)));
end
end
end else begin: gen_no_ecc_tweak
always_comb begin
data_tweak_lw_ic0 = '0;
for (int i = 0; i < IC_LINE_BEATS; i++) begin
data_tweak_lw_ic0 |= (LineSizeECC'({data_tweak_ic0}) << (i * ADDR_W));
data_tweak_lw_ic0 |= (LineSizeECC'({data_tweak_ic0, {IC_LINE_W{1'b0}}}) <<
(i * ADDR_W));
end
end
end

// Pipeline the tweak to IC1 to align with the data RAM output timing.
logic [ADDR_W-IC_LINE_W-1:0] data_tweak_ic1;
always_ff @(posedge clk_i or negedge rst_ni) begin
if (!rst_ni) begin
data_tweak_lw_ic1 <= '0;
data_tweak_ic1 <= '0;
end else if (data_req_ic0) begin
data_tweak_lw_ic1 <= data_tweak_lw_ic0;
data_tweak_ic1 <= data_tweak_ic0;
end
end

// Replicate the ADDR_W-bit tweak to match the LineSizeECC width.
if (ICacheECC) begin : gen_ecc_tweak_ic1
always_comb begin
data_tweak_lw_ic1 = '0;
for (int i = 0; i < IC_LINE_BEATS; i++) begin
data_tweak_lw_ic1 |= (LineSizeECC'({data_tweak_ic1, {IC_LINE_W{1'b0}}}) <<
(i * (ADDR_W + IC_DATA_ECC_SIZE)));
end
end
end else begin : gen_no_ecc_tweak_ic1
always_comb begin
data_tweak_lw_ic1 = '0;
for (int i = 0; i < IC_LINE_BEATS; i++) begin
data_tweak_lw_ic1 |= (LineSizeECC'({data_tweak_ic1, {IC_LINE_W{1'b0}}}) << (i * ADDR_W));
end
end
end

Expand All @@ -384,11 +403,30 @@ module ibex_icache import ibex_pkg::*; #(
end

// Pipeline the tag tweak to IC1 to align with the tag RAM output timing.
logic [IC_INDEX_W-1:0] tag_index_ic1;
always_ff @(posedge clk_i or negedge rst_ni) begin
if (!rst_ni) begin
tag_tweak_lw_ic1 <= '0;
tag_index_ic1 <= '0;
end else if (tag_req_ic0) begin
tag_tweak_lw_ic1 <= tag_tweak_lw_ic0;
tag_index_ic1 <= tag_index_ic0;
end
end

// Extend tag_index_ic1 to full TagSizeECC width for use at the read XOR.
if (ICacheECC) begin : gen_ecc_tag_tweak_ic1
always_comb begin
tag_tweak_lw_ic1 = '0;
for (int i = 0; i < IC_LINE_BEATS; i++) begin
tag_tweak_lw_ic1 |= (TagSizeECC'({tag_index_ic1}) <<
(i * (IC_INDEX_W + IC_TAG_ECC_SIZE)));
end
end
end else begin : gen_no_ecc_tag_tweak_ic1
always_comb begin
tag_tweak_lw_ic1 = '0;
for (int i = 0; i < IC_LINE_BEATS; i++) begin
tag_tweak_lw_ic1 |= (TagSizeECC'({tag_index_ic1}) << (i * IC_INDEX_W));
end
end
end
end else begin: gen_no_tweak_infection
Expand Down Expand Up @@ -424,12 +462,6 @@ module ibex_icache import ibex_pkg::*; #(
// Tweak infection, XOR the data with the tweak before writing to RAM.
assign ic_data_wdata_o = data_wdata_ic0 ^ data_tweak_lw_ic0;

// Data RAMs inputs
// Tweak infection, un-XOR the data using the tweak.
for (genvar way = 0; way < IC_NUM_WAYS; way++) begin : gen_data_untweak
assign data_rdata_ic1[way] = ic_data_rdata_i[way] ^ data_tweak_lw_ic1;
end

always_ff @(posedge clk_i or negedge rst_ni) begin
if (!rst_ni) begin
lookup_valid_ic1 <= 1'b0;
Expand Down Expand Up @@ -470,12 +502,12 @@ module ibex_icache import ibex_pkg::*; #(

assign tag_hit_ic1 = |tag_match_ic1;

// Hit data mux
// Hit data mux. Un-XOR the tweak only for the matching way.
always_comb begin
hit_data_ecc_ic1 = 'b0;
for (int way = 0; way < IC_NUM_WAYS; way++) begin
if (tag_match_ic1[way]) begin
hit_data_ecc_ic1 |= data_rdata_ic1[way];
hit_data_ecc_ic1 |= ic_data_rdata_i[way] ^ data_tweak_lw_ic1;
end
end
end
Expand Down
Loading