From d5b90705762b72bee8304d67c559f69ad358ce02 Mon Sep 17 00:00:00 2001 From: Jiuyang Liu Date: Sun, 13 Oct 2024 11:09:28 +0800 Subject: [PATCH] [om] refactor the omreader API --- omreader/src/Main.scala | 85 ------------ omreader/src/t1/T1.scala | 45 +++++++ omreader/src/t1rocketv/T1RocketTile.scala | 45 +++++++ omreaderlib/src/Interface.scala | 102 -------------- omreaderlib/src/OMReader.scala | 17 +++ omreaderlib/src/T1OMReaderAPI.scala | 106 +++++++++++++++ omreaderlib/src/t1/T1.scala | 90 +++++++++++++ omreaderlib/src/t1emu/Testbench.scala | 51 +++++++ omreaderlib/src/t1rocketv/T1RocketTile.scala | 132 +++++++++++++++++++ 9 files changed, 486 insertions(+), 187 deletions(-) delete mode 100644 omreader/src/Main.scala create mode 100644 omreader/src/t1/T1.scala create mode 100644 omreader/src/t1rocketv/T1RocketTile.scala delete mode 100644 omreaderlib/src/Interface.scala create mode 100644 omreaderlib/src/OMReader.scala create mode 100644 omreaderlib/src/T1OMReaderAPI.scala create mode 100644 omreaderlib/src/t1/T1.scala create mode 100644 omreaderlib/src/t1emu/Testbench.scala create mode 100644 omreaderlib/src/t1rocketv/T1RocketTile.scala diff --git a/omreader/src/Main.scala b/omreader/src/Main.scala deleted file mode 100644 index b7a967260..000000000 --- a/omreader/src/Main.scala +++ /dev/null @@ -1,85 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -// SPDX-FileCopyrightText: 2022 Jiuyang Liu - -package org.chipsalliance.t1.omreader - -import java.io.BufferedInputStream -import mainargs._ -import chisel3.panamaom._ -import org.chipsalliance.t1.omreaderlib._ - -object Main { - implicit object PathRead extends TokensReader.Simple[os.Path] { - def shortName = "path" - def read(strs: Seq[String]): Either[String, os.Path] = Right(os.Path(strs.head, os.pwd)) - } - - @main - def run( - @arg(name = "mlirbc-file") mlirbcFile: Option[os.Path], - @arg(name = "dump-methods") dumpMethods: Flag, - @arg(name = "eval") eval: Option[String] - ) = { - val t1Reader = (mlirbcFile match { - case Some(path) => OMReader.fromFile(path) - case None => - val stdin = new BufferedInputStream(System.in) - val bytes = Stream.continually(stdin.read).takeWhile(_ != -1).map(_.toByte).toArray - OMReader.fromBytes(bytes) - }).t1Reader - - if (eval.nonEmpty) { - println(SimpleInputEval(t1Reader.entry, eval.get)) - } else if (dumpMethods.value) { - t1Reader.dumpMethods() - } else { - t1Reader.dumpAll() - } - } - - @main - def vlen(@arg(name = "mlirbc-file") mlirbcFile: os.Path) = { - println(simplyGetT1Reader(mlirbcFile).vlen) - } - - @main - def dlen(@arg(name = "mlirbc-file") mlirbcFile: os.Path) = { - println(simplyGetT1Reader(mlirbcFile).dlen) - } - - @main - def march(@arg(name = "mlirbc-file") mlirbcFile: os.Path) = { - println(simplyGetT1Reader(mlirbcFile).march) - } - - @main - def extensionsJson(@arg(name = "mlirbc-file") mlirbcFile: os.Path) = { - println(simplyGetT1Reader(mlirbcFile).extensionsJson) - } - - @main - def decoderInstructionsJson(@arg(name = "mlirbc-file") mlirbcFile: os.Path) = { - println(simplyGetT1Reader(mlirbcFile).decoderInstructionsJson) - } - - @main - def decoderInstructionsJsonPretty(@arg(name = "mlirbc-file") mlirbcFile: os.Path) = { - println(simplyGetT1Reader(mlirbcFile).decoderInstructionsJsonPretty) - } - - def simplyGetT1Reader(mlirbcFile: os.Path) = OMReader.fromFile(mlirbcFile).t1Reader - - def main(args: Array[String]): Unit = ParserForMethods(this).runOrExit(args) -} - -object SimpleInputEval { - def apply(entry: PanamaCIRCTOMEvaluatorValue, input: String): PanamaCIRCTOMEvaluatorValue = { - input.split("\\.").foldLeft(entry) { case (obj, field) => - if (field.forall(_.isDigit)) { - obj.asInstanceOf[PanamaCIRCTOMEvaluatorValueList].getElement(field.toLong) - } else { - obj.asInstanceOf[PanamaCIRCTOMEvaluatorValueObject].field(field) - } - } - } -} diff --git a/omreader/src/t1/T1.scala b/omreader/src/t1/T1.scala new file mode 100644 index 000000000..f949e4019 --- /dev/null +++ b/omreader/src/t1/T1.scala @@ -0,0 +1,45 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: 2022 Jiuyang Liu + +package org.chipsalliance.t1.omreader.t1 + +import mainargs._ +import org.chipsalliance.t1.omreaderlib.t1.T1 + +object T1 { + implicit object PathRead extends TokensReader.Simple[os.Path] { + def shortName = "path" + def read(strs: Seq[String]): Either[String, os.Path] = Right(os.Path(strs.head, os.pwd)) + } + @main + def vlen(@arg(name = "mlirbc-file") mlirbcFile: os.Path) = + println(new T1(os.read.bytes(mlirbcFile)).vlen) + + @main + def dlen(@arg(name = "mlirbc-file") mlirbcFile: os.Path) = + println(new T1(os.read.bytes(mlirbcFile)).dlen) + + @main + def instructions(@arg(name = "mlirbc-file") mlirbcFile: os.Path) = + new T1(os.read.bytes(mlirbcFile)).instructions.foreach(println) + + @main + def extensions( + @arg(name = "mlirbc-file") mlirbcFile: os.Path + ) = + println(new T1(os.read.bytes(mlirbcFile)).extensions.mkString("")) + + @main + def march(@arg(name = "mlirbc-file") mlirbcFile: os.Path) = + println(new T1(os.read.bytes(mlirbcFile)).march) + + @main + def sram(@arg(name = "mlirbc-file") mlirbcFile: os.Path) = + new T1(os.read.bytes(mlirbcFile)).sram.foreach(s => println(upickle.default.write(s))) + + @main + def retime(@arg(name = "mlirbc-file") mlirbcFile: os.Path) = + new T1(os.read.bytes(mlirbcFile)).retime.foreach(r => println(upickle.default.write(r))) + + def main(args: Array[String]): Unit = ParserForMethods(this).runOrExit(args) +} diff --git a/omreader/src/t1rocketv/T1RocketTile.scala b/omreader/src/t1rocketv/T1RocketTile.scala new file mode 100644 index 000000000..bd67122c3 --- /dev/null +++ b/omreader/src/t1rocketv/T1RocketTile.scala @@ -0,0 +1,45 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: 2022 Jiuyang Liu + +package org.chipsalliance.t1.omreader.t1rocketv + +import mainargs._ +import org.chipsalliance.t1.omreaderlib.t1rocketv.T1RocketTile + +object T1RocketTile { + implicit object PathRead extends TokensReader.Simple[os.Path] { + def shortName = "path" + def read(strs: Seq[String]): Either[String, os.Path] = Right(os.Path(strs.head, os.pwd)) + } + @main + def vlen(@arg(name = "mlirbc-file") mlirbcFile: os.Path) = + println(new T1RocketTile(os.read.bytes(mlirbcFile)).vlen) + + @main + def dlen(@arg(name = "mlirbc-file") mlirbcFile: os.Path) = + println(new T1RocketTile(os.read.bytes(mlirbcFile)).dlen) + + @main + def instructions(@arg(name = "mlirbc-file") mlirbcFile: os.Path) = + new T1RocketTile(os.read.bytes(mlirbcFile)).instructions.foreach(println) + + @main + def extensions( + @arg(name = "mlirbc-file") mlirbcFile: os.Path + ) = + println(new T1RocketTile(os.read.bytes(mlirbcFile)).extensions.mkString("")) + + @main + def march(@arg(name = "mlirbc-file") mlirbcFile: os.Path) = + println(new T1RocketTile(os.read.bytes(mlirbcFile)).march) + + @main + def sram(@arg(name = "mlirbc-file") mlirbcFile: os.Path) = + new T1RocketTile(os.read.bytes(mlirbcFile)).sram.foreach(s => println(upickle.default.write(s))) + + @main + def retime(@arg(name = "mlirbc-file") mlirbcFile: os.Path) = + new T1RocketTile(os.read.bytes(mlirbcFile)).retime.foreach(r => println(upickle.default.write(r))) + + def main(args: Array[String]): Unit = ParserForMethods(this).runOrExit(args) +} diff --git a/omreaderlib/src/Interface.scala b/omreaderlib/src/Interface.scala deleted file mode 100644 index a882aa952..000000000 --- a/omreaderlib/src/Interface.scala +++ /dev/null @@ -1,102 +0,0 @@ -package org.chipsalliance.t1.omreaderlib - -import scala.reflect.runtime.universe._ -import chisel3.panamalib.option._ -import chisel3.panamaom._ -import chisel3.panamaconverter.PanamaCIRCTConverter - -object OMReader { - def fromFile(mlirbcFile: os.Path): OMReader = { - new OMReader(os.read.bytes(mlirbcFile)) - } - - def fromBytes(mlirbc: Array[Byte]): OMReader = { - new OMReader(mlirbc) - } -} - -class OMReader private (mlirbc: Array[Byte]) { - private val cvt = PanamaCIRCTConverter.newWithMlirBc(mlirbc) - private val om = cvt.om() - private val evaluator = om.evaluator() - - def t1Reader: T1Reader = new T1Reader(evaluator, om.newBasePathEmpty) -} - -class T1Reader private[omreaderlib] (evaluator: PanamaCIRCTOMEvaluator, basePath: PanamaCIRCTOMEvaluatorValueBasePath) { - val (entry, isSubsystem) = { - evaluator.instantiate("T1Subsystem_Class", Seq(basePath)) match { - case Some(subsystem) => (subsystem, true) - case None => (evaluator.instantiate("T1_Class", Seq(basePath)).get, false) - } - } - private val t1 = { - if (isSubsystem) { - entry - .field("om") - .asInstanceOf[PanamaCIRCTOMEvaluatorValueObject] - .field("t1") - .asInstanceOf[PanamaCIRCTOMEvaluatorValueObject] - } else { - entry - .field("om") - .asInstanceOf[PanamaCIRCTOMEvaluatorValueObject] - } - } - - def vlen: Long = t1.field("vlen").asInstanceOf[PanamaCIRCTOMEvaluatorValuePrimitiveInteger].integer - def dlen: Long = t1.field("dlen").asInstanceOf[PanamaCIRCTOMEvaluatorValuePrimitiveInteger].integer - private def decoderInstructionsJsonImpl: ujson.Value = { - val decoder = t1.field("decoder").asInstanceOf[PanamaCIRCTOMEvaluatorValueObject] - val instructions = decoder.field("instructions").asInstanceOf[PanamaCIRCTOMEvaluatorValueList] - - instructions.elements.map(instruction => { - val instr = instruction.asInstanceOf[PanamaCIRCTOMEvaluatorValueObject] - val attributes = instr.field("attributes").asInstanceOf[PanamaCIRCTOMEvaluatorValueList] - - ujson.Obj( - "attributes" -> attributes.elements.map(attribute => { - val attr = attribute.asInstanceOf[PanamaCIRCTOMEvaluatorValueObject] - val description = attr.field("description").asInstanceOf[PanamaCIRCTOMEvaluatorValuePrimitiveString].toString - val identifier = attr.field("identifier").asInstanceOf[PanamaCIRCTOMEvaluatorValuePrimitiveString].toString - val value = attr.field("value").asInstanceOf[PanamaCIRCTOMEvaluatorValuePrimitiveString].toString - ujson.Obj( - "description" -> description, - "identifier" -> identifier, - "value" -> value - ) - }) - ) - }) - } - def decoderInstructionsJson: String = ujson.write(decoderInstructionsJsonImpl) - def decoderInstructionsJsonPretty: String = ujson.write(decoderInstructionsJsonImpl, 2) - def extensionsJson: String = { - val extensions = t1.field("extensions").asInstanceOf[PanamaCIRCTOMEvaluatorValueList] - val j = extensions.elements.map(_.asInstanceOf[PanamaCIRCTOMEvaluatorValuePrimitiveString].toString) - ujson.write(j) - } - def march: String = t1.field("march").asInstanceOf[PanamaCIRCTOMEvaluatorValuePrimitiveString].toString - - def dumpMethods(): Unit = { - val mirror = runtimeMirror(getClass.getClassLoader).reflect(this) - val methods = - typeOf[T1Reader].decls.toList.filter(m => m.isPublic && m.isMethod && !m.isConstructor && !m.asMethod.isGetter) - methods.foreach(method => { - if (!method.name.toString.startsWith("dump")) { - var value = mirror.reflectMethod(method.asMethod)().toString.replace("\n", "\\n") - - val displayLength = 80 - if (value.length > displayLength) { - value = value.take(displayLength) + s" (... ${value.length - displayLength} characters)" - } - - println(s"${method.name} = $value") - } - }) - } - - def dumpAll(): Unit = { - entry.foreachField((name, value) => println(s".$name => $value")) - } -} diff --git a/omreaderlib/src/OMReader.scala b/omreaderlib/src/OMReader.scala new file mode 100644 index 000000000..49783c69a --- /dev/null +++ b/omreaderlib/src/OMReader.scala @@ -0,0 +1,17 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: 2022 Jiuyang Liu + +package org.chipsalliance.t1.omreaderlib + +import chisel3.panamaconverter.PanamaCIRCTConverter +import chisel3.panamaom._ + +trait OMReader { + val mlirbc: Array[Byte] + val top: String + protected lazy val cvt: PanamaCIRCTConverter = PanamaCIRCTConverter.newWithMlirBc(mlirbc) + protected lazy val om: PanamaCIRCTOM = cvt.om() + protected lazy val evaluator: PanamaCIRCTOMEvaluator = om.evaluator() + protected lazy val basePath: PanamaCIRCTOMEvaluatorValueBasePath = om.newBasePathEmpty() + protected lazy val entry: PanamaCIRCTOMEvaluatorValueObject = evaluator.instantiate(top, Seq(basePath)).get +} diff --git a/omreaderlib/src/T1OMReaderAPI.scala b/omreaderlib/src/T1OMReaderAPI.scala new file mode 100644 index 000000000..0fc21210f --- /dev/null +++ b/omreaderlib/src/T1OMReaderAPI.scala @@ -0,0 +1,106 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: 2022 Jiuyang Liu + +package org.chipsalliance.t1.omreaderlib + +import upickle.default.{macroRW, ReadWriter} + +object SRAM { + implicit val rw: ReadWriter[SRAM] = macroRW +} + +/** The SRAM Module to be replaced. */ +case class SRAM( + moduleName: String, + depth: Int, + width: Int, + read: Int, + write: Int, + readwrite: Int, + maskGranularity: Int) + +object Retime { + implicit val rw: ReadWriter[Retime] = macroRW +} + +/** Module to be retimed. */ +case class Retime(moduleName: String) + +object InstructionAttributes { + implicit val rw: ReadWriter[InstructionAttributes] = macroRW +} + +case class InstructionAttributes( + identifier: String, + description: String, + value: String) + +object Instruction { + implicit val rw: ReadWriter[Instruction] = macroRW +} + +case class Instruction( + instructionName: String, + documentation: String, + bitPat: String, + attributes: Seq[InstructionAttributes]) { + override def toString: String = + s"${instructionName} -> ${attributes.map(a => s"${a.identifier}:${a.value}").mkString(",")}" +} + +object Path { + implicit val rw: ReadWriter[Instruction] = macroRW + def parse(str: String): Path = + str match { + case s"OMReferenceTarget:~${top}|${hier}>${local}" => + Path( + top, + hier + .split("/") + .map(i => { + val s = i.split(":") + (s.head, s.last) + }), + Some(local) + ) + case s"OMReferenceTarget:~${top}|${hier}" => + Path( + top, + hier + .split("/") + .map(i => { + val s = i.split(":") + (s.head, s.last) + }), + None + ) + } +} + +case class Path(top: String, hierarchy: Seq[(String, String)], local: Option[String]) { + def module: String = hierarchy.last._2 + def path: String = hierarchy.map(_._1).mkString(".") +} + +/** Public Module under T1 should implement Modules below. */ +trait T1OMReaderAPI extends OMReader { + + def vlen: Int + + def dlen: Int + + /** all supported RISC-V extensions */ + def extensions: Seq[String] + + /** the march needed by compiler */ + def march: String + + /** All SRAMs with its metadata */ + def sram: Seq[SRAM] + + /** All Modules that need to be retimed */ + def retime: Seq[Retime] + + /** All Instructions with all metadata */ + def instructions: Seq[Instruction] +} diff --git a/omreaderlib/src/t1/T1.scala b/omreaderlib/src/t1/T1.scala new file mode 100644 index 000000000..a2418f76d --- /dev/null +++ b/omreaderlib/src/t1/T1.scala @@ -0,0 +1,90 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: 2022 Jiuyang Liu + +package org.chipsalliance.t1.omreaderlib.t1 + +import chisel3.panamaom._ +import org.chipsalliance.t1.omreaderlib.{Instruction, InstructionAttributes, Path, Retime, SRAM, T1OMReaderAPI} + +/** OM API for [[org.chipsalliance.t1.rtl.T1OM]] */ +class T1(val mlirbc: Array[Byte]) extends T1OMReaderAPI { + val top: String = "T1_Class" + private val t1: PanamaCIRCTOMEvaluatorValueObject = entry.field("om").asInstanceOf[PanamaCIRCTOMEvaluatorValueObject] + def vlen: Int = t1.field("vlen").asInstanceOf[PanamaCIRCTOMEvaluatorValuePrimitiveInteger].integer.toInt + def dlen: Int = t1.field("dlen").asInstanceOf[PanamaCIRCTOMEvaluatorValuePrimitiveInteger].integer.toInt + def instructions: Seq[Instruction] = { + val decoder = t1.field("decoder").asInstanceOf[PanamaCIRCTOMEvaluatorValueObject] + val instructions = decoder.field("instructions").asInstanceOf[PanamaCIRCTOMEvaluatorValueList] + instructions + .elements() + .map(instruction => { + val instr = instruction.asInstanceOf[PanamaCIRCTOMEvaluatorValueObject] + val attributes = instr.field("attributes").asInstanceOf[PanamaCIRCTOMEvaluatorValueList] + instr.field("attributes").asInstanceOf[PanamaCIRCTOMEvaluatorValueList] + Instruction( + instr.field("instructionName").asInstanceOf[PanamaCIRCTOMEvaluatorValuePrimitiveString].toString, + instr.field("documentation").asInstanceOf[PanamaCIRCTOMEvaluatorValuePrimitiveString].toString, + instr.field("bitPat").asInstanceOf[PanamaCIRCTOMEvaluatorValuePrimitiveString].toString, + attributes + .elements() + .map(_.asInstanceOf[PanamaCIRCTOMEvaluatorValueObject]) + .map { attr => + InstructionAttributes( + attr.field("identifier").asInstanceOf[PanamaCIRCTOMEvaluatorValuePrimitiveString].toString, + attr.field("description").asInstanceOf[PanamaCIRCTOMEvaluatorValuePrimitiveString].toString, + attr.field("value").asInstanceOf[PanamaCIRCTOMEvaluatorValuePrimitiveString].toString + ) + } + ) + }) + } + def extensions: Seq[String] = { + val extensions = t1.field("extensions").asInstanceOf[PanamaCIRCTOMEvaluatorValueList] + extensions.elements().map(_.asInstanceOf[PanamaCIRCTOMEvaluatorValuePrimitiveString].toString) + } + def march: String = t1.field("march").asInstanceOf[PanamaCIRCTOMEvaluatorValuePrimitiveString].toString + def sram: Seq[SRAM] = t1 + .field("lanes") + .asInstanceOf[PanamaCIRCTOMEvaluatorValueList] + .elements() + .map(_.asInstanceOf[PanamaCIRCTOMEvaluatorValueObject].field("vrf")) + .flatMap { vrf => + val srams = vrf + .asInstanceOf[PanamaCIRCTOMEvaluatorValueObject] + .field("srams") + .asInstanceOf[PanamaCIRCTOMEvaluatorValueList] + srams.elements().map(_.asInstanceOf[PanamaCIRCTOMEvaluatorValueObject]).map { sram => + SRAM( + moduleName = + Path.parse(sram.field("hierarchy").asInstanceOf[PanamaCIRCTOMEvaluatorValuePath].toString).module, + depth = sram.field("depth").asInstanceOf[PanamaCIRCTOMEvaluatorValuePrimitiveInteger].integer.toInt, + width = sram.field("width").asInstanceOf[PanamaCIRCTOMEvaluatorValuePrimitiveInteger].integer.toInt, + read = sram.field("read").asInstanceOf[PanamaCIRCTOMEvaluatorValuePrimitiveInteger].integer.toInt, + write = sram.field("write").asInstanceOf[PanamaCIRCTOMEvaluatorValuePrimitiveInteger].integer.toInt, + readwrite = sram.field("readwrite").asInstanceOf[PanamaCIRCTOMEvaluatorValuePrimitiveInteger].integer.toInt, + maskGranularity = sram + .field("maskGranularity") + .asInstanceOf[PanamaCIRCTOMEvaluatorValuePrimitiveInteger] + .integer + .toInt + ) + } + } + .distinct + def retime: Seq[Retime] = { + t1 + .field("lanes") + .asInstanceOf[PanamaCIRCTOMEvaluatorValueList] + .elements() + .map(_.asInstanceOf[PanamaCIRCTOMEvaluatorValueObject].field("vfus")) + .flatMap( + _.asInstanceOf[PanamaCIRCTOMEvaluatorValueList] + .elements() + .map(_.asInstanceOf[PanamaCIRCTOMEvaluatorValueObject]) + .filter(_.field("cycles").asInstanceOf[PanamaCIRCTOMEvaluatorValuePrimitiveInteger].integer != 0) + ) + .map(_.field("clock").asInstanceOf[PanamaCIRCTOMEvaluatorValuePath]) + .map(p => Retime(Path.parse(p.toString).module)) + .distinct + } +} diff --git a/omreaderlib/src/t1emu/Testbench.scala b/omreaderlib/src/t1emu/Testbench.scala new file mode 100644 index 000000000..fea02134c --- /dev/null +++ b/omreaderlib/src/t1emu/Testbench.scala @@ -0,0 +1,51 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: 2022 Jiuyang Liu +package org.chipsalliance.t1.omreaderlib.t1rocketv + +import chisel3.panamaom._ +import org.chipsalliance.t1.omreaderlib.{Instruction, InstructionAttributes, Retime, SRAM, T1OMReaderAPI} + +/** OM API for [[org.chipsalliance.t1.rtl.T1OM]] */ +class Testbench(val mlirbc: Array[Byte]) extends T1OMReaderAPI { + val top: String = "Testbench_Class" + private val t1: PanamaCIRCTOMEvaluatorValueObject = entry + .field("om") + .asInstanceOf[PanamaCIRCTOMEvaluatorValueObject] + .field("t1") + .asInstanceOf[PanamaCIRCTOMEvaluatorValueObject] + def vlen: Int = t1.field("vlen").asInstanceOf[PanamaCIRCTOMEvaluatorValuePrimitiveInteger].integer.toInt + def dlen: Int = t1.field("dlen").asInstanceOf[PanamaCIRCTOMEvaluatorValuePrimitiveInteger].integer.toInt + def extensions: Seq[String] = { + val extensions = t1.field("extensions").asInstanceOf[PanamaCIRCTOMEvaluatorValueList] + extensions.elements().map(_.asInstanceOf[PanamaCIRCTOMEvaluatorValuePrimitiveString].toString) + } + def march: String = t1.field("march").asInstanceOf[PanamaCIRCTOMEvaluatorValuePrimitiveString].toString + def instructions: Seq[Instruction] = { + val decoder = t1.field("decoder").asInstanceOf[PanamaCIRCTOMEvaluatorValueObject] + val instructions = decoder.field("instructions").asInstanceOf[PanamaCIRCTOMEvaluatorValueList] + instructions + .elements() + .map(instruction => { + val instr = instruction.asInstanceOf[PanamaCIRCTOMEvaluatorValueObject] + val attributes = instr.field("attributes").asInstanceOf[PanamaCIRCTOMEvaluatorValueList] + instr.field("attributes").asInstanceOf[PanamaCIRCTOMEvaluatorValueList] + Instruction( + instr.field("instructionName").asInstanceOf[PanamaCIRCTOMEvaluatorValuePrimitiveString].toString, + instr.field("documentation").asInstanceOf[PanamaCIRCTOMEvaluatorValuePrimitiveString].toString, + instr.field("bitPat").asInstanceOf[PanamaCIRCTOMEvaluatorValuePrimitiveString].toString, + attributes + .elements() + .map(_.asInstanceOf[PanamaCIRCTOMEvaluatorValueObject]) + .map { attr => + InstructionAttributes( + attr.field("identifier").asInstanceOf[PanamaCIRCTOMEvaluatorValuePrimitiveString].toString, + attr.field("description").asInstanceOf[PanamaCIRCTOMEvaluatorValuePrimitiveString].toString, + attr.field("value").asInstanceOf[PanamaCIRCTOMEvaluatorValuePrimitiveString].toString + ) + } + ) + }) + } + override def sram: Seq[SRAM] = Nil + override def retime: Seq[Retime] = Nil +} diff --git a/omreaderlib/src/t1rocketv/T1RocketTile.scala b/omreaderlib/src/t1rocketv/T1RocketTile.scala new file mode 100644 index 000000000..5688e191c --- /dev/null +++ b/omreaderlib/src/t1rocketv/T1RocketTile.scala @@ -0,0 +1,132 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: 2022 Jiuyang Liu + +package org.chipsalliance.t1.omreaderlib.t1rocketv + +import chisel3.panamaom._ +import org.chipsalliance.t1.omreaderlib.{Instruction, InstructionAttributes, Path, Retime, SRAM, T1OMReaderAPI} + +/** OM API for [[org.chipsalliance.t1.rtl.T1OM]] */ +class T1RocketTile(val mlirbc: Array[Byte]) extends T1OMReaderAPI { + val top: String = "T1RocketTile_Class" + private val tile: PanamaCIRCTOMEvaluatorValueObject = entry + .field("om") + .asInstanceOf[PanamaCIRCTOMEvaluatorValueObject] + private val t1: PanamaCIRCTOMEvaluatorValueObject = tile + .field("t1") + .asInstanceOf[PanamaCIRCTOMEvaluatorValueObject] + def vlen: Int = t1.field("vlen").asInstanceOf[PanamaCIRCTOMEvaluatorValuePrimitiveInteger].integer.toInt + def dlen: Int = t1.field("dlen").asInstanceOf[PanamaCIRCTOMEvaluatorValuePrimitiveInteger].integer.toInt + def instructions: Seq[Instruction] = { + val decoder = t1.field("decoder").asInstanceOf[PanamaCIRCTOMEvaluatorValueObject] + val instructions = decoder.field("instructions").asInstanceOf[PanamaCIRCTOMEvaluatorValueList] + instructions + .elements() + .map(instruction => { + val instr = instruction.asInstanceOf[PanamaCIRCTOMEvaluatorValueObject] + val attributes = instr.field("attributes").asInstanceOf[PanamaCIRCTOMEvaluatorValueList] + instr.field("attributes").asInstanceOf[PanamaCIRCTOMEvaluatorValueList] + Instruction( + instr.field("instructionName").asInstanceOf[PanamaCIRCTOMEvaluatorValuePrimitiveString].toString, + instr.field("documentation").asInstanceOf[PanamaCIRCTOMEvaluatorValuePrimitiveString].toString, + instr.field("bitPat").asInstanceOf[PanamaCIRCTOMEvaluatorValuePrimitiveString].toString, + attributes + .elements() + .map(_.asInstanceOf[PanamaCIRCTOMEvaluatorValueObject]) + .map { attr => + InstructionAttributes( + attr.field("identifier").asInstanceOf[PanamaCIRCTOMEvaluatorValuePrimitiveString].toString, + attr.field("description").asInstanceOf[PanamaCIRCTOMEvaluatorValuePrimitiveString].toString, + attr.field("value").asInstanceOf[PanamaCIRCTOMEvaluatorValuePrimitiveString].toString + ) + } + ) + }) + } + def extensions: Seq[String] = { + val extensions = t1.field("extensions").asInstanceOf[PanamaCIRCTOMEvaluatorValueList] + extensions.elements().map(_.asInstanceOf[PanamaCIRCTOMEvaluatorValuePrimitiveString].toString) + } + def march: String = t1.field("march").asInstanceOf[PanamaCIRCTOMEvaluatorValuePrimitiveString].toString + def vrf: Seq[SRAM] = t1 + .field("lanes") + .asInstanceOf[PanamaCIRCTOMEvaluatorValueList] + .elements() + .map(_.asInstanceOf[PanamaCIRCTOMEvaluatorValueObject].field("vrf")) + .flatMap { vrf => + val srams = vrf + .asInstanceOf[PanamaCIRCTOMEvaluatorValueObject] + .field("srams") + .asInstanceOf[PanamaCIRCTOMEvaluatorValueList] + srams.elements().map(_.asInstanceOf[PanamaCIRCTOMEvaluatorValueObject]).map { sram => + SRAM( + moduleName = + Path.parse(sram.field("hierarchy").asInstanceOf[PanamaCIRCTOMEvaluatorValuePath].toString).module, + depth = sram.field("depth").asInstanceOf[PanamaCIRCTOMEvaluatorValuePrimitiveInteger].integer.toInt, + width = sram.field("width").asInstanceOf[PanamaCIRCTOMEvaluatorValuePrimitiveInteger].integer.toInt, + read = sram.field("read").asInstanceOf[PanamaCIRCTOMEvaluatorValuePrimitiveInteger].integer.toInt, + write = sram.field("write").asInstanceOf[PanamaCIRCTOMEvaluatorValuePrimitiveInteger].integer.toInt, + readwrite = sram.field("readwrite").asInstanceOf[PanamaCIRCTOMEvaluatorValuePrimitiveInteger].integer.toInt, + maskGranularity = sram + .field("maskGranularity") + .asInstanceOf[PanamaCIRCTOMEvaluatorValuePrimitiveInteger] + .integer + .toInt + ) + } + } + .distinct + + def cache: Seq[SRAM] = Seq( + tile + .field("frontend") + .asInstanceOf[PanamaCIRCTOMEvaluatorValueObject] + .field("icache") + .asInstanceOf[PanamaCIRCTOMEvaluatorValueObject], + tile + .field("hellaCache") + .asInstanceOf[PanamaCIRCTOMEvaluatorValueObject] + ) + .flatMap( + _.field("srams") + .asInstanceOf[PanamaCIRCTOMEvaluatorValueList] + .elements() + .map(_.asInstanceOf[PanamaCIRCTOMEvaluatorValueObject]) + .map(sram => + SRAM( + moduleName = + Path.parse(sram.field("hierarchy").asInstanceOf[PanamaCIRCTOMEvaluatorValuePath].toString).module, + depth = sram.field("depth").asInstanceOf[PanamaCIRCTOMEvaluatorValuePrimitiveInteger].integer.toInt, + width = sram.field("width").asInstanceOf[PanamaCIRCTOMEvaluatorValuePrimitiveInteger].integer.toInt, + read = sram.field("read").asInstanceOf[PanamaCIRCTOMEvaluatorValuePrimitiveInteger].integer.toInt, + write = sram.field("write").asInstanceOf[PanamaCIRCTOMEvaluatorValuePrimitiveInteger].integer.toInt, + readwrite = sram.field("readwrite").asInstanceOf[PanamaCIRCTOMEvaluatorValuePrimitiveInteger].integer.toInt, + maskGranularity = sram + .field("maskGranularity") + .asInstanceOf[PanamaCIRCTOMEvaluatorValuePrimitiveInteger] + .integer + .toInt + ) + ) + ) + .distinct + + def sram = vrf ++ cache + def vfu: Seq[Retime] = { + t1 + .field("lanes") + .asInstanceOf[PanamaCIRCTOMEvaluatorValueList] + .elements() + .map(_.asInstanceOf[PanamaCIRCTOMEvaluatorValueObject].field("vfus")) + .flatMap( + _.asInstanceOf[PanamaCIRCTOMEvaluatorValueList] + .elements() + .map(_.asInstanceOf[PanamaCIRCTOMEvaluatorValueObject]) + .filter(_.field("cycles").asInstanceOf[PanamaCIRCTOMEvaluatorValuePrimitiveInteger].integer != 0) + ) + .map(_.field("clock").asInstanceOf[PanamaCIRCTOMEvaluatorValuePath]) + .map(p => Retime(Path.parse(p.toString).module)) + .distinct + } + def retime = vfu +}