Suppress writeback exceptions

This commit is contained in:
Chris Keilbart 2024-08-15 11:01:38 -07:00
parent e3740f5e35
commit 66fe5f7813
10 changed files with 73 additions and 30 deletions

View file

@ -464,6 +464,7 @@ module cva5
.senvcfg (senvcfg),
.wb_packet (wb_packet),
.fp_wb_packet (fp_wb_packet),
.retire_id (retire_ids[0]),
.store_retire (store_retire),
.exception (exception[LS_EXCEPTION]),
.load_store_status(load_store_status),

View file

@ -337,6 +337,7 @@ module decode_and_issue
assign exception.code = ecode;
assign exception.tval = tval;
assign exception.pc = issue.pc;
assign exception.discard = 0;
end endgenerate
////////////////////////////////////////////////////

View file

@ -214,6 +214,7 @@ module branch_unit
assign exception.code = INST_ADDR_MISSALIGNED;
assign exception.tval = new_pc_ex;
assign exception.pc = issue_stage.pc_r;
assign exception.discard = 0;
end
endgenerate

View file

@ -971,6 +971,7 @@ generate if (CONFIG.MODES != BARE) begin : gen_csr_exceptions
assign exception.code = ILLEGAL_INST;
assign exception.pc = issue_stage.pc_r;
assign exception.tval = issue_stage.instruction_r;
assign exception.discard = 1;
end
endgenerate

View file

@ -130,6 +130,7 @@ module gc_unit
logic gc_init_clear;
logic gc_fetch_hold;
logic gc_issue_hold;
logic gc_rename_revert;
logic gc_fetch_flush;
logic gc_fetch_ifence;
logic gc_tlb_flush;
@ -242,6 +243,7 @@ module gc_unit
assign local_gc_exception.code = ILLEGAL_INST;
assign local_gc_exception.tval = issue_stage.instruction_r;
assign local_gc_exception.pc = issue_stage.pc_r;
assign local_gc_exception.discard = 0;
end
endgenerate
@ -355,12 +357,14 @@ generate if (CONFIG.MODES != BARE) begin :gen_gc_m_mode
exception_code_t [NUM_EXCEPTION_SOURCES-1:0] exception_code;
logic [NUM_EXCEPTION_SOURCES-1:0][31:0] exception_tval;
logic [NUM_EXCEPTION_SOURCES-1:0][31:0] exception_pc;
logic [NUM_EXCEPTION_SOURCES-1:0] exception_discard;
logic [31:0] muxed_exception_pc;
for (genvar i = 0; i < NUM_EXCEPTION_SOURCES; i++) begin
assign exception_valid[i] = exception[i].valid;
assign exception_code[i] = exception[i].code;
assign exception_tval[i] = exception[i].tval;
assign exception_discard[i] = exception[i].discard;
assign exception_pc[i] = exception[i].pc;
end
@ -383,10 +387,25 @@ generate if (CONFIG.MODES != BARE) begin :gen_gc_m_mode
.choices(exception_pc),
.sel(muxed_exception_pc),
.*);
assign gc.exception.pc = |exception_valid ? muxed_exception_pc : issue_stage.pc;
assign gc.exception.pc = |exception_valid ? muxed_exception_pc : issue_stage.pc;
assign interrupt_taken = interrupt_pending & (next_state == PRE_ISSUE_FLUSH) & ~(gc.exception.valid) & ~csr_frontend_flush;
//Writeback and rename handling
logic gc_writeback_suppress_r;
logic gc_rename_revert;
always_ff @(posedge clk) begin
if (rst) begin
gc_writeback_suppress_r <= 0;
gc_rename_revert <= 0;
end
else begin
gc_writeback_suppress_r <= gc.writeback_suppress;
gc_rename_revert <= gc_writeback_suppress_r;
end
end
assign gc.writeback_suppress = |(exception_valid & exception_discard);
assign gc.rename_revert = gc_rename_revert;
end endgenerate
//PC determination (trap, flush or return)

View file

