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..211798ec1 --- /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 => Lib} + +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 Lib(os.read.bytes(mlirbcFile)).vlen) + + @main + def dlen(@arg(name = "mlirbc-file") mlirbcFile: os.Path) = + println(new Lib(os.read.bytes(mlirbcFile)).dlen) + + @main + def instructions(@arg(name = "mlirbc-file") mlirbcFile: os.Path) = + new Lib(os.read.bytes(mlirbcFile)).instructions.foreach(println) + + @main + def extensions( + @arg(name = "mlirbc-file") mlirbcFile: os.Path + ) = + println(new Lib(os.read.bytes(mlirbcFile)).extensions.mkString("_")) + + @main + def march(@arg(name = "mlirbc-file") mlirbcFile: os.Path) = + println(new Lib(os.read.bytes(mlirbcFile)).march) + + @main + def sram(@arg(name = "mlirbc-file") mlirbcFile: os.Path) = + new Lib(os.read.bytes(mlirbcFile)).sram.foreach(s => println(upickle.default.write(s))) + + @main + def retime(@arg(name = "mlirbc-file") mlirbcFile: os.Path) = + new Lib(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/t1emu/Testbench.scala b/omreader/src/t1emu/Testbench.scala new file mode 100644 index 000000000..f7e38e14c --- /dev/null +++ b/omreader/src/t1emu/Testbench.scala @@ -0,0 +1,45 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: 2022 Jiuyang Liu + +package org.chipsalliance.t1.omreader.t1emu + +import mainargs._ +import org.chipsalliance.t1.omreaderlib.t1emu.{TestBench => Lib} + +object Testbench { + 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 Lib(os.read.bytes(mlirbcFile)).vlen) + + @main + def dlen(@arg(name = "mlirbc-file") mlirbcFile: os.Path) = + println(new Lib(os.read.bytes(mlirbcFile)).dlen) + + @main + def instructions(@arg(name = "mlirbc-file") mlirbcFile: os.Path) = + new Lib(os.read.bytes(mlirbcFile)).instructions.foreach(println) + + @main + def extensions( + @arg(name = "mlirbc-file") mlirbcFile: os.Path + ) = + println(new Lib(os.read.bytes(mlirbcFile)).extensions.mkString("_")) + + @main + def march(@arg(name = "mlirbc-file") mlirbcFile: os.Path) = + println(new Lib(os.read.bytes(mlirbcFile)).march) + + @main + def sram(@arg(name = "mlirbc-file") mlirbcFile: os.Path) = + new Lib(os.read.bytes(mlirbcFile)).sram.foreach(s => println(upickle.default.write(s))) + + @main + def retime(@arg(name = "mlirbc-file") mlirbcFile: os.Path) = + new Lib(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..e65914437 --- /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 => Lib} + +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 Lib(os.read.bytes(mlirbcFile)).vlen) + + @main + def dlen(@arg(name = "mlirbc-file") mlirbcFile: os.Path) = + println(new Lib(os.read.bytes(mlirbcFile)).dlen) + + @main + def instructions(@arg(name = "mlirbc-file") mlirbcFile: os.Path) = + new Lib(os.read.bytes(mlirbcFile)).instructions.foreach(println) + + @main + def extensions( + @arg(name = "mlirbc-file") mlirbcFile: os.Path + ) = + println(new Lib(os.read.bytes(mlirbcFile)).extensions.mkString("_")) + + @main + def march(@arg(name = "mlirbc-file") mlirbcFile: os.Path) = + println(new Lib(os.read.bytes(mlirbcFile)).march) + + @main + def sram(@arg(name = "mlirbc-file") mlirbcFile: os.Path) = + new Lib(os.read.bytes(mlirbcFile)).sram.foreach(s => println(upickle.default.write(s))) + + @main + def retime(@arg(name = "mlirbc-file") mlirbcFile: os.Path) = + new Lib(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/t1rocketvemu/T1.scala b/omreader/src/t1rocketvemu/T1.scala new file mode 100644 index 000000000..bd7ed9a40 --- /dev/null +++ b/omreader/src/t1rocketvemu/T1.scala @@ -0,0 +1,45 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: 2022 Jiuyang Liu + +package org.chipsalliance.t1.omreader.t1rocketemu + +import mainargs._ +import org.chipsalliance.t1.omreaderlib.t1rocketemu.{TestBench => Lib} + +object Testbench { + 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 Lib(os.read.bytes(mlirbcFile)).vlen) + + @main + def dlen(@arg(name = "mlirbc-file") mlirbcFile: os.Path) = + println(new Lib(os.read.bytes(mlirbcFile)).dlen) + + @main + def instructions(@arg(name = "mlirbc-file") mlirbcFile: os.Path) = + new Lib(os.read.bytes(mlirbcFile)).instructions.foreach(println) + + @main + def extensions( + @arg(name = "mlirbc-file") mlirbcFile: os.Path + ) = + println(new Lib(os.read.bytes(mlirbcFile)).extensions.mkString("_")) + + @main + def march(@arg(name = "mlirbc-file") mlirbcFile: os.Path) = + println(new Lib(os.read.bytes(mlirbcFile)).march) + + @main + def sram(@arg(name = "mlirbc-file") mlirbcFile: os.Path) = + new Lib(os.read.bytes(mlirbcFile)).sram.foreach(s => println(upickle.default.write(s))) + + @main + def retime(@arg(name = "mlirbc-file") mlirbcFile: os.Path) = + new Lib(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..06b008b6b --- /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.t1emu + +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 +} diff --git a/omreaderlib/src/t1rocketvemu/TestBench.scala b/omreaderlib/src/t1rocketvemu/TestBench.scala new file mode 100644 index 000000000..df8687f2f --- /dev/null +++ b/omreaderlib/src/t1rocketvemu/TestBench.scala @@ -0,0 +1,54 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: 2022 Jiuyang Liu +package org.chipsalliance.t1.omreaderlib.t1rocketemu + +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("t1RocketTile") + .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/rocketv/src/Frontend.scala b/rocketv/src/Frontend.scala index 4aa78514c..2aad99178 100644 --- a/rocketv/src/Frontend.scala +++ b/rocketv/src/Frontend.scala @@ -5,8 +5,9 @@ package org.chipsalliance.rocketv import chisel3._ -import chisel3.experimental.hierarchy.{instantiable, Instantiate} +import chisel3.experimental.hierarchy.{instantiable, public, Instance, Instantiate} import chisel3.experimental.{SerializableModule, SerializableModuleParameter} +import chisel3.properties.{AnyClassType, Class, ClassType, Property} import chisel3.util._ import chisel3.util.circt.ClockGate import chisel3.util.experimental.BitSet @@ -229,8 +230,17 @@ class FrontendInterface(parameter: FrontendParameter) extends Bundle { org.chipsalliance.amba.axi4.bundle.AXI4ROIrrevocable(parameter.instructionFetchParameter) val itimAXI: Option[AXI4RWIrrevocable] = parameter.itimParameter.map(p => Flipped(org.chipsalliance.amba.axi4.bundle.AXI4RWIrrevocable(p))) + val om: Property[ClassType] = Output(Property[AnyClassType]()) } +@instantiable +class FrontendOM extends Class { + @public + val icache = IO(Output(Property[AnyClassType]())) + @public + val icacheIn = IO(Input(Property[AnyClassType]())) + icache := icacheIn +} @instantiable class Frontend(val parameter: FrontendParameter) extends FixedIORawModule(new FrontendInterface(parameter)) @@ -238,8 +248,10 @@ class Frontend(val parameter: FrontendParameter) with Public with ImplicitClock with ImplicitReset { - override protected def implicitClock: Clock = io.clock - override protected def implicitReset: Reset = io.reset + override protected def implicitClock: Clock = io.clock + override protected def implicitReset: Reset = io.reset + val omInstance: Instance[FrontendOM] = Instantiate(new FrontendOM) + io.om := omInstance.getPropertyReference.asAnyClassType def xLen = parameter.xLen def fetchWidth = parameter.fetchWidth @@ -292,6 +304,8 @@ class Frontend(val parameter: FrontendParameter) else ClockGate(clock, clock_en) val icache = Instantiate(new ICache(parameter.icacheParameter)) + omInstance.icacheIn := Property(icache.io.om.asAnyClassType) + icache.io.clock := gated_clock icache.io.reset := io.reset icache.io.clock_enabled := clock_en diff --git a/rocketv/src/HellaCache.scala b/rocketv/src/HellaCache.scala index e1c6a70a3..619affd25 100644 --- a/rocketv/src/HellaCache.scala +++ b/rocketv/src/HellaCache.scala @@ -5,8 +5,9 @@ package org.chipsalliance.rocketv import chisel3._ -import chisel3.experimental.hierarchy.{instantiable, Instance, Instantiate} +import chisel3.experimental.hierarchy.{instantiable, public, Instance, Instantiate} import chisel3.experimental.{SerializableModule, SerializableModuleParameter, SourceInfo} +import chisel3.properties.{AnyClassType, Class, ClassType, Property} import chisel3.util.experimental.{BitSet, InlineInstance} import chisel3.util.{ isPow2, @@ -333,6 +334,16 @@ class HellaCacheInterface(parameter: HellaCacheParameter) extends Bundle { org.chipsalliance.amba.axi4.bundle.AXI4RWIrrevocable(parameter.loadStoreParameter) val dtimAXI: Option[AXI4RWIrrevocable] = parameter.dtimParameter.map(p => Flipped(org.chipsalliance.amba.axi4.bundle.AXI4RWIrrevocable(p))) + val om: Property[ClassType] = Output(Property[AnyClassType]()) +} + +@instantiable +class HellaCacheOM extends Class { + val srams = IO(Output(Property[Seq[AnyClassType]]())) + + @public + val sramsIn = IO(Input(Property[Seq[AnyClassType]]())) + srams := sramsIn } @instantiable @@ -350,6 +361,8 @@ class HellaCache(val parameter: HellaCacheParameter) val amoalus: Option[Seq[Instance[AMOALU]]] = parameter.amoaluParameter.map(amoaluParameter => Seq.tabulate(parameter.coreDataBits / parameter.xLen)(i => Instantiate(new AMOALU(amoaluParameter))) ) + val omInstance: Instance[HellaCacheOM] = Instantiate(new HellaCacheOM) + io.om := omInstance.getPropertyReference.asAnyClassType tlb.io.clock := io.clock tlb.io.reset := io.reset @@ -515,6 +528,7 @@ class HellaCache(val parameter: HellaCacheParameter) numReadwritePorts = 1 ) } + omInstance.sramsIn := Property((dataArrays ++ Some(tag_array)).map(_.description.get.asAnyClassType)) /** Data Arbiter 0: data from pending store buffer 1: data from TL-D refill 2: release to TL-A 3: hit path to CPU */ diff --git a/rocketv/src/ICache.scala b/rocketv/src/ICache.scala index 3238f8f78..0e3f7f2b6 100644 --- a/rocketv/src/ICache.scala +++ b/rocketv/src/ICache.scala @@ -5,8 +5,9 @@ package org.chipsalliance.rocketv import chisel3._ -import chisel3.experimental.hierarchy.instantiable +import chisel3.experimental.hierarchy.{instantiable, public, Instance, Instantiate} import chisel3.experimental.{SerializableModule, SerializableModuleParameter} +import chisel3.properties.{AnyClassType, Class, ClassType, Property} import chisel3.util.random.LFSR import chisel3.util._ import org.chipsalliance.amba.axi4.bundle.{AXI4BundleParameter, AXI4ROIrrevocable, AXI4RWIrrevocable} @@ -130,8 +131,18 @@ class ICacheInterface(parameter: ICacheParameter) extends Bundle { val itimAXI: Option[AXI4RWIrrevocable] = parameter.itimAXIParameter.map(p => Flipped(org.chipsalliance.amba.axi4.bundle.AXI4RWIrrevocable(p))) + + val om: Property[ClassType] = Output(Property[AnyClassType]()) } +@instantiable +class ICacheOM extends Class { + val srams = IO(Output(Property[Seq[AnyClassType]]())) + + @public + val sramsIn = IO(Input(Property[Seq[AnyClassType]]())) + srams := sramsIn +} @instantiable class ICache(val parameter: ICacheParameter) extends FixedIORawModule(new ICacheInterface(parameter)) @@ -139,8 +150,10 @@ class ICache(val parameter: ICacheParameter) with Public with ImplicitClock with ImplicitReset { - override protected def implicitClock: Clock = io.clock - override protected def implicitReset: Reset = io.reset + override protected def implicitClock: Clock = io.clock + override protected def implicitReset: Reset = io.reset + val omInstance: Instance[ICacheOM] = Instantiate(new ICacheOM) + io.om := omInstance.getPropertyReference.asAnyClassType // compatiblity mode object Split { @@ -523,6 +536,7 @@ class ICache(val parameter: ICacheParameter) numReadwritePorts = 1 ) } + omInstance.sramsIn := Property((data_arrays ++ Some(tag_array)).map(_.description.get.asAnyClassType)) for ((data_array, i) <- data_arrays.zipWithIndex) { diff --git a/rocketv/src/RocketCore.scala b/rocketv/src/RocketCore.scala index 52ac45afe..d7d739929 100644 --- a/rocketv/src/RocketCore.scala +++ b/rocketv/src/RocketCore.scala @@ -24,6 +24,7 @@ import chisel3.util.{ RegEnable, Valid } +import chisel3.properties.{AnyClassType, Class, ClassType, Property} import org.chipsalliance.rocketv.rvdecoderdbcompat.Causes import org.chipsalliance.rvdecoderdb.Instruction @@ -372,8 +373,12 @@ class RocketInterface(parameter: RocketParameter) extends Bundle { val wfi = Output(Bool()) val traceStall = Input(Bool()) val rocketProbe = Output(Probe(new RocketProbe(parameter), layers.Verification)) + val om: Property[ClassType] = Output(Property[AnyClassType]()) } +@instantiable +class RocketOM extends Class {} + /** The [[Rocket]] is the next version of the RocketCore, All micro architectures are from the original RocketCore. The * development of [[Rocket]] happens in the T1 project. It will be moved to the standalone pacakge until it get * verified. @@ -404,6 +409,8 @@ class Rocket(val parameter: RocketParameter) val mul: Option[Instance[PipelinedMultiplier]] = parameter.mulParameter.map(p => Instantiate(new PipelinedMultiplier(p))) val t1RetireQueue: Option[Queue[T1RdRetire]] = io.t1.map(t1 => Module(new Queue(chiselTypeOf(t1.retire.rd.bits), 32))) + val omInstance: Instance[RocketOM] = Instantiate(new RocketOM) + io.om := omInstance.getPropertyReference.asAnyClassType // compatibility mode. object rocketParams { diff --git a/t1/src/Lane.scala b/t1/src/Lane.scala index e8b74ad00..51929c4ec 100644 --- a/t1/src/Lane.scala +++ b/t1/src/Lane.scala @@ -27,6 +27,11 @@ class LaneOM extends Class { @public val vfusIn = IO(Input(Property[Seq[AnyClassType]]())) vfus := vfusIn + @public + val vrf = IO(Output(Property[AnyClassType]())) + @public + val vrfIn = IO(Input(Property[AnyClassType]())) + vrf := vrfIn } class LaneSlotProbe(instructionIndexBits: Int) extends Bundle { @@ -321,6 +326,7 @@ class Lane(val parameter: LaneParameter) extends Module with SerializableModule[ /** VRF instantces. */ val vrf: Instance[VRF] = Instantiate(new VRF(parameter.vrfParam)) + omInstance.vrfIn := Property(vrf.om.asAnyClassType) /** TODO: review later */ diff --git a/t1/src/VectorFunctionUnit.scala b/t1/src/VectorFunctionUnit.scala index 5d4581332..9450a11d2 100644 --- a/t1/src/VectorFunctionUnit.scala +++ b/t1/src/VectorFunctionUnit.scala @@ -34,6 +34,11 @@ class VFUOM extends Class { @public val cyclesIn = IO(Input(Property[Int]())) cycles := cyclesIn + @public + val clock = IO(Output(Property[Path])) + @public + val clockIn = IO(Input(Property[Path])) + clock := clockIn } @instantiable @@ -48,7 +53,9 @@ abstract class VFUModule(p: VFUParameter) extends Module { @public val responseIO: DecoupledIO[VFUPipeBundle] = IO(Decoupled(p.outputBundle)) om := omInstance.getPropertyReference - omInstance.cyclesIn := Property(p.latency) + // I don't under the parameter of VFU, dirty hack + omInstance.cyclesIn := Property(if (p.singleCycle) 1 else 0) + omInstance.clockIn := Property(Path(clock)) val vfuRequestReady: Option[Bool] = Option.when(!p.singleCycle)(Wire(Bool())) val requestReg: VFUPipeBundle = RegEnable(requestIO.bits, 0.U.asTypeOf(requestIO.bits), requestIO.fire) diff --git a/t1/src/vrf/VRF.scala b/t1/src/vrf/VRF.scala index 3a4c0441b..eaccfee70 100644 --- a/t1/src/vrf/VRF.scala +++ b/t1/src/vrf/VRF.scala @@ -4,12 +4,14 @@ package org.chipsalliance.t1.rtl.vrf import chisel3._ +import chisel3.experimental.hierarchy.Instance import chisel3.experimental.hierarchy.{instantiable, public, Instantiate} import chisel3.experimental.{SerializableModule, SerializableModuleParameter} import chisel3.probe.{define, Probe, ProbeValue} import chisel3.util._ import chisel3.ltl._ import chisel3.ltl.Sequence._ +import chisel3.properties.{AnyClassType, Class, ClassType, Path, Property} import org.chipsalliance.t1.rtl.{ ffo, instIndexL, @@ -117,6 +119,15 @@ case class VRFParam( val vrfReadLatency = 2 } +@instantiable +class VRFOM extends Class { + val srams = IO(Output(Property[Seq[AnyClassType]]())) + + @public + val sramsIn = IO(Input(Property[Seq[AnyClassType]]())) + srams := sramsIn +} + class VRFProbe(parameter: VRFParam) extends Bundle { val valid: Bool = Bool() val requestVd: UInt = UInt(parameter.regNumBits.W) @@ -236,6 +247,12 @@ class VRF(val parameter: VRFParam) extends Module with SerializableModule[VRFPar @public val vrfProbe = IO(Output(Probe(new VRFProbe(parameter), layers.Verification))) + val omInstance: Instance[VRFOM] = Instantiate(new VRFOM) + val omType: ClassType = omInstance.toDefinition.getClassType + @public + val om: Property[ClassType] = IO(Output(Property[AnyClassType]())) + om := omInstance.getPropertyReference.asAnyClassType + // reset sram val sramReady: Bool = RegInit(false.B) val sramResetCount: UInt = RegInit(0.U(log2Ceil(parameter.rfDepth).W)) @@ -479,6 +496,8 @@ class VRF(val parameter: VRFParam) extends Module with SerializableModule[VRFPar rf } + omInstance.sramsIn := Property(rfVec.map(_.description.get.asAnyClassType)) + val initRecord: ValidIO[VRFWriteReport] = WireDefault(0.U.asTypeOf(Valid(new VRFWriteReport(parameter)))) initRecord.valid := true.B initRecord.bits := instructionWriteReport.bits diff --git a/t1rocket/src/T1RocketTile.scala b/t1rocket/src/T1RocketTile.scala index c0b90ccac..8b2fbc520 100644 --- a/t1rocket/src/T1RocketTile.scala +++ b/t1rocket/src/T1RocketTile.scala @@ -3,9 +3,10 @@ package org.chipsalliance.t1.tile import chisel3._ -import chisel3.experimental.hierarchy.{Instance, Instantiate} +import chisel3.experimental.hierarchy.{instantiable, public, Instance, Instantiate} import chisel3.experimental.{SerializableModule, SerializableModuleParameter} import chisel3.probe.{define, Probe, ProbeValue} +import chisel3.properties.{AnyClassType, Class, ClassType, Property} import chisel3.util.experimental.BitSet import chisel3.util.log2Ceil import org.chipsalliance.amba.axi4.bundle.{AXI4BundleParameter, AXI4ROIrrevocable, AXI4RWIrrevocable} @@ -376,6 +377,30 @@ case class T1RocketTileParameter( def t1HightOutstandingParameter: AXI4BundleParameter = t1Parameter.axi4BundleParameter.copy(dataWidth = 32) } +@instantiable +class T1RocketTileOM extends Class { + @public + val rocket = IO(Output(Property[AnyClassType]())) + @public + val rocketIn = IO(Input(Property[AnyClassType]())) + @public + val frontend = IO(Output(Property[AnyClassType]())) + @public + val frontendIn = IO(Input(Property[AnyClassType]())) + @public + val hellaCache = IO(Output(Property[AnyClassType]())) + @public + val hellaCacheIn = IO(Input(Property[AnyClassType]())) + @public + val t1 = IO(Output(Property[AnyClassType]())) + @public + val t1In = IO(Input(Property[AnyClassType]())) + rocket := rocketIn + frontend := frontendIn + hellaCache := hellaCacheIn + t1 := t1In +} + class T1RocketProbe(parameter: T1RocketTileParameter) extends Bundle { val rocketProbe: RocketProbe = Output(new RocketProbe(parameter.rocketParameter)) val fpuProbe: Option[FPUProbe] = parameter.fpuParameter.map(param => Output(new FPUProbe(param))) @@ -418,8 +443,9 @@ class T1RocketTileInterface(parameter: T1RocketTileParameter) extends Bundle { val highOutstandingAXI: AXI4RWIrrevocable = org.chipsalliance.amba.axi4.bundle.AXI4RWIrrevocable(parameter.t1HightOutstandingParameter) + val om: Property[ClassType] = Output(Property[AnyClassType]()) // TODO: merge it. - val t1RocketProbe: T1RocketProbe = Output(Probe(new T1RocketProbe(parameter), layers.Verification)) + val t1RocketProbe: T1RocketProbe = Output(Probe(new T1RocketProbe(parameter), layers.Verification)) } class T1RocketTile(val parameter: T1RocketTileParameter) @@ -435,6 +461,12 @@ class T1RocketTile(val parameter: T1RocketTileParameter) val ptw: Instance[PTW] = Instantiate(new PTW(parameter.ptwParameter)) val fpu: Option[Instance[FPU]] = parameter.fpuParameter.map(fpuParameter => Instantiate(new FPU(fpuParameter))) val t1: Instance[T1] = Instantiate(new T1(parameter.t1Parameter)) + val omInstance: Instance[T1RocketTileOM] = Instantiate(new T1RocketTileOM) + io.om := omInstance.getPropertyReference.asAnyClassType + omInstance.rocketIn := Property(rocket.io.om.asAnyClassType) + omInstance.frontendIn := Property(frontend.io.om.asAnyClassType) + omInstance.hellaCacheIn := Property(hellaCache.io.om.asAnyClassType) + omInstance.t1In := Property(t1.io.om.asAnyClassType) rocket.io.clock := io.clock rocket.io.reset := io.reset diff --git a/t1rocketemu/src/TestBench.scala b/t1rocketemu/src/TestBench.scala index 687c6674d..35adc1911 100644 --- a/t1rocketemu/src/TestBench.scala +++ b/t1rocketemu/src/TestBench.scala @@ -5,20 +5,38 @@ package org.chipsalliance.t1.t1rocketemu import chisel3._ import chisel3.experimental.dataview.DataViewable +import chisel3.experimental.hierarchy.{instantiable, public, Instance, Instantiate} import chisel3.experimental.hierarchy.Instance import chisel3.experimental.{ExtModule, SerializableModule, SerializableModuleGenerator} +import chisel3.properties.{AnyClassType, Class, ClassType, Property} import chisel3.util.circt.dpi.{RawClockedNonVoidFunctionCall, RawUnclockedNonVoidFunctionCall} import chisel3.util.{HasExtModuleInline, PopCount, UIntToOH, Valid} import org.chipsalliance.amba.axi4.bundle._ import org.chipsalliance.t1.t1rocketemu.dpi._ import org.chipsalliance.t1.tile.{T1RocketTile, T1RocketTileParameter} +@instantiable +class TestBenchOM extends Class { + @public + val t1RocketTile = IO(Output(Property[AnyClassType]())) + @public + val t1RocketTileIn = IO(Input(Property[AnyClassType]())) + t1RocketTile := t1RocketTileIn +} + class TestBench(val parameter: T1RocketTileParameter) extends RawModule with SerializableModule[T1RocketTileParameter] with ImplicitClock with ImplicitReset { layer.enable(layers.Verification) + + val omInstance: Instance[TestBenchOM] = Instantiate(new TestBenchOM) + val omType: ClassType = omInstance.toDefinition.getClassType + @public + val om: Property[ClassType] = IO(Output(Property[omType.Type]())) + om := omInstance.getPropertyReference + val clockGen = Module(new ExtModule with HasExtModuleInline { override def desiredName = "ClockGen" setInline( @@ -68,6 +86,7 @@ class TestBench(val parameter: T1RocketTileParameter) override def implicitClock = clockGen.clock.asClock override def implicitReset = clockGen.reset val dut: Instance[T1RocketTile] = SerializableModuleGenerator(classOf[T1RocketTile], parameter).instance() + omInstance.t1RocketTileIn := Property(dut.io.om.asAnyClassType) dut.io.clock := clock dut.io.reset := reset