diff --git a/decoder.sv b/decoder.sv index be769089..3b0cb812 100644 --- a/decoder.sv +++ b/decoder.sv @@ -80,8 +80,8 @@ module riscv_decoder // hwloop signals output logic [2:0] hwloop_we_o, // write enable for hwloop regs + output logic hwloop_target_mux_sel_o, // selects immediate for hwloop target output logic hwloop_start_mux_sel_o, // selects hwloop start address input - output logic hwloop_end_mux_sel_o, // selects hwloop end address input output logic hwloop_cnt_mux_sel_o, // selects hwloop counter input // jump/branches @@ -143,8 +143,8 @@ module riscv_decoder prepost_useincr_o = 1'b1; hwloop_we = 3'b0; + hwloop_target_mux_sel_o = 1'b0; hwloop_start_mux_sel_o = 1'b0; - hwloop_end_mux_sel_o = 1'b0; hwloop_cnt_mux_sel_o = 1'b0; csr_access_o = 1'b0; @@ -576,7 +576,7 @@ module riscv_decoder /////////////////////////////////////////////// `OPCODE_HWLOOP: begin - jump_target_mux_sel_o = `JT_HWLP; // get PC + I imm from jump target adder + hwloop_target_mux_sel_o = 1'b0; unique case (instr_rdata_i[14:12]) 3'b000: begin @@ -584,31 +584,44 @@ module riscv_decoder hwloop_we[0] = 1'b1; hwloop_start_mux_sel_o = 1'b0; end + 3'b001: begin // lp.endi: set end address to PC + I-type immediate hwloop_we[1] = 1'b1; - hwloop_end_mux_sel_o = 1'b0; // jump target end + 3'b010: begin // lp.count: initialize counter from rs1 hwloop_we[2] = 1'b1; hwloop_cnt_mux_sel_o = 1'b1; rega_used_o = 1'b1; end + 3'b011: begin // lp.counti: initialize counter from I-type immediate hwloop_we[2] = 1'b1; hwloop_cnt_mux_sel_o = 1'b0; end + 3'b100: begin // lp.setup: initialize counter from rs1, set start address to // next instruction and end address to PC + I-type immediate hwloop_we = 3'b111; hwloop_start_mux_sel_o = 1'b1; - hwloop_end_mux_sel_o = 1'b0; hwloop_cnt_mux_sel_o = 1'b1; rega_used_o = 1'b1; end + + 3'b101: begin + // lp.setupi: initialize counter from rs1, set start address to + // next instruction and end address to PC + I-type immediate + hwloop_we = 3'b111; + hwloop_target_mux_sel_o = 1'b1; + hwloop_start_mux_sel_o = 1'b1; + hwloop_cnt_mux_sel_o = 1'b1; + rega_used_o = 1'b1; + end + default: begin illegal_insn_o = 1'b1; end diff --git a/id_stage.sv b/id_stage.sv index 5cc0d53f..06b3d07e 100644 --- a/id_stage.sv +++ b/id_stage.sv @@ -252,10 +252,11 @@ module riscv_id_stage logic [2:0] hwloop_we; logic hwloop_jump; logic hwloop_enable; + logic hwloop_target_mux_sel; logic hwloop_start_mux_sel; - logic hwloop_end_mux_sel; logic hwloop_cnt_mux_sel; + logic [31:0] hwloop_target; logic [31:0] hwloop_start; logic [31:0] hwloop_end; logic [31:0] hwloop_cnt; @@ -331,23 +332,26 @@ module riscv_id_stage // hwloop register id assign hwloop_regid = instr[8:7]; // rd contains hwloop register id + // hwloop target mux + always_comb + begin + unique case (hwloop_target_mux_sel) + 1'b0: hwloop_target = current_pc_id_i + imm_i_type; + 1'b1: hwloop_target = current_pc_id_i + {imm_z_type[30:0], 1'b0}; + endcase + end + // hwloop start mux always_comb begin unique case (hwloop_start_mux_sel) - 1'b0: hwloop_start = jump_target; // for PC + I imm + 1'b0: hwloop_start = hwloop_target; // for PC + I imm 1'b1: hwloop_start = current_pc_if_i; // for next PC endcase end // hwloop end mux - always_comb - begin - unique case (hwloop_end_mux_sel) - 1'b0: hwloop_end = jump_target; // for PC + I imm - 1'b1: hwloop_end = jump_target; // TODO: PC + (Z imm << 1) for lp.setupi - endcase - end + assign hwloop_end = hwloop_target; // hwloop cnt mux always_comb @@ -372,9 +376,11 @@ module riscv_id_stage begin : jump_target_mux unique case (jump_target_mux_sel) `JT_JAL: jump_target = current_pc_id_i + imm_uj_type; - `JT_JALR: jump_target = regfile_data_ra_id + imm_i_type; // cannot forward rs1 as path is too long `JT_COND: jump_target = current_pc_id_i + imm_sb_type; - `JT_HWLP: jump_target = current_pc_id_i + imm_i_type; + + // JALR: Cannot forward RS1, since the path is too long + `JT_JALR: jump_target = regfile_data_ra_id + imm_i_type; + default: jump_target = regfile_data_ra_id + imm_i_type; endcase end @@ -592,8 +598,8 @@ module riscv_id_stage // hwloop signals .hwloop_we_o ( hwloop_we ), + .hwloop_target_mux_sel_o ( hwloop_target_mux_sel ), .hwloop_start_mux_sel_o ( hwloop_start_mux_sel ), - .hwloop_end_mux_sel_o ( hwloop_end_mux_sel ), .hwloop_cnt_mux_sel_o ( hwloop_cnt_mux_sel ), // jump/branches diff --git a/include/defines.sv b/include/defines.sv index 0bf22f6e..93c48516 100644 --- a/include/defines.sv +++ b/include/defines.sv @@ -280,7 +280,6 @@ `define BRANCH_COND 2'b11 // conditional branches // jump target mux -`define JT_HWLP 2'b00 `define JT_JAL 2'b01 `define JT_JALR 2'b10 `define JT_COND 2'b11