@ -84,7 +84,8 @@ module load_store_unit
input wb_packet_t wb_packet [CONFIG.NUM_WB_GROUPS],
input fp_wb_packet_t fp_wb_packet [2],
//Retire release
//Retire
input id_t retire_id,
input retire_packet_t store_retire,
exception_interface.unit exception,
@ -172,7 +173,6 @@ module load_store_unit
logic [3:0] be;
//FIFOs
fifo_interface #(.DATA_TYPE(load_attributes_t)) load_attributes();
fifo_interface #(.DATA_TYPE(logic[31:0])) backstop();
load_store_queue_interface lsq();
////////////////////////////////////////////////////
@ -352,7 +352,30 @@ module load_store_unit
assign senv_illegal = CONFIG.INCLUDE_CBO & (issue_attr.is_cbo & issue_attr.cbo_type == INVAL ? senvcfg.cbie == 2'b00 : ~senvcfg.cbcfe);
assign illegal_cbo = CONFIG.MODES == MU ? current_privilege == USER_PRIVILEGE & menv_illegal : (current_privilege != MACHINE_PRIVILEGE & menv_illegal) | (current_privilege == USER_PRIVILEGE & senv_illegal);
assign new_exception = (issue.new_request & ((unaligned_addr & ~issue_attr.is_fence & ~issue_attr.is_cbo) | illegal_cbo)) | tlb.is_fault;
//Hold writeback exceptions until they are ready to retire
logic delay_exception;
logic delayed_exception;
assign delay_exception = (
(issue.new_request & unaligned_addr & (issue_attr.is_load | issue_attr.is_amo) & issue.id != retire_id) |
(tlb.is_fault & tlb_lq & exception_id != retire_id)
);
always_ff @(posedge clk) begin
if (rst)
delayed_exception <= 0;
else if (delay_exception)
delayed_exception <= 1;
else if (new_exception)
delayed_exception <= 0;
end
assign new_exception = (
(issue.new_request & ((unaligned_addr & issue_attr.is_store) | illegal_cbo)) |
(issue.new_request & unaligned_addr & (issue_attr.is_load | issue_attr.is_amo) & issue.id == retire_id) |
(tlb.is_fault & ~tlb_lq) |
(tlb.is_fault & tlb_lq & exception_id == retire_id) |
(delayed_exception & exception_id == retire_id)
);
always_ff @(posedge clk) begin
if (rst)
exception.valid <= 0;
@ -381,8 +404,9 @@ module load_store_unit
if (tlb.is_fault)
exception.code <= is_load_r ? LOAD_PAGE_FAULT : STORE_OR_AMO_PAGE_FAULT;
end
assign exception.possible = (tlb_request_r & ~tlb.done) | exception.valid; //Must suppress issue for issue-time exceptions too
assign exception.possible = (tlb_request_r & ~tlb.done) | exception.valid | delayed_exception; //Must suppress issue for issue-time exceptions too
assign exception.pc = issue_stage.pc_r;
assign exception.discard = tlb_lq;
assign exception_is_store = ~tlb_lq;
end endgenerate
@ -676,7 +700,7 @@ module load_store_unit
logic sign_bit_data [4];
logic sign_bit;
assign unit_muxed_load_data = backstop.valid ? backstop.data_out : unit_data_array[wb_attr.subunit_id];
assign unit_muxed_load_data = unit_data_array[wb_attr.subunit_id];
//Byte/halfword select: assumes aligned operations
assign aligned_load_data[31:16] = unit_muxed_load_data[31:16];
@ -725,17 +749,6 @@ module load_store_unit
assign fp_result = 'x;
end endgenerate
////////////////////////////////////////////////////
//Backstop buffering
//Required if load response overlaps an exception
assign backstop.push = load_response & exception.valid & ~exception_is_store;
assign backstop.potential_push = backstop.push;
assign backstop.data_in = unit_muxed_load_data;
assign backstop.pop = backstop.valid;
cva5_fifo #(.DATA_TYPE(logic[31:0]), .FIFO_DEPTH(1)) backstop_fifo (
.fifo(backstop),
.*);
////////////////////////////////////////////////////
//Output bank
assign wb.rd = final_load_data;

View file

