diff --git a/alu.sv b/alu.sv index 6ed3b321..7ed2873c 100644 --- a/alu.sv +++ b/alu.sv @@ -36,8 +36,8 @@ module riscv_alu input logic [31:0] operand_c_i, 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 [ 4:0] bmask_a_i, + input logic [ 4:0] bmask_b_i, input logic [ 1:0] imm_vec_ext_i, output logic [31:0] result_o, @@ -77,8 +77,9 @@ module riscv_alu assign operand_b_neg = ~operand_b_i; - logic [5:0] div_shift; - logic div_valid; + logic [5:0] div_shift; + logic div_valid; + logic [31:0] bmask; ////////////////////////////////////////////////////////////////////////////////////////// // ____ _ _ _ _ _ _ _ _ // @@ -94,11 +95,14 @@ module riscv_alu logic [31:0] adder_result; logic [35:0] adder_result_expanded; + assign adder_op_b_negate = (operator_i == `ALU_SUB) || (operator_i == `ALU_SUBR) || + (operator_i == `ALU_SUBU) || (operator_i == `ALU_SUBR); + // prepare operand a assign adder_op_a = (operator_i == `ALU_ABS) ? operand_a_neg : operand_a_i; // prepare operand b - assign adder_op_b = (operator_i == `ALU_SUB) ? operand_b_neg : operand_b_i; + assign adder_op_b = adder_op_b_negate ? operand_b_neg : operand_b_i; // prepare carry always_comb @@ -121,7 +125,7 @@ module riscv_alu adder_in_b[ 27] = 1'b0; adder_in_b[35:28] = adder_op_b[31:24]; - if ((operator_i == `ALU_SUB) || (operator_i == `ALU_ABS)) begin + if (adder_op_b_negate || (operator_i == `ALU_ABS)) begin // special case for subtractions and absolute number calculations adder_in_b[0] = 1'b1; @@ -161,11 +165,14 @@ module riscv_alu adder_result_expanded[8:1]}; - // averaging by right shifting of one bit - logic [31:0] result_avg; + // normalization stage + logic [31:0] adder_round_value; + logic [31:0] adder_round_result; - assign result_avg[30:0] = adder_result[31:1]; - assign result_avg[31] = (operator_i == `ALU_AVGU) ? 1'b0 : adder_result[31]; + assign adder_round_value = ((operator_i == `ALU_ADDR) || (operator_i == `ALU_SUBR) || + (operator_i == `ALU_ADDUR) || (operator_i == `ALU_SUBUR)) ? + {1'b0, bmask[31:1]} : '0; + assign adder_round_result = adder_result + adder_round_value; //////////////////////////////////////// @@ -181,6 +188,7 @@ module riscv_alu logic [31:0] shift_amt_left; // amount of shift, if to the left logic [31:0] shift_amt; // amount of shift, to the right logic [31:0] shift_amt_int; // amount of shift, used for the actual shifters + logic [31:0] shift_amt_norm; // amount of shift, used for normalization logic [31:0] shift_op_a; // input of the shifter logic [31:0] shift_result; logic [31:0] shift_right_result; @@ -220,9 +228,22 @@ module riscv_alu (operator_i == `ALU_DIV) || (operator_i == `ALU_DIVU) || (operator_i == `ALU_REM) || (operator_i == `ALU_REMU); + assign shift_use_round = (operator_i == `ALU_ADD) || (operator_i == `ALU_SUB) || + (operator_i == `ALU_ADDR) || (operator_i == `ALU_SUBR) || + (operator_i == `ALU_ADDU) || (operator_i == `ALU_SUBU) || + (operator_i == `ALU_ADDUR) || (operator_i == `ALU_SUBUR); + + assign shift_arithmetic = (operator_i == `ALU_SRA) || + (operator_i == `ALU_ADD) || (operator_i == `ALU_SUB) || + (operator_i == `ALU_ADDR) || (operator_i == `ALU_SUBR); + // choose the bit reversed or the normal input for shift operand a - assign shift_op_a = (shift_left == 1'b1) ? operand_a_rev : operand_a_i; - assign shift_amt_int = (shift_left == 1'b1) ? shift_amt_left : shift_amt; + assign shift_op_a = shift_left ? operand_a_rev : + (shift_use_round ? adder_round_result : operand_a_i); + assign shift_amt_int = shift_use_round ? shift_amt_norm : + (shift_left ? shift_amt_left : shift_amt); + + assign shift_amt_norm = {4{3'b000, bmask_b_i}}; // right shifts, we let the synthesizer optimize this @@ -231,7 +252,7 @@ module riscv_alu case(vector_mode_i) `VEC_MODE16: begin - if(operator_i == `ALU_SRA) + if(shift_arithmetic) begin shift_right_result[31:16] = $unsigned( $signed(shift_op_a[31:16]) >>> shift_amt_int[19:16] ); shift_right_result[15: 0] = $unsigned( $signed(shift_op_a[15: 0]) >>> shift_amt_int[ 3: 0] ); @@ -245,7 +266,7 @@ module riscv_alu `VEC_MODE8: begin - if(operator_i == `ALU_SRA) + if(shift_arithmetic) begin shift_right_result[31:24] = $unsigned( $signed(shift_op_a[31:24]) >>> shift_amt_int[26:24] ); shift_right_result[23:16] = $unsigned( $signed(shift_op_a[23:16]) >>> shift_amt_int[18:16] ); @@ -263,7 +284,7 @@ module riscv_alu default: // VEC_MODE32 begin - if(operator_i == `ALU_SRA) + if(shift_arithmetic) shift_right_result = $unsigned( $signed(shift_op_a) >>> shift_amt_int[4:0] ); else if(operator_i == `ALU_ROR) shift_right_result = {shift_op_a, shift_op_a} >> shift_amt_int[4:0]; @@ -461,6 +482,8 @@ module riscv_alu always_comb begin + ext_half = 'x; + case (vector_mode_i) `VEC_MODE16: begin if (imm_vec_ext_i[0]) @@ -490,7 +513,7 @@ module riscv_alu // sign extend byte if (operator_i == `ALU_EXTBS) - result_ext = {{24 {operand_a_i[7]}}, ext_half[7:0]}; + result_ext = {{24 {ext_half[7]}}, ext_half[7:0]}; // zero extend half word if(operator_i == `ALU_EXTHZ) @@ -498,7 +521,7 @@ module riscv_alu // sign extend half word if(operator_i == `ALU_EXTHS) - result_ext = {{16 {operand_a_i[15]}}, ext_half[15:0]}; + result_ext = {{16 {ext_half[15]}}, ext_half[15:0]}; end @@ -739,21 +762,21 @@ module riscv_alu logic extract_is_signed; logic extract_sign; - logic [31:0] bmask, bmask_first, bmask_inv; + logic [31:0] bmask_first, bmask_inv; logic [31:0] bextins_and; logic [31:0] bextins_result, bclr_result, bset_result; // construct bit mask for insert/extract/bclr/bset // bmask looks like this 00..0011..1100..00 - assign bmask_first = {32'hFFFFFFFE} << imm_bmask_a_i; - assign bmask = (~bmask_first) << imm_bmask_b_i; + assign bmask_first = {32'hFFFFFFFE} << bmask_a_i; + assign bmask = (~bmask_first) << bmask_b_i; assign bmask_inv = ~bmask; assign bextins_and = (operator_i == `ALU_BINS) ? operand_c_i : {32{extract_sign}}; assign extract_is_signed = (operator_i == `ALU_BEXT); - assign extract_sign = extract_is_signed & shift_result[imm_bmask_a_i]; + assign extract_sign = extract_is_signed & shift_result[bmask_a_i]; assign bextins_result = (bmask & shift_result) | (bextins_and & bmask_inv); @@ -827,18 +850,15 @@ module riscv_alu unique case (operator_i) // Standard Operations - `ALU_ADD, - `ALU_SUB: result_o = adder_result; - `ALU_AVG, - `ALU_AVGU: result_o = result_avg; `ALU_AND: result_o = operand_a_i & operand_b_i; `ALU_OR: result_o = operand_a_i | operand_b_i; `ALU_XOR: result_o = operand_a_i ^ operand_b_i; // Shift Operations + `ALU_ADD, `ALU_ADDR, `ALU_ADDU, `ALU_ADDUR, + `ALU_SUB, `ALU_SUBR, `ALU_SUBU, `ALU_SUBUR, `ALU_SLL, - `ALU_SRL, - `ALU_SRA, + `ALU_SRL, `ALU_SRA, `ALU_ROR: result_o = shift_result; // bit manipulation instructions @@ -850,10 +870,11 @@ module riscv_alu `ALU_BSET: result_o = bset_result; // Extension Operations - `ALU_EXTBZ, - `ALU_EXTBS, - `ALU_EXTHZ, - `ALU_EXTHS: result_o = result_ext; + `ALU_EXTBZ, `ALU_EXTBS, + `ALU_EXTHZ, `ALU_EXTHS: result_o = result_ext; + + // pack and shuffle operations + `ALU_SHUF, `ALU_SHUF2, `ALU_PCKLO, `ALU_PCKHI: result_o = pack_result; // Min/Max/Abs/Ins `ALU_MIN, `ALU_MINU, @@ -884,8 +905,6 @@ module riscv_alu `ALU_DIV, `ALU_DIVU, `ALU_REM, `ALU_REMU: result_o = result_div; - `ALU_SHUF, `ALU_SHUF2, `ALU_PCKLO, `ALU_PCKHI: result_o = pack_result; - default: ; // default case to suppress unique warning endcase end diff --git a/decoder.sv b/decoder.sv index ccefaaff..17e68204 100644 --- a/decoder.sv +++ b/decoder.sv @@ -42,7 +42,9 @@ module riscv_decoder output logic regb_used_o, // rs2 is used by current instruction output logic regc_used_o, // rs3 is used by current instruction - output logic imm_bmask_needed_o, // immediate registers for bit manipulation mask is needed + output logic bmask_needed_o, // registers for bit manipulation mask is needed + output logic [ 0:0] bmask_a_mux_o, // bit manipulation mask a mux + output logic [ 1:0] bmask_b_mux_o, // bit manipulation mask a mux // from IF/ID pipeline input logic [31:0] instr_rdata_i, // instruction read from instr memory/cache @@ -173,7 +175,9 @@ module riscv_decoder rega_used_o = 1'b0; regb_used_o = 1'b0; regc_used_o = 1'b0; - imm_bmask_needed_o = 1'b0; + bmask_needed_o = 1'b1; // TODO: only use when necessary + bmask_a_mux_o = `BMASK_A_ZERO; + bmask_b_mux_o = `BMASK_B_ZERO; unique case (instr_rdata_i[6:0]) @@ -426,11 +430,22 @@ module riscv_decoder if (instr_rdata_i[31]) begin // bit-manipulation instructions alu_op_b_mux_sel_o = `OP_B_IMM; - imm_bmask_needed_o = 1'b1; + bmask_needed_o = 1'b1; + bmask_a_mux_o = `BMASK_A_S3; + bmask_b_mux_o = `BMASK_B_S2; unique case (instr_rdata_i[14:12]) - 3'b000: begin alu_operator_o = `ALU_BEXT; imm_b_mux_sel_o = `IMMB_S2; end - 3'b001: begin alu_operator_o = `ALU_BEXTU; imm_b_mux_sel_o = `IMMB_S2; end + 3'b000: begin + alu_operator_o = `ALU_BEXT; + imm_b_mux_sel_o = `IMMB_S2; + bmask_b_mux_o = `BMASK_B_ZERO; + end + 3'b001: begin + alu_operator_o = `ALU_BEXTU; + imm_b_mux_sel_o = `IMMB_S2; + bmask_b_mux_o = `BMASK_B_ZERO; + end + 3'b010: begin alu_operator_o = `ALU_BINS; imm_b_mux_sel_o = `IMMB_S2; @@ -509,8 +524,8 @@ module riscv_decoder end // PULP specific instructions - {6'b00_0010, 3'b000}: alu_operator_o = `ALU_AVG; // Average - {6'b00_0010, 3'b001}: alu_operator_o = `ALU_AVGU; // Average Unsigned + {6'b00_0010, 3'b000}: begin alu_operator_o = `ALU_ADD; bmask_b_mux_o = `BMASK_B_ONE; end // Average + {6'b00_0010, 3'b001}: begin alu_operator_o = `ALU_ADDU; bmask_b_mux_o = `BMASK_B_ONE; end // Average Unsigned {6'b00_0010, 3'b010}: alu_operator_o = `ALU_SLETS; // Set Lower Equal Than {6'b00_0010, 3'b011}: alu_operator_o = `ALU_SLETU; // Set Lower Equal Than Unsigned {6'b00_0010, 3'b100}: alu_operator_o = `ALU_MIN; // Min @@ -576,6 +591,34 @@ module riscv_decoder mult_mac_en = 1'b1; end + 2'b10: begin // add with normalization and rounding + // decide between using unsigned and rounding, and combinations + // thereof + case ({instr_rdata_i[31],instr_rdata_i[14]}) + 2'b00: alu_operator_o = `ALU_ADD; + 2'b01: alu_operator_o = `ALU_ADDR; + 2'b10: alu_operator_o = `ALU_ADDU; + 2'b11: alu_operator_o = `ALU_ADDUR; + endcase + + bmask_a_mux_o = `BMASK_A_ZERO; + bmask_b_mux_o = `BMASK_B_S3; + end + + 2'b11: begin // sub with normalization and rounding + // decide between using unsigned and rounding, and combinations + // thereof + case ({instr_rdata_i[31],instr_rdata_i[14]}) + 2'b00: alu_operator_o = `ALU_SUB; + 2'b01: alu_operator_o = `ALU_SUBR; + 2'b10: alu_operator_o = `ALU_SUBU; + 2'b11: alu_operator_o = `ALU_SUBUR; + endcase + + bmask_a_mux_o = `BMASK_A_ZERO; + bmask_b_mux_o = `BMASK_B_S3; + end + default: begin regfile_alu_we = 1'b0; illegal_insn_o = 1'b1; @@ -612,21 +655,21 @@ module riscv_decoder // now decode the instruction unique case (instr_rdata_i[31:26]) - 6'b00000_0: begin alu_operator_o = `ALU_ADD; imm_b_mux_sel_o = `IMMB_VS; end // pv.add - 6'b00001_0: begin alu_operator_o = `ALU_SUB; imm_b_mux_sel_o = `IMMB_VS; end // pv.sub - 6'b00010_0: begin alu_operator_o = `ALU_AVG; imm_b_mux_sel_o = `IMMB_VS; end // pv.avg - 6'b00011_0: begin alu_operator_o = `ALU_AVGU; imm_b_mux_sel_o = `IMMB_VU; end // pv.avgu - 6'b00100_0: begin alu_operator_o = `ALU_MIN; imm_b_mux_sel_o = `IMMB_VS; end // pv.min - 6'b00101_0: begin alu_operator_o = `ALU_MINU; imm_b_mux_sel_o = `IMMB_VU; end // pv.minu - 6'b00110_0: begin alu_operator_o = `ALU_MAX; imm_b_mux_sel_o = `IMMB_VS; end // pv.max - 6'b00111_0: begin alu_operator_o = `ALU_MAXU; imm_b_mux_sel_o = `IMMB_VU; end // pv.maxu - 6'b01000_0: begin alu_operator_o = `ALU_SRL; imm_b_mux_sel_o = `IMMB_VS; end // pv.srl - 6'b01001_0: begin alu_operator_o = `ALU_SRA; imm_b_mux_sel_o = `IMMB_VS; end // pv.sra - 6'b01010_0: begin alu_operator_o = `ALU_SLL; imm_b_mux_sel_o = `IMMB_VS; end // pv.sll - 6'b01011_0: begin alu_operator_o = `ALU_OR; imm_b_mux_sel_o = `IMMB_VS; end // pv.or - 6'b01100_0: begin alu_operator_o = `ALU_XOR; imm_b_mux_sel_o = `IMMB_VS; end // pv.xor - 6'b01101_0: begin alu_operator_o = `ALU_AND; imm_b_mux_sel_o = `IMMB_VS; end // pv.and - 6'b01110_0: begin alu_operator_o = `ALU_ABS; imm_b_mux_sel_o = `IMMB_VS; end // pv.abs + 6'b00000_0: begin alu_operator_o = `ALU_ADD; imm_b_mux_sel_o = `IMMB_VS; end // pv.add + 6'b00001_0: begin alu_operator_o = `ALU_SUB; imm_b_mux_sel_o = `IMMB_VS; end // pv.sub + 6'b00010_0: begin alu_operator_o = `ALU_ADD; imm_b_mux_sel_o = `IMMB_VS; bmask_b_mux_o = `BMASK_B_ONE; end // pv.avg + 6'b00011_0: begin alu_operator_o = `ALU_ADDU; imm_b_mux_sel_o = `IMMB_VU; bmask_b_mux_o = `BMASK_B_ONE; end // pv.avgu + 6'b00100_0: begin alu_operator_o = `ALU_MIN; imm_b_mux_sel_o = `IMMB_VS; end // pv.min + 6'b00101_0: begin alu_operator_o = `ALU_MINU; imm_b_mux_sel_o = `IMMB_VU; end // pv.minu + 6'b00110_0: begin alu_operator_o = `ALU_MAX; imm_b_mux_sel_o = `IMMB_VS; end // pv.max + 6'b00111_0: begin alu_operator_o = `ALU_MAXU; imm_b_mux_sel_o = `IMMB_VU; end // pv.maxu + 6'b01000_0: begin alu_operator_o = `ALU_SRL; imm_b_mux_sel_o = `IMMB_VS; end // pv.srl + 6'b01001_0: begin alu_operator_o = `ALU_SRA; imm_b_mux_sel_o = `IMMB_VS; end // pv.sra + 6'b01010_0: begin alu_operator_o = `ALU_SLL; imm_b_mux_sel_o = `IMMB_VS; end // pv.sll + 6'b01011_0: begin alu_operator_o = `ALU_OR; imm_b_mux_sel_o = `IMMB_VS; end // pv.or + 6'b01100_0: begin alu_operator_o = `ALU_XOR; imm_b_mux_sel_o = `IMMB_VS; end // pv.xor + 6'b01101_0: begin alu_operator_o = `ALU_AND; imm_b_mux_sel_o = `IMMB_VS; end // pv.and + 6'b01110_0: begin alu_operator_o = `ALU_ABS; imm_b_mux_sel_o = `IMMB_VS; end // pv.abs 6'b01111_0: begin // pv.extract if (instr_rdata_i[12]) diff --git a/ex_stage.sv b/ex_stage.sv index cac2389c..037c41a7 100644 --- a/ex_stage.sv +++ b/ex_stage.sv @@ -39,8 +39,8 @@ module riscv_ex_stage input logic [31:0] alu_operand_a_i, input logic [31:0] alu_operand_b_i, 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 [ 4:0] bmask_a_i, + input logic [ 4:0] bmask_b_i, input logic [ 1:0] imm_vec_ext_i, input logic [ 1:0] alu_vec_mode_i, @@ -132,8 +132,8 @@ module riscv_ex_stage .operand_c_i ( alu_operand_c_i ), .vector_mode_i ( alu_vec_mode_i ), - .imm_bmask_a_i ( imm_bmask_a_i ), - .imm_bmask_b_i ( imm_bmask_b_i ), + .bmask_a_i ( bmask_a_i ), + .bmask_b_i ( bmask_b_i ), .imm_vec_ext_i ( imm_vec_ext_i ), .result_o ( alu_result ), diff --git a/id_stage.sv b/id_stage.sv index 3e7a80b2..7f6137c6 100644 --- a/id_stage.sv +++ b/id_stage.sv @@ -87,8 +87,8 @@ module riscv_id_stage output logic [31:0] alu_operand_a_ex_o, output logic [31:0] alu_operand_b_ex_o, 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 [ 4:0] bmask_a_ex_o, + output logic [ 4:0] bmask_b_ex_o, output logic [ 1:0] imm_vec_ext_ex_o, output logic [ 1:0] alu_vec_mode_ex_o, @@ -195,7 +195,7 @@ module riscv_id_stage logic rega_used_dec; logic regb_used_dec; logic regc_used_dec; - logic imm_bmask_needed_dec; + logic bmask_needed_dec; logic branch_taken_ex; logic [1:0] jump_in_id; @@ -313,8 +313,11 @@ module riscv_id_stage logic [31:0] alu_operand_c; // Immediates for ID - logic [ 4:0] imm_bmask_a_id; - logic [ 4:0] imm_bmask_b_id; + logic [0:0] bmask_a_mux; + logic [1:0] bmask_b_mux; + + logic [ 4:0] bmask_a_id; + logic [ 4:0] bmask_b_id; logic [ 1:0] imm_vec_ext_id; logic [ 1:0] alu_vec_mode; @@ -621,9 +624,24 @@ module riscv_id_stage // // /////////////////////////////////////////////////////////////////////////// - assign imm_bmask_a_id = imm_s3_type[4:0]; - assign imm_bmask_b_id = ((alu_operator == `ALU_BCLR) || (alu_operator == `ALU_BSET) || (alu_operator == `ALU_BINS)) ? - imm_s2_type[4:0] : 0; + always_comb + begin + unique case (bmask_a_mux) + `BMASK_A_ZERO: bmask_a_id = '0; + `BMASK_A_S3: bmask_a_id = imm_s3_type[4:0]; + default: bmask_a_id = '0; + endcase + end + always_comb + begin + unique case (bmask_b_mux) + `BMASK_B_ZERO: bmask_b_id = '0; + `BMASK_B_ONE: bmask_b_id = 5'd1; + `BMASK_B_S2: bmask_b_id = imm_s2_type[4:0]; + `BMASK_B_S3: bmask_b_id = imm_s3_type[4:0]; + default: bmask_b_id = '0; + endcase + end assign imm_vec_ext_id = imm_vu_type[1:0]; @@ -693,7 +711,9 @@ module riscv_id_stage .regb_used_o ( regb_used_dec ), .regc_used_o ( regc_used_dec ), - .imm_bmask_needed_o ( imm_bmask_needed_dec ), + .bmask_needed_o ( bmask_needed_dec ), + .bmask_a_mux_o ( bmask_a_mux ), + .bmask_b_mux_o ( bmask_b_mux ), // from IF/ID pipeline .instr_rdata_i ( instr ), @@ -968,8 +988,8 @@ module riscv_id_stage alu_operand_a_ex_o <= '0; alu_operand_b_ex_o <= '0; alu_operand_c_ex_o <= '0; - imm_bmask_a_ex_o <= '0; - imm_bmask_b_ex_o <= '0; + bmask_a_ex_o <= '0; + bmask_b_ex_o <= '0; imm_vec_ext_ex_o <= '0; alu_vec_mode_ex_o <= '0; @@ -1036,8 +1056,8 @@ module riscv_id_stage alu_operand_a_ex_o <= alu_operand_a; alu_operand_b_ex_o <= alu_operand_b; 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; + bmask_a_ex_o <= bmask_a_id; + bmask_b_ex_o <= bmask_b_id; imm_vec_ext_ex_o <= imm_vec_ext_id; alu_vec_mode_ex_o <= alu_vec_mode; end diff --git a/if_stage.sv b/if_stage.sv index cdc828b7..22f32563 100644 --- a/if_stage.sv +++ b/if_stage.sv @@ -382,4 +382,12 @@ module riscv_if_stage assign if_ready_o = valid & id_ready_i; assign if_valid_o = (~halt_if_i) & if_ready_o; + //---------------------------------------------------------------------------- + // Assertions + //---------------------------------------------------------------------------- + + // there should never be a grant when there is no request + assert property ( + @(posedge clk) (instr_gnt_i) |-> (instr_req_o) ); + endmodule diff --git a/include/riscv_defines.sv b/include/riscv_defines.sv index 39195e83..707a87eb 100644 --- a/include/riscv_defines.sv +++ b/include/riscv_defines.sv @@ -29,7 +29,7 @@ // no traces for synthesis, they are not synthesizable `ifndef SYNTHESIS `define TRACE_EXECUTION -//`define SIMCHECKER +`define SIMCHECKER `endif @@ -90,13 +90,17 @@ `define ALU_OP_WIDTH 6 -`define ALU_ADD 6'b100000 -`define ALU_SUB 6'b100001 -`define ALU_AVG 6'b100010 -`define ALU_AVGU 6'b100011 +`define ALU_ADD 6'b011000 +`define ALU_SUB 6'b011001 +`define ALU_ADDU 6'b011010 +`define ALU_SUBU 6'b011011 +`define ALU_ADDR 6'b011100 +`define ALU_SUBR 6'b011101 +`define ALU_ADDUR 6'b011110 +`define ALU_SUBUR 6'b011111 -`define ALU_XOR 6'b011011 -`define ALU_OR 6'b011010 +`define ALU_XOR 6'b101111 +`define ALU_OR 6'b101110 `define ALU_AND 6'b010101 // Shifts @@ -113,10 +117,10 @@ `define ALU_BSET 6'b101100 // Bit counting -`define ALU_FF1 6'b011110 -`define ALU_FL1 6'b011111 -`define ALU_CNT 6'b011000 -`define ALU_CLB 6'b011001 +`define ALU_FF1 6'b110110 +`define ALU_FL1 6'b110111 +`define ALU_CNT 6'b110100 +`define ALU_CLB 6'b110101 // Sign-/zero-extensions `define ALU_EXTHS 6'b111100 @@ -244,6 +248,15 @@ `define IMMB_SHUF 4'b1000 `define IMMB_CLIP 4'b1001 +// bit mask selection +`define BMASK_A_ZERO 1'b0 +`define BMASK_A_S3 1'b1 + +`define BMASK_B_S2 2'b00 +`define BMASK_B_S3 2'b01 +`define BMASK_B_ZERO 2'b10 +`define BMASK_B_ONE 2'b11 + // operand c selection `define OP_C_REGC_OR_FWD 2'b00 `define OP_C_REGB_OR_FWD 2'b01 diff --git a/include/riscv_tracer_defines.sv b/include/riscv_tracer_defines.sv index ec14110c..23f4e9e1 100644 --- a/include/riscv_tracer_defines.sv +++ b/include/riscv_tracer_defines.sv @@ -55,6 +55,14 @@ `define INSTR_EXTBZ { 7'b0001000, 10'b?, 3'b111, 5'b?, `OPCODE_OP } // pulp specific `define INSTR_PAVG { 7'b0000010, 10'b?, 3'b000, 5'b?, `OPCODE_OP } // pulp specific `define INSTR_PAVGU { 7'b0000010, 10'b?, 3'b001, 5'b?, `OPCODE_OP } // pulp specific +`define INSTR_PADDN { 2'b00, 15'b?, 3'b010, 5'b?, `OPCODE_PULP_OP } // pulp specific +`define INSTR_PADDUN { 2'b10, 15'b?, 3'b010, 5'b?, `OPCODE_PULP_OP } // pulp specific +`define INSTR_PADDRN { 2'b00, 15'b?, 3'b110, 5'b?, `OPCODE_PULP_OP } // pulp specific +`define INSTR_PADDURN { 2'b10, 15'b?, 3'b110, 5'b?, `OPCODE_PULP_OP } // pulp specific +`define INSTR_PSUBN { 2'b00, 15'b?, 3'b011, 5'b?, `OPCODE_PULP_OP } // pulp specific +`define INSTR_PSUBUN { 2'b10, 15'b?, 3'b011, 5'b?, `OPCODE_PULP_OP } // pulp specific +`define INSTR_PSUBRN { 2'b00, 15'b?, 3'b111, 5'b?, `OPCODE_PULP_OP } // pulp specific +`define INSTR_PSUBURN { 2'b10, 15'b?, 3'b111, 5'b?, `OPCODE_PULP_OP } // pulp specific `define INSTR_PABS { 7'b0001010, 10'b?, 3'b000, 5'b?, `OPCODE_OP } // pulp specific `define INSTR_PCLIP { 7'b0001010, 10'b?, 3'b001, 5'b?, `OPCODE_OP } // pulp specific `define INSTR_PCLIPU { 7'b0001010, 10'b?, 3'b010, 5'b?, `OPCODE_OP } // pulp specific diff --git a/riscv_core.sv b/riscv_core.sv index ec68d7c6..894a79db 100644 --- a/riscv_core.sv +++ b/riscv_core.sv @@ -128,8 +128,8 @@ module riscv_core logic [31:0] alu_operand_a_ex; logic [31:0] alu_operand_b_ex; logic [31:0] alu_operand_c_ex; - logic [ 4:0] imm_bmask_a_ex; - logic [ 4:0] imm_bmask_b_ex; + logic [ 4:0] bmask_a_ex; + logic [ 4:0] bmask_b_ex; logic [ 1:0] imm_vec_ext_ex; logic [ 1:0] alu_vec_mode_ex; @@ -387,8 +387,8 @@ module riscv_core .alu_operand_a_ex_o ( alu_operand_a_ex ), .alu_operand_b_ex_o ( alu_operand_b_ex ), .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 ), + .bmask_a_ex_o ( bmask_a_ex ), + .bmask_b_ex_o ( bmask_b_ex ), .imm_vec_ext_ex_o ( imm_vec_ext_ex ), .alu_vec_mode_ex_o ( alu_vec_mode_ex ), @@ -494,8 +494,8 @@ module riscv_core .alu_operand_a_i ( alu_operand_a_ex ), // from ID/EX pipe registers .alu_operand_b_i ( alu_operand_b_ex ), // from ID/EX pipe registers .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 + .bmask_a_i ( bmask_a_ex ), // from ID/EX pipe registers + .bmask_b_i ( 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 diff --git a/riscv_simchecker.sv b/riscv_simchecker.sv index 65cd1581..dd83f05b 100644 --- a/riscv_simchecker.sv +++ b/riscv_simchecker.sv @@ -22,11 +22,17 @@ //////////////////////////////////////////////////////////////////////////////// +`include "riscv_defines.sv" + +// do not import anything if the simchecker is not used +// this gets rid of warnings during simulation +`ifdef SIMCHECKER import "DPI-C" function chandle riscv_checker_init(input int boot_addr, input int core_id, input int cluster_id); import "DPI-C" function int riscv_checker_step(input chandle cpu, input longint simtime, input int cycle, input logic [31:0] pc, input logic [31:0] instr); import "DPI-C" function void riscv_checker_irq(input chandle cpu, input int irq, input int irq_no); import "DPI-C" function void riscv_checker_mem_access(input chandle cpu, input int we, input logic [31:0] addr, input logic [31:0] data); import "DPI-C" function void riscv_checker_reg_access(input chandle cpu, input logic [31:0] addr, input logic [31:0] data); +`endif module riscv_simchecker ( @@ -76,6 +82,7 @@ module riscv_simchecker input logic [31:0] wb_data_rdata ); +`ifdef SIMCHECKER // DPI stuff chandle dpi_simdata; @@ -318,5 +325,6 @@ module riscv_simchecker end end end +`endif endmodule diff --git a/riscv_tracer.sv b/riscv_tracer.sv index 0d034a41..116dcf28 100644 --- a/riscv_tracer.sv +++ b/riscv_tracer.sv @@ -125,7 +125,7 @@ module riscv_tracer function void printInstrTrace(); mem_acc_t mem_acc; begin - $fwrite(f, "%t %15d %h %h %-33s", simtime, + $fwrite(f, "%t %15d %h %h %-36s", simtime, cycles, pc, instr, @@ -166,13 +166,22 @@ module riscv_tracer end endfunction // printRInstr + function void printAddNInstr(input string mnemonic); + begin + regs_read.push_back({>> {rs1, rs1_value}}); + regs_read.push_back({>> {rs2, rs2_value}}); + regs_write.push_back({>> {rd, 'x}}); + str = $sformatf("%-16s x%0d, x%0d, x%0d, 0x%0d", mnemonic, rd, rs1, rs2, $unsigned(imm_s3_type[4:0])); + end + endfunction // printAddNInstr + function void printR1Instr(input string mnemonic); begin regs_read.push_back({>> {rs1, rs1_value}}); regs_write.push_back({>> {rd, 'x}}); str = $sformatf("%-16s x%0d, x%0d", mnemonic, rd, rs1); end - endfunction // printRInstr + endfunction // printR1Instr function void printR3Instr(input string mnemonic); begin @@ -182,7 +191,7 @@ module riscv_tracer regs_write.push_back({>> {rd, 'x}}); str = $sformatf("%-16s x%0d, x%0d, x%0d", mnemonic, rd, rs1, rs2); end - endfunction // printRInstr + endfunction // printR3Instr function void printClipInstr(input string mnemonic); begin @@ -415,6 +424,22 @@ module riscv_tracer string str_sci; string str_imm; begin + + // always read rs1 and write rd + regs_read.push_back({>> {rs1, rs1_value}}); + regs_write.push_back({>> {rd, 'x}}); + + case (instr[14:13]) + 2'b00: str_sci = ""; + 2'b10: str_sci = ".sc"; + 2'b11: str_sci = ".sci"; + endcase + + if (instr[12]) + str_hb = ".b"; + else + str_hb = ".h"; + // set mnemonic case (instr[31:26]) 6'b000000: begin mnemonic = "pv.add"; str_imm = $sformatf("0x%0d", imm_vs_type); end @@ -432,8 +457,8 @@ module riscv_tracer 6'b011000: begin mnemonic = "pv.xor"; str_imm = $sformatf("0x%0d", imm_vs_type); end 6'b011010: begin mnemonic = "pv.and"; str_imm = $sformatf("0x%0d", imm_vs_type); end 6'b011100: begin mnemonic = "pv.abs"; str_imm = $sformatf("0x%0d", imm_vs_type); end - 6'b011110: begin mnemonic = "pv.extract"; str_imm = $sformatf("0x%0d", imm_vs_type); end - 6'b100000: begin mnemonic = "pv.extractu"; str_imm = $sformatf("0x%0d", imm_vu_type); end + 6'b011110: begin mnemonic = "pv.extract"; str_imm = $sformatf("0x%0d", imm_vs_type); str_sci = ""; end + 6'b100000: begin mnemonic = "pv.extractu"; str_imm = $sformatf("0x%0d", imm_vu_type); str_sci = ""; end 6'b100010: begin mnemonic = "pv.insert"; str_imm = $sformatf("0x%0d", imm_vs_type); end // shuffle/pack @@ -461,33 +486,15 @@ module riscv_tracer end endcase - // always read rs1 and write rd - regs_read.push_back({>> {rs1, rs1_value}}); - regs_write.push_back({>> {rd, 'x}}); - - case (instr[14:13]) - 2'b00: begin - str_sci = ""; - str_args = $sformatf("x%0d, x%0d, x%0d", rd, rs1, rs2); - regs_read.push_back({>> {rs2, rs2_value}}); - end - - 2'b10: begin - str_sci = ".sc"; - str_args = $sformatf("x%0d, x%0d, x%0d", rd, rs1, rs2); - regs_read.push_back({>> {rs2, rs2_value_vec}}); - end - - 2'b11: begin - str_sci = ".sci"; - str_args = $sformatf("x%0d, x%0d, %s", rd, rs1, str_imm); - end - endcase - - if (instr[12]) - str_hb = ".b"; - else - str_hb = ".h"; + if (str_sci == "") begin + regs_read.push_back({>> {rs2, rs2_value}}); + str_args = $sformatf("x%0d, x%0d, x%0d", rd, rs1, rs2); + end else if (str_sci == ".sc") begin + regs_read.push_back({>> {rs2, rs2_value_vec}}); + str_args = $sformatf("x%0d, x%0d, x%0d", rd, rs1, rs2); + end else if (str_sci == ".sci") begin + str_args = $sformatf("x%0d, x%0d, %s", rd, rs1, str_imm); + end str_asm = $sformatf("%s%s%s", mnemonic, str_sci, str_hb); @@ -650,6 +657,14 @@ module riscv_tracer `INSTR_EXTBZ: trace.printRInstr("p.extbz"); `INSTR_PAVG: trace.printRInstr("p.avg"); `INSTR_PAVGU: trace.printRInstr("p.avgu"); + `INSTR_PADDN: trace.printAddNInstr("p.addN"); + `INSTR_PADDUN: trace.printAddNInstr("p.adduN"); + `INSTR_PADDRN: trace.printAddNInstr("p.addRN"); + `INSTR_PADDURN: trace.printAddNInstr("p.adduRN"); + `INSTR_PSUBN: trace.printAddNInstr("p.subN"); + `INSTR_PSUBUN: trace.printAddNInstr("p.subuN"); + `INSTR_PSUBRN: trace.printAddNInstr("p.subRN"); + `INSTR_PSUBURN: trace.printAddNInstr("p.subuRN"); `INSTR_PSLET: trace.printRInstr("p.slet"); `INSTR_PSLETU: trace.printRInstr("p.sletu"); `INSTR_PMIN: trace.printRInstr("p.min"); diff --git a/src_files.yml b/src_files.yml index 54867195..e8a87717 100644 --- a/src_files.yml +++ b/src_files.yml @@ -28,6 +28,7 @@ riscv_vip_rtl: ] files: [ riscv_tracer.sv, + riscv_simchecker.sv, ] riscv_regfile_rtl: incdirs: [