Rework instruction cache addressing logic

Signed-off-by: Eric Matthews <ematthew@sfu.ca>
This commit is contained in:
Eric Matthews 2022-07-05 15:08:38 -04:00
parent e6fbbcfeb2
commit fe3c0384fc
5 changed files with 72 additions and 55 deletions

View file

@ -64,10 +64,7 @@ module branch_predictor
localparam BRANCH_ADDR_W = $clog2(CONFIG.BP.ENTRIES);
localparam BTAG_W = get_memory_width() - BRANCH_ADDR_W - 2;
function logic[BTAG_W-1:0] get_tag (input logic[31:0] pc);
return pc[BRANCH_ADDR_W+2 +: BTAG_W];
endfunction
cache_functions_interface #(.TAG_W(BTAG_W), .LINE_W(BRANCH_ADDR_W), .SUB_LINE_W(0)) addr_utils();
typedef struct packed {
logic valid;
@ -101,6 +98,9 @@ module branch_predictor
logic [$clog2(CONFIG.BP.WAYS > 1 ? CONFIG.BP.WAYS : 2)-1:0] hit_way;
logic tag_match;
logic use_predicted_pc;
addr_utils_interface #(CONFIG.IBUS_ADDR.L, CONFIG.IBUS_ADDR.H) ibus_addr_utils ();
/////////////////////////////////////////
genvar i;
@ -108,14 +108,14 @@ module branch_predictor
for (i=0; i<CONFIG.BP.WAYS; i++) begin : gen_branch_tag_banks
branch_predictor_ram #(.C_DATA_WIDTH($bits(branch_table_entry_t)), .C_DEPTH(CONFIG.BP.ENTRIES))
tag_bank (
.clk (clk),
.rst (rst),
.write_addr (br_results.pc[2 +: BRANCH_ADDR_W]),
.write_en (tag_update_way[i]),
.write_data (ex_entry),
.read_addr (bp.next_pc[2 +: BRANCH_ADDR_W]),
.read_en (bp.new_mem_request),
.read_data (if_entry[i]));
.clk (clk),
.rst (rst),
.write_addr (addr_utils.getHashedLineAddr(br_results.pc, i)),
.write_en (tag_update_way[i]),
.write_data (ex_entry),
.read_addr (addr_utils.getHashedLineAddr(bp.next_pc, i)),
.read_en (bp.new_mem_request),
.read_data (if_entry[i]));
end
endgenerate
@ -123,21 +123,21 @@ module branch_predictor
for (i=0; i<CONFIG.BP.WAYS; i++) begin : gen_branch_table_banks
branch_predictor_ram #(.C_DATA_WIDTH(32), .C_DEPTH(CONFIG.BP.ENTRIES))
addr_table (
.clk (clk),
.rst (rst),
.write_addr(br_results.pc[2 +: BRANCH_ADDR_W]),
.write_en(target_update_way[i]),
.write_data(br_results.target_pc),
.read_addr(bp.next_pc[2 +: BRANCH_ADDR_W]),
.read_en(bp.new_mem_request),
.read_data(predicted_pc[i])
.clk (clk),
.rst (rst),
.write_addr (addr_utils.getHashedLineAddr(br_results.pc, i)),
.write_en (target_update_way[i]),
.write_data (br_results.target_pc),
.read_addr (addr_utils.getHashedLineAddr(bp.next_pc, i)),
.read_en (bp.new_mem_request),
.read_data (predicted_pc[i])
);
end
endgenerate
generate if (CONFIG.INCLUDE_BRANCH_PREDICTOR)
for (i=0; i<CONFIG.BP.WAYS; i++) begin : gen_branch_hit_detection
assign tag_matches[i] = ({if_entry[i].valid, if_entry[i].tag} == {1'b1, get_tag(bp.if_pc)});
assign tag_matches[i] = ({if_entry[i].valid, if_entry[i].tag} == {1'b1, addr_utils.getTag(bp.if_pc)});
end
endgenerate
@ -185,7 +185,7 @@ module branch_predictor
////////////////////////////////////////////////////
//Execution stage update
assign ex_entry.valid = 1;
assign ex_entry.tag = get_tag(br_results.pc);
assign ex_entry.tag = addr_utils.getTag(br_results.pc);
assign ex_entry.is_branch = br_results.is_branch;
assign ex_entry.is_return = br_results.is_return;
assign ex_entry.is_call = br_results.is_call;

View file

@ -44,6 +44,8 @@ module icache
localparam derived_cache_config_t SCONFIG = get_derived_cache_params(CONFIG, CONFIG.ICACHE, CONFIG.ICACHE_ADDR);
localparam bit [SCONFIG.SUB_LINE_ADDR_W-1:0] END_OF_LINE_COUNT = SCONFIG.SUB_LINE_ADDR_W'(CONFIG.ICACHE.LINE_W-1);
cache_functions_interface #(.TAG_W(SCONFIG.TAG_W), .LINE_W(SCONFIG.LINE_ADDR_W), .SUB_LINE_W(SCONFIG.SUB_LINE_ADDR_W)) addr_utils();
logic tag_hit;
logic [CONFIG.ICACHE.WAYS-1:0] tag_hit_way;
@ -174,8 +176,9 @@ module icache
icache_tag_banks (
.clk(clk),
.rst(rst), //clears the read_hit_allowed flag
.stage1_addr(new_request_addr),
.stage2_addr(second_cycle_addr),
.stage1_line_addr(addr_utils.getTagLineAddr(new_request_addr)),
.stage2_line_addr(addr_utils.getTagLineAddr(second_cycle_addr)),
.stage2_tag(addr_utils.getTag(second_cycle_addr)),
.update_way(tag_update_way),
.update(tag_update),
.stage1_adv(new_request & icache_on),
@ -189,8 +192,8 @@ module icache
generate for (i=0; i < CONFIG.ICACHE.WAYS; i++) begin : idata_bank_gen
byte_en_BRAM #(CONFIG.ICACHE.LINES*CONFIG.ICACHE.LINE_W) idata_bank (
.clk(clk),
.addr_a(new_request_addr[2 +: SCONFIG.LINE_ADDR_W+SCONFIG.SUB_LINE_ADDR_W]),
.addr_b({second_cycle_addr[(2+SCONFIG.SUB_LINE_ADDR_W) +: SCONFIG.LINE_ADDR_W], word_count}),
.addr_a(addr_utils.getDataLineAddr(new_request_addr)),
.addr_b(addr_utils.getDataLineAddr({second_cycle_addr[31:SCONFIG.SUB_LINE_ADDR_W+2], word_count, 2'b0})),
.en_a(new_request),
.en_b(tag_update_way[i] & l1_response.data_valid),
.be_a('0),

View file

@ -34,8 +34,9 @@ module itag_banks
input logic clk,
input logic rst,
input logic[31:0] stage1_addr,
input logic[31:0] stage2_addr,
input logic[SCONFIG.LINE_ADDR_W-1:0] stage1_line_addr,
input logic[SCONFIG.LINE_ADDR_W-1:0] stage2_line_addr,
input logic[SCONFIG.TAG_W-1:0] stage2_tag,
input logic[CONFIG.ICACHE.WAYS-1:0] update_way,
input logic update,
@ -46,22 +47,11 @@ module itag_banks
output logic[CONFIG.ICACHE.WAYS-1:0] tag_hit_way
);
//Valid + tag
typedef logic [SCONFIG.TAG_W : 0] itag_entry_t;
function logic[SCONFIG.TAG_W-1:0] getTag(logic[31:0] addr);
return addr[2+SCONFIG.SUB_LINE_ADDR_W+SCONFIG.LINE_ADDR_W +: SCONFIG.TAG_W];
endfunction
function logic[SCONFIG.LINE_ADDR_W-1:0] getLineAddr(logic[31:0] addr);
return addr[SCONFIG.LINE_ADDR_W + SCONFIG.SUB_LINE_ADDR_W + 1 : SCONFIG.SUB_LINE_ADDR_W + 2];
endfunction
logic hit_allowed;
itag_entry_t tag_line[CONFIG.ICACHE.WAYS-1:0];
itag_entry_t stage2_tag;
assign stage2_tag = {1'b1, getTag(stage2_addr)};
logic hit_allowed;
always_ff @ (posedge clk) begin
if (rst)
@ -73,23 +63,22 @@ module itag_banks
genvar i;
generate
for (i=0; i < CONFIG.ICACHE.WAYS; i++) begin : tag_bank_gen
tag_bank #(SCONFIG.TAG_W+1, CONFIG.ICACHE.LINES) itag_bank (.*,
.en_a(stage1_adv), .wen_a('0),
.addr_a(getLineAddr(stage1_addr)),
.data_in_a('0), .data_out_a(tag_line[i]),
.en_b(update), .wen_b(update_way[i]),
.addr_b(getLineAddr(stage2_addr)),
.data_in_b(stage2_tag), .data_out_b()
.en_a(stage1_adv),
.wen_a('0),
.addr_a(stage1_line_addr),
.data_in_a('0),
.data_out_a(tag_line[i]),
.en_b(update),
.wen_b(update_way[i]),
.addr_b(stage2_line_addr),
.data_in_b({1'b1, stage2_tag}),
.data_out_b()
);
assign tag_hit_way[i] = ({hit_allowed,stage2_tag} == {1'b1,tag_line[i]});
assign tag_hit_way[i] = ({hit_allowed, 1'b1, stage2_tag} == {1'b1, tag_line[i]});
end
endgenerate
assign tag_hit = |tag_hit_way;
endmodule

View file

@ -270,6 +270,31 @@ interface writeback_store_interface;
);
endinterface
interface cache_functions_interface #(parameter int TAG_W = 8, parameter int LINE_W = 4, parameter int SUB_LINE_W = 2);
function logic [LINE_W-1:0] xor_mask (int WAY);
for (int i = 0; i < LINE_W; i++)
xor_mask[i] = ((WAY % 2) == 0) ? 1'b1 : 1'b0;
endfunction
function logic [LINE_W-1:0] getHashedLineAddr (logic[31:0] addr, int WAY);
getHashedLineAddr = addr[2 + SUB_LINE_W +: LINE_W] ^ (addr[2 + SUB_LINE_W + LINE_W +: LINE_W] & xor_mask(WAY));
endfunction
function logic[TAG_W-1:0] getTag(logic[31:0] addr);
getTag = addr[2 + LINE_W + SUB_LINE_W +: TAG_W];
endfunction
function logic [LINE_W-1:0] getTagLineAddr (logic[31:0] addr);
getTagLineAddr = addr[2 + SUB_LINE_W +: LINE_W];
endfunction
function logic [LINE_W+SUB_LINE_W-1:0] getDataLineAddr (logic[31:0] addr);
getDataLineAddr = addr[2 +: LINE_W + SUB_LINE_W];
endfunction
endinterface
interface addr_utils_interface #(parameter bit [31:0] BASE_ADDR = 32'h00000000, parameter bit [31:0] UPPER_BOUND = 32'hFFFFFFFF);
//Based on the lower and upper address ranges,
//find the number of bits needed to uniquely identify this memory range.

View file

@ -8,7 +8,7 @@ l2_arbiter/l2_external_interfaces.sv
local_memory/local_memory_interface.sv
local_memory/local_mem.sv
core/interfaces.sv
core/internal_interfaces.sv
core/external_interfaces.sv
core/lutrams/lutram_1w_1r.sv
@ -56,7 +56,7 @@ core/store_queue.sv
core/load_store_queue.sv
core/load_store_unit.sv
core/itag_banks.sv
core/icache_tag_banks.sv
core/icache.sv
core/clz.sv