@ -118,7 +118,7 @@ module register_file
.clk,
.waddr(wb_phys_addr[i]),
.raddr(decode_phys_rs_addr),
.ram_write(commit[i].valid),
.ram_write(commit[i].valid & ~gc.writeback_suppress),
.new_ram_data(commit[i].data),
.ram_data_out(regfile_rs_data[i])
);

View file

@ -96,7 +96,7 @@ module renamer
assign free_list.potential_push = (gc.init_clear & ~clear_index[5]) | (wb_retire.valid);
assign free_list.push = free_list.potential_push;
assign free_list.data_in = gc.init_clear ? {1'b1, clear_index[4:0]} : inuse_table_output.previous_phys_addr;
assign free_list.data_in = gc.init_clear ? {1'b1, clear_index[4:0]} : (gc.rename_revert ? inuse_table_output.spec_phys_addr : inuse_table_output.previous_phys_addr);
assign free_list.pop = rename_valid;
////////////////////////////////////////////////////
@ -137,12 +137,12 @@ module renamer
rs_addr_t spec_table_write_index;
rs_addr_t spec_table_write_index_mux [4];
assign spec_table_update = rename_valid | rollback | gc.init_clear;
assign spec_table_update = rename_valid | rollback | gc.init_clear | gc.rename_revert;
logic [1:0] spec_table_sel;
one_hot_to_integer #(.C_WIDTH(3)) spec_table_sel_one_hot_to_int (
.one_hot ({gc.init_clear, rollback, 1'b0}),
one_hot_to_integer #(.C_WIDTH(4)) spec_table_sel_one_hot_to_int (
.one_hot ({gc.init_clear, rollback, gc.rename_revert, 1'b0}),
.int_out (spec_table_sel)
);
@ -150,14 +150,18 @@ module renamer
assign spec_table_write_index_mux[0] = decode.rd_addr;
assign spec_table_next_mux[0].phys_addr = free_list.data_out;
assign spec_table_next_mux[0].wb_group = decode.rd_wb_group;
//gc.rename_revert
assign spec_table_write_index_mux[1] = inuse_table_output.rd_addr;
assign spec_table_next_mux[1].phys_addr = inuse_table_output.previous_phys_addr;
assign spec_table_next_mux[1].wb_group = inuse_table_output.previous_wb_group;
//rollback
assign spec_table_write_index_mux[1] = issue.rd_addr;
assign spec_table_next_mux[1].phys_addr = spec_table_previous_r.phys_addr;
assign spec_table_next_mux[1].wb_group = spec_table_previous_r.wb_group;
assign spec_table_write_index_mux[2] = issue.rd_addr;
assign spec_table_next_mux[2].phys_addr = spec_table_previous_r.phys_addr;
assign spec_table_next_mux[2].wb_group = spec_table_previous_r.wb_group;
//gc.init_clear
assign spec_table_write_index_mux[2] = clear_index[4:0];
assign spec_table_next_mux[2].phys_addr = {1'b0, clear_index[4:0]};
assign spec_table_next_mux[2].wb_group = '0;
assign spec_table_write_index_mux[3] = clear_index[4:0];
assign spec_table_next_mux[3].phys_addr = {1'b0, clear_index[4:0]};
assign spec_table_next_mux[3].wb_group = '0;
assign spec_table_write_index = spec_table_write_index_mux[spec_table_sel];
assign spec_table_next = spec_table_next_mux[spec_table_sel];

View file

@ -188,6 +188,8 @@ package cva5_types;
logic issue_hold;
logic fetch_flush;
logic fetch_ifence;
logic writeback_suppress;
logic rename_revert;
exception_packet_t exception;
logic pc_override;
logic [31:0] pc;

View file

@ -103,9 +103,10 @@ interface exception_interface;
exception_code_t code;
logic [31:0] tval;
logic [31:0] pc;
logic discard;
modport unit (output valid, possible, code, tval, pc);
modport econtrol (input valid, possible, code, tval, pc);
modport unit (output valid, possible, code, tval, pc, discard);
modport econtrol (input valid, possible, code, tval, pc, discard);
endinterface
interface fifo_interface #(parameter type DATA_TYPE = logic);