Skip to content

Commit

Permalink
[cover] refactor rvdecoderdb's old syntax of scala2 to scala3
Browse files Browse the repository at this point in the history
Signed-off-by: Clo91eaf <[email protected]>
  • Loading branch information
Clo91eaf committed Jan 18, 2025
1 parent 3908ce6 commit e41bacc
Show file tree
Hide file tree
Showing 14 changed files with 248 additions and 291 deletions.
3 changes: 1 addition & 2 deletions cover/tests/src/CoverTest.scala
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,7 @@ import os.*

object RVDecoderDBTest extends TestSuite:
val tests = Tests:
test("rvdecoderdb works") {
test("rvdecoderdb works"):
val instTable: Iterable[rvdecoderdb.Instruction] = rvdecoderdb.instructions(os.pwd / "rvdecoderdb" / "riscv-opcodes")
assert(instTable.nonEmpty)
}

62 changes: 29 additions & 33 deletions rvdecoderdb/rvdecoderdb/jvm/src/package.scala
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
package org.chipsalliance

/** Parse instructions from riscv/riscv-opcodes */
package object rvdecoderdb {
def instructions(riscvOpcodes: os.Path, custom: Iterable[os.Path] = Seq.empty): Iterable[Instruction] = {
package object rvdecoderdb:
def instructions(riscvOpcodes: os.Path, custom: Iterable[os.Path] = Seq.empty): Iterable[Instruction] =
parser.parse(
os
.walk(riscvOpcodes)
Expand All @@ -21,31 +21,30 @@ package object rvdecoderdb {
.map(f => (f.baseName, os.read(f), false, true)),
argLut(riscvOpcodes).view.mapValues(a => (a.lsb, a.msb)).toMap
)
}

def argLut(riscvOpcodes: os.Path): Map[String, Arg] = os
.read(riscvOpcodes / "arg_lut.csv")
.split("\n")
.map { str =>
val l = str
.replace(", ", ",")
.replace("\"", "")
.split(",")
l(0) -> Arg(l(0), l(1).toInt, l(2).toInt)
}
.toMap
def argLut(riscvOpcodes: os.Path): Map[String, Arg] =
os.read(riscvOpcodes / "arg_lut.csv")
.split("\n")
.map { str =>
val l = str
.replace(", ", ",")
.replace("\"", "")
.split(",")
l(0) -> Arg(l(0), l(1).toInt, l(2).toInt)
}
.toMap

def causes(riscvOpcodes: os.Path): Map[String, Int] = os
.read(riscvOpcodes / "causes.csv")
.split("\n")
.map { str =>
val l = str
.replace(", ", ",")
.replace("\"", "")
.split(",")
l(1) -> java.lang.Long.decode(l(0)).toInt
}
.toMap
def causes(riscvOpcodes: os.Path): Map[String, Int] =
os.read(riscvOpcodes / "causes.csv")
.split("\n")
.map { str =>
val l = str
.replace(", ", ",")
.replace("\"", "")
.split(",")
l(1) -> java.lang.Long.decode(l(0)).toInt
}
.toMap

def csrs(riscvOpcodes: os.Path): Seq[(String, Int)] =
Seq(os.read(riscvOpcodes / "csrs.csv"), os.read(riscvOpcodes / "csrs32.csv")).flatMap(
Expand All @@ -59,19 +58,16 @@ package object rvdecoderdb {
}.toMap
)

def extractResource(cl: ClassLoader): os.Path = {
def extractResource(cl: ClassLoader): os.Path =
val rvdecoderdbPath = os.temp.dir()
val rvdecoderdbTar = os.temp(os.read(os.resource(cl) / "riscv-opcodes.tar"))
val rvdecoderdbTar = os.temp(os.read(os.resource(cl) / "riscv-opcodes.tar"))
os.proc("tar", "xf", rvdecoderdbTar).call(rvdecoderdbPath)
rvdecoderdbPath
}

@deprecated("remove fromFile")
object fromFile {
object fromFile:
def instructions(riscvOpcodes: os.Path, custom: Iterable[os.Path] = Seq.empty): Iterable[Instruction] =
rvdecoderdb.instructions(riscvOpcodes, custom)
def argLut(riscvOpcodes: os.Path): Map[String, Arg] = rvdecoderdb.argLut(riscvOpcodes)
def causes(riscvOpcodes: os.Path): Map[String, Int] = rvdecoderdb.causes(riscvOpcodes)
def argLut(riscvOpcodes: os.Path): Map[String, Arg] = rvdecoderdb.argLut(riscvOpcodes)
def causes(riscvOpcodes: os.Path): Map[String, Int] = rvdecoderdb.causes(riscvOpcodes)
def csrs(riscvOpcodes: os.Path): Seq[(String, Int)] = rvdecoderdb.csrs(riscvOpcodes)
}
}
85 changes: 39 additions & 46 deletions rvdecoderdb/rvdecoderdb/src/Instruction.scala
Original file line number Diff line number Diff line change
Expand Up @@ -3,66 +3,60 @@

package org.chipsalliance.rvdecoderdb

import upickle.default.{ReadWriter => RW, macroRW}
import upickle.default.{macroRW, ReadWriter => RW}

object Encoding {
object Encoding:
implicit val rw: RW[Encoding] = macroRW

def fromString(str: String): Encoding = {
def fromString(str: String): Encoding =
require(str.length == 32)
Encoding(
str.reverse.zipWithIndex.map {
case (c, i) =>
c match {
case '1' => BigInt(1) << i
case '0' => BigInt(0)
case '?' => BigInt(0)
}
str.reverse.zipWithIndex.map { case (c, i) =>
c match
case '1' => BigInt(1) << i
case '0' => BigInt(0)
case '?' => BigInt(0)
}.sum,
str.reverse.zipWithIndex.map {
case (c, i) =>
c match {
case '1' => BigInt(1) << i
case '0' => BigInt(1) << i
case '?' => BigInt(0)
}
str.reverse.zipWithIndex.map { case (c, i) =>
c match
case '1' => BigInt(1) << i
case '0' => BigInt(1) << i
case '?' => BigInt(0)
}.sum
)
}
}

/** Like chisel3.BitPat, this is a 32-bits field stores the Instruction encoding. */
case class Encoding(value: BigInt, mask: BigInt) {
case class Encoding(value: BigInt, mask: BigInt):
override def toString =
Seq.tabulate(32)(i => if (!mask.testBit(i)) "?" else if (value.testBit(i)) "1" else "0").reverse.mkString
}
Seq.tabulate(32)(i => if !mask.testBit(i) then "?" else if value.testBit(i) then "1" else "0").reverse.mkString

object Arg {
object Arg:
implicit val rw: RW[Arg] = macroRW
}

case class Arg(name: String, msb: Int, lsb: Int) {
case class Arg(name: String, msb: Int, lsb: Int):
override def toString: String = name
}

object InstructionSet {
object InstructionSet:
implicit val rw: RW[InstructionSet] = macroRW
}

/** represent an riscv sub instruction set, aka a file in riscv-opcodes. */
case class InstructionSet(name: String)

object Instruction {
object Instruction:
implicit val rw: RW[Instruction] = macroRW
}

/** All information can be parsed from riscv/riscv-opcode.
*
* @param name name of this instruction
* @param encoding encoding of this instruction
* @param instructionSets base instruction set that this instruction lives in
* @param pseudoFrom if this is defined, means this instruction is an Pseudo Instruction from another instruction
* @param ratified true if this instruction is ratified
* @param name
* name of this instruction
* @param encoding
* encoding of this instruction
* @param instructionSets
* base instruction set that this instruction lives in
* @param pseudoFrom
* if this is defined, means this instruction is an Pseudo Instruction from another instruction
* @param ratified
* true if this instruction is ratified
*/
case class Instruction(
name: String,
Expand All @@ -71,7 +65,7 @@ case class Instruction(
instructionSets: Seq[InstructionSet],
pseudoFrom: Option[Instruction],
ratified: Boolean,
custom: Boolean) {
custom: Boolean):
require(!custom || (custom && !ratified), "All custom instructions are unratified.")

def instructionSet: InstructionSet = instructionSets.head
Expand All @@ -84,20 +78,19 @@ case class Instruction(
instructionSet.name.padTo(16, ' ') +
s"$name${pseudoFrom.map(_.simpleName).map(s => s" [pseudo $s]").getOrElse("")}".padTo(48, ' ') +
s"[${Seq(
Option.when(Utils.isR(this))("R "),
Option.when(Utils.isR4(this))("R4"),
Option.when(Utils.isI(this))("I "),
Option.when(Utils.isS(this))("S "),
Option.when(Utils.isB(this))("B "),
Option.when(Utils.isU(this))("U "),
Option.when(Utils.isJ(this))("J ")
).flatten.headOption.getOrElse(" ")}]".padTo(4, ' ') +
Option.when(Utils.isR(this))("R "),
Option.when(Utils.isR4(this))("R4"),
Option.when(Utils.isI(this))("I "),
Option.when(Utils.isS(this))("S "),
Option.when(Utils.isB(this))("B "),
Option.when(Utils.isU(this))("U "),
Option.when(Utils.isJ(this))("J ")
).flatten.headOption.getOrElse(" ")}]".padTo(4, ' ') +
args.mkString(",").padTo(40, ' ') +
encoding.toString.padTo(48, ' ') +
("[" +
Option.when(custom)("CUSTOM ").getOrElse(Option.when(!ratified)("UNRATIFIED ").getOrElse("")) +
(if (importTo.nonEmpty) Some(importTo.map(_.name).mkString(",")) else None)
(if importTo.nonEmpty then Some(importTo.map(_.name).mkString(",")) else None)
.map(s => s"import to $s")
.getOrElse("") +
"]").replace(" ]", "]").replace("[]", "")
}
3 changes: 1 addition & 2 deletions rvdecoderdb/rvdecoderdb/src/Utils.scala
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

package org.chipsalliance.rvdecoderdb

object Utils {
object Utils:
def isR(instruction: Instruction): Boolean = instruction.args.map(_.name) == Seq("rd", "rs1", "rs2")

def isI(instruction: Instruction): Boolean = instruction.args.map(_.name) == Seq("rd", "rs1", "imm12")
Expand Down Expand Up @@ -36,4 +36,3 @@ object Utils {
def readRs2(instruction: Instruction): Boolean = instruction.args.map(_.name).contains("rs2")

def writeRd(instruction: Instruction): Boolean = instruction.args.map(_.name).contains("rd")
}
Loading

0 comments on commit e41bacc

Please sign in to comment.