Skip to content

Commit

Permalink
[om] add omreader and omreaderlib
Browse files Browse the repository at this point in the history
  • Loading branch information
SpriteOvO committed May 7, 2024
1 parent 38baef2 commit ee38539
Show file tree
Hide file tree
Showing 8 changed files with 327 additions and 0 deletions.
36 changes: 36 additions & 0 deletions build.sc
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,42 @@ trait Elaborator
def chiselIvy = None
}

object omreaderlib extends OMReaderLib

trait OMReaderLib
extends millbuild.common.OMReaderLibModule {
def scalaVersion = T(v.scala)

def panamaconverterModule = panamaconverter

def circtInstallPath = T.input(PathRef(os.Path(T.ctx().env("CIRCT_INSTALL_PATH"))))

def mainargsIvy = v.mainargs

def chiselModule = Some(chisel)
def chiselPluginJar = T(Some(chisel.pluginModule.jar()))
def chiselPluginIvy = None
def chiselIvy = None
}

object omreader extends OMReader

trait OMReader
extends millbuild.common.OMReaderModule {
def scalaVersion = T(v.scala)

def panamaconverterModule = panamaconverter
def omreaderlibModule = omreaderlib

def circtInstallPath = T.input(PathRef(os.Path(T.ctx().env("CIRCT_INSTALL_PATH"))))

def mainargsIvy = v.mainargs

def chiselModule = Some(chisel)
def chiselPluginJar = T(Some(chisel.pluginModule.jar()))
def chiselPluginIvy = None
def chiselIvy = None
}

/** A simple release flow for T1 generator:
* package required dependency to flat jar.
Expand Down
29 changes: 29 additions & 0 deletions common.sc
Original file line number Diff line number Diff line change
Expand Up @@ -129,3 +129,32 @@ trait ElaboratorModule
super.forkArgs() ++ Seq("--enable-native-access=ALL-UNNAMED", "--enable-preview", s"-Djava.library.path=${ circtInstallPath().path / "lib"}")
)
}

trait OMReaderLibModule
extends ScalaModule
with HasChisel {
def panamaconverterModule: ScalaModule
def circtInstallPath: T[PathRef]
override def moduleDeps = super.moduleDeps ++ Seq(panamaconverterModule)
def mainargsIvy: Dep
override def ivyDeps = T(super.ivyDeps() ++ Seq(mainargsIvy))
override def javacOptions = T(super.javacOptions() ++ Seq("--enable-preview", "--release", "21"))
override def forkArgs: T[Seq[String]] = T(
super.forkArgs() ++ Seq("--enable-native-access=ALL-UNNAMED", "--enable-preview", s"-Djava.library.path=${ circtInstallPath().path / "lib"}")
)
}

trait OMReaderModule
extends ScalaModule
with HasChisel {
def panamaconverterModule: ScalaModule
def omreaderlibModule: ScalaModule
def circtInstallPath: T[PathRef]
override def moduleDeps = super.moduleDeps ++ Seq(panamaconverterModule, omreaderlibModule)
def mainargsIvy: Dep
override def ivyDeps = T(super.ivyDeps() ++ Seq(mainargsIvy))
override def javacOptions = T(super.javacOptions() ++ Seq("--enable-preview", "--release", "21"))
override def forkArgs: T[Seq[String]] = T(
super.forkArgs() ++ Seq("--enable-native-access=ALL-UNNAMED", "--enable-preview", s"-Djava.library.path=${ circtInstallPath().path / "lib"}")
)
}
2 changes: 2 additions & 0 deletions nix/t1/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ lib.makeScope newScope
configgen = _millOutput.configgen // { meta.mainProgram = "configgen"; };
t1package = _millOutput.t1package;

omreader = self.callPackage ./omreader.nix { };
submodules = self.callPackage ./submodules.nix { };

riscv-opcodes-src = self.submodules.sources.riscv-opcodes.src;
Expand Down Expand Up @@ -71,6 +72,7 @@ lib.makeScope newScope
elaborate = innerSelf.callPackage ./elaborate.nix { target = "ip"; /* use-binder = true; */ };
mlirbc = innerSelf.callPackage ./mlirbc.nix { inherit elaborate; };
rtl = innerSelf.callPackage ./rtl.nix { inherit mlirbc; };
omreaderlib = innerSelf.callPackage ./omreaderlib.nix { inherit mlirbc; };

emu-elaborate = innerSelf.callPackage ./elaborate.nix { target = "ipemu"; /* use-binder = true; */ };
emu-mlirbc = innerSelf.callPackage ./mlirbc.nix { elaborate = emu-elaborate; };
Expand Down
25 changes: 25 additions & 0 deletions nix/t1/om.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{ stdenvNoCC
, lib

, omreader
, circt
, mlirbc
}:

let
omReaderArgs = lib.filter (s: s != "") [
"--mlirbc-file"
"${mlirbc}/${mlirbc.elaborateTarget}-${mlirbc.elaborateConfig}.mlirbc"
];
in
stdenvNoCC.mkDerivation {
name = "t1-${mlirbc.elaborateConfig}-${mlirbc.elaborateTarget}-om";

nativeBuildInputs = [ circt omreader ];

buildCommand = ''
omreader ${lib.escapeShellArgs omReaderArgs}
'';

meta.description = "Call CLI dumps OM properties from MLIR bytecodes";
}
90 changes: 90 additions & 0 deletions nix/t1/omreader.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
{ lib
, stdenv
, fetchMillDeps
, makeWrapper
, jdk21

# chisel deps
, mill
, espresso
, circt-full
, jextract-21
, strip-nondeterminism

, submodules
}:

let
self = stdenv.mkDerivation rec {
name = "omreader";

src = with lib.fileset; toSource {
root = ./../..;
fileset = unions [
./../../build.sc
./../../common.sc
./../../omreader
./../../omreaderlib
];
};

passthru.millDeps = fetchMillDeps {
inherit name;
src = with lib.fileset; toSource {
root = ./../..;
fileset = unions [
./../../build.sc
./../../common.sc
];
};
millDepsHash = "sha256-ZgcBH7p4/F8Jn6qmsTKmwN6PLVXi37iuRCD0xYxvEO4=";
nativeBuildInputs = [ submodules.setupHook ];
};

passthru.editable = self.overrideAttrs (_: {
shellHook = ''
setupSubmodulesEditable
mill mill.bsp.BSP/install 0
'';
});

shellHook = ''
setupSubmodules
'';

nativeBuildInputs = [
mill
jextract-21
strip-nondeterminism
circt-full

makeWrapper
passthru.millDeps.setupHook

submodules.setupHook
];

env = {
CIRCT_INSTALL_PATH = circt-full;
JAVA_TOOL_OPTIONS = "--enable-preview";
};

buildPhase = ''
mill -i 'omreader.assembly'
'';

installPhase = ''
mkdir -p "$out"/bin "$out"/share/java
strip-nondeterminism out/omreader/assembly.dest/out.jar
mv out/omreader/assembly.dest/out.jar "$out"/share/java/omreader.jar
makeWrapper ${jdk21}/bin/java "$out"/bin/omreader --add-flags "--enable-preview --enable-native-access=ALL-UNNAMED -Djava.library.path=${circt-full}/lib -jar $out/share/java/omreader.jar"
echo "$(cat "$out"/bin/omreader) 2> /dev/null" > "$out"/bin/omreader
'';

meta = {
description = "CLI reads OM properties from MLIR bytecodes";
mainProgram = "omreader";
};
};
in
self
66 changes: 66 additions & 0 deletions omreader/src/Main.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
// SPDX-License-Identifier: Apache-2.0
// SPDX-FileCopyrightText: 2022 Jiuyang Liu <[email protected]>

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)
}

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)
}
}
}
}
64 changes: 64 additions & 0 deletions omreaderlib/src/Interface.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
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

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")) {
val value = mirror.reflectMethod(method.asMethod)()
println(s"${method.name} = $value")
}
})
}

def dumpAll(): Unit = {
entry.foreachField((name, value) => println(s".$name => $value"))
}
}
15 changes: 15 additions & 0 deletions t1/src/T1.scala
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,18 @@ import org.chipsalliance.t1.rtl.vrf.{RamType, VRFParam, VRFProbe}
// 3. Lane(Retime, VRF memory type, id, multiple instances(does it affect dedup? not for sure))
@instantiable
class T1OM extends Class {
@public
val vlen = IO(Output(Property[Int]()))
@public
val vlenIn = IO(Input(Property[Int]()))
vlen := vlenIn

@public
val dlen = IO(Output(Property[Int]()))
@public
val dlenIn = IO(Input(Property[Int]()))
dlen := dlenIn

@public
val lanes = IO(Output(Property[Seq[AnyClassType]]()))
@public
Expand Down Expand Up @@ -264,6 +276,9 @@ class T1(val parameter: T1Parameter) extends Module with SerializableModule[T1Pa
val om: Property[ClassType] = IO(Output(Property[omType.Type]()))
om := omInstance.getPropertyReference

omInstance.vlenIn := Property(parameter.vLen)
omInstance.dlenIn := Property(parameter.dLen)

/** request from CPU.
* because the interrupt and exception of previous instruction is unpredictable,
* and the `kill` logic in Vector processor is too high,
Expand Down

0 comments on commit ee38539

Please sign in to comment.