diff --git a/controller.sv b/controller.sv index cbe313bc..4e796b4b 100644 --- a/controller.sv +++ b/controller.sv @@ -216,7 +216,6 @@ module riscv_controller if (fetch_enable_i || exc_req_i) begin - // TODO: Check if we need to handle IRQs here ctrl_fsm_ns = FIRST_FETCH; end end // case: SLEEP @@ -242,11 +241,9 @@ module riscv_controller pc_set_o = 1'b1; exc_ack_o = 1'b1; - // TODO: Check - if (jump_in_dec_i == `BRANCH_JALR || jump_in_dec_i == `BRANCH_JAL) - save_pc_if_o = 1'b1; - else - save_pc_id_o = 1'b1; + // TODO: This assumes that the pipeline is always flushed before + // going to sleep. + save_pc_id_o = 1'b1; end end @@ -289,11 +286,7 @@ module riscv_controller pc_set_o = 1'b1; exc_ack_o = 1'b1; - // TODO: Check - if (jump_in_dec_i == `BRANCH_JALR || jump_in_dec_i == `BRANCH_JAL) - save_pc_if_o = 1'b1; - else - save_pc_id_o = 1'b1; + save_pc_id_o = 1'b1; // we don't have to change our current state here as the prefetch // buffer is automatically invalidated, thus the next instruction diff --git a/exc_controller.sv b/exc_controller.sv index 139495aa..3bc8bbcb 100644 --- a/exc_controller.sv +++ b/exc_controller.sv @@ -43,6 +43,9 @@ module riscv_exc_controller input logic ecall_insn_i, // ecall instruction encountered input logic eret_insn_i, // eret instruction encountered + input logic lsu_load_err_i, + input logic lsu_store_err_i, + // to CSR output logic [5:0] cause_o, output logic save_cause_o @@ -58,7 +61,11 @@ module riscv_exc_controller integer i; - assign req_int = illegal_insn_i | ecall_insn_i | (irq_enable_i & (|irq_i)); + assign req_int = illegal_insn_i + | ecall_insn_i + | lsu_load_err_i + | lsu_store_err_i + | (irq_enable_i & (|irq_i)); // Exception cause and ISR address selection @@ -85,6 +92,16 @@ module riscv_exc_controller cause_int = 6'b0_00010; pc_mux_int = `EXC_PC_ILLINSN; end + + if (lsu_load_err_i) begin + cause_int = 6'b0_00101; + pc_mux_int = `EXC_PC_LOAD; + end + + if (lsu_store_err_i) begin + cause_int = 6'b0_00111; + pc_mux_int = `EXC_PC_STORE; + end end always_ff @(posedge clk, negedge rst_n) diff --git a/id_stage.sv b/id_stage.sv index 95991926..9202d00e 100644 --- a/id_stage.sv +++ b/id_stage.sv @@ -129,6 +129,9 @@ module riscv_id_stage output logic save_pc_if_o, output logic save_pc_id_o, + input logic lsu_load_err_i, + input logic lsu_store_err_i, + // Debug Unit Signals input logic dbg_flush_pipe_i, input logic dbg_st_en_i, @@ -719,6 +722,9 @@ module riscv_id_stage .ecall_insn_i ( is_decoding_o & ecall_insn_dec ), .eret_insn_i ( is_decoding_o & eret_insn_dec ), + .lsu_load_err_i ( lsu_load_err_i ), + .lsu_store_err_i ( lsu_store_err_i ), + .cause_o ( exc_cause_o ), .save_cause_o ( save_exc_cause_o ) ); diff --git a/if_stage.sv b/if_stage.sv index bd515576..75149bdb 100644 --- a/if_stage.sv +++ b/if_stage.sv @@ -149,7 +149,9 @@ module riscv_if_stage unique case (exc_pc_mux_i) `EXC_PC_ILLINSN: exc_pc = { boot_addr_i[31:8], `EXC_OFF_ILLINSN }; `EXC_PC_ECALL: exc_pc = { boot_addr_i[31:8], `EXC_OFF_ECALL }; + `EXC_PC_LOAD: exc_pc = { boot_addr_i[31:8], `EXC_OFF_LSUERR }; `EXC_PC_IRQ: exc_pc = { boot_addr_i[31:8], 1'b0, exc_vec_pc_mux_i[4:0], 2'b0 }; + // TODO: Add case for EXC_PC_STORE as soon as it differs from load default: exc_pc = { boot_addr_i[31:8], `EXC_OFF_ILLINSN }; endcase end @@ -197,7 +199,7 @@ module riscv_if_stage .clk ( clk ), .rst_n ( rst_n ), - .req_i ( 1'b1 ), // TODO: FETCH_ENABLE! + .req_i ( 1'b1 ), .branch_i ( branch_req ), .addr_i ( fetch_addr_n ), @@ -226,7 +228,7 @@ module riscv_if_stage .clk ( clk ), .rst_n ( rst_n ), - .req_i ( 1'b1 ), // TODO: FETCH_ENABLE! + .req_i ( 1'b1 ), .branch_i ( branch_req ), .addr_i ( fetch_addr_n ), diff --git a/include/defines.sv b/include/defines.sv index 8de87ca7..35b3bd0d 100644 --- a/include/defines.sv +++ b/include/defines.sv @@ -307,7 +307,9 @@ // Exception PC mux selector defines `define EXC_PC_ILLINSN 2'b00 `define EXC_PC_ECALL 2'b01 -`define EXC_PC_IRQ 2'b10 +`define EXC_PC_LOAD 2'b10 +`define EXC_PC_STORE 2'b10 +`define EXC_PC_IRQ 2'b11 // Exceptions offsets // target address = {boot_addr[31:8], EXC_OFF} (boot_addr must be 32 BYTE aligned!) @@ -315,6 +317,7 @@ `define EXC_OFF_RST 8'h80 `define EXC_OFF_ILLINSN 8'h84 `define EXC_OFF_ECALL 8'h88 +`define EXC_OFF_LSUERR 8'h8c // Hardware loop registers diff --git a/riscv_core.sv b/riscv_core.sv index 692780ec..24510c4a 100644 --- a/riscv_core.sv +++ b/riscv_core.sv @@ -95,6 +95,9 @@ module riscv_core logic branch_done; // Branch already done + logic lsu_load_err; + logic lsu_store_err; + // ID performance counter signals logic is_decoding; @@ -134,7 +137,6 @@ module riscv_core logic [4:0] regfile_alu_waddr_ex; logic regfile_alu_we_ex; - logic [4:0] regfile_alu_waddr_fw; logic regfile_alu_we_fw; logic [31:0] regfile_alu_wdata_fw; @@ -388,6 +390,8 @@ module riscv_core .save_exc_cause_o ( save_exc_cause ), .save_pc_if_o ( save_pc_if ), // control signal to save pc .save_pc_id_o ( save_pc_id ), // control signal to save pc + .lsu_load_err_i ( lsu_load_err ), + .lsu_store_err_i ( lsu_store_err ), // Debug Unit Signals .dbg_flush_pipe_i ( dbg_flush_pipe ),