mirror of
https://github.com/openhwgroup/cva5.git
synced 2025-04-22 21:17:46 -04:00
Suppress writeback exceptions
This commit is contained in:
parent
e3740f5e35
commit
66fe5f7813
10 changed files with 73 additions and 30 deletions
|
@ -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),
|
||||
|
|
|
@ -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
|
||||
////////////////////////////////////////////////////
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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])
|
||||
);
|
||||
|
|
|
@ -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];
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue