diff --git a/src/main/scala/rocket/Instructions.scala b/src/main/scala/rocket/Instructions.scala index adf1183388f..f79388f64ad 100644 --- a/src/main/scala/rocket/Instructions.scala +++ b/src/main/scala/rocket/Instructions.scala @@ -76,17 +76,26 @@ object Instructions { def C_J = BitPat("b????????????????101???????????01") def C_JALR = BitPat("b????????????????1001?????0000010") def C_JR = BitPat("b????????????????1000?????0000010") + def C_LBU = BitPat("b????????????????100000????????00") def C_LD = BitPat("b????????????????011???????????00") def C_LDSP = BitPat("b????????????????011???????????10") + def C_LH = BitPat("b????????????????100001???1????00") + def C_LHU = BitPat("b????????????????100001???0????00") def C_LI = BitPat("b????????????????010???????????01") def C_LUI = BitPat("b????????????????011???????????01") def C_LW = BitPat("b????????????????010???????????00") def C_LWSP = BitPat("b????????????????010???????????10") + def C_MUL = BitPat("b????????????????100111???10???01") def C_MV = BitPat("b????????????????1000??????????10") def C_NOP = BitPat("b????????????????000?00000?????01") + def C_NOT = BitPat("b????????????????100111???1110101") def C_OR = BitPat("b????????????????100011???10???01") + def C_SB = BitPat("b????????????????100010????????00") def C_SD = BitPat("b????????????????111???????????00") def C_SDSP = BitPat("b????????????????111???????????10") + def C_SEXT_B = BitPat("b????????????????100111???1100101") + def C_SEXT_H = BitPat("b????????????????100111???1101101") + def C_SH = BitPat("b????????????????100011???0????00") def C_SLLI = BitPat("b????????????????000???????????10") def C_SRAI = BitPat("b????????????????100?01????????01") def C_SRLI = BitPat("b????????????????100?00????????01") @@ -95,6 +104,9 @@ object Instructions { def C_SW = BitPat("b????????????????110???????????00") def C_SWSP = BitPat("b????????????????110???????????10") def C_XOR = BitPat("b????????????????100011???01???01") + def C_ZEXT_B = BitPat("b????????????????100111???1100001") + def C_ZEXT_H = BitPat("b????????????????100111???1101001") + def C_ZEXT_W = BitPat("b????????????????100111???1110001") def CBO_CLEAN = BitPat("b000000000001?????010000000001111") def CBO_FLUSH = BitPat("b000000000010?????010000000001111") def CBO_INVAL = BitPat("b000000000000?????010000000001111") @@ -1729,4 +1741,4 @@ object CSRs { res += mhpmcounter31h res.toArray } -} +} \ No newline at end of file diff --git a/src/main/scala/rocket/RVC.scala b/src/main/scala/rocket/RVC.scala index cc54c293558..d92a4254957 100644 --- a/src/main/scala/rocket/RVC.scala +++ b/src/main/scala/rocket/RVC.scala @@ -16,7 +16,17 @@ class ExpandedInstruction extends Bundle { val rs3 = UInt(5.W) } -class RVCDecoder(x: UInt, xLen: Int, useAddiForMv: Boolean = false) { +/* Parameters for RVCDecoder + - Zcb extension contains the compressed I-type (c.lbu, lhu, lh, sb, sh) , M-type (c.mul) + and Bit Manip instructions. + - **usingCompressedSuiteB** parameter is used to enable/disable "Zcb" extension in RocketCore. + - If Zcb is enabled, furthur **usingBitManip** and **usingMulDiv** parameters (if set as True) are used to decode + the corresponding BitManip and M type Instructions. + - If **usingCompressedSuiteB** parameter is not set (i.e. False), decoder will give "unimp" + instruction if it encounters any Zcb instruction. Same is true for **usingBitManip** and **usingMulDiv**. +*/ + +class RVCDecoder(x: UInt, xLen: Int, useAddiForMv: Boolean = false, usingBitManip: Boolean = false, usingMulDiv: Boolean = false, usingCompressedSuiteB: Boolean = false) { def inst(bits: UInt, rd: UInt = x(11,7), rs1: UInt = x(19,15), rs2: UInt = x(24,20), rs3: UInt = x(31,27)) = { val res = Wire(new ExpandedInstruction) res.bits := bits @@ -32,6 +42,8 @@ class RVCDecoder(x: UInt, xLen: Int, useAddiForMv: Boolean = false) { def rs2 = x(6,2) def rd = x(11,7) def addi4spnImm = Cat(x(10,7), x(12,11), x(5), x(6), 0.U(2.W)) + def lbImm = Cat(x(5), x(6)) + def lhImm = Cat(x(5), 0.U(1.W)) def lwImm = Cat(x(5), x(12,10), x(6), 0.U(2.W)) def ldImm = Cat(x(6,5), x(12,10), 0.U(3.W)) def lwspImm = Cat(x(3,2), x(12), x(6,4), 0.U(2.W)) @@ -60,7 +72,19 @@ class RVCDecoder(x: UInt, xLen: Int, useAddiForMv: Boolean = false) { if (xLen == 32) inst(Cat(lwImm, rs1p, 2.U(3.W), rs2p, 0x07.U(7.W)), rs2p, rs1p, rs2p) else ld } - def unimp = inst(Cat(lwImm >> 5, rs2p, rs1p, 2.U(3.W), lwImm(4,0), 0x3F.U(7.W)), rs2p, rs1p, rs2p) + def zcb_q0 = { + if (usingCompressedSuiteB){ + def lbu = Cat(lbImm, rs1p, 4.U(3.W), rs2p, 0x03.U(7.W)) + def lh = { + val func3 = Mux(x(6), 1.U(3.W), 5.U(3.W)) + Cat(lhImm, rs1p, func3, rs2p, 0x03.U(7.W)) + } + def sb = Cat(rs2p, rs1p, 0.U(3.W), 0.U(3.W), lbImm(1,0), 0x23.U(7.W)) + def sh = Cat(rs2p, rs1p, 1.U(3.W), 0.U(3.W), lhImm(1,0), 0x23.U(7.W)) + inst(Seq(lbu, lh, sb, sh)(x(11,10)), rs2p, rs1p, rs2p) + } + else inst(Cat(lwImm >> 5, rs2p, rs1p, 2.U(3.W), lwImm(4,0), 0x3F.U(7.W)), rs2p, rs1p, rs2p) // unimp + } def sd = inst(Cat(ldImm >> 5, rs2p, rs1p, 3.U(3.W), ldImm(4,0), 0x23.U(7.W)), rs2p, rs1p, rs2p) def sw = inst(Cat(lwImm >> 5, rs2p, rs1p, 2.U(3.W), lwImm(4,0), 0x23.U(7.W)), rs2p, rs1p, rs2p) def fsd = inst(Cat(ldImm >> 5, rs2p, rs1p, 3.U(3.W), ldImm(4,0), 0x27.U(7.W)), rs2p, rs1p, rs2p) @@ -68,7 +92,7 @@ class RVCDecoder(x: UInt, xLen: Int, useAddiForMv: Boolean = false) { if (xLen == 32) inst(Cat(lwImm >> 5, rs2p, rs1p, 2.U(3.W), lwImm(4,0), 0x27.U(7.W)), rs2p, rs1p, rs2p) else sd } - Seq(addi4spn, fld, lw, flw, unimp, fsd, sw, fsw) + Seq(addi4spn, fld, lw, flw, zcb_q0, fsd, sw, fsw) } def q1 = { @@ -96,15 +120,45 @@ class RVCDecoder(x: UInt, xLen: Int, useAddiForMv: Boolean = false) { def bnez = inst(Cat(bImm(12), bImm(10,5), x0, rs1p, 1.U(3.W), bImm(4,1), bImm(11), 0x63.U(7.W)), x0, rs1p, x0) def arith = { def srli = Cat(shamt, rs1p, 5.U(3.W), rs1p, 0x13.U(7.W)) - def srai = srli | (1 << 30).U + def srai = Cat(0x10.U, srli) def andi = Cat(addiImm, rs1p, 7.U(3.W), rs1p, 0x13.U(7.W)) def rtype = { - val funct = Seq(0.U, 4.U, 6.U, 7.U, 0.U, 0.U, 2.U, 3.U)(Cat(x(12), x(6,5))) + val funct = Seq(0.U, 4.U, 6.U, 7.U, 0.U, 0.U, 0.U, 3.U)(Cat(x(12), x(6,5))) val sub = Mux(x(6,5) === 0.U, (1 << 30).U, 0.U) - val opc = Mux(x(12), 0x3B.U(7.W), 0x33.U(7.W)) - Cat(rs2p, rs1p, funct, rs1p, opc) | sub + val opc = Mux(x(12), Mux(x(6), 0x33.U(7.W), 0x3B.U(7.W)), 0x33.U(7.W)) + def mul = { + if(usingMulDiv && usingCompressedSuiteB) Mux(Cat(x(12), x(6,5)) === 6.U, (1 << 25).U, 0.U) + else 0.U + } + def zca = Cat(rs2p, rs1p, funct, rs1p, opc) | sub | mul + def zcb_q1 = { + def unimp = Cat(lwImm >> 5, rs2p, rs1p, 2.U(3.W), lwImm(4,0), 0x3F.U(7.W)) + if(usingCompressedSuiteB){ + def zextb = Cat(0xFF.U, rs1p, 7.U(3.W), rs1p, 0x13.U(7.W)) + def not = Cat(0xFFF.U, rs1p, 4.U(3.W), rs1p, 0x13.U(7.W)) + def sextb = Cat(0x604.U, rs1p, 1.U(3.W), rs1p, 0x13.U(7.W)) + def sexth = Cat(0x605.U, rs1p, 1.U(3.W), rs1p, 0x13.U(7.W)) + def zextw = Cat(4.U, x0, rs1p, 0.U(3.W), rs1p, 0x3B.U(7.W)) + def zexth = { + val zexth_common = Cat(0x80.U, rs1p, 4.U(3.W), rs1p) + if (xLen == 32) Cat(zexth_common, 0x33.U(7.W)) + else Cat(zexth_common, 0x3B.U(7.W)) + } + if(usingBitManip){ + Seq(zextb, sextb, zexth, sexth, zextw, not, unimp, unimp)(x(4,2)) + } else { + Mux (x(4,2)=== 5.U, not, Mux (x(4,2) === 0.U, zextb, unimp)) + } + } + else unimp + } + Mux(Cat(x(12), x(6,5)) === 7.U, zcb_q1, zca) + } + def op2 = { + if(usingCompressedSuiteB) Mux(Cat(x(15,10), x(6,2)) === 0x4FC.U, x0, rs2p) + else rs2p } - inst(Seq(srli, srai, andi, rtype)(x(11,10)), rs1p, rs1p, rs2p) + inst(Seq(srli, srai, andi, rtype)(x(11,10)), rs1p, rs1p, op2) } Seq(addi, jal, li, lui, arith, j, beqz, bnez) } @@ -164,9 +218,9 @@ class RVCExpander(useAddiForMv: Boolean = false)(implicit val p: Parameters) ext if (usingCompressed) { io.rvc := io.in(1,0) =/= 3.U - io.out := new RVCDecoder(io.in, p(XLen), useAddiForMv).decode + io.out := new RVCDecoder(io.in, p(XLen), useAddiForMv, usingBitManip, usingMulDiv, usingCompressedSuiteB).decode } else { io.rvc := false.B - io.out := new RVCDecoder(io.in, p(XLen), useAddiForMv).passthrough + io.out := new RVCDecoder(io.in, p(XLen), useAddiForMv, usingBitManip, usingMulDiv, usingCompressedSuiteB).passthrough } } diff --git a/src/main/scala/rocket/RocketCore.scala b/src/main/scala/rocket/RocketCore.scala index f07fdb75baa..68bc29332d4 100644 --- a/src/main/scala/rocket/RocketCore.scala +++ b/src/main/scala/rocket/RocketCore.scala @@ -23,6 +23,7 @@ case class RocketCoreParams( useAtomics: Boolean = true, useAtomicsOnlyForIO: Boolean = false, useCompressed: Boolean = true, + useCompressedSuiteB: Boolean = false, useRVE: Boolean = false, useSCIE: Boolean = false, useBitManip: Boolean = false, diff --git a/src/main/scala/tile/BaseTile.scala b/src/main/scala/tile/BaseTile.scala index 1265cb622bb..0ae7674ce66 100644 --- a/src/main/scala/tile/BaseTile.scala +++ b/src/main/scala/tile/BaseTile.scala @@ -113,6 +113,10 @@ trait HasNonDiplomaticTileParameters { Option.when(tileParams.core.useConditionalZero)(Seq("zicond")) ++ Some(Seq("zicsr", "zifencei", "zihpm")) ++ Option.when(tileParams.core.fpu.nonEmpty && tileParams.core.fpu.get.fLen >= 16 && tileParams.core.fpu.get.minFLen <= 16)(Seq("zfh")) ++ + Option.when(tileParams.core.useCompressed)(Seq("zca")) ++ + Option.when(tileParams.core.useCompressedSuiteB)(Seq("zcb")) ++ + Option.when(tileParams.core.useCompressed && tileParams.core.fpu.nonEmpty && tileParams.core.fpu.get.fLen > 32)(Seq("zcd")) ++ + Option.when(tileParams.core.useCompressed && tileParams.core.fpu.nonEmpty)(Seq("zcf")) ++ Option.when(tileParams.core.useBitManip)(Seq("zba", "zbb", "zbc")) ++ Option.when(tileParams.core.hasBitManipCrypto)(Seq("zbkb", "zbkc", "zbkx")) ++ Option.when(tileParams.core.useBitManip)(Seq("zbs")) ++ diff --git a/src/main/scala/tile/Core.scala b/src/main/scala/tile/Core.scala index 70c47836785..934c4dbfeba 100644 --- a/src/main/scala/tile/Core.scala +++ b/src/main/scala/tile/Core.scala @@ -22,6 +22,7 @@ trait CoreParams { val useAtomics: Boolean val useAtomicsOnlyForIO: Boolean val useCompressed: Boolean + val useCompressedSuiteB: Boolean val useBitManip: Boolean val useBitManipCrypto: Boolean val useVector: Boolean = false @@ -86,6 +87,7 @@ trait HasCoreParameters extends HasTileParameters { val usingAtomicsOnlyForIO = coreParams.useAtomicsOnlyForIO val usingAtomicsInCache = usingAtomics && !usingAtomicsOnlyForIO val usingCompressed = coreParams.useCompressed + val usingCompressedSuiteB = coreParams.useCompressedSuiteB && usingCompressed val usingBitManip = coreParams.useBitManip val usingBitManipCrypto = coreParams.hasBitManipCrypto val usingVector = coreParams.useVector