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

Add Object Model support for T1 #529

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
6 changes: 3 additions & 3 deletions flake.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

15 changes: 15 additions & 0 deletions nix/overlay.nix
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,21 @@ in
# Override "nixpkgs" circt with "nixpkgs-for-circt".
# To update the "nixpkgs-for-circt" input, run `nix flake lock --update-input nixpkgs-for-circt`.
circt = self.inputs.nixpkgs-for-circt.legacyPackages."${final.system}".circt;
# uncomment this to build circt from source.
# circt = self.inputs.nixpkgs-for-circt.legacyPackages."${final.system}".circt.overrideAttrs (old: rec {
# version = "1.73.0";
# src = final.fetchFromGitHub {
# owner = "llvm";
# repo = "circt";
# rev = "firtool-${version}";
# sha256 = "sha256-C50PiToXrKf94Vg1yv++3xVhIuCW/KVPs0yLv5Fg0dY=";
# fetchSubmodules = true;
# };
# preConfigure = ''
# find ./test -name '*.mlir' -exec sed -i 's|/usr/bin/env|${final.coreutils}/bin/env|g' {} \;
# substituteInPlace cmake/modules/GenVersionFile.cmake --replace "unknown git version" "nightly"
# '';
# });
espresso = final.callPackage ./pkgs/espresso.nix { };
dramsim3 = final.callPackage ./pkgs/dramsim3.nix { };
libspike = final.callPackage ./pkgs/libspike.nix { };
Expand Down
8 changes: 4 additions & 4 deletions nix/t1/_sources/generated.json
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@
},
"chisel": {
"cargoLocks": null,
"date": "2024-03-27",
"date": "2024-04-24",
"extract": null,
"name": "chisel",
"passthru": null,
Expand All @@ -73,11 +73,11 @@
"name": null,
"owner": "chipsalliance",
"repo": "chisel",
"rev": "9177535ff1be47ffd99034bf0154c0f1ec637419",
"sha256": "sha256-smqNuOnmz+MeVGyS7mdIzegniQ/6EJH4CFqK4JntvrI=",
"rev": "08edb717185201dffdad1c808fbe32df914aa55f",
"sha256": "sha256-AYqkdMJE2Ct8T6M+oTrEVPlLmWM7uvl3UQnPv6tjUwA=",
"type": "github"
},
"version": "9177535ff1be47ffd99034bf0154c0f1ec637419"
"version": "08edb717185201dffdad1c808fbe32df914aa55f"
},
"diplomacy": {
"cargoLocks": null,
Expand Down
8 changes: 4 additions & 4 deletions nix/t1/_sources/generated.nix
Original file line number Diff line number Diff line change
Expand Up @@ -39,15 +39,15 @@
};
chisel = {
pname = "chisel";
version = "9177535ff1be47ffd99034bf0154c0f1ec637419";
version = "08edb717185201dffdad1c808fbe32df914aa55f";
src = fetchFromGitHub {
owner = "chipsalliance";
repo = "chisel";
rev = "9177535ff1be47ffd99034bf0154c0f1ec637419";
rev = "08edb717185201dffdad1c808fbe32df914aa55f";
fetchSubmodules = false;
sha256 = "sha256-smqNuOnmz+MeVGyS7mdIzegniQ/6EJH4CFqK4JntvrI=";
sha256 = "sha256-AYqkdMJE2Ct8T6M+oTrEVPlLmWM7uvl3UQnPv6tjUwA=";
};
date = "2024-03-27";
date = "2024-04-24";
};
diplomacy = {
pname = "diplomacy";
Expand Down
2 changes: 1 addition & 1 deletion nix/t1/t1.nix
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ let
./../../common.sc
];
};
millDepsHash = "sha256-Ri0aB4SxBdwuNOnBvvsTwVdAnvtiKIW5EMrulDX4sVo=";
millDepsHash = "sha256-rkS/bTDnjnyzdQyTIhfLj3e0mMdDn4fzv/660rO3qYg=";
nativeBuildInputs = [ submodules.setupHook ];
};

Expand Down
9 changes: 9 additions & 0 deletions rocket/src/AbstractT1.scala
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package org.chipsalliance.t1.rockettile

import chisel3._
import chisel3.properties.{ClassType, Path, Property}
import chisel3.util._
import chisel3.util.experimental.BitSet
import freechips.rocketchip.diplomacy._
Expand Down Expand Up @@ -154,6 +155,13 @@ abstract class AbstractLazyT1()(implicit p: Parameters) extends LazyModule {
BundleBridgeSource(() => Valid(new VectorResponse(xLen)))
val hazardControlNode: BundleBridgeSource[VectorHazardControl] =
BundleBridgeSource(() => Output(new VectorHazardControl))
// Diplomacy is dirty and doesn't support Property yet, this is a dirty hack and will be bore from top
val om = InModuleBody {
// TODO: maybe affect by [[https://github.com/llvm/circt/issues/6866]]:
// Abstract T1 cannot view the classpath in T1OM.
val t1OMType = ClassType.unsafeGetClassTypeByName("T1OM")
IO(Output(Property[t1OMType.Type]())).suggestName("T1OM")
}
}

/** This is a vector interface comply to chipsalliance/t1 project.
Expand All @@ -164,6 +172,7 @@ abstract class AbstractLazyT1ModuleImp(val outer: AbstractLazyT1)(implicit p: Pa
val csr: CSRInterface = outer.csrSinkNode.bundle
val response: ValidIO[VectorResponse] = outer.responseNode.bundle
val hazardControl: VectorHazardControl = outer.hazardControlNode.bundle
val om: Property[ClassType] = outer.om
}

trait HasLazyT1 { this: BaseTile =>
Expand Down
6 changes: 3 additions & 3 deletions subsystem/src/LazyT1.scala
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,14 @@ package org.chipsalliance.t1.subsystem

import chisel3._
import chisel3.experimental.SerializableModuleGenerator
import chisel3.properties.{ClassType, Path, Property}
import freechips.rocketchip.diplomacy.AddressSet
import freechips.rocketchip.subsystem.{BaseSubsystem, InstantiatesHierarchicalElements}
import org.chipsalliance.cde.config._
import org.chipsalliance.t1.rockettile.{AbstractLazyT1, AbstractLazyT1ModuleImp, T1LSUParameter}
import org.chipsalliance.t1.rtl.{T1, T1Parameter}

case object T1Generator extends Field[SerializableModuleGenerator[T1, T1Parameter]]
trait HasT1Tiles { this: BaseSubsystem with InstantiatesHierarchicalElements =>
lazy val t1Tiles = totalTiles.values.collect { case r: org.chipsalliance.t1.rocketcore.T1Tile => r }
}

class LazyT1()(implicit p: Parameters) extends AbstractLazyT1 {
lazy val module = new LazyT1Imp(this)
Expand Down Expand Up @@ -82,4 +80,6 @@ class LazyT1Imp(outer: LazyT1)(implicit p: Parameters) extends AbstractLazyT1Mod
bundle.d.ready := t1.memoryPorts(i).d.ready

}

om := t1.om
}
29 changes: 27 additions & 2 deletions subsystem/src/Subsystem.scala
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@
package org.chipsalliance.t1.subsystem

import chisel3._
import chisel3.experimental.hierarchy.{Definition, Instance, Instantiate, instantiable, public}
import chisel3.experimental.{SerializableModuleGenerator, UnlocatableSourceInfo}
import chisel3.properties.Class.ClassDefinitionOps
import chisel3.util.experimental.BitSet
import chisel3.util.{BitPat, Counter}
import freechips.rocketchip.devices.debug.DebugModuleKey
Expand All @@ -17,9 +19,24 @@ import freechips.rocketchip.tile.{FPUParams, MaxHartIdBits, XLen}
import freechips.rocketchip.tilelink.{BroadcastFilter, HasTLBusParams, TLBusWrapper, TLBusWrapperConnection, TLBusWrapperInstantiationLike, TLBusWrapperTopology, TLEdge, TLFIFOFixer, TLFragmenter, TLInwardNode, TLManagerNode, TLOutwardNode, TLSlaveParameters, TLSlavePortParameters, TLWidthWidget, TLXbar}
import freechips.rocketchip.util.Location
import org.chipsalliance.cde.config._
import org.chipsalliance.t1.rocketcore.{T1CrossingParams, T1TileAttachParams, T1TileParams}
import org.chipsalliance.t1.rocketcore.{T1CrossingParams, T1Tile, T1TileAttachParams, T1TileParams}
import org.chipsalliance.t1.rockettile.BuildT1
import org.chipsalliance.t1.rtl.{T1, T1Parameter}
import org.chipsalliance.t1.rtl.{T1, T1OM, T1Parameter}
import chisel3.properties.{Class, ClassType, Path, Property}
import chisel3.util.experimental.BoringUtils.bore


/** The top OM we need to read. */
@instantiable
class T1SubsystemOM extends Class {
val t1OMType: ClassType = Instantiate.definition(new T1OM).getClassType
@public
val t1 = IO(Output(Property[t1OMType.Type]()))
@public
val t1In = IO(Input(Property[t1OMType.Type]()))
t1 := t1In
// TODO: add memory ranges, scalar core info, here.
}

// The Subsystem that T1 lives in.
case object T1Subsystem extends HierarchicalLocation("T1Subsystem")
Expand Down Expand Up @@ -423,6 +440,14 @@ class T1Subsystem(implicit p: Parameters)
}.unzip

// IOs
val t1OM = InModuleBody {
val omInstance: Instance[T1SubsystemOM] = Instantiate(new T1SubsystemOM)
val omType: ClassType = omInstance.toDefinition.getClassType
val om: Property[ClassType] = IO(Output(Property[omType.Type]()))
om := omInstance.getPropertyReference
omInstance.t1In := bore(totalTiles.head._2.asInstanceOf[T1Tile].t1.map(_.om).get)
om
}
val scalarPort = InModuleBody { scalarMemoryNode.makeIOs() }
val mmioPort = InModuleBody { mmioNode.makeIOs() }
val vectorPorts = InModuleBody {
Expand Down
42 changes: 28 additions & 14 deletions t1/src/Lane.scala
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,25 @@
package org.chipsalliance.t1.rtl

import chisel3._
import chisel3.experimental.hierarchy.{Instance, Instantiate, instantiable, public}
import chisel3.experimental.hierarchy.{Definition, Instance, Instantiate, instantiable, public}
import chisel3.experimental.{SerializableModule, SerializableModuleParameter}
import chisel3.probe.{Probe, ProbeValue, define}
import chisel3.properties.{AnyClassType, Class, ClassType, Path, Property}
import chisel3.util._
import chisel3.util.experimental.decode.DecodeBundle
import org.chipsalliance.t1.rtl.decoder.Decoder
import org.chipsalliance.t1.rtl.lane._
import org.chipsalliance.t1.rtl.vrf.{RamType, VRF, VRFParam, VRFProbe}

@instantiable
class LaneOM extends Class {
@public
val vfus = IO(Output(Property[Seq[AnyClassType]]()))
@public
val vfusIn = IO(Input(Property[Seq[AnyClassType]]()))
vfus := vfusIn
}

class LaneSlotProbe extends Bundle {
val stage0EnqueueReady: Bool = Bool()
val stage0EnqueueValid: Bool = Bool()
Expand Down Expand Up @@ -159,6 +169,11 @@ case class LaneParameter(
*/
@instantiable
class Lane(val parameter: LaneParameter) extends Module with SerializableModule[LaneParameter] {
val omInstance: Instance[LaneOM] = Instantiate(new LaneOM)
val omType: ClassType = omInstance.toDefinition.getClassType
@public
val om: Property[ClassType] = IO(Output(Property[omType.Type]()))
om := omInstance.getPropertyReference

/** laneIndex is a IO constant for D/I and physical implementations. */
@public
Expand Down Expand Up @@ -796,19 +811,18 @@ class Lane(val parameter: LaneParameter) extends Module with SerializableModule[

// VFU
// TODO: reuse logic, adder, multiplier datapath
{
val decodeResultVec: Seq[DecodeBundle] = slotControl.map(_.laneRequest.decodeResult)

vfuConnect(parameter.vfuInstantiateParameter)(
requestVec,
executeEnqueueValid,
decodeResultVec,
executeEnqueueFire,
responseVec,
executeOccupied,
VFUNotClear
)
}
val decodeResultVec: Seq[DecodeBundle] = slotControl.map(_.laneRequest.decodeResult)

val vfus: Seq[Instance[VFUModule]] = instantiateVFU(parameter.vfuInstantiateParameter)(
requestVec,
executeEnqueueValid,
decodeResultVec,
executeEnqueueFire,
responseVec,
executeOccupied,
VFUNotClear
)
omInstance.vfusIn := Property(vfus.map(_.om.asAnyClassType))

// It’s been a long time since I selected it. Need pipe
val queueBeforeMaskWrite: Queue[VRFWriteRequest] =
Expand Down
24 changes: 23 additions & 1 deletion t1/src/T1.scala
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,31 @@
package org.chipsalliance.t1.rtl

import chisel3._
import chisel3.experimental.hierarchy.{Instance, Instantiate, public}
import chisel3.experimental.hierarchy.{Definition, Instance, Instantiate, instantiable, public}
import chisel3.experimental.{SerializableModule, SerializableModuleParameter}
import chisel3.util._
import chisel3.util.experimental.decode._
import tilelink.{TLBundle, TLBundleParameter, TLChannelAParameter, TLChannelDParameter}
import chisel3.probe.{Probe, ProbeValue, define, force}
import chisel3.properties.{AnyClassType, Class, ClassType, Property}
import chisel3.util.experimental.BitSet
import org.chipsalliance.t1.rtl.decoder.Decoder
import org.chipsalliance.t1.rtl.lsu.{LSU, LSUParameter, LSUProbe}
import org.chipsalliance.t1.rtl.vrf.{RamType, VRFParam, VRFProbe}

// TODO: this should be a object model. There should 3 object model here:
// 1. T1SubsystemOM(T1(OM), MemoryRegion, Cache configuration)
// 2. T1(Lane(OM), VLEN, DLEN, uarch parameters, customer IDs(for floorplan);)
// 3. Lane(Retime, VRF memory type, id, multiple instances(does it affect dedup? not for sure))
@instantiable
class T1OM extends Class {
@public
val lanes = IO(Output(Property[Seq[AnyClassType]]()))
@public
val lanesIn = IO(Input(Property[Seq[AnyClassType]]()))
lanes := lanesIn
}

object T1Parameter {
implicit def bitSetP:upickle.default.ReadWriter[BitSet] = upickle.default.readwriter[String].bimap[BitSet](
bs => bs.terms.map("b" + _.rawString).mkString("\n"),
Expand Down Expand Up @@ -244,6 +258,11 @@ class T1Probe(param: T1Parameter) extends Bundle {
* The logic of [[T1]] contains the Vector Sequencer and Mask Unit.
*/
class T1(val parameter: T1Parameter) extends Module with SerializableModule[T1Parameter] {
val omInstance: Instance[T1OM] = Instantiate(new T1OM)
val omType: ClassType = omInstance.toDefinition.getClassType
@public
val om: Property[ClassType] = IO(Output(Property[omType.Type]()))
om := omInstance.getPropertyReference

/** request from CPU.
* because the interrupt and exception of previous instruction is unpredictable,
Expand Down Expand Up @@ -1493,6 +1512,9 @@ class T1(val parameter: T1Parameter) extends Module with SerializableModule[T1Pa
define(laneVrfProbes(index), lane.vrfProbe)
lane
}

omInstance.lanesIn := Property(laneVec.map(_.om.asAnyClassType))

define(lsuProbe, lsu.probe)

writeQueueClearVec := VecInit(laneVec.map(_.writeQueueValid))
Expand Down
25 changes: 19 additions & 6 deletions t1/src/VectorFunctionUnit.scala
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ package org.chipsalliance.t1.rtl

import chisel3._
import chisel3.experimental.SerializableModuleGenerator
import chisel3.experimental.hierarchy.{instantiable, public}
import chisel3.properties.Property
import chisel3.experimental.hierarchy.{Instance, Instantiate, instantiable, public}
import chisel3.properties.{Class, ClassType, Path, Property}
import org.chipsalliance.t1.rtl.decoder.BoolField
import chisel3.util._

Expand All @@ -26,16 +26,29 @@ class VFUPipeBundle extends Bundle {
val tag: UInt = UInt(2.W)
}

@instantiable
// TODO: expose more metadatas to VFU OM, this is important for documentation generator.
class VFUOM extends Class {
@public
val cycles = IO(Output(Property[Int]()))
@public
val cyclesIn = IO(Input(Property[Int]()))
cycles := cyclesIn
}

@instantiable
abstract class VFUModule(p: VFUParameter) extends Module {
val omInstance: Instance[VFUOM] = Instantiate(new VFUOM)
val omType: ClassType = omInstance.toDefinition.getClassType

@public
val om: Property[ClassType] = IO(Output(Property[omType.Type]()))
@public
val requestIO: DecoupledIO[VFUPipeBundle] = IO(Flipped(Decoupled(p.inputBundle)))
@public
val responseIO: DecoupledIO[VFUPipeBundle] = IO(Decoupled(p.outputBundle))
// FFUModule is a behavior Module which should be retimed to [[latency]] cycles.
@public
val retime: Option[Property[Int]] = Option.when(p.latency > 1)(IO(Property[Int]()))
retime.foreach(_ := Property(p.latency))
om := omInstance.getPropertyReference
omInstance.cyclesIn := Property(p.latency)

val vfuRequestReady: Option[Bool] = Option.when(!p.singleCycle)(Wire(Bool()))
val requestReg: VFUPipeBundle = RegEnable(requestIO.bits, 0.U.asTypeOf(requestIO.bits), requestIO.fire)
Expand Down
Loading
Loading