Skip to content

Commit

Permalink
.
Browse files Browse the repository at this point in the history
  • Loading branch information
sequencer committed Sep 28, 2023
1 parent 2c1e8d1 commit 3f88fdf
Show file tree
Hide file tree
Showing 6 changed files with 388 additions and 232 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
package freechips.rocketchip.rocket

import chisel3.util._
import freechips.rocketchip.rocket._

object CustomInstructions {
def MNRET = BitPat("b01110000001000000000000001110011")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ package freechips.rocketchip.rocket
import chisel3._
import chisel3.util.BitPat
import chisel3.util.experimental.decode._
import freechips.rocketchip.rocket._

object DecodeLogic
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import chisel3._
import chisel3.util._
import org.chipsalliance.cde.config.Parameters
import freechips.rocketchip.util._
import freechips.rocketchip.rocket._
import Instructions._
import CustomInstructions._

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
package freechips.rocketchip.rocket

import chisel3.util._
import freechips.rocketchip.rocket._

/* make EXTENSIONS="rv_* rv64*" inst.chisel */

Expand Down
156 changes: 116 additions & 40 deletions src/main/scala/rocket/Decoder.scala
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ package org.chipsalliance.rocketcore.decoder
import chisel3._
import chisel3.util.BitPat
import chisel3.util.experimental.decode._
import org.chipsalliance.rvdecoderdb.{Instruction, InstructionSet, Utils}
import org.chipsalliance.rvdecoderdb.{Encoding, Instruction, InstructionSet, Utils}

// behave like ChiselEnum, but for compatibility, use UInt for now.
// This is going to be upstreamed to Chisel in the future.
Expand All @@ -31,40 +31,96 @@ trait UOPDecodeField[T <: DecodePattern] extends DecodeField[T, UInt] {
}

/** DecodePattern for an RISC-V instruction */
trait RocketDecodePattern extends DecodePattern {
def instruction: Instruction

def isRoCC = false
case class RocketDecodePattern(instruction: Instruction) extends DecodePattern {
def isRoCC: Boolean = instruction.instructionSet.name == "rv_rocc"

override def bitPat: BitPat = BitPat(instruction.encoding.toString)
}

/** factory to generate the rocket core decoder. */
abstract class InstructionDecoder {
val instructions: Seq[Instruction]

/** if this is true, use div block for mul. */
val pipelinedMul: Boolean
// FIXME: Encoding
object CustomInstructions {
private def rocket(name: String, encoding: Encoding) =
Instruction(name, encoding, Seq(), Seq(InstructionSet("rv_rocket")), None, false, true)

val rocketSet = Seq(
rocket("c.flush.d.l1", Encoding.fromString("111111000000?????000000001110011")),
rocket("c.discard.d.l1", Encoding.fromString("111111000010?????000000001110011")),
rocket("cease", Encoding.fromString("00110000010100000000000001110011"))
).map(RocketDecodePattern.apply)

private def rocc(name: String, encoding: Encoding) =
Instruction(name, encoding, Seq(), Seq(InstructionSet("rv_rocc")), None, false, true)
val roccSet = Seq(
rocc("custom0", Encoding.fromString("?????????????????000?????0001011")),
rocc("custom0.rs1", Encoding.fromString("?????????????????010?????0001011")),
rocc("custom0.rs1.rs2", Encoding.fromString("?????????????????011?????0001011")),
rocc("custom0.rd", Encoding.fromString("?????????????????100?????0001011")),
rocc("custom0.rd.rs1", Encoding.fromString("?????????????????110?????0001011")),
rocc("custom0.rd.rs1.rs2", Encoding.fromString("?????????????????111?????0001011")),
rocc("custom1", Encoding.fromString("?????????????????000?????0101011")),
rocc("custom1.rs1", Encoding.fromString("?????????????????010?????0101011")),
rocc("custom1.rs1.rs2", Encoding.fromString("?????????????????011?????0101011")),
rocc("custom1.rd", Encoding.fromString("?????????????????100?????0101011")),
rocc("custom1.rd.rs1", Encoding.fromString("?????????????????110?????0101011")),
rocc("custom1.rd.rs1.rs2", Encoding.fromString("?????????????????111?????0101011")),
rocc("custom2", Encoding.fromString("?????????????????000?????1011011")),
rocc("custom2.rs1", Encoding.fromString("?????????????????010?????1011011")),
rocc("custom2.rs1.rs2", Encoding.fromString("?????????????????011?????1011011")),
rocc("custom2.rd", Encoding.fromString("?????????????????100?????1011011")),
rocc("custom2.rd.rs1", Encoding.fromString("?????????????????110?????1011011")),
rocc("custom2.rd.rs1.rs2", Encoding.fromString("?????????????????111?????1011011")),
rocc("custom3", Encoding.fromString("?????????????????000?????1111011")),
rocc("custom3.rs1", Encoding.fromString("?????????????????010?????1111011")),
rocc("custom3.rs1.rs2", Encoding.fromString("?????????????????011?????1111011")),
rocc("custom3.rd", Encoding.fromString("?????????????????100?????1111011")),
rocc("custom3.rd.rs1", Encoding.fromString("?????????????????110?????1111011")),
rocc("custom3.rd.rs1.rs2", Encoding.fromString("?????????????????111?????1111011"))
).map(RocketDecodePattern.apply)
}

/** if this is true, use ablu for ALU which supports zb zk */
val useABLU: Boolean
val instructionDecodePatterns: Seq[RocketDecodePattern] = instructions.map(instr =>
new RocketDecodePattern {
override def instruction: Instruction = instr
}
)
val instructionDecodeFields: Seq[DecodeField[RocketDecodePattern, _ <: Data]] = Seq(
/** Parameter for InstructionDecoder
* @param instructions Instructions supported by
* @param pipelinedMul
* @param fenceIFlushDCache
*/
case class InstructionDecoderParameter(
instructions: Seq[Instruction],
pipelinedMul: Boolean,
fenceIFlushDCache: Boolean
)
/** factory to generate the rocket core decoder. */
class InstructionDecoder(p: InstructionDecoderParameter) {
private val instructions = p.instructions

// functions below is my little reminder, which is used for future rocket core refactoring, just keep it, I'll remove it later in the future.
private def hasAnySetIn(sets: String*): Boolean = sets.exists(set => instructions.flatMap(_.instructionSets.map(_.name)).exists(_.contains(set)))
private def xLen32: Boolean = instructions.flatMap(_.instructionSets.map(_.name)).exists(_.startsWith("rv32_"))
private def xLen64: Boolean = instructions.flatMap(_.instructionSets.map(_.name)).exists(_.startsWith("rv64_"))
require(Seq(xLen32, xLen64).count(a => a) == 1, "rocket cannot support both rv32 and rv64 in the same time")
private def fLen0: Boolean = !fLen32 && !fLen64
private def fLen32: Boolean = hasAnySetIn("rv_f", "rv32_f", "rv64_f")
private def fLen64: Boolean = hasAnySetIn("rv_d", "rv32_d", "rv64_d")
private def zfh: Boolean = hasAnySetIn("rv_zfh", "rv64_zfh", "rv_d_zfh")
private def usingAtomics: Boolean = hasAnySetIn("rv_a", "rv64_a")
private def usingBitManip: Boolean = hasAnySetIn("rv_zba", "rv64_zba", "rv_zbb", "rv32_zbb", "rv64_zbb", "rv_zbc", "rv_zbs")
private def usingBitManipCrypto: Boolean = hasAnySetIn("rv_zbkb", "rv32_zbkb", "rv64_zbkb", "rv_zbkc", "rv_zbkx")
private def usingCryptoNIST: Boolean = hasAnySetIn("rv32_zknd", "rv64_zknd", "rv32_zkne", "rv64_zkne", "rv_zknh", "rv32_zknh", "rv64_zknh", "rv_zkn", "rv32_zkn", "rv64_zkn")
private def usingCryptoSM: Boolean = hasAnySetIn("rv_zksed", "rv_zksh", "rv_zks", "rv32_zks", "rv64_zks", "rv_zk")
private def usingConditionalZero = hasAnySetIn("rv_zicond")

/** use ablu for ALU which supports zb zk */
private val useABLU: Boolean = usingBitManip || usingBitManipCrypto || usingCryptoNIST || usingCryptoSM

private val instructionDecodePatterns: Seq[RocketDecodePattern] = instructions.map(RocketDecodePattern.apply)
private val instructionDecodeFields: Seq[DecodeField[RocketDecodePattern, _ <: Data]] = Seq(
isLegal,
useFPU,
isFPU,
isRoCC,
isBranch,
isJal,
isJalr,
readRs2,
readRs1,
zbk,
zkn,
zks,
rxs2,
rxs1,
selAlu2,
selAlu1,
selImm,
Expand All @@ -82,19 +138,20 @@ abstract class InstructionDecoder {
fenceI,
fence,
amo,
dp
dp,
// TODO: refactor ABLU encoding in the future.
zbk,
zkn,
zks,
) ++ (if (useABLU) Some(abluFn) else Some(aluFn))
val sets: Seq[InstructionSet] = instructions.map(_.instructionSets.head)

val table: DecodeTable[RocketDecodePattern] = new DecodeTable[RocketDecodePattern](
instructionDecodePatterns,
instructionDecodeFields
) {
// FIXME: in Chisel
override val table: TruthTable = TruthTable(
instructionDecodePatterns.map { op =>
op.bitPat -> instructionDecodeFields.reverse.map(_.genTable(op)).reduce(_ ## _)
},
instructionDecodePatterns.map(op =>op.bitPat -> instructionDecodeFields.reverse.map(_.genTable(op)).reduce(_ ## _)),
instructionDecodeFields.reverse.map(_.dc).reduce(_ ## _)
)
}
Expand All @@ -108,7 +165,7 @@ abstract class InstructionDecoder {
override def genTable(op: RocketDecodePattern): BitPat = y
}

object useFPU extends BoolDecodeField[RocketDecodePattern] {
object isFPU extends BoolDecodeField[RocketDecodePattern] {
override def name: String = "fp"

override def dc: BitPat = n
Expand Down Expand Up @@ -149,13 +206,13 @@ abstract class InstructionDecoder {
}
}

object readRs2 extends BoolDecodeField[RocketDecodePattern] {
object rxs2 extends BoolDecodeField[RocketDecodePattern] {
override def name: String = "rxs2"

override def genTable(op: RocketDecodePattern): BitPat = if (Utils.readRs2(op.instruction)) y else n
}

object readRs1 extends BoolDecodeField[RocketDecodePattern] {
object rxs1 extends BoolDecodeField[RocketDecodePattern] {
override def name: String = "rxs1"

override def genTable(op: RocketDecodePattern): BitPat = if (Utils.readRs1(op.instruction)) y else n
Expand Down Expand Up @@ -208,6 +265,7 @@ abstract class InstructionDecoder {

object zkn extends BoolDecodeField[RocketDecodePattern] {
override def name: String = "zkn"

override def genTable(op: RocketDecodePattern): BitPat = op.instruction.instructionSet.name match {
// format: off
case s if Seq("rv32_zknd", "rv64_zknd", "rv32_zkne", "rv64_zkne", "rv_zknh", "rv32_zknh", "rv64_zknh", "rv_zksed").contains(s) => y
Expand Down Expand Up @@ -242,6 +300,7 @@ abstract class InstructionDecoder {

object aluDoubleWords extends BoolDecodeField[RocketDecodePattern] {
override def name: String = "alu_dw"

override def genTable(op: RocketDecodePattern): BitPat = {
op.instruction.name match {
// format: off
Expand All @@ -260,6 +319,7 @@ abstract class InstructionDecoder {
op.instruction.name match {
// format: off
case i if Seq("lb", "lh", "lw", "lbu", "lhu", "sb", "sh", "sw", "hlv_b", "hlv_bu", "hlv_h", "hlv_hu", "hlv_w", "hsv_b", "hsv_h", "hsv_w", "ld", "lwu", "sd", "hlv_d", "hsv_d", "hlv_wu", "amoadd_w", "amoxor_w", "amoswap_w", "amoand_w", "amoor_w", "amomin_w", "amominu_w", "amomax_w", "amomaxu_w", "lr_w", "sc_w", "amoadd_d", "amoswap_d", "amoxor_d", "amoand_d", "amoor_d", "amomin_d", "amominu_d", "amomax_d", "amomaxu_d", "lr_d", "sc_d", "flh", "fsh", "flw", "fsw", "fld", "fsd").contains(i) => y
case i if Seq("fence.i").contains(i) && p.fenceIFlushDCache => y
case _ => dc
// format: on
}
Expand Down Expand Up @@ -318,7 +378,7 @@ abstract class InstructionDecoder {
object mul extends BoolDecodeField[RocketDecodePattern] {
override def name: String = "mul"

override def genTable(op: RocketDecodePattern): BitPat = if (!pipelinedMul) n
override def genTable(op: RocketDecodePattern): BitPat = if (!p.pipelinedMul) n
else {
op.instruction.name match {
// format: off
Expand All @@ -334,15 +394,16 @@ abstract class InstructionDecoder {

override def genTable(op: RocketDecodePattern): BitPat = op.instruction.name match {
// format: off
case i if Seq("mul", "mulh", "mulhu", "mulhsu", "mulw").contains(i) && !pipelinedMul => y
case i if Seq("mul", "mulh", "mulhu", "mulhsu", "mulw").contains(i) && !p.pipelinedMul => y
case i if Seq("div", "divu", "rem", "remu", "divw", "divuw", "remw", "remuw").contains(i) => y
case _ => n
case _ => n
// format: on
}
}

object wxd extends BoolDecodeField[RocketDecodePattern] {
override def name: String = "wxd"

override def genTable(op: RocketDecodePattern): BitPat = if (Utils.writeRd(op.instruction)) y else n
}

Expand Down Expand Up @@ -416,10 +477,11 @@ abstract class InstructionDecoder {
case i if Seq("amoor.d", "amoor.w").contains(i) => UOPMEM.xaOr
case i if Seq("amoswap.d", "amoswap.w").contains(i) => UOPMEM.xaSwap
case i if Seq("amoxor.d", "amoxor.w").contains(i) => UOPMEM.xaXor
case i if Seq("fence.i").contains(i) && p.fenceIFlushDCache => UOPMEM.flushAll
case i if Seq("lr.d", "lr.w").contains(i) => UOPMEM.xlr
case i if Seq("fld", "flh", "flw", "hlv.b", "hlv.bu", "hlv.d", "hlv.h", "hlv.hu", "hlv.w", "hlv.wu", "lb", "lbu", "ld", "lh", "lhu", "lw", "lwu").contains(i) => UOPMEM.xrd
case i if Seq("sc.d", "sc.w").contains(i) => UOPMEM.xsc
case i if Seq("fsd", "fsh", "fsw", "hsv.b", "hsv.d", "hsv.h", "hsv.w", "sb", "sd", "sh", "sw").contains(i)=> UOPMEM.xwr
case i if Seq("fsd", "fsh", "fsw", "hsv.b", "hsv.d", "hsv.h", "hsv.w", "sb", "sd", "sh", "sw").contains(i) => UOPMEM.xwr
case _ => UOPMEM.dontCare
// format: on
}
Expand Down Expand Up @@ -450,7 +512,7 @@ abstract class InstructionDecoder {
override def genTable(op: RocketDecodePattern): BitPat = op.instruction.name match {
// format: off
case i if Seq("csrrc", "csrrci").contains(i) => UOPCSR.c
case i if Seq("cdiscard.d.l1", "cease", "cflush.d.l1", "dret", "ebreak", "ecall", "hfence.gvma", "hfence.vvma", "hlv.b", "hlv.bu", "hlv.d", "hlv.h", "hlv.hu", "hlv.w", "hlv.wu", "hlvx.hu", "hlvx.wu", "hsv.b", "hsv.d", "hsv.h", "hsv.w", "mnret", "mret", "sfence.vma", "sret", "wfi").contains(i) => UOPCSR.i
case i if Seq("cdiscard.d.l1", "cease", "cflush.d.l1", "dret", "ebreak", "ecall", "hfence.gvma", "hfence.vvma", "hlv.b", "hlv.bu", "hlv.d", "hlv.h", "hlv.hu", "hlv.w", "hlv.wu", "hlvx.hu", "hlvx.wu", "hsv.b", "hsv.d", "hsv.h", "hsv.w", "mnret", "mret", "sfence.vma", "sret", "wfi", "cease").contains(i) => UOPCSR.i
case i if Seq("csrrs", "csrrsi").contains(i) => UOPCSR.s
case i if Seq("csrrw", "csrrwi").contains(i) => UOPCSR.w
case _ => UOPCSR.dontCare
Expand Down Expand Up @@ -496,17 +558,25 @@ abstract class InstructionDecoder {
def sgeu: BitPat = encode(15)

def div: BitPat = xor

def divu: BitPat = sr

def rem: BitPat = or

def remu: BitPat = and

def mul: BitPat = add

def mulh: BitPat = sl

def mulhsu: BitPat = seq

def mulhu: BitPat = sne
}

object aluFn extends UOPDecodeField[RocketDecodePattern] {
override def name: String = "alu_fn"

override def genTable(op: RocketDecodePattern): BitPat = op.instruction.name match {
// format: off
case i if Seq("add", "addi", "addiw", "addw", "amoadd.d", "amoadd.w", "amoand.d", "amoand.w", "amomax.d", "amomax.w", "amomaxu.d", "amomaxu.w", "amomin.d", "amomin.w", "amominu.d", "amominu.w", "amoor.d", "amoor.w", "amoswap.d", "amoswap.w", "amoxor.d", "amoxor.w", "auipc", "cdiscard.d.l1", "cflush.d.l1", "csrrc", "csrrci", "csrrs", "csrrsi", "csrrw", "csrrwi", "fld", "flh", "flw", "fsd", "fsh", "fsw", "hfence.gvma", "hfence.vvma", "hlv.b", "hlv.bu", "hlv.d", "hlv.h", "hlv.hu", "hlv.w", "hlv.wu", "hlvx.hu", "hlvx.wu", "hsv.b", "hsv.d", "hsv.h", "hsv.w", "jal", "jalr", "lb", "lbu", "ld", "lh", "lhu", "lr.d", "lr.w", "lui", "lw", "lwu", "sb", "sc.d", "sc.w", "sd", "sfence.vma", "sh", "sw", "and", "andi").contains(i) => UOPALU.add
Expand All @@ -523,7 +593,7 @@ abstract class InstructionDecoder {
case i if Seq("bge").contains(i) => UOPALU.sge
case i if Seq("bgeu").contains(i) => UOPALU.sgeu
case i if Seq("sll", "slli", "slli", "slliw", "sllw").contains(i) => UOPALU.sl
case i if Seq("blt" ,"slt" ,"slti").contains(i) => UOPALU.slt
case i if Seq("blt", "slt", "slti").contains(i) => UOPALU.slt
case i if Seq("bltu", "sltiu", "sltu").contains(i) => UOPALU.sltu
case i if Seq("bne").contains(i) => UOPALU.sne
case i if Seq("srl", "srli", "srli", "srliw", "srlw").contains(i) => UOPALU.sr
Expand All @@ -533,6 +603,7 @@ abstract class InstructionDecoder {
case _ => UOPALU.dontCare
// format: on
}

override def uopType: UOPALU.type = UOPALU
}

Expand Down Expand Up @@ -848,17 +919,21 @@ abstract class InstructionDecoder {
case i if Seq("auipc", "jal").contains(i) => UOPA1.pc
case i if Seq("add", "add.uw", "addi", "addiw", "addw", "aes32dsi", "aes32dsmi", "aes32esi", "aes32esmi", "aes64ds", "aes64dsm", "aes64es", "aes64esm", "aes64im", "aes64ks1i", "aes64ks2", "amoadd.d", "amoadd.w", "amoand.d", "amoand.w", "amomax.d", "amomax.w", "amomaxu.d", "amomaxu.w", "amomin.d", "amomin.w", "amominu.d", "amominu.w", "amoor.d", "amoor.w", "amoswap.d", "amoswap.w", "amoxor.d", "amoxor.w", "and", "andi", "andn", "bclr", "bclri", "bclri", "beq", "bext", "bexti", "bexti", "bge", "bgeu", "binv", "binvi", "binvi", "blt", "bltu", "bne", "brev8", "bset", "bseti", "bseti", "cdiscard.d.l1", "cflush.d.l1", "clmul", "clmulh", "clmulr", "clz", "clzw", "cpop", "cpopw", "csrrc", "csrrs", "csrrw", "ctz", "ctzw", "czero.eqz", "czero.nez", "div", "divu", "divuw", "divw", "fcvt.d.l", "fcvt.d.lu", "fcvt.d.w", "fcvt.d.wu", "fcvt.h.l", "fcvt.h.lu", "fcvt.h.w", "fcvt.h.wu", "fcvt.s.l", "fcvt.s.lu", "fcvt.s.w", "fcvt.s.wu", "fld", "flh", "flw", "fmv.d.x", "fmv.h.x", "fmv.w.x", "fsd", "fsh", "fsw", "hfence.gvma", "hfence.vvma", "hlv.b", "hlv.bu", "hlv.d", "hlv.h", "hlv.hu", "hlv.w", "hlv.wu", "hlvx.hu", "hlvx.wu", "hsv.b", "hsv.d", "hsv.h", "hsv.w", "jalr", "lb", "lbu", "ld", "lh", "lhu", "lr.d", "lr.w", "lw", "lwu", "max", "maxu", "min", "minu", "mul", "mulh", "mulhsu", "mulhu", "mulw", "or", "orc.b", "ori", "orn", "pack", "packh", "packw", "rem", "remu", "remuw", "remw", "rev8", "rev8", "rol", "rolw", "ror", "rori", "rori", "roriw", "rorw", "sb", "sc.d", "sc.w", "sd", "sext.b", "sext.h", "sfence.vma", "sh", "sh1add", "sh1add.uw", "sh2add", "sh2add.uw", "sh3add", "sh3add.uw", "sha256sig0", "sha256sig1", "sha256sum0", "sha256sum1", "sha512sig0", "sha512sig0h", "sha512sig0l", "sha512sig1", "sha512sig1h", "sha512sig1l", "sha512sum0", "sha512sum0r", "sha512sum1", "sha512sum1r", "sll", "slli", "slli", "slli.uw", "slliw", "sllw", "slt", "slti", "sltiu", "sltu", "sm3p0", "sm3p1", "sm4ed", "sm4ks", "sra", "srai", "srai", "sraiw", "sraw", "srl", "srli", "srli", "srliw", "srlw", "sub", "subw", "sw", "unzip", "xnor", "xor", "xori", "xperm4", "xperm8", "zext.h", "zext.h", "zip").contains(i) => UOPA1.rs1
case i if Seq("csrrci", "csrrsi", "csrrwi", "lui").contains(i) => UOPA1.zero
case i => UOPA1.dontCare
case _ => UOPA1.dontCare
}

override def uopType: UOPA1.type = UOPA1
}

object UOPA2 extends UOP {
def width = 2

def zero: BitPat = encode(0)

def size: BitPat = encode(1)

def rs2: BitPat = encode(2)

def imm: BitPat = encode(3)
}

Expand All @@ -878,6 +953,7 @@ abstract class InstructionDecoder {
}

// Custom extensions

/** Rocket Custom Coprocessor, add FU at commit stage */
object isRoCC extends BoolDecodeField[RocketDecodePattern] {
override def name: String = "rocc"
Expand Down
Loading

0 comments on commit 3f88fdf

Please sign in to comment.