diff --git a/src/main/scala/rocket/ALU.scala b/src/main/scala/rocket/ALU.scala index 7ccab76f824..af78e4f65b6 100644 --- a/src/main/scala/rocket/ALU.scala +++ b/src/main/scala/rocket/ALU.scala @@ -31,6 +31,11 @@ object ALU { def FN_UNARY = 16.U def FN_ROL = 17.U def FN_ROR = 18.U + def FN_BEXT = 19.U + + def FN_ANDN = 24.U + def FN_ORN = 25.U + def FN_XNOR = 26.U def FN_MAX = 28.U def FN_MIN = 29.U @@ -56,10 +61,11 @@ object ALU { def cmpUnsigned(cmd: UInt) = cmd(1) def cmpInverted(cmd: UInt) = cmd(0) def cmpEq(cmd: UInt) = !cmd(3) - def shiftReverse(cmd: UInt) = !cmd.isOneOf(FN_SR, FN_SRA, FN_ROR) + def shiftReverse(cmd: UInt) = !cmd.isOneOf(FN_SR, FN_SRA, FN_ROR, FN_BEXT) + def bwInvRs2(cmd: UInt) = cmd.isOneOf(FN_ANDN, FN_ORN, FN_XNOR) } - import ALU._ +import ALU._ abstract class AbstractALU(implicit p: Parameters) extends CoreModule()(p) { @@ -78,6 +84,7 @@ class ALU(implicit p: Parameters) extends AbstractALU()(p) { // ADD, SUB val in2_inv = Mux(isSub(io.fn), ~io.in2, io.in2) val in1_xor_in2 = io.in1 ^ in2_inv + val in1_and_in2 = io.in1 & in2_inv io.adder_out := io.in1 + in2_inv + isSub(io.fn) // SLT, SLTU @@ -99,8 +106,8 @@ class ALU(implicit p: Parameters) extends AbstractALU()(p) { val shin = Mux(shiftReverse(io.fn), Reverse(shin_r), shin_r) val shout_r = (Cat(isSub(io.fn) & shin(xLen-1), shin).asSInt >> shamt)(xLen-1,0) val shout_l = Reverse(shout_r) - val shout = Mux(io.fn === FN_SR || io.fn === FN_SRA, shout_r, 0.U) | - Mux(io.fn === FN_SL, shout_l, 0.U) + val shout = Mux(io.fn === FN_SR || io.fn === FN_SRA || io.fn === FN_BEXT, shout_r, 0.U) | + Mux(io.fn === FN_SL, shout_l, 0.U) // CZEQZ, CZNEZ val in2_not_zero = io.in2.orR @@ -109,10 +116,11 @@ class ALU(implicit p: Parameters) extends AbstractALU()(p) { ) // AND, OR, XOR - val logic = Mux(io.fn === FN_XOR || io.fn === FN_OR, in1_xor_in2, 0.U) | - Mux(io.fn === FN_OR || io.fn === FN_AND, io.in1 & io.in2, 0.U) + val logic = Mux(io.fn === FN_XOR || io.fn === FN_OR || io.fn === FN_ORN || io.fn === FN_XNOR, in1_xor_in2, 0.U) | + Mux(io.fn === FN_OR || io.fn === FN_AND || io.fn === FN_ORN || io.fn === FN_ANDN, in1_and_in2, 0.U) - val shift_logic = (isCmp (io.fn) && slt) | logic | shout + val bext_mask = Mux(coreParams.useZbs.B && io.fn === FN_BEXT, 1.U, ~(0.U(xLen.W))) + val shift_logic = (isCmp (io.fn) && slt) | logic | (shout & bext_mask) val shift_logic_cond = cond_out match { case Some(co) => shift_logic | co case _ => shift_logic diff --git a/src/main/scala/rocket/Configs.scala b/src/main/scala/rocket/Configs.scala index ac4b0f6db9e..9212166082a 100644 --- a/src/main/scala/rocket/Configs.scala +++ b/src/main/scala/rocket/Configs.scala @@ -229,6 +229,8 @@ class WithCoreClockGatingEnabled extends RocketCoreConf class WithPgLevels(n: Int) extends RocketCoreConfig(_.copy(pgLevels = n)) class WithZba extends RocketCoreConfig(_.copy(useZba = true)) class WithZbb extends RocketCoreConfig(_.copy(useZbb = true)) +class WithZbs extends RocketCoreConfig(_.copy(useZbs = true)) +class WithB extends RocketCoreConfig(_.copy(useZba = true, useZbb = true, useZbs = true)) class WithSV48 extends WithPgLevels(4) class WithSV39 extends WithPgLevels(3) diff --git a/src/main/scala/rocket/Consts.scala b/src/main/scala/rocket/Consts.scala index d9d41aa14ef..10f5201a365 100644 --- a/src/main/scala/rocket/Consts.scala +++ b/src/main/scala/rocket/Consts.scala @@ -37,7 +37,9 @@ trait ScalarOpConstants { def A2_SIZE = 1.U(3.W) def A2_RS2 = 2.U(3.W) def A2_IMM = 3.U(3.W) - def A2_RS2INV = 4.U(3.W) + def A2_RS2OH = 4.U(3.W) + def A2_IMMOH = 5.U(3.W) + def X = BitPat("b?") def N = BitPat("b0") diff --git a/src/main/scala/rocket/IDecode.scala b/src/main/scala/rocket/IDecode.scala index 87089f8a6f8..2c80aa5f9c8 100644 --- a/src/main/scala/rocket/IDecode.scala +++ b/src/main/scala/rocket/IDecode.scala @@ -466,9 +466,9 @@ class Zba64Decode(implicit val p: Parameters) extends DecodeConstants class ZbbDecode(implicit val p: Parameters) extends DecodeConstants { val table: Array[(BitPat, List[BitPat])] = Array( - ANDN -> List(Y,N,N,N,N,N,Y,Y,A2_RS2INV,A1_RS1,IMM_X,DW_XPR,FN_AND, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N), - ORN -> List(Y,N,N,N,N,N,Y,Y,A2_RS2INV,A1_RS1,IMM_X,DW_XPR,FN_OR , N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N), - XNOR -> List(Y,N,N,N,N,N,Y,Y,A2_RS2INV,A1_RS1,IMM_X,DW_XPR,FN_XOR, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N), + ANDN -> List(Y,N,N,N,N,N,Y,Y,A2_RS2 ,A1_RS1,IMM_X,DW_XPR,FN_ANDN, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N), + ORN -> List(Y,N,N,N,N,N,Y,Y,A2_RS2 ,A1_RS1,IMM_X,DW_XPR,FN_ORN, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N), + XNOR -> List(Y,N,N,N,N,N,Y,Y,A2_RS2 ,A1_RS1,IMM_X,DW_XPR,FN_XNOR, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N), CLZ -> List(Y,N,N,N,N,N,N,Y,A2_IMM ,A1_RS1,IMM_I,DW_XPR,FN_UNARY, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N), CPOP -> List(Y,N,N,N,N,N,N,Y,A2_IMM ,A1_RS1,IMM_I,DW_XPR,FN_UNARY, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N), CTZ -> List(Y,N,N,N,N,N,N,Y,A2_IMM ,A1_RS1,IMM_I,DW_XPR,FN_UNARY, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N), @@ -508,6 +508,21 @@ class Zbb32Decode(implicit val p: Parameters) extends DecodeConstants ) } +class ZbsDecode(implicit val p: Parameters) extends DecodeConstants +{ + val table: Array[(BitPat, List[BitPat])] = Array( + BCLR -> List(Y,N,N,N,N,N,Y,Y,A2_RS2OH ,A1_RS1,IMM_X,DW_XPR,FN_ANDN, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N), + BCLRI -> List(Y,N,N,N,N,N,N,Y,A2_IMMOH ,A1_RS1,IMM_I,DW_XPR,FN_ANDN, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N), + BEXT -> List(Y,N,N,N,N,N,Y,Y,A2_RS2 ,A1_RS1,IMM_X,DW_XPR,FN_BEXT, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N), + BEXTI -> List(Y,N,N,N,N,N,N,Y,A2_IMM ,A1_RS1,IMM_I,DW_XPR,FN_BEXT, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N), + BINV -> List(Y,N,N,N,N,N,Y,Y,A2_RS2OH ,A1_RS1,IMM_X,DW_XPR,FN_XOR , N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N), + BINVI -> List(Y,N,N,N,N,N,N,Y,A2_IMMOH ,A1_RS1,IMM_I,DW_XPR,FN_XOR , N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N), + BSET -> List(Y,N,N,N,N,N,Y,Y,A2_RS2OH ,A1_RS1,IMM_X,DW_XPR,FN_OR , N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N), + BSETI -> List(Y,N,N,N,N,N,N,Y,A2_IMMOH ,A1_RS1,IMM_I,DW_XPR,FN_OR , N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N), + ) +} + + class RoCCDecode(implicit val p: Parameters) extends DecodeConstants { diff --git a/src/main/scala/rocket/RocketCore.scala b/src/main/scala/rocket/RocketCore.scala index 986705802ae..381858b2320 100644 --- a/src/main/scala/rocket/RocketCore.scala +++ b/src/main/scala/rocket/RocketCore.scala @@ -28,6 +28,7 @@ case class RocketCoreParams( useConditionalZero: Boolean = false, useZba: Boolean = false, useZbb: Boolean = false, + useZbs: Boolean = false, nLocalInterrupts: Int = 0, useNMI: Boolean = false, nBreakpoints: Int = 1, @@ -67,7 +68,6 @@ case class RocketCoreParams( val instBits: Int = if (useCompressed) 16 else 32 val lrscCycles: Int = 80 // worst case is 14 mispredicted branches + slop val traceHasWdata: Boolean = debugROB.isDefined // ooo wb, so no wdata in trace - val useZbs: Boolean = false override val useVector = vector.isDefined override val vectorUseDCache = vector.map(_.useDCache).getOrElse(false) override def vLen = vector.map(_.vLen).getOrElse(0) @@ -236,6 +236,7 @@ class Rocket(tile: RocketTile)(implicit p: Parameters) extends CoreModule()(p) usingVector.option(new VCFGDecode) ++: (if (coreParams.useZba) new ZbaDecode +: (xLen > 32).option(new Zba64Decode).toSeq else Nil) ++: (if (coreParams.useZbb) Seq(new ZbbDecode, if (xLen == 32) new Zbb32Decode else new Zbb64Decode) else Nil) ++: + coreParams.useZbs.option(new ZbsDecode) ++: Seq(new IDecode) } flatMap(_.table) @@ -473,12 +474,15 @@ class Rocket(tile: RocketTile)(implicit p: Parameters) extends CoreModule()(p) A1_PC -> ex_reg_pc.asSInt, A1_RS1SHL -> (if (rocketParams.useZba) ex_rs1shl.asSInt else 0.S) )) + val ex_op2_oh = UIntToOH(Mux(ex_ctrl.sel_alu2(0), (ex_reg_inst >> 20).asUInt, ex_rs(1))(log2Ceil(xLen)-1,0)).asSInt val ex_op2 = MuxLookup(ex_ctrl.sel_alu2, 0.S)(Seq( A2_RS2 -> ex_rs(1).asSInt, A2_IMM -> ex_imm, A2_SIZE -> Mux(ex_reg_rvc, 2.S, 4.S), - A2_RS2INV -> (if (rocketParams.useZbb) (~ex_rs(1)).asSInt else 0.S) - )) + ) ++ (if (coreParams.useZbs) Seq( + A2_RS2OH -> ex_op2_oh, + A2_IMMOH -> ex_op2_oh, + ) else Nil)) val (ex_new_vl, ex_new_vconfig) = if (usingVector) { val ex_new_vtype = VType.fromUInt(MuxCase(ex_rs(1), Seq(