diff --git a/.gitlab-ci/expected_synth.yml b/.gitlab-ci/expected_synth.yml index e8f875f68c..5d530fd938 100644 --- a/.gitlab-ci/expected_synth.yml +++ b/.gitlab-ci/expected_synth.yml @@ -1,6 +1,6 @@ cv64a6_imafdc_sv39: gates: 545030 cv32a60x: - gates: 160467 + gates: 160719 cv32a6_embedded: gates: 127410 diff --git a/core/alu.sv b/core/alu.sv index 164ba37210..0e0d3aa0db 100644 --- a/core/alu.sv +++ b/core/alu.sv @@ -275,16 +275,16 @@ module alu import ariane_pkg::*; #( // Single bit instructions operations BCLR, BCLRI: result_o = fu_data_i.operand_a & ~bit_indx; - BEXT, BEXTI: result_o = |(fu_data_i.operand_a & bit_indx); + BEXT, BEXTI: result_o = {{riscv::XLEN-1{1'b0}}, |(fu_data_i.operand_a & bit_indx)}; BINV, BINVI: result_o = fu_data_i.operand_a ^ bit_indx; BSET, BSETI: result_o = fu_data_i.operand_a | bit_indx; // Count Leading/Trailing Zeros CLZ, CTZ : result_o = (lz_tz_empty) ? (lz_tz_count + 1) : lz_tz_count; - CLZW, CTZW: result_o = (lz_tz_wempty) ? 32 : lz_tz_wcount; + CLZW, CTZW: result_o = (lz_tz_wempty) ? 32 : {{riscv::XLEN-5{1'b0}}, lz_tz_wcount}; // Count population - CPOP, CPOPW: result_o = cpop; + CPOP, CPOPW: result_o = {{(riscv::XLEN-($clog2(riscv::XLEN))){1'b0}}, cpop}; // Sign and Zero Extend SEXTB: result_o = {{riscv::XLEN-8{fu_data_i.operand_a[7]}}, fu_data_i.operand_a[7:0]}; diff --git a/core/decoder.sv b/core/decoder.sv index a938fa614e..86dd567e7f 100644 --- a/core/decoder.sv +++ b/core/decoder.sv @@ -293,16 +293,16 @@ module decoder import ariane_pkg::*; #( // decode vectorial FP instruction unique case (instr.rvftype.vecfltop) 5'b00001 : begin - instruction_o.op = ariane_pkg::FADD; // vfadd.vfmt - Vectorial FP Addition - instruction_o.rs1 = '0; // Operand A is set to 0 - instruction_o.rs2 = instr.rvftype.rs1; // Operand B is set to rs1 - imm_select = IIMM; // Operand C is set to rs2 + instruction_o.op = ariane_pkg::FADD; // vfadd.vfmt - Vectorial FP Addition + instruction_o.rs1 = '0; // Operand A is set to 0 + instruction_o.rs2[4:0] = instr.rvftype.rs1; // Operand B is set to rs1 + imm_select = IIMM; // Operand C is set to rs2 end 5'b00010 : begin - instruction_o.op = ariane_pkg::FSUB; // vfsub.vfmt - Vectorial FP Subtraction - instruction_o.rs1 = '0; // Operand A is set to 0 - instruction_o.rs2 = instr.rvftype.rs1; // Operand B is set to rs1 - imm_select = IIMM; // Operand C is set to rs2 + instruction_o.op = ariane_pkg::FSUB; // vfsub.vfmt - Vectorial FP Subtraction + instruction_o.rs1 = '0; // Operand A is set to 0 + instruction_o.rs2[4:0] = instr.rvftype.rs1; // Operand B is set to rs1 + imm_select = IIMM; // Operand C is set to rs2 end 5'b00011 : instruction_o.op = ariane_pkg::FMUL; // vfmul.vfmt - Vectorial FP Multiplication 5'b00100 : instruction_o.op = ariane_pkg::FDIV; // vfdiv.vfmt - Vectorial FP Division @@ -330,7 +330,7 @@ module decoder import ariane_pkg::*; #( 5'b01100 : begin unique case (instr.rvftype.rs2) inside // operation encoded in rs2, `inside` for matching ? 5'b00000 : begin - instruction_o.rs2 = instr.rvftype.rs1; // set rs2 = rs1 so we can map FMV to SGNJ in the unit + instruction_o.rs2[4:0] = instr.rvftype.rs1; // set rs2 = rs1 so we can map FMV to SGNJ in the unit if (instr.rvftype.repl) instruction_o.op = ariane_pkg::FMV_X2F; // vfmv.vfmt.x - GPR to FPR Move else @@ -345,9 +345,9 @@ module decoder import ariane_pkg::*; #( 5'b00010 : instruction_o.op = ariane_pkg::FCVT_F2I; // vfcvt.x.vfmt - Vectorial FP to Int Conversion 5'b00011 : instruction_o.op = ariane_pkg::FCVT_I2F; // vfcvt.vfmt.x - Vectorial Int to FP Conversion 5'b001?? : begin - instruction_o.op = ariane_pkg::FCVT_F2F; // vfcvt.vfmt.vfmt - Vectorial FP to FP Conversion - instruction_o.rs2 = instr.rvftype.rd; // set rs2 = rd as target vector for conversion - imm_select = IIMM; // rs2 holds part of the intruction + instruction_o.op = ariane_pkg::FCVT_F2F; // vfcvt.vfmt.vfmt - Vectorial FP to FP Conversion + instruction_o.rs2[4:0] = instr.rvftype.rd; // set rs2 = rd as target vector for conversion + imm_select = IIMM; // rs2 holds part of the intruction // TODO CHECK R bit for valid fmt combinations // determine source format unique case (instr.rvftype.rs2[21:20]) @@ -515,9 +515,9 @@ module decoder import ariane_pkg::*; #( end else begin instruction_o.fu = (instr.rtype.funct7 == 7'b000_0001) ? MULT : ALU; end - instruction_o.rs1 = instr.rtype.rs1; - instruction_o.rs2 = instr.rtype.rs2; - instruction_o.rd = instr.rtype.rd; + instruction_o.rs1[4:0] = instr.rtype.rs1; + instruction_o.rs2[4:0] = instr.rtype.rs2; + instruction_o.rd[4:0] = instr.rtype.rd; unique case ({instr.rtype.funct7, instr.rtype.funct3}) {7'b000_0000, 3'b000}: instruction_o.op = ariane_pkg::ADD; // Add @@ -813,8 +813,8 @@ module decoder import ariane_pkg::*; #( if (FP_PRESENT && fs_i != riscv::Off) begin // only generate decoder if FP extensions are enabled (static) instruction_o.fu = STORE; imm_select = SIMM; - instruction_o.rs1 = instr.stype.rs1; - instruction_o.rs2 = instr.stype.rs2; + instruction_o.rs1[4:0] = instr.stype.rs1; + instruction_o.rs2[4:0] = instr.stype.rs2; // determine store size unique case (instr.stype.funct3) // Only process instruction if corresponding extension is active (static) @@ -836,8 +836,8 @@ module decoder import ariane_pkg::*; #( if (FP_PRESENT && fs_i != riscv::Off) begin // only generate decoder if FP extensions are enabled (static) instruction_o.fu = LOAD; imm_select = IIMM; - instruction_o.rs1 = instr.itype.rs1; - instruction_o.rd = instr.itype.rd; + instruction_o.rs1[4:0] = instr.itype.rs1; + instruction_o.rd[4:0] = instr.itype.rd; // determine load size unique case (instr.itype.funct3) // Only process instruction if corresponding extension is active (static) @@ -863,12 +863,12 @@ module decoder import ariane_pkg::*; #( riscv::OpcodeNmsub, riscv::OpcodeNmadd: begin if (FP_PRESENT && fs_i != riscv::Off) begin // only generate decoder if FP extensions are enabled (static) - instruction_o.fu = FPU; - instruction_o.rs1 = instr.r4type.rs1; - instruction_o.rs2 = instr.r4type.rs2; - instruction_o.rd = instr.r4type.rd; - imm_select = RS3; // rs3 into result field - check_fprm = 1'b1; + instruction_o.fu = FPU; + instruction_o.rs1[4:0] = instr.r4type.rs1; + instruction_o.rs2[4:0] = instr.r4type.rs2; + instruction_o.rd[4:0] = instr.r4type.rd; + imm_select = RS3; // rs3 into result field + check_fprm = 1'b1; // select the correct fused operation unique case (instr.r4type.opcode) default: instruction_o.op = ariane_pkg::FMADD; // fmadd.fmt - FP Fused multiply-add @@ -916,24 +916,24 @@ module decoder import ariane_pkg::*; #( riscv::OpcodeOpFp: begin if (FP_PRESENT && fs_i != riscv::Off) begin // only generate decoder if FP extensions are enabled (static) - instruction_o.fu = FPU; - instruction_o.rs1 = instr.rftype.rs1; - instruction_o.rs2 = instr.rftype.rs2; - instruction_o.rd = instr.rftype.rd; - check_fprm = 1'b1; + instruction_o.fu = FPU; + instruction_o.rs1[4:0] = instr.rftype.rs1; + instruction_o.rs2[4:0] = instr.rftype.rs2; + instruction_o.rd[4:0] = instr.rftype.rd; + check_fprm = 1'b1; // decode FP instruction unique case (instr.rftype.funct5) 5'b00000: begin - instruction_o.op = ariane_pkg::FADD; // fadd.fmt - FP Addition - instruction_o.rs1 = '0; // Operand A is set to 0 - instruction_o.rs2 = instr.rftype.rs1; // Operand B is set to rs1 - imm_select = IIMM; // Operand C is set to rs2 + instruction_o.op = ariane_pkg::FADD; // fadd.fmt - FP Addition + instruction_o.rs1 = '0; // Operand A is set to 0 + instruction_o.rs2[4:0] = instr.rftype.rs1; // Operand B is set to rs1 + imm_select = IIMM; // Operand C is set to rs2 end 5'b00001: begin - instruction_o.op = ariane_pkg::FSUB; // fsub.fmt - FP Subtraction - instruction_o.rs1 = '0; // Operand A is set to 0 - instruction_o.rs2 = instr.rftype.rs1; // Operand B is set to rs1 - imm_select = IIMM; // Operand C is set to rs2 + instruction_o.op = ariane_pkg::FSUB; // fsub.fmt - FP Subtraction + instruction_o.rs1 = '0; // Operand A is set to 0 + instruction_o.rs2[4:0] = instr.rftype.rs1; // Operand B is set to rs1 + imm_select = IIMM; // Operand C is set to rs2 end 5'b00010: instruction_o.op = ariane_pkg::FMUL; // fmul.fmt - FP Multiplication 5'b00011: instruction_o.op = ariane_pkg::FDIV; // fdiv.fmt - FP Division @@ -965,9 +965,9 @@ module decoder import ariane_pkg::*; #( end end 5'b01000: begin - instruction_o.op = ariane_pkg::FCVT_F2F; // fcvt.fmt.fmt - FP to FP Conversion - instruction_o.rs2 = instr.rvftype.rs1; // tie rs2 to rs1 to be safe (vectors use rs2) - imm_select = IIMM; // rs2 holds part of the intruction + instruction_o.op = ariane_pkg::FCVT_F2F; // fcvt.fmt.fmt - FP to FP Conversion + instruction_o.rs2[4:0] = instr.rvftype.rs1; // tie rs2 to rs1 to be safe (vectors use rs2) + imm_select = IIMM; // rs2 holds part of the intruction if (|instr.rftype.rs2[24:23]) illegal_instr = 1'b1; // bits [22:20] used, other bits must be 0 // check source format unique case (instr.rftype.rs2[22:20]) @@ -1002,8 +1002,8 @@ module decoder import ariane_pkg::*; #( if (|instr.rftype.rs2[24:22]) illegal_instr = 1'b1; // bits [21:20] used, other bits must be 0 end 5'b11100: begin - instruction_o.rs2 = instr.rftype.rs1; // set rs2 = rs1 so we can map FMV to SGNJ in the unit - check_fprm = 1'b0; // instruction encoded in rm, do the check here + instruction_o.rs2[4:0] = instr.rftype.rs1; // set rs2 = rs1 so we can map FMV to SGNJ in the unit + check_fprm = 1'b0; // instruction encoded in rm, do the check here if (instr.rftype.rm == 3'b000 || (XF16ALT && instr.rftype.rm == 3'b100)) // FP16ALT has separate encoding instruction_o.op = ariane_pkg::FMV_F2X; // fmv.ifmt.fmt - FPR to GPR Move else if (instr.rftype.rm == 3'b001 || (XF16ALT && instr.rftype.rm == 3'b101)) // FP16ALT has separate encoding @@ -1014,8 +1014,8 @@ module decoder import ariane_pkg::*; #( end 5'b11110: begin instruction_o.op = ariane_pkg::FMV_X2F; // fmv.fmt.ifmt - GPR to FPR Move - instruction_o.rs2 = instr.rftype.rs1; // set rs2 = rs1 so we can map FMV to SGNJ in the unit - check_fprm = 1'b0; // instruction encoded in rm, do the check here + instruction_o.rs2[4:0] = instr.rftype.rs1; // set rs2 = rs1 so we can map FMV to SGNJ in the unit + check_fprm = 1'b0; // instruction encoded in rm, do the check here if (!(instr.rftype.rm == 3'b000 || (XF16ALT && instr.rftype.rm == 3'b100))) illegal_instr = 1'b1; // rs2 must be zero @@ -1175,12 +1175,12 @@ module decoder import ariane_pkg::*; #( end if (CVXIF_PRESENT) begin if (is_illegal_i || illegal_instr) begin - instruction_o.fu = CVXIF; - instruction_o.rs1 = instr.r4type.rs1; - instruction_o.rs2 = instr.r4type.rs2; - instruction_o.rd = instr.r4type.rd; - instruction_o.op = ariane_pkg::OFFLOAD; - imm_select = RS3; + instruction_o.fu = CVXIF; + instruction_o.rs1[4:0] = instr.r4type.rs1; + instruction_o.rs2[4:0] = instr.r4type.rs2; + instruction_o.rd[4:0] = instr.r4type.rd; + instruction_o.op = ariane_pkg::OFFLOAD; + imm_select = RS3; end end diff --git a/core/include/ariane_pkg.sv b/core/include/ariane_pkg.sv index c596cdc648..47e2045328 100644 --- a/core/include/ariane_pkg.sv +++ b/core/include/ariane_pkg.sv @@ -109,7 +109,7 @@ package ariane_pkg; function automatic logic range_check(logic[63:0] base, logic[63:0] len, logic[63:0] address); // if len is a power of two, and base is properly aligned, this check could be simplified // Extend base by one bit to prevent an overflow. - return (address >= base) && (address < (65'(base)+len)); + return (address >= base) && (({1'b0, address}) < (65'(base)+len)); endfunction : range_check function automatic logic is_inside_nonidempotent_regions (ariane_cfg_t Cfg, logic[63:0] address); diff --git a/core/issue_read_operands.sv b/core/issue_read_operands.sv index 75e3738c8f..8801dd284f 100644 --- a/core/issue_read_operands.sv +++ b/core/issue_read_operands.sv @@ -370,8 +370,8 @@ module issue_read_operands import ariane_pkg::*; #( // or check that the target destination register will be written in this cycle by the // commit stage for (int unsigned i = 0; i < CVA6Cfg.NrCommitPorts; i++) - if (is_rd_fpr(issue_instr_i.op) ? (we_fpr_i[i] && waddr_i[i] == issue_instr_i.rd) - : (we_gpr_i[i] && waddr_i[i] == issue_instr_i.rd)) begin + if (is_rd_fpr(issue_instr_i.op) ? (we_fpr_i[i] && waddr_i[i] == issue_instr_i.rd[4:0]) + : (we_gpr_i[i] && waddr_i[i] == issue_instr_i.rd[4:0])) begin issue_ack_o = 1'b1; end end diff --git a/core/mmu_sv32/cva6_tlb_sv32.sv b/core/mmu_sv32/cva6_tlb_sv32.sv index 34b2a825fe..404d77d5d7 100644 --- a/core/mmu_sv32/cva6_tlb_sv32.sv +++ b/core/mmu_sv32/cva6_tlb_sv32.sv @@ -75,7 +75,7 @@ module cva6_tlb_sv32 import ariane_pkg::*; #( for (int unsigned i = 0; i < TLB_ENTRIES; i++) begin // first level match, this may be a mega page, check the ASID flags as well // if the entry is associated to a global address, don't match the ASID (ASID is don't care) - if (tags_q[i].valid && ((lu_asid_i == tags_q[i].asid) || content_q[i].g) && vpn1 == tags_q[i].vpn1) begin + if (tags_q[i].valid && ((lu_asid_i == tags_q[i].asid[ASID_WIDTH-1:0]) || content_q[i].g) && vpn1 == tags_q[i].vpn1) begin if (tags_q[i].is_4M || vpn0 == tags_q[i].vpn0) begin lu_is_4M_o = tags_q[i].is_4M; lu_content_o = content_q[i]; @@ -116,10 +116,10 @@ module cva6_tlb_sv32 import ariane_pkg::*; #( else if (asid_to_be_flushed_is0 && ( (vaddr_vpn0_match[i] && vaddr_vpn1_match[i]) || (vaddr_vpn1_match[i] && tags_q[i].is_4M) ) && (~vaddr_to_be_flushed_is0)) tags_n[i].valid = 1'b0; // the entry is flushed if it's not global and asid and vaddr both matches with the entry to be flushed ("SFENCE.VMA vaddr asid" case) - else if ((!content_q[i].g) && ((vaddr_vpn0_match[i] && vaddr_vpn1_match[i]) || (vaddr_vpn1_match[i] && tags_q[i].is_4M)) && (asid_to_be_flushed_i == tags_q[i].asid) && (!vaddr_to_be_flushed_is0) && (!asid_to_be_flushed_is0)) + else if ((!content_q[i].g) && ((vaddr_vpn0_match[i] && vaddr_vpn1_match[i]) || (vaddr_vpn1_match[i] && tags_q[i].is_4M)) && (asid_to_be_flushed_i == tags_q[i].asid[ASID_WIDTH-1:0]) && (!vaddr_to_be_flushed_is0) && (!asid_to_be_flushed_is0)) tags_n[i].valid = 1'b0; // the entry is flushed if it's not global, and the asid matches and vaddr is 0. ("SFENCE.VMA 0 asid" case) - else if ((!content_q[i].g) && (vaddr_to_be_flushed_is0) && (asid_to_be_flushed_i == tags_q[i].asid) && (!asid_to_be_flushed_is0)) + else if ((!content_q[i].g) && (vaddr_to_be_flushed_is0) && (asid_to_be_flushed_i == tags_q[i].asid[ASID_WIDTH-1:0]) && (!asid_to_be_flushed_is0)) tags_n[i].valid = 1'b0; // normal replacement end else if (update_i.valid & replace_en[i]) begin