diff --git a/alu.sv b/alu.sv index 88fa9f77..61a87a58 100644 --- a/alu.sv +++ b/alu.sv @@ -167,9 +167,9 @@ module riscv_alu end assign is_equal = (operand_a_i == operand_b_i); - assign is_greater = $signed({operand_a_i[31] & cmp_signed, operand_a_i[30:0]}) + assign is_greater = $signed({operand_a_i[31] & cmp_signed, operand_a_i[31:0]}) > - $signed({operand_b_i[31] & cmp_signed, operand_b_i[30:0]}); + $signed({operand_b_i[31] & cmp_signed, operand_b_i[31:0]}); // generate comparison result always_comb diff --git a/cs_registers.sv b/cs_registers.sv index 71e43bb6..0836fd13 100644 --- a/cs_registers.sv +++ b/cs_registers.sv @@ -178,7 +178,7 @@ module riscv_cs_registers unique case (csr_op_i) `CSR_OP_WRITE: csr_wdata_int = csr_wdata_i; `CSR_OP_SET: csr_wdata_int = csr_wdata_i | csr_rdata_o; - `CSR_OP_CLEAR: csr_wdata_int = csr_wdata_i & ~(csr_rdata_o); + `CSR_OP_CLEAR: csr_wdata_int = (~csr_wdata_i) & csr_rdata_o; `CSR_OP_NONE: begin csr_wdata_int = csr_wdata_i; diff --git a/id_stage.sv b/id_stage.sv index 9202d00e..e31311e0 100644 --- a/id_stage.sv +++ b/id_stage.sv @@ -46,6 +46,8 @@ module riscv_id_stage input logic [31:0] instr_rdata_i, // comes from pipeline of IF stage output logic instr_req_o, + input logic id_execute_i, + // Jumps and branches output logic [1:0] jump_in_id_o, output logic [1:0] jump_in_ex_o, @@ -53,6 +55,7 @@ module riscv_id_stage output logic [31:0] jump_target_o, // IF and ID stage signals + output logic clear_id_execute_o, output logic pc_set_o, output logic [2:0] pc_mux_sel_o, output logic [1:0] exc_pc_mux_o, @@ -309,6 +312,14 @@ module riscv_id_stage regfile_waddr_id : regfile_addr_ra_id; + // ID execute signal control + // This signal is used to detect when an instruction first enters the ID + // stage. Based on this hardware loops are decremented and it's also useful + // for exceptions, i.e. to suppress the illegal instruction signal during + // an if stall of a jump. + assign clear_id_execute_o = (~jr_stall) | (|hwloop_end_addr); + + /////////////////////////////////////////////// // _ ___ ___ ___ ___ ____ // // | | | \ \ / / | / _ \ / _ \| _ \ // @@ -773,7 +784,7 @@ module riscv_id_stage .hwloop_regid_i ( hwloop_regid ), // from controller - .stall_id_i ( ~id_valid_o ), + .stall_id_i ( id_execute_i ), // to hwloop controller .hwloop_start_addr_o ( hwloop_start_addr ), diff --git a/if_stage.sv b/if_stage.sv index 75149bdb..4d38a903 100644 --- a/if_stage.sv +++ b/if_stage.sv @@ -55,6 +55,7 @@ module riscv_if_stage input logic [RDATA_WIDTH-1:0] instr_rdata_i, // Output of IF Pipeline stage + output logic id_execute_o, // execute current instruction in ID output logic [31:0] instr_rdata_id_o, // read instruction is sampled and sent to ID stage for decoding output logic is_compressed_id_o, // compressed decoder thinks this is a compressed instruction output logic illegal_c_insn_id_o, // compressed decoder thinks this is an invalid instruction @@ -62,6 +63,7 @@ module riscv_if_stage output logic [31:0] current_pc_id_o, // Forwarding ports - control signals + input logic clear_id_execute_i, // clear execute bit input logic pc_set_i, // set the program counter to a new value input logic [31:0] exception_pc_reg_i, // address used to restore PC when the interrupt/exception is served input logic [2:0] pc_mux_sel_i, // sel for pc multiplexer @@ -394,6 +396,7 @@ module riscv_if_stage begin : IF_ID_PIPE_REGISTERS if (rst_n == 1'b0) begin + id_execute_o <= 1'b0; instr_rdata_id_o <= '0; illegal_c_insn_id_o <= 1'b0; is_compressed_id_o <= 1'b0; @@ -401,12 +404,16 @@ module riscv_if_stage end else begin + if (clear_id_execute_i) + id_execute_o <= 1'b0; + if (if_valid_o) begin : ENABLED_PIPE - instr_rdata_id_o <= instr_decompressed; - illegal_c_insn_id_o <= illegal_c_insn; - is_compressed_id_o <= instr_compressed_int; - current_pc_id_o <= current_pc_if_o; + id_execute_o <= 1'b0; + instr_rdata_id_o <= instr_decompressed; + illegal_c_insn_id_o <= illegal_c_insn; + is_compressed_id_o <= instr_compressed_int; + current_pc_id_o <= current_pc_if_o; end end end diff --git a/riscv_core.sv b/riscv_core.sv index 24510c4a..b1fcb056 100644 --- a/riscv_core.sv +++ b/riscv_core.sv @@ -83,11 +83,14 @@ module riscv_core // IF/ID signals + logic id_execute; logic [31:0] instr_rdata_id; // Instruction sampled inside IF stage logic is_compressed_id; logic illegal_c_insn_id; // Illegal compressed instruction sent to ID stage logic [31:0] current_pc_if; // Current Program counter logic [31:0] current_pc_id; // Current Program counter + + logic clear_id_execute; logic pc_set; logic [2:0] pc_mux_sel_id; // Mux selector for next PC logic [1:0] exc_pc_mux_id; // Mux selector for exception PC @@ -250,16 +253,18 @@ module riscv_core .instr_rdata_i ( instr_rdata_i ), // outputs to ID stage + .id_execute_o ( id_execute ), .instr_rdata_id_o ( instr_rdata_id ), .is_compressed_id_o ( is_compressed_id ), .illegal_c_insn_id_o ( illegal_c_insn_id ), - .current_pc_if_o ( current_pc_if ), // current pc in IF stage - .current_pc_id_o ( current_pc_id ), // current pc in ID stage + .current_pc_if_o ( current_pc_if ), + .current_pc_id_o ( current_pc_id ), // control signals + .clear_id_execute_i ( clear_id_execute ), .pc_set_i ( pc_set ), - .exception_pc_reg_i ( epcr ), // Exception PC register - .pc_mux_sel_i ( pc_mux_sel_id ), // sel for pc multiplexer + .exception_pc_reg_i ( epcr ), // exception return address + .pc_mux_sel_i ( pc_mux_sel_id ), // sel for pc multiplexer .exc_pc_mux_i ( exc_pc_mux_id ), .exc_vec_pc_mux_i ( exc_vec_pc_mux_id ), @@ -312,12 +317,16 @@ module riscv_core .instr_rdata_i ( instr_rdata_id ), .instr_req_o ( instr_req_int ), + .id_execute_i ( id_execute ), + // Jumps and branches .jump_in_id_o ( jump_in_id ), .jump_in_ex_o ( jump_in_ex ), .branch_decision_i ( branch_decision ), .jump_target_o ( jump_target_id ), + // IF and ID control signals + .clear_id_execute_o ( clear_id_execute ), .pc_set_o ( pc_set ), .pc_mux_sel_o ( pc_mux_sel_id ), .exc_pc_mux_o ( exc_pc_mux_id ),