mirror of
https://github.com/openhwgroup/cva5.git
synced 2025-04-20 12:07:53 -04:00
Rework instruction cache addressing logic
Signed-off-by: Eric Matthews <ematthew@sfu.ca>
This commit is contained in:
parent
e6fbbcfeb2
commit
fe3c0384fc
5 changed files with 72 additions and 55 deletions
|
@ -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;
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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
|
|
@ -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.
|
|
@ -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
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue