Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Backport T1Rocket and T1Rocket testbench #745

Closed
wants to merge 5 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 31 additions & 0 deletions build.sc
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,21 @@ trait RocketV
def chiselIvy = None
}

object t1rocket extends T1Rocket

trait T1Rocket
extends millbuild.common.T1RocketModule
with ScalafmtModule {
def scalaVersion = T(v.scala)
def rocketModule = rocketv
def t1Module = t1

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

object ipemu extends IPEmulator

trait IPEmulator
Expand All @@ -161,6 +176,20 @@ trait RocketEmulator extends millbuild.common.RocketEmulatorModule {
def chiselIvy = None
}

object t1rocketemu extends T1RocketEmulator

trait T1RocketEmulator
extends millbuild.common.T1RocketEmulatorModule {
def scalaVersion = T(v.scala)

def t1rocketModule = t1rocket

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

object panamaconverter extends PanamaConverter

trait PanamaConverter
Expand Down Expand Up @@ -188,6 +217,8 @@ trait Elaborator
ipemu,
rocketv,
rocketemu,
t1rocket,
t1rocketemu,
)

def mainargsIvy = v.mainargs
Expand Down
17 changes: 17 additions & 0 deletions common.sc
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,16 @@ trait RocketVModule
def moduleDeps = super.moduleDeps ++ Seq(axi4Module, hardfloatModule)
}

// Link T1 example: RocketV+T1
trait T1RocketModule
extends ScalaModule
with HasChisel {
def rocketModule: ScalaModule
def t1Module: ScalaModule

def moduleDeps = super.moduleDeps ++ Seq(rocketModule, t1Module)
}

trait EmuHelperModule
extends ScalaModule
with HasChisel
Expand All @@ -101,6 +111,13 @@ trait IPEmulatorModule
def moduleDeps = super.moduleDeps ++ Seq(t1Module)
}

trait T1RocketEmulatorModule
extends ScalaModule
with HasChisel {
def t1rocketModule: ScalaModule
def moduleDeps = super.moduleDeps ++ Seq(t1rocketModule)
}

trait ElaboratorModule
extends ScalaModule
with HasChisel {
Expand Down
70 changes: 46 additions & 24 deletions elaborator/src/Main.scala
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import mainargs._
import org.chipsalliance.t1.rtl.T1Parameter
import org.chipsalliance.rocketv.RocketTileParameter
import chisel3.panamalib.option._
import org.chipsalliance.t1.tile.T1RocketTileParameter

object Main {
implicit object PathRead extends TokensReader.Simple[os.Path] {
Expand All @@ -28,11 +29,15 @@ object Main {
).foldLeft(
Seq(
chisel3.stage.ChiselGeneratorAnnotation(gen),
chisel3.panamaconverter.stage.FirtoolOptionsAnnotation(FirtoolOptions(Set(
BuildMode(BuildModeDebug),
PreserveValues(PreserveValuesModeNamed),
DisableUnknownAnnotations(true)
))),
chisel3.panamaconverter.stage.FirtoolOptionsAnnotation(
FirtoolOptions(
Set(
BuildMode(BuildModeDebug),
PreserveValues(PreserveValuesModeNamed),
DisableUnknownAnnotations(true)
)
)
)
): firrtl.AnnotationSeq
) { case (annos, stage) => stage.transform(annos) }
.flatMap {
Expand All @@ -42,9 +47,9 @@ object Main {
case chisel3.panamaconverter.stage.PanamaCIRCTConverterAnnotation(converter) =>
if (binderMlirbcOut.nonEmpty) panamaCIRCTConverter = converter
None
case _: chisel3.panamaconverter.stage.FirtoolOptionsAnnotation => None
case _: chisel3.stage.DesignAnnotation[_] => None
case _: chisel3.stage.ChiselCircuitAnnotation => None
case _: chisel3.panamaconverter.stage.FirtoolOptionsAnnotation => None
case _: chisel3.stage.DesignAnnotation[_] => None
case _: chisel3.stage.ChiselCircuitAnnotation => None
case a => Some(a)
}

Expand All @@ -63,31 +68,48 @@ object Main {
case class IPConfig(
@arg(name = "ip-config", short = 'c') ipConfig: os.Path) {
def generator = upickle.default
.read[chisel3.experimental.SerializableModuleGenerator[org.chipsalliance.t1.rtl.T1, org.chipsalliance.t1.rtl.T1Parameter]](ujson.read(os.read(ipConfig)))
.read[chisel3.experimental.SerializableModuleGenerator[
org.chipsalliance.t1.rtl.T1,
org.chipsalliance.t1.rtl.T1Parameter
]](ujson.read(os.read(ipConfig)))
def parameter: T1Parameter = generator.parameter
}

case class RocketConfig(
@arg(name = "rocket-config", short = 'c') rocketConfig: os.Path) {
def generator = upickle.default
.read[chisel3.experimental.SerializableModuleGenerator[org.chipsalliance.rocketv.RocketTile, org.chipsalliance.rocketv.RocketTileParameter]](ujson.read(os.read(rocketConfig)))
.read[chisel3.experimental.SerializableModuleGenerator[
org.chipsalliance.rocketv.RocketTile,
org.chipsalliance.rocketv.RocketTileParameter
]](ujson.read(os.read(rocketConfig)))
def parameter: RocketTileParameter = generator.parameter
}

implicit def ipConfig: ParserForClass[IPConfig] = ParserForClass[IPConfig]
implicit def rocketConfig: ParserForClass[RocketConfig] = ParserForClass[RocketConfig]

// format: off
@main def ip(elaborateConfig: ElaborateConfig, ipConfig: IPConfig): Unit = elaborateConfig.elaborate(() =>
ipConfig.generator.module()
)
@main def ipemu(elaborateConfig: ElaborateConfig, ipConfig: IPConfig): Unit = elaborateConfig.elaborate(() =>
new org.chipsalliance.t1.ipemu.TestBench(ipConfig.generator)
)
@main def rocketemu(elaborateConfig: ElaborateConfig, rocketConfig: RocketConfig): Unit = elaborateConfig.elaborate(() =>
new org.chipsalliance.t1.rocketv.TestBench(rocketConfig.generator)
)
// format: on
case class T1RocketConfig(
@arg(name = "t1rocket-config", short = 'c') rocketConfig: os.Path) {
def generator = upickle.default
.read[chisel3.experimental.SerializableModuleGenerator[
org.chipsalliance.t1.tile.T1RocketTile,
org.chipsalliance.t1.tile.T1RocketTileParameter
]](ujson.read(os.read(rocketConfig)))
def parameter: T1RocketTileParameter = generator.parameter
}

implicit def ipConfig: ParserForClass[IPConfig] = ParserForClass[IPConfig]
implicit def rocketConfig: ParserForClass[RocketConfig] = ParserForClass[RocketConfig]
implicit def t1RocketConfig: ParserForClass[T1RocketConfig] = ParserForClass[T1RocketConfig]

@main def ip(elaborateConfig: ElaborateConfig, ipConfig: IPConfig): Unit =
elaborateConfig.elaborate(() => ipConfig.generator.module())

@main def ipemu(elaborateConfig: ElaborateConfig, ipConfig: IPConfig): Unit =
elaborateConfig.elaborate(() => new org.chipsalliance.t1.ipemu.TestBench(ipConfig.generator))

@main def rocketemu(elaborateConfig: ElaborateConfig, rocketConfig: RocketConfig): Unit =
elaborateConfig.elaborate(() => new org.chipsalliance.t1.rocketv.TestBench(rocketConfig.generator))

@main def t1rocketemu(elaborateConfig: ElaborateConfig, t1rocketConfig: T1RocketConfig): Unit =
elaborateConfig.elaborate(() => new org.chipsalliance.t1.t1rocketemu.TestBench(t1rocketConfig.generator))

def main(args: Array[String]): Unit = ParserForMethods(this).runOrExit(args)
}
102 changes: 102 additions & 0 deletions elaborator/src/t1rocket/T1RocketTile.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
// SPDX-License-Identifier: Apache-2.0
// SPDX-FileCopyrightText: 2024 Jiuyang Liu <[email protected]>
package org.chipsalliance.t1.elaborator.t1rocketv

import chisel3.util.BitPat
import chisel3.util.experimental.BitSet
import mainargs._
import org.chipsalliance.t1.elaborator.Elaborator
import org.chipsalliance.t1.rtl.vrf.RamType
import org.chipsalliance.t1.rtl.vrf.RamType.{p0rp1w, p0rw, p0rwp1rw}
import org.chipsalliance.t1.tile.{T1RocketTile, T1RocketTileParameter}

// --instructionSets rv32_i --instructionSets rv_a --instructionSets rv_c --instructionSets rv_v --instructionSets Zve32x --instructionSets zvl1024b --cacheBlockBytes 32 --nPMPs 8 --cacheable 80000000-ffffffff --sideEffects 00000000-1fffffff --dcacheNSets 64 --dcacheNWays 4 --dcacheRowBits 32 --iCacheNSets 32 --iCacheNWays 4 --iCachePrefetch false --dLen 256 --vrfBankSize 2 --vrfRamType p0rp1w
object T1RocketTile extends Elaborator {
implicit object BitSetRead extends TokensReader.Simple[BitSet] {
def shortName = "bitset"
def read(strs: Seq[String]) = {
Right(
strs.head
.split(",")
.map { opt =>
if (opt.contains("-")) {
val range = opt.split("-")
require(range.size == 2)
val from = BigInt(range.head, 16)
val to = BigInt(range.last, 16) + 1
BitSet.fromRange(from, to - from, range.head.length * 4)
} else if (opt.contains("+")) {
val range = opt.split("\\+")
require(range.size == 2)
val from = BigInt(range.head, 16)
val length = BigInt(range.last, 16)
BitSet.fromRange(from, length, range.head.length * 4)
} else {
BitPat(s"b$opt")
}
}
.reduce(_.union(_))
)
}
}

implicit object RamTypeRead extends TokensReader.Simple[RamType] {
def shortName = "ramtype"
def read(strs: Seq[String]) = {
Right(
strs.head match {
case "p0rw" => p0rw
case "p0rp1w" => p0rp1w
case "p0rwp1rw" => p0rwp1rw
}
)
}
}

@main
case class T1RocketTileParameterMain(
@arg(name = "instructionSets") instructionSets: Seq[String],
@arg(name = "cacheBlockBytes") cacheBlockBytes: Int,
@arg(name = "nPMPs") nPMPs: Int,
@arg(name = "cacheable") cacheable: BitSet,
@arg(name = "sideEffects") sideEffects: BitSet,
@arg(name = "dcacheNSets") dcacheNSets: Int,
@arg(name = "dcacheNWays") dcacheNWays: Int,
@arg(name = "dcacheRowBits") dcacheRowBits: Int,
@arg(name = "iCacheNSets") iCacheNSets: Int,
@arg(name = "iCacheNWays") iCacheNWays: Int,
@arg(name = "iCachePrefetch") iCachePrefetch: Boolean,
@arg(name = "dLen") dLen: Int,
@arg(name = "vrfBankSize") vrfBankSize: Int,
@arg(name = "vrfRamType") vrfRamType: RamType
) {
def convert: T1RocketTileParameter = T1RocketTileParameter(
instructionSets: Seq[String],
cacheBlockBytes: Int,
nPMPs: Int,
cacheable: BitSet,
sideEffects: BitSet,
dcacheNSets: Int,
dcacheNWays: Int,
dcacheRowBits: Int,
iCacheNSets: Int,
iCacheNWays: Int,
iCachePrefetch: Boolean,
dLen: Int,
vrfBankSize: Int,
vrfRamType: RamType
)
}

implicit def T1RocketTileParameterMainParser: ParserForClass[T1RocketTileParameterMain] =
ParserForClass[T1RocketTileParameterMain]

@main
def config(@arg(name = "parameter") parameter: T1RocketTileParameterMain) = configImpl(parameter.convert)

@main
def design(@arg(name = "parameter") parameter: os.Path, @arg(name = "run-firtool") runFirtool: mainargs.Flag) =
designImpl[T1RocketTile, T1RocketTileParameter](parameter, runFirtool.value)

def main(args: Array[String]): Unit = ParserForMethods(this).runOrExit(args)
}
1 change: 1 addition & 0 deletions nix/overlay.nix
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ rec {

t1-script = final.callPackage ../script { };
inherit (t1-script) t1-helper ci-helper;
dev-mode = final.callPackage ./pkgs/dev-mode { };

# stdenv for compiling rvv programs, with ilp32f newlib and clang
rv32-stdenv = rv32_pkgs.stdenv.override {
Expand Down
8 changes: 8 additions & 0 deletions nix/pkgs/dev-mode/default.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{ mkShellNoCC, jq, ncurses, gettext }:
mkShellNoCC {
name = "t1-dev-mode";
nativeBuildInputs = [ jq ncurses gettext ];
shellHook = ''
source ${./dev-mode.sh}
'';
}
Loading
Loading