diff --git a/alu.sv b/alu.sv index 0a66dd21..ea223f3d 100644 --- a/alu.sv +++ b/alu.sv @@ -35,6 +35,7 @@ module riscv_alu input logic [ 1:0] vector_mode_i, input logic [ 4:0] imm_bmask_a_i, input logic [ 4:0] imm_bmask_b_i, + input logic [ 1:0] imm_vec_ext_i, output logic [31:0] result_o, output logic comparison_result_o @@ -379,21 +380,21 @@ module riscv_alu begin sel_minmax[3:0] = is_greater ^ {4{do_min}}; - // if(operator_i == `ALU_INS) - // begin - // if(vector_mode_i == `VEC_MODE16) - // begin - // sel_minmax[1:0] = {2{vec_ext_i[0]}}; - // sel_minmax[3:2] = ~{2{vec_ext_i[0]}}; - // end - // else // `VEC_MODE8 - // begin - // sel_minmax[0] = (vec_ext_i != 2'b00); - // sel_minmax[1] = (vec_ext_i != 2'b01); - // sel_minmax[2] = (vec_ext_i != 2'b10); - // sel_minmax[3] = (vec_ext_i != 2'b11); - // end - // end + if(operator_i == `ALU_INS) + begin + if(vector_mode_i == `VEC_MODE16) + begin + sel_minmax[1:0] = {2{imm_vec_ext_i[0]}}; + sel_minmax[3:2] = ~{2{imm_vec_ext_i[0]}}; + end + else // `VEC_MODE8 + begin + sel_minmax[0] = (imm_vec_ext_i != 2'b00); + sel_minmax[1] = (imm_vec_ext_i != 2'b01); + sel_minmax[2] = (imm_vec_ext_i != 2'b10); + sel_minmax[3] = (imm_vec_ext_i != 2'b11); + end + end end assign result_minmax[31:24] = (sel_minmax[3] == 1'b1) ? operand_a_i[31:24] : minmax_b[31:24]; @@ -413,23 +414,47 @@ module riscv_alu ////////////////////////////////////////////////// logic [31:0] result_ext; + logic [15:0] ext_half; + + always_comb + begin + case (vector_mode_i) + `VEC_MODE16: begin + if (imm_vec_ext_i[0]) + ext_half[15:0] = operand_a_i[31:16]; + else + ext_half[15:0] = operand_a_i[15: 0]; + end + + `VEC_MODE8: begin + case (imm_vec_ext_i[1:0]) + 2'b11: ext_half[7:0] = operand_a_i[31:24]; + 2'b10: ext_half[7:0] = operand_a_i[23:16]; + 2'b01: ext_half[7:0] = operand_a_i[15: 8]; + 2'b00: ext_half[7:0] = operand_a_i[ 7: 0]; + endcase + end + + default: ext_half[15:0] = operand_a_i[15:0]; + endcase + end always_comb begin // zero extend byte - result_ext = {24'b0, operand_a_i[7:0]}; + result_ext = {24'b0, ext_half[7:0]}; // sign extend byte if (operator_i == `ALU_EXTBS) - result_ext = {{24 {operand_a_i[7]}}, operand_a_i[7:0]}; + result_ext = {{24 {operand_a_i[7]}}, ext_half[7:0]}; // zero extend half word if(operator_i == `ALU_EXTHZ) - result_ext = {16'b0, operand_a_i[15:0]}; + result_ext = {16'b0, ext_half[15:0]}; // sign extend half word if(operator_i == `ALU_EXTHS) - result_ext = {{16 {operand_a_i[15]}}, operand_a_i[15:0]}; + result_ext = {{16 {operand_a_i[15]}}, ext_half[15:0]}; end @@ -581,10 +606,11 @@ module riscv_alu `ALU_EXTHZ, `ALU_EXTHS: result_o = result_ext; - // Min/Max/Abs + // Min/Max/Abs/Ins `ALU_MIN, `ALU_MINU, `ALU_MAX, `ALU_MAXU, - `ALU_ABS: result_o = result_minmax; + `ALU_ABS, + `ALU_INS: result_o = result_minmax; // Comparison Operations `ALU_EQ, `ALU_NE, `ALU_GTU, `ALU_GEU, `ALU_LTU, `ALU_LEU, `ALU_GTS, `ALU_GES, `ALU_LTS, `ALU_LES: diff --git a/decoder.sv b/decoder.sv index 8530a514..9751e322 100644 --- a/decoder.sv +++ b/decoder.sv @@ -574,6 +574,27 @@ module riscv_decoder 6'b01101_0: begin alu_operator_o = `ALU_AND; immediate_mux_sel_o = `IMM_VS; end // pv.and 6'b01110_0: begin alu_operator_o = `ALU_ABS; immediate_mux_sel_o = `IMM_VS; end // pv.abs + 6'b01111_0: begin // pv.extract + if (instr_rdata_i[12]) + alu_operator_o = `ALU_EXTBS; + else + alu_operator_o = `ALU_EXTHS; + end + + 6'b10000_0: begin // pv.extractu + if (instr_rdata_i[12]) + alu_operator_o = `ALU_EXTBZ; + else + alu_operator_o = `ALU_EXTHZ; + end + + 6'b10001_0: begin // pv.insert + alu_operator_o = `ALU_INS; + regc_used_o = 1'b1; + regc_mux_o = `REGC_RD; + alu_op_b_mux_sel_o = `OP_B_REGC_OR_FWD; + end + // comparisons, always have bit 26 set 6'b00000_1: begin alu_operator_o = `ALU_EQ; immediate_mux_sel_o = `IMM_VS; end // pv.cmpeq 6'b00001_1: begin alu_operator_o = `ALU_NE; immediate_mux_sel_o = `IMM_VS; end // pv.cmpne diff --git a/ex_stage.sv b/ex_stage.sv index 5f053aec..4ef51269 100644 --- a/ex_stage.sv +++ b/ex_stage.sv @@ -41,6 +41,7 @@ module riscv_ex_stage input logic [31:0] alu_operand_c_i, input logic [ 4:0] imm_bmask_a_i, input logic [ 4:0] imm_bmask_b_i, + input logic [ 1:0] imm_vec_ext_i, input logic [ 1:0] alu_vec_mode_i, // Multiplier signals @@ -128,6 +129,7 @@ module riscv_ex_stage .vector_mode_i ( alu_vec_mode_i ), .imm_bmask_a_i ( imm_bmask_a_i ), .imm_bmask_b_i ( imm_bmask_b_i ), + .imm_vec_ext_i ( imm_vec_ext_i ), .result_o ( alu_result ), .comparison_result_o ( alu_cmp_result ) diff --git a/id_stage.sv b/id_stage.sv index 774b2a77..23bfba6c 100644 --- a/id_stage.sv +++ b/id_stage.sv @@ -89,6 +89,7 @@ module riscv_id_stage output logic [31:0] alu_operand_c_ex_o, output logic [ 4:0] imm_bmask_a_ex_o, output logic [ 4:0] imm_bmask_b_ex_o, + output logic [ 1:0] imm_vec_ext_ex_o, output logic [ 1:0] alu_vec_mode_ex_o, output logic [4:0] regfile_waddr_ex_o, @@ -306,6 +307,7 @@ module riscv_id_stage // Immediates for ID logic [ 4:0] imm_bmask_a_id; logic [ 4:0] imm_bmask_b_id; + logic [ 1:0] imm_vec_ext_id; logic [ 1:0] alu_vec_mode; logic scalar_replication; @@ -594,6 +596,7 @@ module riscv_id_stage assign imm_bmask_b_id = ((alu_operator == `ALU_BCLR) || (alu_operator == `ALU_BSET) || (alu_operator == `ALU_BINS)) ? imm_s2_type[4:0] : 0; + assign imm_vec_ext_id = imm_vu_type[1:0]; ///////////////////////////////////////////////////////// // ____ _____ ____ ___ ____ _____ _____ ____ ____ // @@ -936,6 +939,7 @@ module riscv_id_stage alu_operand_c_ex_o <= '0; imm_bmask_a_ex_o <= '0; imm_bmask_b_ex_o <= '0; + imm_vec_ext_ex_o <= '0; alu_vec_mode_ex_o <= '0; mult_operand_a_ex_o <= '0; @@ -1001,6 +1005,7 @@ module riscv_id_stage alu_operand_c_ex_o <= alu_operand_c; imm_bmask_a_ex_o <= imm_bmask_a_id; imm_bmask_b_ex_o <= imm_bmask_b_id; + imm_vec_ext_ex_o <= imm_vec_ext_id; alu_vec_mode_ex_o <= alu_vec_mode; end diff --git a/include/riscv_defines.sv b/include/riscv_defines.sv index d262c131..0c16cc43 100644 --- a/include/riscv_defines.sv +++ b/include/riscv_defines.sv @@ -145,11 +145,15 @@ // Absolute value `define ALU_ABS 6'b010100 +// Insert/extract +`define ALU_INS 6'b101101 + // min/max `define ALU_MIN 6'b010000 `define ALU_MINU 6'b010001 `define ALU_MAX 6'b010010 `define ALU_MAXU 6'b010011 +`define ALU_MAXU 6'b010011 // vector modes diff --git a/riscv_core.sv b/riscv_core.sv index 06c807ad..85e1663b 100644 --- a/riscv_core.sv +++ b/riscv_core.sv @@ -129,6 +129,7 @@ module riscv_core logic [31:0] alu_operand_c_ex; logic [ 4:0] imm_bmask_a_ex; logic [ 4:0] imm_bmask_b_ex; + logic [ 1:0] imm_vec_ext_ex; logic [ 1:0] alu_vec_mode_ex; // Multiplier Control @@ -383,6 +384,7 @@ module riscv_core .alu_operand_c_ex_o ( alu_operand_c_ex ), .imm_bmask_a_ex_o ( imm_bmask_a_ex ), .imm_bmask_b_ex_o ( imm_bmask_b_ex ), + .imm_vec_ext_ex_o ( imm_vec_ext_ex ), .alu_vec_mode_ex_o ( alu_vec_mode_ex ), .regfile_waddr_ex_o ( regfile_waddr_ex ), @@ -486,6 +488,7 @@ module riscv_core .alu_operand_c_i ( alu_operand_c_ex ), // from ID/EX pipe registers .imm_bmask_a_i ( imm_bmask_a_ex ), // from ID/EX pipe registers .imm_bmask_b_i ( imm_bmask_b_ex ), // from ID/EX pipe registers + .imm_vec_ext_i ( imm_vec_ext_ex ), // from ID/EX pipe registers .alu_vec_mode_i ( alu_vec_mode_ex ), // from ID/EX pipe registers // Multipler