diff --git a/ariane.sv b/ariane.sv index 06c1636e1..a0846a500 100644 --- a/ariane.sv +++ b/ariane.sv @@ -114,6 +114,7 @@ module ariane .illegal_c_insn_id_o ( illegal_c_insn_id_o ), .pc_if_o ( pc_if_o ), .pc_id_o ( pc_id_o ), + .ex_o ( exception_o ), .boot_addr_i ( boot_addr_i ) ); @@ -129,7 +130,7 @@ module ariane .instruction_i ( instr_rdata_id_o ), .instruction_valid_i ( instr_valid_id_o ), .pc_if_i ( pc_if_o ), // PC from if - .ex_i ( '{default: 0} ), // exception from if + .ex_i ( exception_o ), // exception from if .ready_o ( ready_o ), .operator_o ( operator_o ), .operand_a_o ( operand_a_o ), diff --git a/decoder.sv b/decoder.sv index 72d1801da..188f6d25e 100644 --- a/decoder.sv +++ b/decoder.sv @@ -41,7 +41,6 @@ module decoder ( imm_select = NOIMM; illegal_instr_o = 1'b0; instruction_o.valid = 1'b0; - instruction_o.ex = ex_i; instruction_o.fu = NONE; instruction_o.op = ADD; instruction_o.rs1 = 5'b0; @@ -108,7 +107,9 @@ module decoder ( default: illegal_instr_o = 1'b1; endcase end - + // -------------------------------- + // Reg-Immediate Operations + // -------------------------------- OPCODE_OPIMM: begin instruction_o.fu = ALU; imm_select = IIMM; @@ -214,7 +215,9 @@ module decoder ( endcase end end - + // -------------------------------- + // Sign extend immediate + // -------------------------------- always_comb begin : sign_extend imm_i_type = { {52 {instruction_i[31]}}, instruction_i[31:20] }; imm_iz_type = { 52'b0, instruction_i[31:20] }; @@ -229,7 +232,7 @@ module decoder ( imm_vs_type = { {58 {instruction_i[24]}}, instruction_i[24:20], instruction_i[25] }; imm_vu_type = { 58'b0, instruction_i[24:20], instruction_i[25] }; - // NOIMM, PCIMM, IIMM, SIMM, BIMM, BIMM, UIMM, JIMM + // NOIMM, PCIMM, IIMM, SIMM, BIMM, BIMM, UIMM, JIMM // select immediate case (imm_select) PCIMM: begin @@ -262,5 +265,15 @@ module decoder ( end endcase end + // -------------------------------- + // Exception handling + // -------------------------------- + always_comb begin : exception_handling + instruction_o.ex = ex_i; + if (~ex_i.valid && illegal_instr_o) begin + instruction_o.ex.valid = 1'b1; + instruction_o.ex.cause = ILLEGAL_INSTR; + end + end endmodule \ No newline at end of file diff --git a/id_stage.sv b/id_stage.sv index 4d6dc1077..38195e63a 100644 --- a/id_stage.sv +++ b/id_stage.sv @@ -140,5 +140,4 @@ module id_stage #( .we_a_i (we_a_i ) ); - endmodule \ No newline at end of file diff --git a/if_stage.sv b/if_stage.sv index 13c85420e..168e69f6b 100644 --- a/if_stage.sv +++ b/if_stage.sv @@ -49,6 +49,7 @@ module if_stage ( output logic illegal_c_insn_id_o, // compressed decoder thinks this is an invalid instruction output logic [63:0] pc_if_o, output logic [63:0] pc_id_o, + output exception ex_o, input logic [63:0] boot_addr_i ); @@ -184,6 +185,7 @@ module if_stage ( illegal_c_insn_id_o <= 1'b0; is_compressed_id_o <= 1'b0; pc_id_o <= '0; + ex_o <= '{default: 0}; end else begin @@ -195,6 +197,9 @@ module if_stage ( illegal_c_insn_id_o <= illegal_c_insn; is_compressed_id_o <= instr_compressed_int; pc_id_o <= pc_if_o; + ex_o.epc <= pc_if_o; + ex_o.cause <= 64'b0; // TODO: Output exception + ex_o.valid <= 1'b0; // TODO: Output exception end else if (clear_instr_valid_i) begin instr_valid_id_o <= 1'b0; end diff --git a/include/ariane_pkg.svh b/include/ariane_pkg.svh index 1d89df43d..ecc0001d9 100644 --- a/include/ariane_pkg.svh +++ b/include/ariane_pkg.svh @@ -73,7 +73,6 @@ package ariane_pkg; logic valid; // is the result valid logic use_imm; // should we use the immediate as operand b? logic use_pc; // set if we need to use the PC as operand A, PC from exception - // logic [63:0] imm; // maybe we can get this into the results field exception ex; // exception has occurred } scoreboard_entry; @@ -154,4 +153,18 @@ package ariane_pkg; PRIV_LVL_U = 2'b00 } priv_lvl_t; + // ---------------------- + // Exception Cause Codes + // ---------------------- + localparam INSTR_ADDR_MISALIGNED = 64'h0; + localparam INSTR_ACCESS_FAULT = 64'h1; + localparam ILLEGAL_INSTR = 64'h2; + localparam BREAKPOINT = 64'h3; + localparam LD_ADDR_MISALIGNED = 64'h4; + localparam LD_ACCESS_FAULT = 64'h5; + localparam ST_ADDR_MISALIGNED = 64'h6; + localparam ST_ACCESS_FAULT = 64'h7; + localparam ENV_CALL_UMODE = 64'h8; + localparam ENV_CALL_SMODE = 64'h9; + localparam ENV_CALL_MMODE = 64'hB; endpackage