diff --git a/.github/workflows/mill-ci.yml b/.github/workflows/mill-ci.yml
index 0d03a2eb5ae..a75ab0300fc 100644
--- a/.github/workflows/mill-ci.yml
+++ b/.github/workflows/mill-ci.yml
@@ -25,7 +25,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
- config: [DefaultConfig, DefaultBufferlessConfig, DefaultRV32Config, TinyConfig, DefaultFP16Config]
+ config: [DefaultConfig, DefaultBufferlessConfig, DefaultRV32Config, TinyConfig, DefaultFP16Config, DefaultBConfig, DefaultRV32BConfig]
steps:
- uses: actions/checkout@v2
with:
diff --git a/.gitmodules b/.gitmodules
index 77819d7f768..b64ce5416e0 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -1,9 +1,13 @@
-[submodule "hardfloat"]
- path = hardfloat
+[submodule "dependencies/hardfloat"]
+ path = dependencies/hardfloat
url = https://github.com/ucb-bar/berkeley-hardfloat.git
-[submodule "torture"]
- path = torture
- url = https://github.com/ucb-bar/riscv-torture.git
-[submodule "cde"]
- path = cde
+[submodule "dependencies/cde"]
+ path = dependencies/cde
url = https://github.com/chipsalliance/cde.git
+[submodule "dependencies/chisel"]
+ path = dependencies/chisel
+ url = https://github.com/chipsalliance/chisel.git
+[submodule "dependencies/diplomacy"]
+ path = dependencies/diplomacy
+ url = https://github.com/chipsalliance/diplomacy.git
+ branch = master
diff --git a/build.sc b/build.sc
index 429da095900..b63c6ae7900 100644
--- a/build.sc
+++ b/build.sc
@@ -2,20 +2,37 @@ import mill._
import mill.scalalib._
import mill.scalalib.publish._
import coursier.maven.MavenRepository
-import $file.hardfloat.common
-import $file.cde.common
+import $file.dependencies.hardfloat.common
+import $file.dependencies.cde.common
+import $file.dependencies.diplomacy.common
+import $file.dependencies.chisel.build
import $file.common
object v {
- val scala = "2.13.10"
+ val scala = "2.13.12"
// the first version in this Map is the mainly supported version which will be used to run tests
val chiselCrossVersions = Map(
- "3.6.0" -> (ivy"edu.berkeley.cs::chisel3:3.6.0", ivy"edu.berkeley.cs:::chisel3-plugin:3.6.0"),
- "5.0.0" -> (ivy"org.chipsalliance::chisel:5.0.0", ivy"org.chipsalliance:::chisel-plugin:5.0.0"),
+ "5.1.0" -> (ivy"org.chipsalliance::chisel:5.1.0", ivy"org.chipsalliance:::chisel-plugin:5.1.0"),
+ // build from project from source
+ "source" -> (ivy"org.chipsalliance::chisel:99", ivy"org.chipsalliance:::chisel-plugin:99"),
)
val mainargs = ivy"com.lihaoyi::mainargs:0.5.0"
val json4sJackson = ivy"org.json4s::json4s-jackson:4.0.5"
val scalaReflect = ivy"org.scala-lang:scala-reflect:${scala}"
+ val sourcecode = ivy"com.lihaoyi::sourcecode:0.3.1"
+ val sonatypesSnapshots = Seq(
+ MavenRepository("https://s01.oss.sonatype.org/content/repositories/snapshots")
+ )
+}
+
+// Build form source only for dev
+object chisel extends Chisel
+
+trait Chisel
+ extends millbuild.dependencies.chisel.build.Chisel {
+ def crossValue = v.scala
+ override def millSourcePath = os.pwd / "dependencies" / "chisel"
+ def scalaVersion = T(v.scala)
}
object macros extends Macros
@@ -33,33 +50,60 @@ trait Macros
object hardfloat extends mill.define.Cross[Hardfloat](v.chiselCrossVersions.keys.toSeq)
trait Hardfloat
- extends millbuild.hardfloat.common.HardfloatModule
+ extends millbuild.dependencies.hardfloat.common.HardfloatModule
with RocketChipPublishModule
with Cross.Module[String] {
def scalaVersion: T[String] = T(v.scala)
- override def millSourcePath = os.pwd / "hardfloat" / "hardfloat"
+ override def millSourcePath = os.pwd / "dependencies" / "hardfloat" / "hardfloat"
+
+ def chiselModule = Option.when(crossValue == "source")(chisel)
- def chiselModule = None
+ def chiselPluginJar = T(Option.when(crossValue == "source")(chisel.pluginModule.jar()))
- def chiselPluginJar = None
+ def chiselIvy = Option.when(crossValue != "source")(v.chiselCrossVersions(crossValue)._1)
- def chiselIvy = Some(v.chiselCrossVersions(crossValue)._1)
+ def chiselPluginIvy = Option.when(crossValue != "source")(v.chiselCrossVersions(crossValue)._2)
- def chiselPluginIvy = Some(v.chiselCrossVersions(crossValue)._2)
+ def repositoriesTask = T.task(super.repositoriesTask() ++ v.sonatypesSnapshots)
}
object cde extends CDE
trait CDE
- extends millbuild.cde.common.CDEModule
+ extends millbuild.dependencies.cde.common.CDEModule
with RocketChipPublishModule
with ScalaModule {
def scalaVersion: T[String] = T(v.scala)
- override def millSourcePath = os.pwd / "cde" / "cde"
+ override def millSourcePath = os.pwd / "dependencies" / "cde" / "cde"
+}
+
+object diplomacy extends mill.define.Cross[Diplomacy](v.chiselCrossVersions.keys.toSeq)
+
+trait Diplomacy
+ extends millbuild.dependencies.diplomacy.common.DiplomacyModule
+ with RocketChipPublishModule
+ with Cross.Module[String] {
+
+ override def scalaVersion: T[String] = T(v.scala)
+
+ override def millSourcePath = os.pwd / "dependencies" / "diplomacy" / "diplomacy"
+
+ // dont use chisel from source
+ def chiselModule = Option.when(crossValue == "source")(chisel)
+ def chiselPluginJar = T(Option.when(crossValue == "source")(chisel.pluginModule.jar()))
+
+ // use chisel from ivy
+ def chiselIvy = Option.when(crossValue != "source")(v.chiselCrossVersions(crossValue)._1)
+ def chiselPluginIvy = Option.when(crossValue != "source")(v.chiselCrossVersions(crossValue)._2)
+
+ // use CDE from source until published to sonatype
+ def cdeModule = cde
+
+ def sourcecodeIvy = v.sourcecode
}
object rocketchip extends Cross[RocketChip](v.chiselCrossVersions.keys.toSeq)
@@ -73,13 +117,13 @@ trait RocketChip
override def millSourcePath = super.millSourcePath / os.up
- def chiselModule = None
+ def chiselModule = Option.when(crossValue == "source")(chisel)
- def chiselPluginJar = None
+ def chiselPluginJar = T(Option.when(crossValue == "source")(chisel.pluginModule.jar()))
- def chiselIvy = Some(v.chiselCrossVersions(crossValue)._1)
+ def chiselIvy = Option.when(crossValue != "source")(v.chiselCrossVersions(crossValue)._1)
- def chiselPluginIvy = Some(v.chiselCrossVersions(crossValue)._2)
+ def chiselPluginIvy = Option.when(crossValue != "source")(v.chiselCrossVersions(crossValue)._2)
def macrosModule = macros
@@ -87,9 +131,15 @@ trait RocketChip
def cdeModule = cde
+ def diplomacyModule = diplomacy(crossValue)
+
+ def diplomacyIvy = None
+
def mainargsIvy = v.mainargs
def json4sJacksonIvy = v.json4sJackson
+
+ def repositoriesTask = T.task(super.repositoriesTask() ++ v.sonatypesSnapshots)
}
trait RocketChipPublishModule
@@ -108,7 +158,6 @@ trait RocketChipPublishModule
override def publishVersion: T[String] = T("1.6-SNAPSHOT")
}
-
// Tests
trait Emulator extends Cross.Module2[String, String] {
val top: String = crossValue
@@ -267,6 +316,7 @@ object emulator extends Cross[Emulator](
("freechips.rocketchip.system.TestHarness", "freechips.rocketchip.system.DefaultBufferlessConfig"),
// RocketSuiteC
("freechips.rocketchip.system.TestHarness", "freechips.rocketchip.system.TinyConfig"),
+
// Unittest
("freechips.rocketchip.unittest.TestHarness", "freechips.rocketchip.unittest.AMBAUnitTestConfig"),
("freechips.rocketchip.unittest.TestHarness", "freechips.rocketchip.unittest.TLSimpleUnitTestConfig"),
@@ -294,6 +344,9 @@ object emulator extends Cross[Emulator](
//
("freechips.rocketchip.system.TestHarness", "freechips.rocketchip.system.DefaultRV32Config"),
("freechips.rocketchip.system.TestHarness", "freechips.rocketchip.system.DefaultFP16Config"),
+ ("freechips.rocketchip.system.TestHarness", "freechips.rocketchip.system.DefaultBConfig"),
+ ("freechips.rocketchip.system.TestHarness", "freechips.rocketchip.system.DefaultRV32BConfig"),
+
)
object `runnable-riscv-test` extends mill.Cross[RiscvTest](
@@ -355,8 +408,8 @@ object `runnable-riscv-test` extends mill.Cross[RiscvTest](
("freechips.rocketchip.system.TestHarness", "freechips.rocketchip.system.DefaultRV32Config", "rv32uc-v", "none"),
("freechips.rocketchip.system.TestHarness", "freechips.rocketchip.system.DefaultRV32Config", "rv32uf-p", "none"),
("freechips.rocketchip.system.TestHarness", "freechips.rocketchip.system.DefaultRV32Config", "rv32uf-v", "none"),
- ("freechips.rocketchip.system.TestHarness", "freechips.rocketchip.system.DefaultRV32Config", "rv32ui-p", "none"),
- ("freechips.rocketchip.system.TestHarness", "freechips.rocketchip.system.DefaultRV32Config", "rv32ui-v", "none"),
+ ("freechips.rocketchip.system.TestHarness", "freechips.rocketchip.system.DefaultRV32Config", "rv32ui-p", "ma_data"),
+ ("freechips.rocketchip.system.TestHarness", "freechips.rocketchip.system.DefaultRV32Config", "rv32ui-v", "ma_data"),
("freechips.rocketchip.system.TestHarness", "freechips.rocketchip.system.DefaultRV32Config", "rv32um-p", "none"),
("freechips.rocketchip.system.TestHarness", "freechips.rocketchip.system.DefaultRV32Config", "rv32um-v", "none"),
@@ -368,11 +421,17 @@ object `runnable-riscv-test` extends mill.Cross[RiscvTest](
// lsrc is not implemented if usingDataScratchpad
("freechips.rocketchip.system.TestHarness", "freechips.rocketchip.system.TinyConfig", "rv32ua-p", "lrsc"),
("freechips.rocketchip.system.TestHarness", "freechips.rocketchip.system.TinyConfig", "rv32uc-p", "none"),
- ("freechips.rocketchip.system.TestHarness", "freechips.rocketchip.system.TinyConfig", "rv32ui-p", "none"),
+ ("freechips.rocketchip.system.TestHarness", "freechips.rocketchip.system.TinyConfig", "rv32ui-p", "ma_data"),
("freechips.rocketchip.system.TestHarness", "freechips.rocketchip.system.TinyConfig", "rv32um-p", "none"),
("freechips.rocketchip.system.TestHarness", "freechips.rocketchip.system.DefaultFP16Config", "rv64uzfh-p", "none"),
("freechips.rocketchip.system.TestHarness", "freechips.rocketchip.system.DefaultFP16Config", "rv64uzfh-v", "none"),
+ ("freechips.rocketchip.system.TestHarness", "freechips.rocketchip.system.DefaultBConfig", "rv64uzba-p", "none"),
+ ("freechips.rocketchip.system.TestHarness", "freechips.rocketchip.system.DefaultBConfig", "rv64uzbb-p", "none"),
+ ("freechips.rocketchip.system.TestHarness", "freechips.rocketchip.system.DefaultBConfig", "rv64uzbs-p", "none"),
+ ("freechips.rocketchip.system.TestHarness", "freechips.rocketchip.system.DefaultRV32BConfig", "rv32uzba-p", "none"),
+ ("freechips.rocketchip.system.TestHarness", "freechips.rocketchip.system.DefaultRV32BConfig", "rv32uzbb-p", "none"),
+ ("freechips.rocketchip.system.TestHarness", "freechips.rocketchip.system.DefaultRV32BConfig", "rv32uzbs-p", "none"),
)
object `runnable-arch-test` extends mill.Cross[ArchTest](
diff --git a/common.sc b/common.sc
index 574f0ad4310..d11edcc116a 100644
--- a/common.sc
+++ b/common.sc
@@ -42,19 +42,18 @@ trait RocketChipModule
// should be hardfloat/common.sc#HardfloatModule
def hardfloatModule: ScalaModule
- // should be cde/common.sc#CDEModule
- def cdeModule: ScalaModule
+ def diplomacyModule: ScalaModule
def mainargsIvy: Dep
def json4sJacksonIvy: Dep
- override def moduleDeps = super.moduleDeps ++ Seq(macrosModule, hardfloatModule, cdeModule)
+ override def moduleDeps = super.moduleDeps ++ Seq(macrosModule, hardfloatModule, diplomacyModule)
override def ivyDeps = T(
super.ivyDeps() ++ Agg(
mainargsIvy,
- json4sJacksonIvy
+ json4sJacksonIvy,
)
)
}
diff --git a/cde b/dependencies/cde
similarity index 100%
rename from cde
rename to dependencies/cde
diff --git a/dependencies/chisel b/dependencies/chisel
new file mode 160000
index 00000000000..e3bcc90db37
--- /dev/null
+++ b/dependencies/chisel
@@ -0,0 +1 @@
+Subproject commit e3bcc90db37f1aec9f8048813f4f0666098d9bee
diff --git a/dependencies/diplomacy b/dependencies/diplomacy
new file mode 160000
index 00000000000..edf375300d9
--- /dev/null
+++ b/dependencies/diplomacy
@@ -0,0 +1 @@
+Subproject commit edf375300d99a4c260a214d7c1553de0040771d7
diff --git a/hardfloat b/dependencies/hardfloat
similarity index 100%
rename from hardfloat
rename to dependencies/hardfloat
diff --git a/docs/src/diplomacy/adder_tutorial.md b/docs/src/diplomacy/adder_tutorial.md
index 9ab77ff29d5..2548ac43dc8 100644
--- a/docs/src/diplomacy/adder_tutorial.md
+++ b/docs/src/diplomacy/adder_tutorial.md
@@ -38,7 +38,7 @@ behavior of typical Chisel width inference.
```scala mdoc:invisible
import chipsalliance.rocketchip.config.{Config, Parameters}
import chisel3._
-import chisel3.internal.sourceinfo.SourceInfo
+import chisel3.experimental.SourceInfo
import chisel3.stage.ChiselStage
import chisel3.util.random.FibonacciLFSR
import freechips.rocketchip.diplomacy.{SimpleNodeImp, RenderedEdge, ValName, SourceNode,
diff --git a/flake.lock b/flake.lock
index b0128cb6f91..e0cf2cdc548 100644
--- a/flake.lock
+++ b/flake.lock
@@ -1,12 +1,15 @@
{
"nodes": {
"flake-utils": {
+ "inputs": {
+ "systems": "systems"
+ },
"locked": {
- "lastModified": 1676283394,
- "narHash": "sha256-XX2f9c3iySLCw54rJ/CZs+ZK6IQy7GXNY4nSOyu2QG4=",
+ "lastModified": 1694529238,
+ "narHash": "sha256-zsNZZGTGnMOf9YpHKJqMSsa0dXbfmxeoJ7xHlrt+xmY=",
"owner": "numtide",
"repo": "flake-utils",
- "rev": "3db36a8b464d0c4532ba1c7dda728f4576d6d073",
+ "rev": "ff7b65b44d01cf9ba6a71320833626af21126384",
"type": "github"
},
"original": {
@@ -17,11 +20,11 @@
},
"nixpkgs": {
"locked": {
- "lastModified": 1676300157,
- "narHash": "sha256-1HjRzfp6LOLfcj/HJHdVKWAkX9QRAouoh6AjzJiIerU=",
+ "lastModified": 1696019113,
+ "narHash": "sha256-X3+DKYWJm93DRSdC5M6K5hLqzSya9BjibtBsuARoPco=",
"owner": "NixOS",
"repo": "nixpkgs",
- "rev": "545c7a31e5dedea4a6d372712a18e00ce097d462",
+ "rev": "f5892ddac112a1e9b3612c39af1b72987ee5783a",
"type": "github"
},
"original": {
@@ -36,6 +39,21 @@
"flake-utils": "flake-utils",
"nixpkgs": "nixpkgs"
}
+ },
+ "systems": {
+ "locked": {
+ "lastModified": 1681028828,
+ "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
+ "owner": "nix-systems",
+ "repo": "default",
+ "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
+ "type": "github"
+ },
+ "original": {
+ "owner": "nix-systems",
+ "repo": "default",
+ "type": "github"
+ }
}
},
"root": "root",
diff --git a/flake.nix b/flake.nix
index d9a19fcf541..28d32e91fb4 100644
--- a/flake.nix
+++ b/flake.nix
@@ -20,7 +20,8 @@
mill
dtc
verilator cmake ninja
- python3 python3Packages.bootstrapped-pip
+ python3
+ python3Packages.pip
pkgsCross.riscv64-embedded.buildPackages.gcc
pkgsCross.riscv64-embedded.buildPackages.gdb
openocd
diff --git a/overlay.nix b/overlay.nix
index c7698a02821..3cd0989b795 100644
--- a/overlay.nix
+++ b/overlay.nix
@@ -8,12 +8,12 @@ final: prev: {
});
riscvTests = final.pkgsCross.riscv64-embedded.stdenv.mkDerivation rec {
pname = "riscv-tests";
- version = "55bbcc8c06637a31cc01970881ba8072838a9121";
+ version = "f2f748ebb9cf8ea049103f85c4cbf7e8a2927b16";
src = final.fetchgit {
url = "https://github.com/riscv-software-src/riscv-tests.git";
rev = "${version}";
fetchSubmodules = true;
- sha256 = "sha256-TcIU+WFQxPqAG7lvfKPgHm4CnBpTkosqe+fYOxS+J7I=";
+ sha256 = "sha256-E3RfrP+PFIYy9c/pY04jYPxeGpnfgWwjV8iwL5+s+9w=";
};
enableParallelBuilding = true;
diff --git a/src/main/resources/META-INF/services/firrtl.options.RegisteredLibrary b/src/main/resources/META-INF/services/firrtl.options.RegisteredLibrary
deleted file mode 100644
index abfcceb0559..00000000000
--- a/src/main/resources/META-INF/services/firrtl.options.RegisteredLibrary
+++ /dev/null
@@ -1 +0,0 @@
-firrtl.passes.memlib.MemLibOptions
diff --git a/src/main/resources/vsrc/RoccBlackBox.v b/src/main/resources/vsrc/RoccBlackBox.v
index 5c0a0766c95..4588cd38def 100644
--- a/src/main/resources/vsrc/RoccBlackBox.v
+++ b/src/main/resources/vsrc/RoccBlackBox.v
@@ -15,153 +15,156 @@ module RoccBlackBox
fLen = 64,
FPConstants_FLAGS_SZ = 5)
( input clock,
- input reset,
- output rocc_cmd_ready,
- input rocc_cmd_valid,
- input [6:0] rocc_cmd_bits_inst_funct,
- input [4:0] rocc_cmd_bits_inst_rs2,
- input [4:0] rocc_cmd_bits_inst_rs1,
- input rocc_cmd_bits_inst_xd,
- input rocc_cmd_bits_inst_xs1,
- input rocc_cmd_bits_inst_xs2,
- input [4:0] rocc_cmd_bits_inst_rd,
- input [6:0] rocc_cmd_bits_inst_opcode,
- input [xLen-1:0] rocc_cmd_bits_rs1,
- input [xLen-1:0] rocc_cmd_bits_rs2,
- input rocc_cmd_bits_status_debug,
- input rocc_cmd_bits_status_cease,
- input rocc_cmd_bits_status_wfi,
- input [31:0] rocc_cmd_bits_status_isa,
- input [PRV_SZ-1:0] rocc_cmd_bits_status_dprv,
- input rocc_cmd_bits_status_dv,
- input [PRV_SZ-1:0] rocc_cmd_bits_status_prv,
- input rocc_cmd_bits_status_v,
- input rocc_cmd_bits_status_sd,
- input [22:0] rocc_cmd_bits_status_zero2,
- input rocc_cmd_bits_status_mpv,
- input rocc_cmd_bits_status_gva,
- input rocc_cmd_bits_status_mbe,
- input rocc_cmd_bits_status_sbe,
- input [1:0] rocc_cmd_bits_status_sxl,
- input [1:0] rocc_cmd_bits_status_uxl,
- input rocc_cmd_bits_status_sd_rv32,
- input [7:0] rocc_cmd_bits_status_zero1,
- input rocc_cmd_bits_status_tsr,
- input rocc_cmd_bits_status_tw,
- input rocc_cmd_bits_status_tvm,
- input rocc_cmd_bits_status_mxr,
- input rocc_cmd_bits_status_sum,
- input rocc_cmd_bits_status_mprv,
- input [1:0] rocc_cmd_bits_status_xs,
- input [1:0] rocc_cmd_bits_status_fs,
- input [1:0] rocc_cmd_bits_status_vs,
- input [1:0] rocc_cmd_bits_status_mpp,
- input [0:0] rocc_cmd_bits_status_spp,
- input rocc_cmd_bits_status_mpie,
- input rocc_cmd_bits_status_ube,
- input rocc_cmd_bits_status_spie,
- input rocc_cmd_bits_status_upie,
- input rocc_cmd_bits_status_mie,
- input rocc_cmd_bits_status_hie,
- input rocc_cmd_bits_status_sie,
- input rocc_cmd_bits_status_uie,
- input rocc_resp_ready,
- output rocc_resp_valid,
- output [4:0] rocc_resp_bits_rd,
- output [xLen-1:0] rocc_resp_bits_data,
- input rocc_mem_req_ready,
- output rocc_mem_req_valid,
- output [coreMaxAddrBits-1:0] rocc_mem_req_bits_addr,
- output [dcacheReqTagBits-1:0] rocc_mem_req_bits_tag,
- output [M_SZ-1:0] rocc_mem_req_bits_cmd,
+ input reset,
+ output rocc_cmd_ready,
+ input rocc_cmd_valid,
+ input [6:0] rocc_cmd_bits_inst_funct,
+ input [4:0] rocc_cmd_bits_inst_rs2,
+ input [4:0] rocc_cmd_bits_inst_rs1,
+ input rocc_cmd_bits_inst_xd,
+ input rocc_cmd_bits_inst_xs1,
+ input rocc_cmd_bits_inst_xs2,
+ input [4:0] rocc_cmd_bits_inst_rd,
+ input [6:0] rocc_cmd_bits_inst_opcode,
+ input [xLen-1:0] rocc_cmd_bits_rs1,
+ input [xLen-1:0] rocc_cmd_bits_rs2,
+ input rocc_cmd_bits_status_debug,
+ input rocc_cmd_bits_status_cease,
+ input rocc_cmd_bits_status_wfi,
+ input [31:0] rocc_cmd_bits_status_isa,
+ input [PRV_SZ-1:0] rocc_cmd_bits_status_dprv,
+ input rocc_cmd_bits_status_dv,
+ input [PRV_SZ-1:0] rocc_cmd_bits_status_prv,
+ input rocc_cmd_bits_status_v,
+ input rocc_cmd_bits_status_sd,
+ input [22:0] rocc_cmd_bits_status_zero2,
+ input rocc_cmd_bits_status_mpv,
+ input rocc_cmd_bits_status_gva,
+ input rocc_cmd_bits_status_mbe,
+ input rocc_cmd_bits_status_sbe,
+ input [1:0] rocc_cmd_bits_status_sxl,
+ input [1:0] rocc_cmd_bits_status_uxl,
+ input rocc_cmd_bits_status_sd_rv32,
+ input [7:0] rocc_cmd_bits_status_zero1,
+ input rocc_cmd_bits_status_tsr,
+ input rocc_cmd_bits_status_tw,
+ input rocc_cmd_bits_status_tvm,
+ input rocc_cmd_bits_status_mxr,
+ input rocc_cmd_bits_status_sum,
+ input rocc_cmd_bits_status_mprv,
+ input [1:0] rocc_cmd_bits_status_xs,
+ input [1:0] rocc_cmd_bits_status_fs,
+ input [1:0] rocc_cmd_bits_status_vs,
+ input [1:0] rocc_cmd_bits_status_mpp,
+ input [0:0] rocc_cmd_bits_status_spp,
+ input rocc_cmd_bits_status_mpie,
+ input rocc_cmd_bits_status_ube,
+ input rocc_cmd_bits_status_spie,
+ input rocc_cmd_bits_status_upie,
+ input rocc_cmd_bits_status_mie,
+ input rocc_cmd_bits_status_hie,
+ input rocc_cmd_bits_status_sie,
+ input rocc_cmd_bits_status_uie,
+ input rocc_resp_ready,
+ output rocc_resp_valid,
+ output [4:0] rocc_resp_bits_rd,
+ output [xLen-1:0] rocc_resp_bits_data,
+ input rocc_mem_req_ready,
+ output rocc_mem_req_valid,
+ output [coreMaxAddrBits-1:0] rocc_mem_req_bits_addr,
+ output [dcacheReqTagBits-1:0] rocc_mem_req_bits_tag,
+ output [M_SZ-1:0] rocc_mem_req_bits_cmd,
output [mem_req_bits_size_width-1:0] rocc_mem_req_bits_size,
- output rocc_mem_req_bits_signed,
- output rocc_mem_req_bits_phys,
- output rocc_mem_req_bits_no_alloc,
- output rocc_mem_req_bits_no_xcpt,
- output [1:0] rocc_mem_req_bits_dprv,
- output rocc_mem_req_bits_dv,
- output [coreDataBits-1:0] rocc_mem_req_bits_data,
- output [coreDataBytes-1:0] rocc_mem_req_bits_mask,
- output rocc_mem_s1_kill,
- output [coreDataBits-1:0] rocc_mem_s1_data_data,
- output [coreDataBytes-1:0] rocc_mem_s1_data_mask,
- input rocc_mem_s2_nack,
- input rocc_mem_s2_nack_cause_raw,
- output rocc_mem_s2_kill,
- input rocc_mem_s2_uncached,
- input [paddrBits-1:0] rocc_mem_s2_paddr,
- input [vaddrBitsExtended-1:0] rocc_mem_s2_gpa,
- input rocc_mem_s2_gpa_is_pte,
- input rocc_mem_resp_valid,
- input [coreMaxAddrBits-1:0] rocc_mem_resp_bits_addr,
- input [dcacheReqTagBits-1:0] rocc_mem_resp_bits_tag,
- input [M_SZ-1:0] rocc_mem_resp_bits_cmd,
- input [mem_req_bits_size_width-1:0] rocc_mem_resp_bits_size,
- input rocc_mem_resp_bits_signed,
- input [coreDataBits-1:0] rocc_mem_resp_bits_data,
- input [coreDataBytes-1:0] rocc_mem_resp_bits_mask,
- input rocc_mem_resp_bits_replay,
- input rocc_mem_resp_bits_has_data,
- input [coreDataBits-1:0] rocc_mem_resp_bits_data_word_bypass,
- input [coreDataBits-1:0] rocc_mem_resp_bits_data_raw,
- input [coreDataBits-1:0] rocc_mem_resp_bits_store_data,
- input [1:0] rocc_mem_resp_bits_dprv,
- input rocc_mem_resp_bits_dv,
- input rocc_mem_replay_next,
- input rocc_mem_s2_xcpt_ma_ld,
- input rocc_mem_s2_xcpt_ma_st,
- input rocc_mem_s2_xcpt_pf_ld,
- input rocc_mem_s2_xcpt_pf_st,
- input rocc_mem_s2_xcpt_gf_ld,
- input rocc_mem_s2_xcpt_gf_st,
- input rocc_mem_s2_xcpt_ae_ld,
- input rocc_mem_s2_xcpt_ae_st,
- input rocc_mem_ordered,
- input rocc_mem_perf_acquire,
- input rocc_mem_perf_release,
- input rocc_mem_perf_grant,
- input rocc_mem_perf_tlbMiss,
- input rocc_mem_perf_blocked,
- input rocc_mem_perf_canAcceptStoreThenLoad,
- input rocc_mem_perf_canAcceptStoreThenRMW,
- input rocc_mem_perf_canAcceptLoadThenLoad,
- input rocc_mem_perf_storeBufferEmptyAfterLoad,
- input rocc_mem_perf_storeBufferEmptyAfterStore,
- output rocc_mem_keep_clock_enabled,
- input rocc_mem_clock_enabled,
- output rocc_busy,
- output rocc_interrupt,
- input rocc_exception,
- input rocc_fpu_req_ready,
- output rocc_fpu_req_valid,
- output rocc_fpu_req_bits_ldst,
- output rocc_fpu_req_bits_wen,
- output rocc_fpu_req_bits_ren1,
- output rocc_fpu_req_bits_ren2,
- output rocc_fpu_req_bits_ren3,
- output rocc_fpu_req_bits_swap12,
- output rocc_fpu_req_bits_swap23,
- output [1:0] rocc_fpu_req_bits_typeTagIn,
- output [1:0] rocc_fpu_req_bits_typeTagOut,
- output rocc_fpu_req_bits_fromint,
- output rocc_fpu_req_bits_toint,
- output rocc_fpu_req_bits_fastpipe,
- output rocc_fpu_req_bits_fma,
- output rocc_fpu_req_bits_div,
- output rocc_fpu_req_bits_sqrt,
- output rocc_fpu_req_bits_wflags,
- output [FPConstants_RM_SZ-1:0] rocc_fpu_req_bits_rm,
- output [1:0] rocc_fpu_req_bits_fmaCmd,
- output [1:0] rocc_fpu_req_bits_typ,
- output [1:0] rocc_fpu_req_bits_fmt,
- output [fLen:0] rocc_fpu_req_bits_in1,
- output [fLen:0] rocc_fpu_req_bits_in2,
- output [fLen:0] rocc_fpu_req_bits_in3,
- output rocc_fpu_resp_ready,
- input rocc_fpu_resp_valid,
- input [fLen:0] rocc_fpu_resp_bits_data,
- input [FPConstants_FLAGS_SZ-1:0] rocc_fpu_resp_bits_exc );
+ output rocc_mem_req_bits_signed,
+ output rocc_mem_req_bits_phys,
+ output rocc_mem_req_bits_no_alloc,
+ output rocc_mem_req_bits_no_xcpt,
+ output rocc_mem_req_bits_no_resp,
+ output [1:0] rocc_mem_req_bits_dprv,
+ output rocc_mem_req_bits_dv,
+ output [coreDataBits-1:0] rocc_mem_req_bits_data,
+ output [coreDataBytes-1:0] rocc_mem_req_bits_mask,
+ output rocc_mem_s1_kill,
+ output [coreDataBits-1:0] rocc_mem_s1_data_data,
+ output [coreDataBytes-1:0] rocc_mem_s1_data_mask,
+ input rocc_mem_s2_nack,
+ input rocc_mem_s2_nack_cause_raw,
+ output rocc_mem_s2_kill,
+ input rocc_mem_s2_uncached,
+ input [paddrBits-1:0] rocc_mem_s2_paddr,
+ input [vaddrBitsExtended-1:0] rocc_mem_s2_gpa,
+ input rocc_mem_s2_gpa_is_pte,
+ input rocc_mem_resp_valid,
+ input [coreMaxAddrBits-1:0] rocc_mem_resp_bits_addr,
+ input [dcacheReqTagBits-1:0] rocc_mem_resp_bits_tag,
+ input [M_SZ-1:0] rocc_mem_resp_bits_cmd,
+ input [mem_req_bits_size_width-1:0] rocc_mem_resp_bits_size,
+ input rocc_mem_resp_bits_signed,
+ input [coreDataBits-1:0] rocc_mem_resp_bits_data,
+ input [coreDataBytes-1:0] rocc_mem_resp_bits_mask,
+ input rocc_mem_resp_bits_replay,
+ input rocc_mem_resp_bits_has_data,
+ input [coreDataBits-1:0] rocc_mem_resp_bits_data_word_bypass,
+ input [coreDataBits-1:0] rocc_mem_resp_bits_data_raw,
+ input [coreDataBits-1:0] rocc_mem_resp_bits_store_data,
+ input [1:0] rocc_mem_resp_bits_dprv,
+ input rocc_mem_resp_bits_dv,
+ input rocc_mem_replay_next,
+ input rocc_mem_s2_xcpt_ma_ld,
+ input rocc_mem_s2_xcpt_ma_st,
+ input rocc_mem_s2_xcpt_pf_ld,
+ input rocc_mem_s2_xcpt_pf_st,
+ input rocc_mem_s2_xcpt_gf_ld,
+ input rocc_mem_s2_xcpt_gf_st,
+ input rocc_mem_s2_xcpt_ae_ld,
+ input rocc_mem_s2_xcpt_ae_st,
+ input rocc_mem_ordered,
+ input rocc_mem_store_pending,
+ input rocc_mem_perf_acquire,
+ input rocc_mem_perf_release,
+ input rocc_mem_perf_grant,
+ input rocc_mem_perf_tlbMiss,
+ input rocc_mem_perf_blocked,
+ input rocc_mem_perf_canAcceptStoreThenLoad,
+ input rocc_mem_perf_canAcceptStoreThenRMW,
+ input rocc_mem_perf_canAcceptLoadThenLoad,
+ input rocc_mem_perf_storeBufferEmptyAfterLoad,
+ input rocc_mem_perf_storeBufferEmptyAfterStore,
+ output rocc_mem_keep_clock_enabled,
+ input rocc_mem_clock_enabled,
+ output rocc_busy,
+ output rocc_interrupt,
+ input rocc_exception,
+ input rocc_fpu_req_ready,
+ output rocc_fpu_req_valid,
+ output rocc_fpu_req_bits_ldst,
+ output rocc_fpu_req_bits_wen,
+ output rocc_fpu_req_bits_ren1,
+ output rocc_fpu_req_bits_ren2,
+ output rocc_fpu_req_bits_ren3,
+ output rocc_fpu_req_bits_swap12,
+ output rocc_fpu_req_bits_swap23,
+ output [1:0] rocc_fpu_req_bits_typeTagIn,
+ output [1:0] rocc_fpu_req_bits_typeTagOut,
+ output rocc_fpu_req_bits_fromint,
+ output rocc_fpu_req_bits_toint,
+ output rocc_fpu_req_bits_fastpipe,
+ output rocc_fpu_req_bits_fma,
+ output rocc_fpu_req_bits_div,
+ output rocc_fpu_req_bits_sqrt,
+ output rocc_fpu_req_bits_wflags,
+ output [FPConstants_RM_SZ-1:0] rocc_fpu_req_bits_rm,
+ output [1:0] rocc_fpu_req_bits_fmaCmd,
+ output [1:0] rocc_fpu_req_bits_typ,
+ output [1:0] rocc_fpu_req_bits_fmt,
+ output [fLen:0] rocc_fpu_req_bits_in1,
+ output [fLen:0] rocc_fpu_req_bits_in2,
+ output [fLen:0] rocc_fpu_req_bits_in3,
+ output rocc_fpu_req_bits_vec,
+ output rocc_fpu_resp_ready,
+ input rocc_fpu_resp_valid,
+ input [fLen:0] rocc_fpu_resp_bits_data,
+ input [FPConstants_FLAGS_SZ-1:0] rocc_fpu_resp_bits_exc );
assign rocc_cmd_ready = 1'b1;
diff --git a/src/main/scala/amba/ahb/AHBLite.scala b/src/main/scala/amba/ahb/AHBLite.scala
index 633b46fc594..7e80611690c 100644
--- a/src/main/scala/amba/ahb/AHBLite.scala
+++ b/src/main/scala/amba/ahb/AHBLite.scala
@@ -4,7 +4,7 @@ package freechips.rocketchip.amba.ahb
import chisel3._
import org.chipsalliance.cde.config.Parameters
-import freechips.rocketchip.diplomacy._
+import org.chipsalliance.diplomacy.lazymodule.{LazyModule, LazyModuleImp}
class AHBLite()(implicit p: Parameters) extends LazyModule {
val node = AHBMasterAdapterNode(
diff --git a/src/main/scala/amba/ahb/Nodes.scala b/src/main/scala/amba/ahb/Nodes.scala
index 461157407f1..33c33ccd213 100644
--- a/src/main/scala/amba/ahb/Nodes.scala
+++ b/src/main/scala/amba/ahb/Nodes.scala
@@ -4,8 +4,11 @@ package freechips.rocketchip.amba.ahb
import chisel3._
import chisel3.experimental.SourceInfo
+
import org.chipsalliance.cde.config.{Parameters, Field}
-import freechips.rocketchip.diplomacy._
+
+import org.chipsalliance.diplomacy.ValName
+import org.chipsalliance.diplomacy.nodes.{SimpleNodeImp, RenderedEdge, OutwardNode, InwardNode, SourceNode, SinkNode, IdentityNode, AdapterNode, MixedNexusNode, NexusNode}
case object AHBSlaveMonitorBuilder extends Field[AHBSlaveMonitorArgs => AHBSlaveMonitorBase]
diff --git a/src/main/scala/amba/ahb/Parameters.scala b/src/main/scala/amba/ahb/Parameters.scala
index 62c951604df..0039b928b7c 100644
--- a/src/main/scala/amba/ahb/Parameters.scala
+++ b/src/main/scala/amba/ahb/Parameters.scala
@@ -2,11 +2,17 @@
package freechips.rocketchip.amba.ahb
-import chisel3.util._
import chisel3.experimental.SourceInfo
+import chisel3.util._
+
import org.chipsalliance.cde.config.Parameters
-import freechips.rocketchip.diplomacy._
-import freechips.rocketchip.util._
+
+import org.chipsalliance.diplomacy.nodes.BaseNode
+
+import freechips.rocketchip.resources.{Resource, Device, ResourceAddress, ResourcePermissions}
+import freechips.rocketchip.diplomacy.{AddressSet, RegionType, TransferSizes}
+import freechips.rocketchip.util.{BundleField, BundleFieldBase, BundleKeyBase}
+
import scala.math.{max, min}
case class AHBSlaveParameters(
diff --git a/src/main/scala/amba/ahb/RegisterRouter.scala b/src/main/scala/amba/ahb/RegisterRouter.scala
index a8721aedf3e..e2619b66c8c 100644
--- a/src/main/scala/amba/ahb/RegisterRouter.scala
+++ b/src/main/scala/amba/ahb/RegisterRouter.scala
@@ -3,12 +3,18 @@
package freechips.rocketchip.amba.ahb
import chisel3._
-import chisel3.util._
+import chisel3.util.{log2Up, log2Ceil, Decoupled}
+
import org.chipsalliance.cde.config.Parameters
-import freechips.rocketchip.diplomacy._
-import freechips.rocketchip.regmapper._
+
+import org.chipsalliance.diplomacy.ValName
+import org.chipsalliance.diplomacy.nodes.{SinkNode}
+
+import freechips.rocketchip.diplomacy.{AddressSet, TransferSizes}
+import freechips.rocketchip.regmapper.{RegMapperParams, RegField, RegMapperInput, RegisterRouter, RegMapper}
import freechips.rocketchip.interrupts.{IntSourceNode, IntSourcePortSimple}
-import freechips.rocketchip.util._
+import freechips.rocketchip.util.MaskGen
+
import scala.math.min
case class AHBRegisterNode(address: AddressSet, concurrency: Int = 0, beatBytes: Int = 4, undefZero: Boolean = true, executable: Boolean = false)(implicit valName: ValName)
@@ -68,50 +74,6 @@ case class AHBRegisterNode(address: AddressSet, concurrency: Int = 0, beatBytes:
}
}
-// These convenience methods below combine to make it possible to create a AHB
-// register mapped device from a totally abstract register mapped device.
-
-@deprecated("Use HasAHBControlRegMap+HasInterruptSources traits in place of AHBRegisterRouter+AHBRegBundle+AHBRegModule", "rocket-chip 1.3")
-abstract class AHBRegisterRouterBase(address: AddressSet, interrupts: Int, concurrency: Int, beatBytes: Int, undefZero: Boolean, executable: Boolean)(implicit p: Parameters) extends LazyModule
-{
- val node = AHBRegisterNode(address, concurrency, beatBytes, undefZero, executable)
- val intnode = IntSourceNode(IntSourcePortSimple(num = interrupts))
-}
-
-@deprecated("AHBRegBundleArg is no longer necessary, use IO(...) to make any additional IOs", "rocket-chip 1.3")
-case class AHBRegBundleArg()(implicit val p: Parameters)
-
-@deprecated("AHBRegBundleBase is no longer necessary, use IO(...) to make any additional IOs", "rocket-chip 1.3")
-class AHBRegBundleBase(arg: AHBRegBundleArg) extends Bundle
-{
- implicit val p = arg.p
-}
-
-@deprecated("Use HasAHBControlRegMap+HasInterruptSources traits in place of AHBRegisterRouter+AHBRegBundle+AHBRegModule", "rocket-chip 1.3")
-class AHBRegBundle[P](val params: P, arg: AHBRegBundleArg) extends AHBRegBundleBase(arg)
-
-@deprecated("Use HasAHBControlRegMap+HasInterruptSources traits in place of AHBRegisterRouter+AHBRegBundle+AHBRegModule", "rocket-chip 1.3")
-class AHBRegModule[P, B <: AHBRegBundleBase](val params: P, bundleBuilder: => B, router: AHBRegisterRouterBase)
- extends LazyModuleImp(router) with HasRegMap
-{
- val io = IO(bundleBuilder)
- val interrupts = if (router.intnode.out.isEmpty) Vec(0, Bool()) else router.intnode.out(0)._1
- def regmap(mapping: RegField.Map*) = router.node.regmap(mapping:_*)
-}
-
-@deprecated("Use HasAHBControlRegMap+HasInterruptSources traits in place of AHBRegisterRouter+AHBRegBundle+AHBRegModule", "rocket-chip 1.3")
-class AHBRegisterRouter[B <: AHBRegBundleBase, M <: LazyModuleImp]
- (val base: BigInt, val interrupts: Int = 0, val size: BigInt = 4096, val concurrency: Int = 0, val beatBytes: Int = 4, undefZero: Boolean = true, executable: Boolean = false)
- (bundleBuilder: AHBRegBundleArg => B)
- (moduleBuilder: (=> B, AHBRegisterRouterBase) => M)(implicit p: Parameters)
- extends AHBRegisterRouterBase(AddressSet(base, size-1), interrupts, concurrency, beatBytes, undefZero, executable)
-{
- require (isPow2(size))
- // require (size >= 4096) ... not absolutely required, but highly recommended
-
- lazy val module = moduleBuilder(bundleBuilder(AHBRegBundleArg()), this)
-}
-
/** Mix this trait into a RegisterRouter to be able to attach its register map to an AXI4 bus */
trait HasAHBControlRegMap { this: RegisterRouter =>
// Externally, this node should be used to connect the register control port to a bus
diff --git a/src/main/scala/amba/ahb/SRAM.scala b/src/main/scala/amba/ahb/SRAM.scala
index 51c8cddad3e..a4a8bdeae3b 100644
--- a/src/main/scala/amba/ahb/SRAM.scala
+++ b/src/main/scala/amba/ahb/SRAM.scala
@@ -5,9 +5,12 @@ package freechips.rocketchip.amba.ahb
import chisel3._
import chisel3.util._
import org.chipsalliance.cde.config.Parameters
-import freechips.rocketchip.diplomacy._
-import freechips.rocketchip.util._
+import org.chipsalliance.diplomacy.lazymodule.{LazyModule, LazyModuleImp}
+
+import freechips.rocketchip.diplomacy.{AddressSet, RegionType, TransferSizes}
+import freechips.rocketchip.resources.{DiplomaticSRAM, HasJustOneSeqMem}
import freechips.rocketchip.tilelink.LFSRNoiseMaker
+import freechips.rocketchip.util.{MaskGen, DataToAugmentedData, SeqMemToAugmentedSeqMem, PlusArg}
class AHBRAM(
address: AddressSet,
diff --git a/src/main/scala/amba/ahb/Test.scala b/src/main/scala/amba/ahb/Test.scala
index bf28459454b..43a57977dcc 100644
--- a/src/main/scala/amba/ahb/Test.scala
+++ b/src/main/scala/amba/ahb/Test.scala
@@ -3,12 +3,16 @@
package freechips.rocketchip.amba.ahb
import chisel3._
+
import org.chipsalliance.cde.config.Parameters
+
+import org.chipsalliance.diplomacy.lazymodule.{LazyModule, LazyModuleImp, SimpleLazyModule}
+
import freechips.rocketchip.devices.tilelink.TLTestRAM
-import freechips.rocketchip.diplomacy._
+import freechips.rocketchip.diplomacy.{AddressSet, BufferParams}
import freechips.rocketchip.regmapper.{RRTest0, RRTest1}
-import freechips.rocketchip.tilelink._
-import freechips.rocketchip.unittest._
+import freechips.rocketchip.tilelink.{TLFuzzer, TLRAMModel, TLToAHB, TLDelayer, TLBuffer, TLErrorEvaluator, TLFragmenter}
+import freechips.rocketchip.unittest.{UnitTestModule, UnitTest}
class AHBRRTest0(address: BigInt)(implicit p: Parameters)
extends RRTest0(address)
diff --git a/src/main/scala/amba/ahb/ToTL.scala b/src/main/scala/amba/ahb/ToTL.scala
index f08feb167bf..e34d7c262ba 100644
--- a/src/main/scala/amba/ahb/ToTL.scala
+++ b/src/main/scala/amba/ahb/ToTL.scala
@@ -4,11 +4,17 @@ package freechips.rocketchip.amba.ahb
import chisel3._
import chisel3.util._
-import freechips.rocketchip.amba._
+
import org.chipsalliance.cde.config.Parameters
-import freechips.rocketchip.diplomacy._
-import freechips.rocketchip.tilelink._
-import freechips.rocketchip.util._
+
+import org.chipsalliance.diplomacy.ValName
+import org.chipsalliance.diplomacy.nodes.{MixedAdapterNode}
+import org.chipsalliance.diplomacy.lazymodule.{LazyModule, LazyModuleImp}
+
+import freechips.rocketchip.amba.{AMBAProtField, AMBAProt}
+import freechips.rocketchip.diplomacy.TransferSizes
+import freechips.rocketchip.tilelink.{TLImp, TLMasterPortParameters, TLMessages, TLMasterParameters, TLMasterToSlaveTransferSizes}
+import freechips.rocketchip.util.{BundleMap, MaskGen, DataToAugmentedData}
case class AHBToTLNode()(implicit valName: ValName) extends MixedAdapterNode(AHBImpSlave, TLImp)(
dFn = { case mp =>
diff --git a/src/main/scala/amba/ahb/Xbar.scala b/src/main/scala/amba/ahb/Xbar.scala
index 2db7d5cd187..d685ac1bed9 100644
--- a/src/main/scala/amba/ahb/Xbar.scala
+++ b/src/main/scala/amba/ahb/Xbar.scala
@@ -3,10 +3,14 @@
package freechips.rocketchip.amba.ahb
import chisel3._
-import chisel3.util._
+import chisel3.util.Mux1H
+
import org.chipsalliance.cde.config.Parameters
-import freechips.rocketchip.diplomacy._
-import freechips.rocketchip.util._
+import org.chipsalliance.diplomacy.lazymodule.{LazyModule, LazyModuleImp}
+
+import freechips.rocketchip.diplomacy.AddressDecoder
+import freechips.rocketchip.util.BundleField
+
class AHBFanout()(implicit p: Parameters) extends LazyModule {
val node = new AHBFanoutNode(
diff --git a/src/main/scala/amba/ahb/package.scala b/src/main/scala/amba/ahb/package.scala
index 8477adb2fbe..ffcf196951a 100644
--- a/src/main/scala/amba/ahb/package.scala
+++ b/src/main/scala/amba/ahb/package.scala
@@ -2,7 +2,7 @@
package freechips.rocketchip.amba
-import freechips.rocketchip.diplomacy._
+import org.chipsalliance.diplomacy.nodes.{InwardNodeHandle, OutwardNodeHandle, SimpleNodeHandle}
package object ahb
{
diff --git a/src/main/scala/amba/apb/Nodes.scala b/src/main/scala/amba/apb/Nodes.scala
index 183a058e8e8..e2dd9307c74 100644
--- a/src/main/scala/amba/apb/Nodes.scala
+++ b/src/main/scala/amba/apb/Nodes.scala
@@ -4,8 +4,11 @@ package freechips.rocketchip.amba.apb
import chisel3._
import chisel3.experimental.SourceInfo
+
import org.chipsalliance.cde.config.{Parameters, Field}
-import freechips.rocketchip.diplomacy._
+
+import org.chipsalliance.diplomacy.ValName
+import org.chipsalliance.diplomacy.nodes.{SimpleNodeImp,RenderedEdge, InwardNode, OutwardNode, SourceNode, SinkNode, NexusNode, IdentityNode}
case object APBMonitorBuilder extends Field[APBMonitorArgs => APBMonitorBase]
diff --git a/src/main/scala/amba/apb/Parameters.scala b/src/main/scala/amba/apb/Parameters.scala
index 5c07d827f65..f39c8b03fef 100644
--- a/src/main/scala/amba/apb/Parameters.scala
+++ b/src/main/scala/amba/apb/Parameters.scala
@@ -2,11 +2,17 @@
package freechips.rocketchip.amba.apb
-import chisel3.util._
+import chisel3.util.{isPow2, log2Up}
import chisel3.experimental.SourceInfo
+
import org.chipsalliance.cde.config.Parameters
-import freechips.rocketchip.diplomacy._
-import freechips.rocketchip.util._
+
+import org.chipsalliance.diplomacy.nodes.BaseNode
+
+import freechips.rocketchip.diplomacy.{AddressSet, RegionType}
+import freechips.rocketchip.resources.{Resource, Device, ResourceAddress, ResourcePermissions}
+import freechips.rocketchip.util.{BundleField, BundleKeyBase, BundleFieldBase}
+
import scala.math.max
case class APBSlaveParameters(
diff --git a/src/main/scala/amba/apb/RegisterRouter.scala b/src/main/scala/amba/apb/RegisterRouter.scala
index 9000399570c..07b62a5c67b 100644
--- a/src/main/scala/amba/apb/RegisterRouter.scala
+++ b/src/main/scala/amba/apb/RegisterRouter.scala
@@ -3,10 +3,15 @@
package freechips.rocketchip.amba.apb
import chisel3._
-import chisel3.util._
+import chisel3.util.{Decoupled, log2Up, log2Ceil}
+
import org.chipsalliance.cde.config.Parameters
-import freechips.rocketchip.diplomacy._
-import freechips.rocketchip.regmapper._
+
+import org.chipsalliance.diplomacy.ValName
+import org.chipsalliance.diplomacy.nodes.SinkNode
+
+import freechips.rocketchip.diplomacy.AddressSet
+import freechips.rocketchip.regmapper.{RegField, RegMapperParams, RegMapperInput, RegMapper, RegisterRouter}
import freechips.rocketchip.interrupts.{IntSourceNode, IntSourcePortSimple}
case class APBRegisterNode(address: AddressSet, concurrency: Int = 0, beatBytes: Int = 4, undefZero: Boolean = true, executable: Boolean = false)(implicit valName: ValName)
@@ -49,50 +54,6 @@ case class APBRegisterNode(address: AddressSet, concurrency: Int = 0, beatBytes:
}
}
-// These convenience methods below combine to make it possible to create a APB
-// register mapped device from a totally abstract register mapped device.
-
-@deprecated("Use HasAPBControlRegMap+HasInterruptSources traits in place of APBRegisterRouter+APBRegBundle+APBRegModule", "rocket-chip 1.3")
-abstract class APBRegisterRouterBase(address: AddressSet, interrupts: Int, concurrency: Int, beatBytes: Int, undefZero: Boolean, executable: Boolean)(implicit p: Parameters) extends LazyModule
-{
- val node = APBRegisterNode(address, concurrency, beatBytes, undefZero, executable)
- val intnode = IntSourceNode(IntSourcePortSimple(num = interrupts))
-}
-
-@deprecated("APBRegBundleArg is no longer necessary, use IO(...) to make any additional IOs", "rocket-chip 1.3")
-case class APBRegBundleArg()(implicit val p: Parameters)
-
-@deprecated("AXI4RegBundleBase is no longer necessary, use IO(...) to make any additional IOs", "rocket-chip 1.3")
-class APBRegBundleBase(arg: APBRegBundleArg) extends Bundle
-{
- implicit val p = arg.p
-}
-
-@deprecated("Use HasAPBControlRegMap+HasInterruptSources traits in place of APBRegisterRouter+APBRegBundle+APBRegModule", "rocket-chip 1.3")
-class APBRegBundle[P](val params: P, arg: APBRegBundleArg) extends APBRegBundleBase(arg)
-
-@deprecated("Use HasAPBControlRegMap+HasInterruptSources traits in place of APBRegisterRouter+APBRegBundle+APBRegModule", "rocket-chip 1.3")
-class APBRegModule[P, B <: APBRegBundleBase](val params: P, bundleBuilder: => B, router: APBRegisterRouterBase)
- extends LazyModuleImp(router) with HasRegMap
-{
- val io = IO(bundleBuilder)
- val interrupts = if (router.intnode.out.isEmpty) Vec(0, Bool()) else router.intnode.out(0)._1
- def regmap(mapping: RegField.Map*) = router.node.regmap(mapping:_*)
-}
-
-@deprecated("Use HasAPBControlRegMap+HasInterruptSources traits in place of APBRegisterRouter+APBRegBundle+APBRegModule", "rocket-chip 1.3")
-class APBRegisterRouter[B <: APBRegBundleBase, M <: LazyModuleImp]
- (val base: BigInt, val interrupts: Int = 0, val size: BigInt = 4096, val concurrency: Int = 0, val beatBytes: Int = 4, undefZero: Boolean = true, executable: Boolean = false)
- (bundleBuilder: APBRegBundleArg => B)
- (moduleBuilder: (=> B, APBRegisterRouterBase) => M)(implicit p: Parameters)
- extends APBRegisterRouterBase(AddressSet(base, size-1), interrupts, concurrency, beatBytes, undefZero, executable)
-{
- require (isPow2(size))
- // require (size >= 4096) ... not absolutely required, but highly recommended
-
- lazy val module = moduleBuilder(bundleBuilder(APBRegBundleArg()), this)
-}
-
/** Mix this trait into a RegisterRouter to be able to attach its register map to an AXI4 bus */
trait HasAPBControlRegMap { this: RegisterRouter =>
// Externally, this node should be used to connect the register control port to a bus
diff --git a/src/main/scala/amba/apb/SRAM.scala b/src/main/scala/amba/apb/SRAM.scala
index 1e8325e2d5f..8c5a9c27487 100644
--- a/src/main/scala/amba/apb/SRAM.scala
+++ b/src/main/scala/amba/apb/SRAM.scala
@@ -3,11 +3,16 @@
package freechips.rocketchip.amba.apb
import chisel3._
-import chisel3.util._
+import chisel3.util.{Cat, log2Ceil, RegEnable}
+
import org.chipsalliance.cde.config.Parameters
-import freechips.rocketchip.diplomacy._
-import freechips.rocketchip.util._
+
+import org.chipsalliance.diplomacy.lazymodule.{LazyModule, LazyModuleImp}
+
+import freechips.rocketchip.diplomacy.{AddressSet, RegionType}
+import freechips.rocketchip.resources.{DiplomaticSRAM, HasJustOneSeqMem}
import freechips.rocketchip.tilelink.LFSRNoiseMaker
+import freechips.rocketchip.util.SeqMemToAugmentedSeqMem
class APBRAM(
address: AddressSet,
diff --git a/src/main/scala/amba/apb/Test.scala b/src/main/scala/amba/apb/Test.scala
index 4b8d48c4b9a..0c907079b89 100644
--- a/src/main/scala/amba/apb/Test.scala
+++ b/src/main/scala/amba/apb/Test.scala
@@ -3,10 +3,14 @@
package freechips.rocketchip.amba.apb
import chisel3._
+
import org.chipsalliance.cde.config.Parameters
-import freechips.rocketchip.diplomacy._
+
+import org.chipsalliance.diplomacy.lazymodule.{LazyModule, LazyModuleImp}
+
+import freechips.rocketchip.diplomacy.{BufferParams, AddressSet}
import freechips.rocketchip.regmapper.{RRTest0, RRTest1}
-import freechips.rocketchip.tilelink._
+import freechips.rocketchip.tilelink.{TLFuzzer, TLRAMModel, TLToAPB, TLDelayer, TLBuffer, TLFragmenter}
import freechips.rocketchip.unittest._
class APBRRTest0(address: BigInt)(implicit p: Parameters)
diff --git a/src/main/scala/amba/apb/ToTL.scala b/src/main/scala/amba/apb/ToTL.scala
index 48511d13436..39d01ab5515 100644
--- a/src/main/scala/amba/apb/ToTL.scala
+++ b/src/main/scala/amba/apb/ToTL.scala
@@ -4,11 +4,16 @@ package freechips.rocketchip.amba.apb
import chisel3._
import chisel3.util._
-import freechips.rocketchip.amba._
+
import org.chipsalliance.cde.config.Parameters
-import freechips.rocketchip.diplomacy._
-import freechips.rocketchip.tilelink._
-import freechips.rocketchip.util._
+
+import org.chipsalliance.diplomacy.ValName
+import org.chipsalliance.diplomacy.nodes.{MixedAdapterNode}
+import org.chipsalliance.diplomacy.lazymodule.{LazyModule, LazyModuleImp}
+
+import freechips.rocketchip.amba.{AMBAProt, AMBAProtField}
+import freechips.rocketchip.diplomacy.TransferSizes
+import freechips.rocketchip.tilelink.{TLImp, TLMessages, TLMasterPortParameters, TLMasterParameters}
case class APBToTLNode()(implicit valName: ValName) extends MixedAdapterNode(APBImp, TLImp)(
dFn = { mp =>
@@ -53,7 +58,7 @@ class APBToTL()(implicit p: Parameters) extends LazyModule
val beat = TransferSizes(beatBytes, beatBytes)
//TODO: The double negative here is to work around Chisel's broken implementation of widening ~x.
- val aligned_addr = ~in.paddr
+ val aligned_addr = ~(~in.paddr | (beatBytes-1).U)
require(beatBytes == in.params.dataBits/8,
s"TL beatBytes(${beatBytes}) doesn't match expected APB data width(${in.params.dataBits})")
val data_size = (log2Ceil(beatBytes)).U
diff --git a/src/main/scala/amba/apb/Xbar.scala b/src/main/scala/amba/apb/Xbar.scala
index 849edaa5f19..3f50fbb4ea1 100644
--- a/src/main/scala/amba/apb/Xbar.scala
+++ b/src/main/scala/amba/apb/Xbar.scala
@@ -3,10 +3,14 @@
package freechips.rocketchip.amba.apb
import chisel3._
-import chisel3.util._
+import chisel3.util.Mux1H
+
import org.chipsalliance.cde.config.Parameters
-import freechips.rocketchip.diplomacy._
-import freechips.rocketchip.util._
+
+import org.chipsalliance.diplomacy.lazymodule.{LazyModule, LazyModuleImp}
+
+import freechips.rocketchip.diplomacy.AddressDecoder
+import freechips.rocketchip.util.BundleField
class APBFanout()(implicit p: Parameters) extends LazyModule {
val node = new APBNexusNode(
diff --git a/src/main/scala/amba/apb/package.scala b/src/main/scala/amba/apb/package.scala
index f5acbf903d9..872fd22be23 100644
--- a/src/main/scala/amba/apb/package.scala
+++ b/src/main/scala/amba/apb/package.scala
@@ -2,7 +2,7 @@
package freechips.rocketchip.amba
-import freechips.rocketchip.diplomacy._
+import org.chipsalliance.diplomacy.nodes.{InwardNodeHandle, OutwardNodeHandle, SimpleNodeHandle}
package object apb
{
diff --git a/src/main/scala/amba/axi4/AsyncCrossing.scala b/src/main/scala/amba/axi4/AsyncCrossing.scala
index 3e086738ee4..b9303e5c108 100644
--- a/src/main/scala/amba/axi4/AsyncCrossing.scala
+++ b/src/main/scala/amba/axi4/AsyncCrossing.scala
@@ -3,11 +3,17 @@
package freechips.rocketchip.amba.axi4
import chisel3._
+
import org.chipsalliance.cde.config.Parameters
-import freechips.rocketchip.diplomacy._
-import freechips.rocketchip.tilelink._
+
+import org.chipsalliance.diplomacy.nodes.{NodeHandle}
+import org.chipsalliance.diplomacy.lazymodule.{LazyModule, LazyModuleImp}
+
+import freechips.rocketchip.diplomacy.{AddressSet}
+import freechips.rocketchip.prci.{AsynchronousCrossing}
+import freechips.rocketchip.tilelink.{TLRAMModel, TLFuzzer, TLToAXI4}
import freechips.rocketchip.subsystem.CrossingWrapper
-import freechips.rocketchip.util._
+import freechips.rocketchip.util.{ToAsyncBundle, FromAsyncBundle, AsyncQueueParams, Pow2ClockDivider}
/**
* Source(Master) side for AXI4 crossing clock domain
diff --git a/src/main/scala/amba/axi4/Buffer.scala b/src/main/scala/amba/axi4/Buffer.scala
index 71c3fdff30d..2b768e87ca5 100644
--- a/src/main/scala/amba/axi4/Buffer.scala
+++ b/src/main/scala/amba/axi4/Buffer.scala
@@ -4,8 +4,13 @@ package freechips.rocketchip.amba.axi4
import chisel3._
import chisel3.util.{Queue, IrrevocableIO}
+
import org.chipsalliance.cde.config.Parameters
-import freechips.rocketchip.diplomacy._
+
+import org.chipsalliance.diplomacy.lazymodule.{LazyModule, LazyModuleImp}
+
+import freechips.rocketchip.diplomacy.BufferParams
+
import scala.math.min
/**
diff --git a/src/main/scala/amba/axi4/Credited.scala b/src/main/scala/amba/axi4/Credited.scala
index e2a0d59776d..3dbea790f8b 100644
--- a/src/main/scala/amba/axi4/Credited.scala
+++ b/src/main/scala/amba/axi4/Credited.scala
@@ -3,10 +3,15 @@
package freechips.rocketchip.amba.axi4
import chisel3._
+
import org.chipsalliance.cde.config.Parameters
-import freechips.rocketchip.diplomacy._
-import freechips.rocketchip.tilelink._
+
+import org.chipsalliance.diplomacy.lazymodule.{LazyModule, LazyModuleImp}
+
+import freechips.rocketchip.diplomacy.{AddressSet}
+import freechips.rocketchip.prci.{CreditedCrossing}
import freechips.rocketchip.subsystem.CrossingWrapper
+import freechips.rocketchip.tilelink._
import freechips.rocketchip.util._
class AXI4CreditedBuffer(delay: AXI4CreditedDelay)(implicit p: Parameters) extends LazyModule
diff --git a/src/main/scala/amba/axi4/CrossingHelper.scala b/src/main/scala/amba/axi4/CrossingHelper.scala
index ebeb9dbb1e0..aaa1a372304 100644
--- a/src/main/scala/amba/axi4/CrossingHelper.scala
+++ b/src/main/scala/amba/axi4/CrossingHelper.scala
@@ -3,8 +3,9 @@
package freechips.rocketchip.amba.axi4
import org.chipsalliance.cde.config.Parameters
-import freechips.rocketchip.diplomacy._
-import freechips.rocketchip.prci.{ResetCrossingType, NoResetCrossing, StretchedResetCrossing}
+import org.chipsalliance.diplomacy.lazymodule.{LazyScope}
+
+import freechips.rocketchip.prci.{ResetCrossingType, NoResetCrossing, StretchedResetCrossing, CrossingType, ClockCrossingType, NoCrossing, AsynchronousCrossing, RationalCrossing, SynchronousCrossing, CreditedCrossing}
trait AXI4OutwardCrossingHelper {
type HelperCrossingType <: CrossingType
diff --git a/src/main/scala/amba/axi4/Deinterleaver.scala b/src/main/scala/amba/axi4/Deinterleaver.scala
index 27f99823a5e..461507a5e0c 100644
--- a/src/main/scala/amba/axi4/Deinterleaver.scala
+++ b/src/main/scala/amba/axi4/Deinterleaver.scala
@@ -5,8 +5,12 @@ package freechips.rocketchip.amba.axi4
import chisel3._
import chisel3.util.{Cat, isPow2, log2Ceil, ReadyValidIO,
log2Up, OHToUInt, Queue, QueueIO, UIntToOH}
+
import org.chipsalliance.cde.config.Parameters
-import freechips.rocketchip.diplomacy._
+
+import org.chipsalliance.diplomacy.lazymodule.{LazyModule, LazyModuleImp}
+
+import freechips.rocketchip.diplomacy.{BufferParams, TransferSizes}
import freechips.rocketchip.util.leftOR
/** This adapter deinterleaves read responses on the R channel.
diff --git a/src/main/scala/amba/axi4/Delayer.scala b/src/main/scala/amba/axi4/Delayer.scala
index 37a8297abbb..58ceb88b7f9 100644
--- a/src/main/scala/amba/axi4/Delayer.scala
+++ b/src/main/scala/amba/axi4/Delayer.scala
@@ -3,9 +3,12 @@
package freechips.rocketchip.amba.axi4
import chisel3._
-import chisel3.util._
+import chisel3.util.IrrevocableIO
+
import org.chipsalliance.cde.config.Parameters
-import freechips.rocketchip.diplomacy._
+
+import org.chipsalliance.diplomacy.lazymodule.{LazyModule, LazyModuleImp}
+
import freechips.rocketchip.tilelink.LFSRNoiseMaker
/**
diff --git a/src/main/scala/amba/axi4/Filter.scala b/src/main/scala/amba/axi4/Filter.scala
index 77833e2594d..9093aa05448 100644
--- a/src/main/scala/amba/axi4/Filter.scala
+++ b/src/main/scala/amba/axi4/Filter.scala
@@ -2,8 +2,11 @@
package freechips.rocketchip.amba.axi4
-import org.chipsalliance.cde.config._
-import freechips.rocketchip.diplomacy._
+import org.chipsalliance.cde.config.Parameters
+
+import org.chipsalliance.diplomacy.lazymodule.{LazyModule, LazyModuleImp}
+
+import freechips.rocketchip.diplomacy.{AddressSet, TransferSizes}
class AXI4Filter(
Sfilter: AXI4SlaveParameters => Option[AXI4SlaveParameters] = AXI4Filter.Sidentity,
diff --git a/src/main/scala/amba/axi4/Fragmenter.scala b/src/main/scala/amba/axi4/Fragmenter.scala
index 60ec2dc5597..85505374088 100644
--- a/src/main/scala/amba/axi4/Fragmenter.scala
+++ b/src/main/scala/amba/axi4/Fragmenter.scala
@@ -3,10 +3,14 @@
package freechips.rocketchip.amba.axi4
import chisel3._
-import chisel3.util._
+import chisel3.util.{Mux1H, Queue, IrrevocableIO, log2Ceil, UIntToOH}
+
import org.chipsalliance.cde.config.Parameters
-import freechips.rocketchip.diplomacy._
-import freechips.rocketchip.util._
+
+import org.chipsalliance.diplomacy.lazymodule.{LazyModule, LazyModuleImp}
+
+import freechips.rocketchip.diplomacy.{AddressDecoder, AddressSet, TransferSizes}
+import freechips.rocketchip.util.{ControlKey, SimpleBundleField, rightOR, leftOR, OH1ToOH, UIntToOH1}
case object AXI4FragLast extends ControlKey[Bool]("real_last")
case class AXI4FragLastField() extends SimpleBundleField(AXI4FragLast)(Output(Bool()), false.B)
diff --git a/src/main/scala/amba/axi4/IdIndexer.scala b/src/main/scala/amba/axi4/IdIndexer.scala
index 49cb9d92974..4687d5dc0f8 100644
--- a/src/main/scala/amba/axi4/IdIndexer.scala
+++ b/src/main/scala/amba/axi4/IdIndexer.scala
@@ -3,11 +3,15 @@
package freechips.rocketchip.amba.axi4
import chisel3._
-import org.chipsalliance.cde.config.Parameters
-import freechips.rocketchip.diplomacy._
-import freechips.rocketchip.util._
import chisel3.util.{log2Ceil, Cat}
+import org.chipsalliance.cde.config.Parameters
+
+import org.chipsalliance.diplomacy.lazymodule.{LazyModule, LazyModuleImp}
+
+import freechips.rocketchip.diplomacy.IdRange
+import freechips.rocketchip.util.{ControlKey, SimpleBundleField}
+
case object AXI4ExtraId extends ControlKey[UInt]("extra_id")
case class AXI4ExtraIdField(width: Int) extends SimpleBundleField(AXI4ExtraId)(Output(UInt(width.W)), 0.U)
diff --git a/src/main/scala/amba/axi4/Nodes.scala b/src/main/scala/amba/axi4/Nodes.scala
index 8fcf58066d9..da53aa92ea6 100644
--- a/src/main/scala/amba/axi4/Nodes.scala
+++ b/src/main/scala/amba/axi4/Nodes.scala
@@ -4,8 +4,12 @@ package freechips.rocketchip.amba.axi4
import chisel3._
import chisel3.experimental.SourceInfo
+
import org.chipsalliance.cde.config.{Parameters, Field}
-import freechips.rocketchip.diplomacy._
+
+import org.chipsalliance.diplomacy.ValName
+import org.chipsalliance.diplomacy.nodes.{SimpleNodeImp, RenderedEdge, OutwardNode, InwardNode, SourceNode, SinkNode, NexusNode, AdapterNode, IdentityNode, MixedAdapterNode}
+
import freechips.rocketchip.util.AsyncQueueParams
case object AXI4MonitorBuilder extends Field[AXI4MonitorArgs => AXI4MonitorBase]
diff --git a/src/main/scala/amba/axi4/Parameters.scala b/src/main/scala/amba/axi4/Parameters.scala
index b059fb1927e..088c226d825 100644
--- a/src/main/scala/amba/axi4/Parameters.scala
+++ b/src/main/scala/amba/axi4/Parameters.scala
@@ -3,11 +3,17 @@
package freechips.rocketchip.amba.axi4
import chisel3.experimental.SourceInfo
+import chisel3.util.{isPow2, log2Up}
+
import org.chipsalliance.cde.config.Parameters
-import freechips.rocketchip.diplomacy._
-import freechips.rocketchip.util._
+
+import org.chipsalliance.diplomacy.nodes.BaseNode
+
+import freechips.rocketchip.diplomacy.{AddressSet, RegionType, TransferSizes, IdRange, BufferParams, IdMap, IdMapEntry, DirectedBuffers}
+import freechips.rocketchip.resources.{Resource, Device, ResourceAddress, ResourcePermissions}
+import freechips.rocketchip.util.{BundleField, BundleFieldBase, BundleKeyBase, AsyncQueueParams, CreditedDelay}
+
import scala.math.max
-import chisel3.util.{isPow2, log2Up}
/**
* Parameters for AXI4 slave
diff --git a/src/main/scala/amba/axi4/RegisterRouter.scala b/src/main/scala/amba/axi4/RegisterRouter.scala
index 827c64e4952..be48fa2eaf9 100644
--- a/src/main/scala/amba/axi4/RegisterRouter.scala
+++ b/src/main/scala/amba/axi4/RegisterRouter.scala
@@ -3,10 +3,16 @@
package freechips.rocketchip.amba.axi4
import chisel3._
-import chisel3.util._
+import chisel3.util.{Decoupled, Queue, log2Ceil, log2Up}
+
import org.chipsalliance.cde.config.Parameters
-import freechips.rocketchip.diplomacy._
-import freechips.rocketchip.regmapper._
+
+import org.chipsalliance.diplomacy.ValName
+import org.chipsalliance.diplomacy.nodes.{SinkNode}
+
+import freechips.rocketchip.diplomacy.{AddressSet, TransferSizes}
+import freechips.rocketchip.prci.{NoCrossing}
+import freechips.rocketchip.regmapper.{RegField, RegMapper, RegMapperInput, RegMapperParams, RegisterRouter}
import freechips.rocketchip.interrupts.{IntSourceNode, IntSourcePortSimple}
import freechips.rocketchip.util._
@@ -83,50 +89,6 @@ case class AXI4RegisterNode(address: AddressSet, concurrency: Int = 0, beatBytes
}
}
-// These convenience methods below combine to make it possible to create a AXI4
-// register mapped device from a totally abstract register mapped device.
-
-@deprecated("Use HasAXI4ControlRegMap+HasInterruptSources traits in place of AXI4RegisterRouter+AXI4RegBundle+AXI4RegModule", "rocket-chip 1.3")
-abstract class AXI4RegisterRouterBase(address: AddressSet, interrupts: Int, concurrency: Int, beatBytes: Int, undefZero: Boolean, executable: Boolean)(implicit p: Parameters) extends LazyModule
-{
- val node = AXI4RegisterNode(address, concurrency, beatBytes, undefZero, executable)
- val intnode = IntSourceNode(IntSourcePortSimple(num = interrupts))
-}
-
-@deprecated("AXI4RegBundleArg is no longer necessary, use IO(...) to make any additional IOs", "rocket-chip 1.3")
-case class AXI4RegBundleArg()(implicit val p: Parameters)
-
-@deprecated("AXI4RegBundleBase is no longer necessary, use IO(...) to make any additional IOs", "rocket-chip 1.3")
-class AXI4RegBundleBase(arg: AXI4RegBundleArg) extends Bundle
-{
- implicit val p = arg.p
-}
-
-@deprecated("Use HasAXI4ControlRegMap+HasInterruptSources traits in place of AXI4RegisterRouter+AXI4RegBundle+AXI4RegModule", "rocket-chip 1.3")
-class AXI4RegBundle[P](val params: P, arg: AXI4RegBundleArg) extends AXI4RegBundleBase(arg)
-
-@deprecated("Use HasAXI4ControlRegMap+HasInterruptSources traits in place of AXI4RegisterRouter+AXI4RegBundle+AXI4RegModule", "rocket-chip 1.3")
-class AXI4RegModule[P, B <: AXI4RegBundleBase](val params: P, bundleBuilder: => B, router: AXI4RegisterRouterBase)
- extends LazyModuleImp(router) with HasRegMap
-{
- val io = IO(bundleBuilder)
- val interrupts = if (router.intnode.out.isEmpty) Vec(0, Bool()) else router.intnode.out(0)._1
- def regmap(mapping: RegField.Map*) = router.node.regmap(mapping:_*)
-}
-
-@deprecated("Use HasAXI4ControlRegMap+HasInterruptSources traits in place of AXI4RegisterRouter+AXI4RegBundle+AXI4RegModule", "rocket-chip 1.3")
-class AXI4RegisterRouter[B <: AXI4RegBundleBase, M <: LazyModuleImp]
- (val base: BigInt, val interrupts: Int = 0, val size: BigInt = 4096, val concurrency: Int = 0, val beatBytes: Int = 4, undefZero: Boolean = true, executable: Boolean = false)
- (bundleBuilder: AXI4RegBundleArg => B)
- (moduleBuilder: (=> B, AXI4RegisterRouterBase) => M)(implicit p: Parameters)
- extends AXI4RegisterRouterBase(AddressSet(base, size-1), interrupts, concurrency, beatBytes, undefZero, executable)
-{
- require (isPow2(size))
- // require (size >= 4096) ... not absolutely required, but highly recommended
-
- lazy val module = moduleBuilder(bundleBuilder(AXI4RegBundleArg()), this)
-}
-
/** Mix this trait into a RegisterRouter to be able to attach its register map to an AXI4 bus */
trait HasAXI4ControlRegMap { this: RegisterRouter =>
protected val controlNode = AXI4RegisterNode(
diff --git a/src/main/scala/amba/axi4/SRAM.scala b/src/main/scala/amba/axi4/SRAM.scala
index 791634deacf..f4838b73ab0 100644
--- a/src/main/scala/amba/axi4/SRAM.scala
+++ b/src/main/scala/amba/axi4/SRAM.scala
@@ -3,11 +3,16 @@
package freechips.rocketchip.amba.axi4
import chisel3._
-import chisel3.util._
+import chisel3.util.{Cat, log2Ceil}
+
import org.chipsalliance.cde.config.Parameters
-import freechips.rocketchip.diplomacy._
-import freechips.rocketchip.util._
-import freechips.rocketchip.amba._
+
+import org.chipsalliance.diplomacy.lazymodule.{LazyModule, LazyModuleImp}
+
+import freechips.rocketchip.amba.AMBACorrupt
+import freechips.rocketchip.diplomacy.{AddressSet, RegionType, TransferSizes}
+import freechips.rocketchip.resources.{DiplomaticSRAM, HasJustOneSeqMem}
+import freechips.rocketchip.util.{BundleMap, SeqMemToAugmentedSeqMem}
/**
* AXI4 slave device to provide a RAM storage
diff --git a/src/main/scala/amba/axi4/Test.scala b/src/main/scala/amba/axi4/Test.scala
index f6a6ccd9cab..ccda7093807 100644
--- a/src/main/scala/amba/axi4/Test.scala
+++ b/src/main/scala/amba/axi4/Test.scala
@@ -3,9 +3,13 @@
package freechips.rocketchip.amba.axi4
import chisel3._
+
import org.chipsalliance.cde.config.Parameters
+
+import org.chipsalliance.diplomacy.lazymodule.{LazyModule, LazyModuleImp, SimpleLazyModule}
+
import freechips.rocketchip.devices.tilelink._
-import freechips.rocketchip.diplomacy._
+import freechips.rocketchip.diplomacy.{AddressSet, BufferParams}
import freechips.rocketchip.regmapper.{RRTest0, RRTest1}
import freechips.rocketchip.tilelink._
import freechips.rocketchip.unittest._
diff --git a/src/main/scala/amba/axi4/ToTL.scala b/src/main/scala/amba/axi4/ToTL.scala
index 54ef0f0029c..833be2e4e28 100644
--- a/src/main/scala/amba/axi4/ToTL.scala
+++ b/src/main/scala/amba/axi4/ToTL.scala
@@ -3,12 +3,18 @@
package freechips.rocketchip.amba.axi4
import chisel3._
-import chisel3.util._
-import freechips.rocketchip.amba._
+import chisel3.util.{Cat, log2Up, log2Ceil, UIntToOH, Queue}
+
import org.chipsalliance.cde.config.Parameters
-import freechips.rocketchip.diplomacy._
-import freechips.rocketchip.tilelink._
-import freechips.rocketchip.util._
+
+import org.chipsalliance.diplomacy.ValName
+import org.chipsalliance.diplomacy.nodes.{MixedAdapterNode, InwardNodeImp}
+import org.chipsalliance.diplomacy.lazymodule.{LazyModule, LazyModuleImp}
+
+import freechips.rocketchip.amba.{AMBACorrupt, AMBAProt, AMBAProtField}
+import freechips.rocketchip.diplomacy.{IdRange, IdMapEntry, TransferSizes}
+import freechips.rocketchip.tilelink.{TLImp, TLMasterParameters, TLMasterPortParameters, TLArbiter}
+import freechips.rocketchip.util.{OH1ToUInt, UIntToOH1}
case class AXI4ToTLIdMapEntry(tlId: IdRange, axi4Id: IdRange, name: String)
extends IdMapEntry
diff --git a/src/main/scala/amba/axi4/UserYanker.scala b/src/main/scala/amba/axi4/UserYanker.scala
index a332f5399d3..93e69cd4b92 100644
--- a/src/main/scala/amba/axi4/UserYanker.scala
+++ b/src/main/scala/amba/axi4/UserYanker.scala
@@ -3,10 +3,13 @@
package freechips.rocketchip.amba.axi4
import chisel3._
-import chisel3.util._
+import chisel3.util.{Queue, QueueIO, UIntToOH}
+
import org.chipsalliance.cde.config.Parameters
-import freechips.rocketchip.diplomacy._
-import freechips.rocketchip.util._
+
+import org.chipsalliance.diplomacy.lazymodule.{LazyModule, LazyModuleImp}
+
+import freechips.rocketchip.util.BundleMap
/** This adapter prunes all user bit fields of the echo type from request messages,
* storing them in queues and echoing them back when matching response messages are received.
diff --git a/src/main/scala/amba/axi4/Xbar.scala b/src/main/scala/amba/axi4/Xbar.scala
index be65db13834..291e92acdbe 100644
--- a/src/main/scala/amba/axi4/Xbar.scala
+++ b/src/main/scala/amba/axi4/Xbar.scala
@@ -3,12 +3,16 @@
package freechips.rocketchip.amba.axi4
import chisel3._
-import chisel3.util._
-import org.chipsalliance.cde.config._
-import freechips.rocketchip.diplomacy._
-import freechips.rocketchip.util._
-import freechips.rocketchip.unittest._
-import freechips.rocketchip.tilelink._
+import chisel3.util.{Cat, Queue, UIntToOH, log2Ceil, OHToUInt, Mux1H, IrrevocableIO}
+
+import org.chipsalliance.cde.config.Parameters
+
+import org.chipsalliance.diplomacy.lazymodule.{LazyModule, LazyModuleImp}
+
+import freechips.rocketchip.diplomacy.{AddressDecoder, AddressSet, BufferParams}
+import freechips.rocketchip.tilelink.{TLArbiter, TLXbar, TLFilter, TLFuzzer, TLToAXI4, TLRAMModel}
+import freechips.rocketchip.unittest.{UnitTest, UnitTestModule}
+import freechips.rocketchip.util.BundleField
/**
* AXI4 Crossbar. It connects multiple AXI4 masters to slaves.
@@ -85,7 +89,12 @@ class AXI4Xbar(
// Transform input bundles
val in = Wire(Vec(io_in.size, new AXI4Bundle(wide_bundle)))
for (i <- 0 until in.size) {
- in(i).squeezeAll :<>= io_in(i).squeezeAll
+ in(i).aw.bits.user := DontCare
+ in(i).aw.bits.echo := DontCare
+ in(i).ar.bits.user := DontCare
+ in(i).ar.bits.echo := DontCare
+ in(i).w.bits.user := DontCare
+ in(i).squeezeAll.waiveAll :<>= io_in(i).squeezeAll.waiveAll
// Handle size = 1 gracefully (Chisel3 empty range is broken)
def trim(id: UInt, size: Int) = if (size <= 1) 0.U else id(log2Ceil(size)-1, 0)
@@ -168,7 +177,9 @@ class AXI4Xbar(
// Transform output bundles
val out = Wire(Vec(io_out.size, new AXI4Bundle(wide_bundle)))
for (i <- 0 until out.size) {
- io_out(i).squeezeAll :<>= out(i).squeezeAll
+ out(i).b.bits.user := DontCare
+ out(i).r.bits.user := DontCare
+ io_out(i).squeezeAll.waiveAll :<>= out(i).squeezeAll.waiveAll
if (io_in.size > 1) {
// Block AW if we cannot record the W source
diff --git a/src/main/scala/amba/axi4/package.scala b/src/main/scala/amba/axi4/package.scala
index d1673572f5b..57a5e8759e1 100644
--- a/src/main/scala/amba/axi4/package.scala
+++ b/src/main/scala/amba/axi4/package.scala
@@ -2,8 +2,10 @@
package freechips.rocketchip.amba
-import freechips.rocketchip.diplomacy.{HasClockDomainCrossing, _}
-import freechips.rocketchip.prci.{HasResetDomainCrossing}
+import org.chipsalliance.diplomacy.ValName
+import org.chipsalliance.diplomacy.nodes.{SimpleNodeHandle, OutwardNodeHandle, InwardNodeHandle}
+
+import freechips.rocketchip.prci.{HasClockDomainCrossing, HasResetDomainCrossing}
/**
* Provide bundles, adapters and devices etc for AMBA AXI4 protocol.
@@ -15,15 +17,15 @@ package object axi4
type AXI4InwardNode = InwardNodeHandle[AXI4MasterPortParameters, AXI4SlavePortParameters, AXI4EdgeParameters, AXI4Bundle]
implicit class AXI4ClockDomainCrossing(private val x: HasClockDomainCrossing) extends AnyVal {
- def crossIn (n: AXI4InwardNode) (implicit valName: ValName) = AXI4InwardClockCrossingHelper(valName.name, x, n)
- def crossOut(n: AXI4OutwardNode)(implicit valName: ValName) = AXI4OutwardClockCrossingHelper(valName.name, x, n)
+ def crossIn (n: AXI4InwardNode) (implicit valName: ValName) = AXI4InwardClockCrossingHelper(valName.value, x, n)
+ def crossOut(n: AXI4OutwardNode)(implicit valName: ValName) = AXI4OutwardClockCrossingHelper(valName.value, x, n)
def cross(n: AXI4InwardNode) (implicit valName: ValName) = crossIn(n)
def cross(n: AXI4OutwardNode)(implicit valName: ValName) = crossOut(n)
}
implicit class AXI4ResetDomainCrossing(private val x: HasResetDomainCrossing) extends AnyVal {
- def crossIn (n: AXI4InwardNode) (implicit valName: ValName) = AXI4InwardResetCrossingHelper(valName.name, x, n)
- def crossOut(n: AXI4OutwardNode)(implicit valName: ValName) = AXI4OutwardResetCrossingHelper(valName.name, x, n)
+ def crossIn (n: AXI4InwardNode) (implicit valName: ValName) = AXI4InwardResetCrossingHelper(valName.value, x, n)
+ def crossOut(n: AXI4OutwardNode)(implicit valName: ValName) = AXI4OutwardResetCrossingHelper(valName.value, x, n)
def cross(n: AXI4InwardNode) (implicit valName: ValName) = crossIn(n)
def cross(n: AXI4OutwardNode)(implicit valName: ValName) = crossOut(n)
}
diff --git a/src/main/scala/amba/axis/Buffer.scala b/src/main/scala/amba/axis/Buffer.scala
index a9ea9198d17..4ba04c950b8 100644
--- a/src/main/scala/amba/axis/Buffer.scala
+++ b/src/main/scala/amba/axis/Buffer.scala
@@ -2,8 +2,10 @@
package freechips.rocketchip.amba.axis
-import org.chipsalliance.cde.config._
-import freechips.rocketchip.diplomacy._
+import org.chipsalliance.cde.config.Parameters
+import org.chipsalliance.diplomacy.lazymodule.{LazyModule, LazyModuleImp}
+
+import freechips.rocketchip.diplomacy.BufferParams
class AXISBuffer(val params: BufferParams)(implicit p: Parameters) extends LazyModule
{
diff --git a/src/main/scala/amba/axis/Nodes.scala b/src/main/scala/amba/axis/Nodes.scala
index a82a2e2601b..133f79985a9 100644
--- a/src/main/scala/amba/axis/Nodes.scala
+++ b/src/main/scala/amba/axis/Nodes.scala
@@ -3,8 +3,10 @@
package freechips.rocketchip.amba.axis
import chisel3.experimental.SourceInfo
+
import org.chipsalliance.cde.config.Parameters
-import freechips.rocketchip.diplomacy._
+import org.chipsalliance.diplomacy.ValName
+import org.chipsalliance.diplomacy.nodes.{SimpleNodeImp, SourceNode, SinkNode, NexusNode, AdapterNode, OutwardNode, IdentityNode, RenderedEdge, InwardNode}
object AXISImp extends SimpleNodeImp[AXISMasterPortParameters, AXISSlavePortParameters, AXISEdgeParameters, AXISBundle]
{
diff --git a/src/main/scala/amba/axis/Parameters.scala b/src/main/scala/amba/axis/Parameters.scala
index ea97a941e5c..bcc928bf36e 100644
--- a/src/main/scala/amba/axis/Parameters.scala
+++ b/src/main/scala/amba/axis/Parameters.scala
@@ -1,11 +1,16 @@
// See LICENSE.SiFive for license details.
package freechips.rocketchip.amba.axis
-import chisel3.util._
import chisel3.experimental.SourceInfo
+import chisel3.util.{isPow2, log2Ceil}
+
import org.chipsalliance.cde.config.Parameters
-import freechips.rocketchip.util._
-import freechips.rocketchip.diplomacy._
+import org.chipsalliance.diplomacy.nodes.BaseNode
+
+import freechips.rocketchip.diplomacy.{TransferSizes, IdRange}
+import freechips.rocketchip.resources.{Resource}
+import freechips.rocketchip.util.{BundleFieldBase, BundleField}
+
class AXISSlaveParameters private (
val name: String,
diff --git a/src/main/scala/amba/axis/Xbar.scala b/src/main/scala/amba/axis/Xbar.scala
index 7338bb4287c..cf154028f9c 100644
--- a/src/main/scala/amba/axis/Xbar.scala
+++ b/src/main/scala/amba/axis/Xbar.scala
@@ -3,10 +3,12 @@
package freechips.rocketchip.amba.axis
import chisel3._
-import chisel3.util._
-import org.chipsalliance.cde.config._
-import freechips.rocketchip.diplomacy._
-import freechips.rocketchip.tilelink._
+import chisel3.util.{Cat, log2Ceil, Mux1H}
+
+import org.chipsalliance.cde.config.{Config, Parameters}
+import org.chipsalliance.diplomacy.lazymodule.{LazyModule, LazyModuleImp}
+
+import freechips.rocketchip.tilelink.{TLXbar, TLArbiter}
class AXISXbar(beatBytes: Int, policy: TLArbiter.Policy = TLArbiter.roundRobin)(implicit p: Parameters) extends LazyModule
{
diff --git a/src/main/scala/amba/axis/package.scala b/src/main/scala/amba/axis/package.scala
index 07183b86975..00500055acd 100644
--- a/src/main/scala/amba/axis/package.scala
+++ b/src/main/scala/amba/axis/package.scala
@@ -2,7 +2,7 @@
package freechips.rocketchip.amba
-import freechips.rocketchip.diplomacy._
+import org.chipsalliance.diplomacy.nodes.{InwardNodeHandle, OutwardNodeHandle, NodeHandle}
package object axis
{
diff --git a/src/main/scala/amba/package.scala b/src/main/scala/amba/package.scala
index 2af015abd9b..75a971c7f75 100644
--- a/src/main/scala/amba/package.scala
+++ b/src/main/scala/amba/package.scala
@@ -3,7 +3,8 @@
package freechips.rocketchip
import chisel3._
-import freechips.rocketchip.util._
+
+import freechips.rocketchip.util.{ControlKey, DataKey, BundleField}
package object amba {
class AMBAProtBundle extends Bundle {
@@ -31,4 +32,4 @@ package object amba {
// Used to convert a TileLink corrupt signal into an AMBA user bit
case object AMBACorrupt extends DataKey[Bool]("corrupt")
case class AMBACorruptField() extends BundleField[Bool](AMBACorrupt, Output(Bool()), x => x := false.B)
-}
\ No newline at end of file
+}
diff --git a/src/main/scala/aop/Select.scala b/src/main/scala/aop/Select.scala
deleted file mode 100644
index 132b859ed12..00000000000
--- a/src/main/scala/aop/Select.scala
+++ /dev/null
@@ -1,121 +0,0 @@
-// See LICENSE.SiFive for license details.
-
-package freechips.rocketchip.aop
-
-import chisel3.Data
-import org.chipsalliance.cde.config.Parameters
-import freechips.rocketchip.diplomacy.{
- AnyMixedNode,
- BaseNode,
- InwardNode,
- LazyModule,
- MixedNode,
- OutwardNode,
-}
-
-/** Combinators for finding specific sets of [[LazyModule]]s/[[Node]]s.
- *
- * These can be used for e.g. finding specific TLBundles in a design and
- * placing monitors or annotating metadata.
- */
-object Select {
-
- /** Contains information about an inward edge of a node
- */
- case class InwardEdge[Bundle <: Data, EdgeInParams](
- params: Parameters,
- bundle: Bundle,
- edge: EdgeInParams,
- node: OutwardNode[_, _, Bundle],
- )
-
- /** Contains information about an outward edge of a node
- */
- case class OutwardEdge[Bundle <: Data, EdgeOutParams](
- params: Parameters,
- bundle: Bundle,
- edge: EdgeOutParams,
- node: InwardNode[_, _, Bundle],
- )
-
- /** Collects the [[InwardEdge]]s of a node. Defined as a separate method so
- * that the bundle/edge types can be set properly
- */
- private def getInwardEdges[BI <: Data, EI](node: MixedNode[_, _, EI, BI, _, _, _, _ <: Data]): Iterable[InwardEdge[BI, EI]] = {
- node.iPorts.zip(node.in).map {
- case ((_, node, params, _), (bundle, edge)) =>
- InwardEdge(params, bundle, edge, node)
- }
- }
-
- /** Applies the collect function to each [[InwardEdge]] of a node
- */
- def collectInwardEdges[T](node: BaseNode)(collect: PartialFunction[InwardEdge[_ <: Data, _], T]): Iterable[T] = {
- node match {
- case node: AnyMixedNode => getInwardEdges(node).collect(collect)
- case _ => Seq.empty
- }
- }
-
- /** Collects the [[OutwardEdge]]s of a node. Defined as a separate method so
- * that the bundle/edge types can be set properly
- */
- private def getOutwardEdges[BO <: Data, EO](node: MixedNode[_, _, _, _ <: Data, _, _, EO, BO]): Iterable[OutwardEdge[BO, EO]] = {
- node.oPorts.zip(node.out).map {
- case ((_, node, params, _), (bundle, edge)) =>
- OutwardEdge(params, bundle, edge, node)
- }
- }
-
- /** Applies the collect function to each [[OutardEdge]] of a node
- */
- def collectOutwardEdges[T](node: BaseNode)(collect: PartialFunction[OutwardEdge[_ <: Data, _], T]): Iterable[T] = {
- node match {
- case node: AnyMixedNode => getOutwardEdges(node).collect(collect)
- case _ => Seq.empty
- }
- }
-
- /** Applies the collect function to a [[LazyModule]] and recursively to all
- * of its children.
- */
- def collectDeep[T](lmod: LazyModule)(collect: PartialFunction[LazyModule, T]): Iterable[T] = {
- collect.lift(lmod) ++
- lmod.getChildren.flatMap { child =>
- collectDeep(child)(collect)
- }
- }
-
- /** Applies the collect function to a [[LazyModule]] and its children if the
- * filter function returns true. Stops recursing when the filter function
- * returns false. e.g.
- * for this hierarchy
- * A
- * / \
- * B C
- * / \ \
- * D E F
- *
- * the following select function
- * {{{
- * filterCollectDeep(A) {
- * case B => false
- * case _ => true
- * } { m =>
- * printl(m)
- * }
- * }}}
- *
- * will only print modules A, C, and F
- */
- def filterCollectDeep[T](lmod: LazyModule)(filter: LazyModule => Boolean)(collect: PartialFunction[LazyModule, T]): Iterable[T] = {
- if (filter(lmod)) {
- collect.lift(lmod) ++
- lmod.getChildren.flatMap { child =>
- filterCollectDeep(child)(filter)(collect)
- }
- } else {
- Iterable.empty
- }
- }
-}
diff --git a/src/main/scala/aop/package.scala b/src/main/scala/aop/package.scala
new file mode 100644
index 00000000000..a773e153552
--- /dev/null
+++ b/src/main/scala/aop/package.scala
@@ -0,0 +1,6 @@
+package freechips.rocketchip
+
+object aop {
+ @deprecated("aop has moved to the standalone diplomacy library.", "rocketchip 2.0.0")
+ val Select = _root_.org.chipsalliance.diplomacy.aop.Select
+}
diff --git a/src/main/scala/devices/debug/APB.scala b/src/main/scala/devices/debug/APB.scala
index 8191bb65835..8397eae8fc2 100644
--- a/src/main/scala/devices/debug/APB.scala
+++ b/src/main/scala/devices/debug/APB.scala
@@ -1,10 +1,13 @@
// See LICENSE.SiFive for license details.
package freechips.rocketchip.devices.debug
+
import org.chipsalliance.cde.config._
-import freechips.rocketchip.diplomacy._
-import freechips.rocketchip.regmapper._
-import freechips.rocketchip.amba.apb.{APBRegisterNode}
+import org.chipsalliance.diplomacy.lazymodule._
+
+import freechips.rocketchip.amba.apb.APBRegisterNode
+import freechips.rocketchip.diplomacy.AddressSet
+import freechips.rocketchip.regmapper.RegField
case object APBDebugRegistersKey extends Field[Map[Int, Seq[RegField]]](Map())
diff --git a/src/main/scala/devices/debug/Custom.scala b/src/main/scala/devices/debug/Custom.scala
index 22086988a28..b359c01be10 100644
--- a/src/main/scala/devices/debug/Custom.scala
+++ b/src/main/scala/devices/debug/Custom.scala
@@ -3,11 +3,13 @@
package freechips.rocketchip.devices.debug
import chisel3._
+import chisel3.experimental._
import chisel3.util._
-import chisel3.experimental.SourceInfo
-import freechips.rocketchip.diplomacy.{LazyModule, LazyModuleImp, NexusNode, RenderedEdge,
- SimpleNodeImp, SinkNode, SourceNode, ValName}
-import org.chipsalliance.cde.config.Parameters
+
+import org.chipsalliance.cde.config._
+import org.chipsalliance.diplomacy._
+import org.chipsalliance.diplomacy.lazymodule._
+import org.chipsalliance.diplomacy.nodes._
case class DebugCustomParams(
addrs: List[Int],
@@ -68,7 +70,7 @@ class DebugCustomXbar(
)
lazy val module = new Impl
- class Impl extends LazyModuleImp(this) {
+ class Impl extends LazyRawModuleImp(this) {
// require only one sink
require(node.out.size == 1, "Must have exactly one sink node, not ${node.out.size}")
// send address to all sources
diff --git a/src/main/scala/devices/debug/DMI.scala b/src/main/scala/devices/debug/DMI.scala
index 014b838bfc6..eeffdc2917c 100644
--- a/src/main/scala/devices/debug/DMI.scala
+++ b/src/main/scala/devices/debug/DMI.scala
@@ -4,10 +4,13 @@ package freechips.rocketchip.devices.debug
import chisel3._
import chisel3.util._
+
import org.chipsalliance.cde.config._
-import freechips.rocketchip.util._
-import freechips.rocketchip.diplomacy._
-import freechips.rocketchip.tilelink._
+import org.chipsalliance.diplomacy.lazymodule._
+
+import freechips.rocketchip.diplomacy.TransferSizes
+import freechips.rocketchip.tilelink.{TLClientNode, TLMasterParameters, TLMasterPortParameters, TLMasterToSlaveTransferSizes}
+import freechips.rocketchip.util.ParameterizedBundle
/** Constant values used by both Debug Bus Response & Request
*/
diff --git a/src/main/scala/devices/debug/Debug.scala b/src/main/scala/devices/debug/Debug.scala
index fec2caa14a3..efaf345fb5f 100755
--- a/src/main/scala/devices/debug/Debug.scala
+++ b/src/main/scala/devices/debug/Debug.scala
@@ -5,24 +5,29 @@ package freechips.rocketchip.devices.debug
import chisel3._
import chisel3.util._
+
import org.chipsalliance.cde.config._
-import freechips.rocketchip.diplomacy._
-import freechips.rocketchip.regmapper._
+import org.chipsalliance.diplomacy.lazymodule._
+
+import freechips.rocketchip.amba.apb.{APBFanout, APBToTL}
+import freechips.rocketchip.devices.debug.systembusaccess.{SBToTL, SystemBusAccessModule}
+import freechips.rocketchip.devices.tilelink.{DevNullParams, TLBusBypass, TLError}
+import freechips.rocketchip.diplomacy.{AddressSet, BufferParams}
+import freechips.rocketchip.resources.{Description, Device, Resource, ResourceBindings, ResourceString, SimpleDevice}
+import freechips.rocketchip.interrupts.{IntNexusNode, IntSinkParameters, IntSinkPortParameters, IntSourceParameters, IntSourcePortParameters, IntSyncCrossingSource, IntSyncIdentityNode}
+import freechips.rocketchip.regmapper.{RegField, RegFieldAccessType, RegFieldDesc, RegFieldGroup, RegFieldWrType, RegReadFn, RegWriteFn}
import freechips.rocketchip.rocket.{CSRs, Instructions}
import freechips.rocketchip.tile.MaxHartIdBits
-import freechips.rocketchip.tilelink._
-import freechips.rocketchip.devices.tilelink.{DevNullParams, TLError}
-import freechips.rocketchip.interrupts._
-import freechips.rocketchip.util._
-import freechips.rocketchip.devices.debug.systembusaccess._
-import freechips.rocketchip.devices.tilelink.TLBusBypass
-import freechips.rocketchip.amba.apb.{APBToTL, APBFanout}
+import freechips.rocketchip.tilelink.{TLAsyncCrossingSink, TLAsyncCrossingSource, TLBuffer, TLRegisterNode, TLXbar}
+import freechips.rocketchip.util.{Annotated, AsyncBundle, AsyncQueueParams, AsyncResetSynchronizerShiftReg, FromAsyncBundle, ParameterizedBundle, ResetSynchronizerShiftReg, ToAsyncBundle}
+
+import freechips.rocketchip.util.SeqBoolBitwiseOps
+import freechips.rocketchip.util.SeqToAugmentedSeq
import freechips.rocketchip.util.BooleanToAugmentedBoolean
object DsbBusConsts {
def sbAddrWidth = 12
- def sbIdWidth = 10
-
+ def sbIdWidth = 10
}
object DsbRegAddrs{
@@ -667,7 +672,7 @@ class TLDebugModuleOuterAsync(device: Device)(implicit p: Parameters) extends La
val cfg = p(DebugModuleKey).get
- val dmiXbar = LazyModule (new TLXbar())
+ val dmiXbar = LazyModule (new TLXbar(nameSuffix = Some("dmixbar")))
val dmi2tlOpt = (!p(ExportDebug).apb).option({
val dmi2tl = LazyModule(new DMIToTL())
@@ -693,7 +698,8 @@ class TLDebugModuleOuterAsync(device: Device)(implicit p: Parameters) extends La
})
val dmOuter = LazyModule( new TLDebugModuleOuter(device))
- val intnode = IntSyncCrossingSource(alreadyRegistered = true) :*= dmOuter.intnode
+ val intnode = IntSyncIdentityNode()
+ intnode :*= IntSyncCrossingSource(alreadyRegistered = true) :*= dmOuter.intnode
val dmiBypass = LazyModule(new TLBusBypass(beatBytes=4, bufferError=false, maxAtomic=0, maxTransfer=4))
val dmiInnerNode = TLAsyncCrossingSource() := dmiBypass.node := dmiXbar.node
@@ -727,6 +733,7 @@ class TLDebugModuleOuterAsync(device: Device)(implicit p: Parameters) extends La
childClock := io.dmi_clock
childReset := io.dmi_reset
+ override def provideImplicitClockToLazyChildren = true
withClockAndReset(childClock, childReset) {
dmi2tlOpt.foreach { _.module.io.dmi <> io.dmi.get }
@@ -916,7 +923,7 @@ class TLDebugModuleInner(device: Device, getNComponents: () => Int, beatBytes: I
// Outer.hamask doesn't consider the hart selected by dmcontrol.hartsello,
// so append it here
when (selectedHartReg < nComponents.U) {
- hamaskFull(selectedHartReg) := true.B
+ hamaskFull(if (nComponents == 1) 0.U(0.W) else selectedHartReg) := true.B
}
io.innerCtrl.ready := true.B
@@ -1040,7 +1047,7 @@ class TLDebugModuleInner(device: Device, getNComponents: () => Int, beatBytes: I
}
}
}
- DMCS2RdData.haltgroup := hgParticipateHart(selectedHartReg)
+ DMCS2RdData.haltgroup := hgParticipateHart(if (nComponents == 1) 0.U(0.W) else selectedHartReg)
if (nExtTriggers > 0) {
val hgSelect = Reg(Bool())
@@ -1724,7 +1731,7 @@ class TLDebugModuleInner(device: Device, getNComponents: () => Int, beatBytes: I
// This is not an initialization!
val ctrlStateReg = Reg(chiselTypeOf(CtrlState(Waiting)))
- val hartHalted = haltedBitRegs(selectedHartReg)
+ val hartHalted = haltedBitRegs(if (nComponents == 1) 0.U(0.W) else selectedHartReg)
val ctrlStateNxt = WireInit(ctrlStateReg)
//------------------------
@@ -1898,6 +1905,7 @@ class TLDebugModuleInnerAsync(device: Device, getNComponents: () => Int, beatByt
childClock := io.debug_clock
childReset := io.debug_reset
+ override def provideImplicitClockToLazyChildren = true
val dmactive_synced = withClockAndReset(childClock, childReset) {
val dmactive_synced = AsyncResetSynchronizerShiftReg(in=io.dmactive, sync=3, name=Some("dmactiveSync"))
@@ -1986,6 +1994,7 @@ class TLDebugModule(beatBytes: Int)(implicit p: Parameters) extends LazyModule {
childClock := io.tl_clock
childReset := io.tl_reset
+ override def provideImplicitClockToLazyChildren = true
dmOuter.module.io.dmi.foreach { dmOuterDMI =>
dmOuterDMI <> io.dmi.get.dmi
diff --git a/src/main/scala/devices/debug/Periphery.scala b/src/main/scala/devices/debug/Periphery.scala
index 8d015a08169..8aa3214af9b 100644
--- a/src/main/scala/devices/debug/Periphery.scala
+++ b/src/main/scala/devices/debug/Periphery.scala
@@ -3,18 +3,21 @@
package freechips.rocketchip.devices.debug
import chisel3._
-import chisel3.experimental.{IntParam, noPrefix}
+import chisel3.experimental.{noPrefix, IntParam}
import chisel3.util._
-import chisel3.util.HasBlackBoxResource
-import org.chipsalliance.cde.config.{Field, Parameters}
-import freechips.rocketchip.subsystem._
-import freechips.rocketchip.amba.apb._
-import freechips.rocketchip.diplomacy._
-import freechips.rocketchip.jtag._
-import freechips.rocketchip.util._
-import freechips.rocketchip.prci.{ClockSinkParameters, ClockSinkNode}
-import freechips.rocketchip.tilelink._
-import freechips.rocketchip.interrupts.{NullIntSyncSource, IntSyncXbar}
+
+import org.chipsalliance.cde.config._
+import org.chipsalliance.diplomacy.lazymodule._
+
+import freechips.rocketchip.amba.apb.{APBBundle, APBBundleParameters, APBMasterNode, APBMasterParameters, APBMasterPortParameters}
+import freechips.rocketchip.interrupts.{IntSyncXbar, NullIntSyncSource}
+import freechips.rocketchip.jtag.JTAGIO
+import freechips.rocketchip.prci.{ClockSinkNode, ClockSinkParameters}
+import freechips.rocketchip.subsystem.{BaseSubsystem, CBUS, FBUS, ResetSynchronous, SubsystemResetSchemeKey, TLBusWrapperLocation}
+import freechips.rocketchip.tilelink.{TLFragmenter, TLWidthWidget}
+import freechips.rocketchip.util.{AsyncResetSynchronizerShiftReg, CanHavePSDTestModeIO, ClockGate, PSDTestMode, PlusArg, ResetSynchronizerShiftReg}
+
+import freechips.rocketchip.util.BooleanToAugmentedBoolean
/** Protocols used for communicating with external debugging tools */
sealed trait DebugExportProtocol
@@ -84,7 +87,7 @@ trait HasPeripheryDebug { this: BaseSubsystem =>
lazy val debugOpt = p(DebugModuleKey).map { params =>
val tlDM = LazyModule(new TLDebugModule(tlbus.beatBytes))
- tlDM.node := tlbus.coupleTo("debug"){ TLFragmenter(tlbus) := _ }
+ tlDM.node := tlbus.coupleTo("debug"){ TLFragmenter(tlbus.beatBytes, tlbus.blockBytes, nameSuffix = Some("Debug")) := _ }
tlDM.dmInner.dmInner.customNode := debugCustomXbarOpt.get.node
(apbDebugNodeOpt zip tlDM.apbNodeOpt) foreach { case (master, slave) =>
@@ -99,7 +102,7 @@ trait HasPeripheryDebug { this: BaseSubsystem =>
tlDM
}
- lazy val debugNode = debugOpt.map(_.intnode).getOrElse(IntSyncXbar() := NullIntSyncSource())
+ val debugNode = debugOpt.map(_.intnode)
val psd = InModuleBody {
val psd = IO(new PSDIO)
@@ -323,6 +326,9 @@ object Debug {
debug.clockeddmi.foreach { d =>
d.dmi.req.valid := false.B
+ d.dmi.req.bits.addr := 0.U
+ d.dmi.req.bits.data := 0.U
+ d.dmi.req.bits.op := 0.U
d.dmi.resp.ready := true.B
d.dmiClock := false.B.asClock
d.dmiReset := true.B.asAsyncReset
@@ -344,6 +350,7 @@ object Debug {
t.out.ack := t.out.req
}
debug.disableDebug.foreach { x => x := false.B }
+ debug.dmactiveAck := false.B
debug.ndreset
}.getOrElse(false.B)
}
diff --git a/src/main/scala/devices/debug/SBA.scala b/src/main/scala/devices/debug/SBA.scala
index f35b27ac05a..568291a221f 100644
--- a/src/main/scala/devices/debug/SBA.scala
+++ b/src/main/scala/devices/debug/SBA.scala
@@ -4,13 +4,16 @@ package freechips.rocketchip.devices.debug.systembusaccess
import chisel3._
import chisel3.util._
-import freechips.rocketchip.amba._
+
import org.chipsalliance.cde.config._
-import freechips.rocketchip.diplomacy._
-import freechips.rocketchip.regmapper._
-import freechips.rocketchip.tilelink._
+import org.chipsalliance.diplomacy.lazymodule._
+
+import freechips.rocketchip.amba.{AMBAProt, AMBAProtField}
+import freechips.rocketchip.devices.debug.{DebugModuleKey, RWNotify, SBCSFields, WNotifyVal}
+import freechips.rocketchip.diplomacy.TransferSizes
+import freechips.rocketchip.regmapper.{RegField, RegFieldDesc, RegFieldGroup, RegFieldWrType}
+import freechips.rocketchip.tilelink.{TLClientNode, TLMasterParameters, TLMasterPortParameters}
import freechips.rocketchip.util.property
-import freechips.rocketchip.devices.debug._
object SystemBusAccessState extends scala.Enumeration {
type SystemBusAccessState = Value
@@ -304,7 +307,7 @@ class SBToTL(implicit p: Parameters) extends LazyModule {
val counter = RegInit(0.U((log2Ceil(cfg.maxSupportedSBAccess/8)+1).W))
val vecData = Wire(Vec(cfg.maxSupportedSBAccess/8, UInt(8.W)))
vecData.zipWithIndex.map { case (vd, i) => vd := io.dataIn(8*i+7,8*i) }
- muxedData := vecData(counter)
+ muxedData := vecData(counter(log2Ceil(vecData.size)-1,0))
// Need an additional check to determine if address is safe for Get/Put
val rdLegal_addr = edge.manager.supportsGetSafe(io.addrIn, io.sizeIn, Some(TransferSizes(1,cfg.maxSupportedSBAccess/8)))
diff --git a/src/main/scala/devices/tilelink/BootROM.scala b/src/main/scala/devices/tilelink/BootROM.scala
index 9ffdac9e65e..7cbfcca6df8 100644
--- a/src/main/scala/devices/tilelink/BootROM.scala
+++ b/src/main/scala/devices/tilelink/BootROM.scala
@@ -3,12 +3,16 @@
package freechips.rocketchip.devices.tilelink
import chisel3._
-import chisel3.util.log2Ceil
-import org.chipsalliance.cde.config.{Field, Parameters}
-import freechips.rocketchip.subsystem.{BaseSubsystem, HierarchicalLocation, HasTiles, TLBusWrapperLocation}
-import freechips.rocketchip.diplomacy._
-import freechips.rocketchip.tilelink._
-import freechips.rocketchip.prci.{ClockSinkDomain}
+import chisel3.util._
+
+import org.chipsalliance.cde.config._
+import org.chipsalliance.diplomacy.bundlebridge._
+import org.chipsalliance.diplomacy.lazymodule._
+
+import freechips.rocketchip.diplomacy.{AddressSet, RegionType, TransferSizes}
+import freechips.rocketchip.resources.{Resource, SimpleDevice}
+import freechips.rocketchip.subsystem._
+import freechips.rocketchip.tilelink.{TLFragmenter, TLManagerNode, TLSlaveParameters, TLSlavePortParameters}
import java.nio.ByteBuffer
import java.nio.file.{Files, Paths}
@@ -66,11 +70,10 @@ object BootROM {
* at a configurable location, but also drives the tiles' reset vectors to point
* at its 'hang' address parameter value.
*/
- def attach(params: BootROMParams, subsystem: BaseSubsystem with HasTiles, where: TLBusWrapperLocation)
+ def attach(params: BootROMParams, subsystem: BaseSubsystem with HasHierarchicalElements with HasTileInputConstants, where: TLBusWrapperLocation)
(implicit p: Parameters): TLROM = {
val tlbus = subsystem.locateTLBusWrapper(where)
- val bootROMDomainWrapper = LazyModule(new ClockSinkDomain(take = None))
- bootROMDomainWrapper.clockNode := tlbus.fixedClockNode
+ val bootROMDomainWrapper = tlbus.generateSynchronousDomain("BootROM").suggestName("bootrom_domain")
val bootROMResetVectorSourceNode = BundleBridgeSource[UInt]()
lazy val contents = {
@@ -83,7 +86,7 @@ object BootROM {
LazyModule(new TLROM(params.address, params.size, contents, true, tlbus.beatBytes))
}
- bootrom.node := tlbus.coupleTo("bootrom"){ TLFragmenter(tlbus) := _ }
+ bootrom.node := tlbus.coupleTo("bootrom"){ TLFragmenter(tlbus, Some("BootROM")) := _ }
// Drive the `subsystem` reset vector to the `hang` address of this Boot ROM.
subsystem.tileResetVectorNexusNode := bootROMResetVectorSourceNode
InModuleBody {
diff --git a/src/main/scala/devices/tilelink/BusBlocker.scala b/src/main/scala/devices/tilelink/BusBlocker.scala
index e86505826c2..60707b8f33b 100644
--- a/src/main/scala/devices/tilelink/BusBlocker.scala
+++ b/src/main/scala/devices/tilelink/BusBlocker.scala
@@ -3,10 +3,14 @@
package freechips.rocketchip.devices.tilelink
import chisel3._
-import org.chipsalliance.cde.config.Parameters
-import freechips.rocketchip.diplomacy.{AddressSet, LazyModule, LazyModuleImp, SimpleDevice}
+
+import org.chipsalliance.cde.config._
+import org.chipsalliance.diplomacy.lazymodule._
+
+import freechips.rocketchip.diplomacy.{AddressSet}
+import freechips.rocketchip.resources.{SimpleDevice}
import freechips.rocketchip.regmapper.{RegField, RegFieldDesc}
-import freechips.rocketchip.tilelink.{TLFragmenter, TLRegisterNode, TLBusWrapper, TLNameNode, TLNode}
+import freechips.rocketchip.tilelink.{TLBusWrapper, TLFragmenter, TLNameNode, TLNode, TLRegisterNode}
/** Parameterize a BasicBusBlocker.
*
diff --git a/src/main/scala/devices/tilelink/CLINT.scala b/src/main/scala/devices/tilelink/CLINT.scala
index 8156706ee8d..81c7051ae46 100644
--- a/src/main/scala/devices/tilelink/CLINT.scala
+++ b/src/main/scala/devices/tilelink/CLINT.scala
@@ -3,14 +3,18 @@
package freechips.rocketchip.devices.tilelink
import chisel3._
-import chisel3.util.ShiftRegister
-import org.chipsalliance.cde.config.{Field, Parameters}
-import freechips.rocketchip.diplomacy._
-import freechips.rocketchip.interrupts._
-import freechips.rocketchip.regmapper._
-import freechips.rocketchip.subsystem._
-import freechips.rocketchip.tilelink._
-import freechips.rocketchip.util._
+import chisel3.util._
+
+import org.chipsalliance.cde.config._
+import org.chipsalliance.diplomacy.lazymodule._
+
+import freechips.rocketchip.diplomacy.{AddressSet}
+import freechips.rocketchip.resources.{Resource, SimpleDevice}
+import freechips.rocketchip.interrupts.{IntNexusNode, IntSinkParameters, IntSinkPortParameters, IntSourceParameters, IntSourcePortParameters}
+import freechips.rocketchip.regmapper.{RegField, RegFieldDesc, RegFieldGroup}
+import freechips.rocketchip.subsystem.{BaseSubsystem, CBUS, TLBusWrapperLocation}
+import freechips.rocketchip.tilelink.{TLFragmenter, TLRegisterNode}
+import freechips.rocketchip.util.Annotated
object CLINTConsts
{
@@ -102,18 +106,17 @@ class CLINT(params: CLINTParams, beatBytes: Int)(implicit p: Parameters) extends
/** Trait that will connect a CLINT to a subsystem */
trait CanHavePeripheryCLINT { this: BaseSubsystem =>
- val clintOpt = p(CLINTKey).map { params =>
+ val (clintOpt, clintDomainOpt, clintTickOpt) = p(CLINTKey).map { params =>
val tlbus = locateTLBusWrapper(p(CLINTAttachKey).slaveWhere)
- val clint = LazyModule(new CLINT(params, cbus.beatBytes))
- clint.node := tlbus.coupleTo("clint") { TLFragmenter(tlbus) := _ }
-
- // Override the implicit clock and reset -- could instead include a clockNode in the clint, and make it a RawModuleImp?
- InModuleBody {
- clint.module.clock := tlbus.module.clock
- clint.module.reset := tlbus.module.reset
- }
-
- clint
-
- }
+ val clintDomainWrapper = tlbus.generateSynchronousDomain("CLINT").suggestName("clint_domain")
+ val clint = clintDomainWrapper { LazyModule(new CLINT(params, tlbus.beatBytes)) }
+ clintDomainWrapper { clint.node := tlbus.coupleTo("clint") { TLFragmenter(tlbus, Some("CLINT")) := _ } }
+ val clintTick = clintDomainWrapper { InModuleBody {
+ val tick = IO(Input(Bool()))
+ clint.module.io.rtcTick := tick
+ tick
+ }}
+
+ (clint, clintDomainWrapper, clintTick)
+ }.unzip3
}
diff --git a/src/main/scala/devices/tilelink/CanHaveBuiltInDevices.scala b/src/main/scala/devices/tilelink/CanHaveBuiltInDevices.scala
index 96ba3def845..6fad3f637d0 100644
--- a/src/main/scala/devices/tilelink/CanHaveBuiltInDevices.scala
+++ b/src/main/scala/devices/tilelink/CanHaveBuiltInDevices.scala
@@ -2,9 +2,11 @@
package freechips.rocketchip.devices.tilelink
-import org.chipsalliance.cde.config.Parameters
-import freechips.rocketchip.diplomacy._
-import freechips.rocketchip.tilelink._
+import org.chipsalliance.cde.config._
+import org.chipsalliance.diplomacy.lazymodule._
+
+import freechips.rocketchip.diplomacy.{AddressSet, BufferParams}
+import freechips.rocketchip.tilelink.{HasTLBusParams, TLBuffer, TLCacheCork, TLCacheCorkParams, TLFragmenter, TLOutwardNode, TLTempNode}
case class BuiltInZeroDeviceParams(
addr: AddressSet,
@@ -63,4 +65,3 @@ object BuiltInDevices {
trait CanHaveBuiltInDevices {
def builtInDevices: BuiltInDevices
}
-
diff --git a/src/main/scala/devices/tilelink/ClockBlocker.scala b/src/main/scala/devices/tilelink/ClockBlocker.scala
index 9076b6b08b0..6ee0f482288 100644
--- a/src/main/scala/devices/tilelink/ClockBlocker.scala
+++ b/src/main/scala/devices/tilelink/ClockBlocker.scala
@@ -3,12 +3,15 @@
package freechips.rocketchip.devices.tilelink
import chisel3._
-import org.chipsalliance.cde.config.Parameters
-import freechips.rocketchip.diplomacy._
-import freechips.rocketchip.prci._
-import freechips.rocketchip.regmapper._
-import freechips.rocketchip.tilelink._
-import freechips.rocketchip.util._
+import org.chipsalliance.cde.config._
+import org.chipsalliance.diplomacy.lazymodule._
+
+import freechips.rocketchip.diplomacy.{AddressSet}
+import freechips.rocketchip.resources.{SimpleDevice}
+import freechips.rocketchip.prci.ClockAdapterNode
+import freechips.rocketchip.regmapper.{RegField, RegFieldDesc}
+import freechips.rocketchip.tilelink.TLRegisterNode
+import freechips.rocketchip.util.ClockGate
/** This device extends a basic bus blocker by allowing it to gate the clocks of the device
* whose tilelink port is being blocked. For now it is only possible to block
diff --git a/src/main/scala/devices/tilelink/Deadlock.scala b/src/main/scala/devices/tilelink/Deadlock.scala
index 3756d94c61e..0d5e970b216 100644
--- a/src/main/scala/devices/tilelink/Deadlock.scala
+++ b/src/main/scala/devices/tilelink/Deadlock.scala
@@ -5,6 +5,7 @@ package freechips.rocketchip.devices.tilelink
import chisel3._
import org.chipsalliance.cde.config.Parameters
import freechips.rocketchip.diplomacy._
+import freechips.rocketchip.resources.{SimpleDevice}
/** Adds a /dev/null slave that does not raise ready for any incoming traffic.
* !!! WARNING: This device WILL cause your bus to deadlock for as long as you
diff --git a/src/main/scala/devices/tilelink/DevNull.scala b/src/main/scala/devices/tilelink/DevNull.scala
index 8b2eab69901..9d3462e715c 100644
--- a/src/main/scala/devices/tilelink/DevNull.scala
+++ b/src/main/scala/devices/tilelink/DevNull.scala
@@ -2,9 +2,15 @@
package freechips.rocketchip.devices.tilelink
-import org.chipsalliance.cde.config.Parameters
-import freechips.rocketchip.diplomacy._
-import freechips.rocketchip.tilelink._
+import org.chipsalliance.cde.config._
+import org.chipsalliance.diplomacy.lazymodule._
+
+import freechips.rocketchip.diplomacy.{AddressSet, RegionType, TransferSizes}
+import freechips.rocketchip.resources.{SimpleDevice}
+import freechips.rocketchip.prci.{HasClockDomainCrossing}
+import freechips.rocketchip.tilelink.{TLManagerNode, TLSlaveParameters, TLSlavePortParameters}
+
+import freechips.rocketchip.tilelink.TLClockDomainCrossing
case class DevNullParams(
address: Seq[AddressSet],
diff --git a/src/main/scala/devices/tilelink/Error.scala b/src/main/scala/devices/tilelink/Error.scala
index dd6541d20f8..cb048c3aab3 100644
--- a/src/main/scala/devices/tilelink/Error.scala
+++ b/src/main/scala/devices/tilelink/Error.scala
@@ -4,9 +4,12 @@ package freechips.rocketchip.devices.tilelink
import chisel3._
import chisel3.util._
-import org.chipsalliance.cde.config.Parameters
-import freechips.rocketchip.diplomacy._
-import freechips.rocketchip.tilelink._
+
+import org.chipsalliance.cde.config._
+import org.chipsalliance.diplomacy.lazymodule._
+
+import freechips.rocketchip.resources.SimpleDevice
+import freechips.rocketchip.tilelink.{TLArbiter, TLMessages, TLPermissions}
/** Adds a /dev/null slave that generates TL error response messages */
class TLError(params: DevNullParams, buffer: Boolean = true, beatBytes: Int = 4)(implicit p: Parameters)
@@ -57,7 +60,7 @@ class TLError(params: DevNullParams, buffer: Boolean = true, beatBytes: Int = 4)
// ReleaseAck is not allowed to report failure
dc.bits.opcode := ReleaseAck
- dc.bits.param := VecInit(toB, toN, toN)(c.bits.param)
+ dc.bits.param := VecInit(toB, toN, toN)(c.bits.param(1,0))
dc.bits.size := c.bits.size
dc.bits.source := c.bits.source
dc.bits.sink := 0.U
diff --git a/src/main/scala/devices/tilelink/MaskROM.scala b/src/main/scala/devices/tilelink/MaskROM.scala
index f4169a85a84..8a01ec5fd7b 100644
--- a/src/main/scala/devices/tilelink/MaskROM.scala
+++ b/src/main/scala/devices/tilelink/MaskROM.scala
@@ -4,11 +4,17 @@ package freechips.rocketchip.devices.tilelink
import chisel3._
import chisel3.util._
-import org.chipsalliance.cde.config.{Field, Parameters}
-import freechips.rocketchip.diplomacy._
+
+import org.chipsalliance.cde.config._
+import org.chipsalliance.diplomacy.lazymodule._
+
+import freechips.rocketchip.diplomacy.{RegionType, AddressSet, TransferSizes}
+import freechips.rocketchip.resources.{SimpleDevice}
import freechips.rocketchip.subsystem.{Attachable, HierarchicalLocation, TLBusWrapperLocation}
-import freechips.rocketchip.tilelink._
-import freechips.rocketchip.util._
+import freechips.rocketchip.tilelink.{TLFragmenter, TLManagerNode, TLSlaveParameters, TLSlavePortParameters, TLWidthWidget}
+import freechips.rocketchip.util.{ROMConfig, ROMGenerator}
+
+import freechips.rocketchip.util.DataToAugmentedData
case class MaskROMParams(address: BigInt, name: String, depth: Int = 2048, width: Int = 32)
diff --git a/src/main/scala/devices/tilelink/MasterMux.scala b/src/main/scala/devices/tilelink/MasterMux.scala
index 3ebedcde084..c1ddf82477b 100644
--- a/src/main/scala/devices/tilelink/MasterMux.scala
+++ b/src/main/scala/devices/tilelink/MasterMux.scala
@@ -3,9 +3,17 @@
package freechips.rocketchip.devices.tilelink
import chisel3._
-import org.chipsalliance.cde.config.Parameters
-import freechips.rocketchip.diplomacy._
-import freechips.rocketchip.tilelink._
+
+import org.chipsalliance.cde.config._
+import org.chipsalliance.diplomacy._
+import org.chipsalliance.diplomacy.lazymodule._
+
+import freechips.rocketchip.diplomacy.{AddressSet, TransferSizes}
+import freechips.rocketchip.tilelink.{
+ LFSR64, TLBundleA, TLBundleC, TLBundleE, TLClientNode, TLCustomNode, TLFilter, TLFragmenter,
+ TLFuzzer, TLMasterParameters, TLMasterPortParameters, TLPermissions, TLRAM, TLRAMModel,
+ TLSlaveParameters, TLSlavePortParameters
+}
class MasterMuxNode(uFn: Seq[TLMasterPortParameters] => TLMasterPortParameters)(implicit valName: ValName) extends TLCustomNode
{
diff --git a/src/main/scala/devices/tilelink/PhysicalFilter.scala b/src/main/scala/devices/tilelink/PhysicalFilter.scala
index 1c52bffca83..c56bfeb4bc3 100644
--- a/src/main/scala/devices/tilelink/PhysicalFilter.scala
+++ b/src/main/scala/devices/tilelink/PhysicalFilter.scala
@@ -4,11 +4,16 @@ package freechips.rocketchip.devices.tilelink
import chisel3._
import chisel3.util._
-import org.chipsalliance.cde.config.Parameters
-import freechips.rocketchip.diplomacy._
-import freechips.rocketchip.regmapper._
-import freechips.rocketchip.tilelink._
-import freechips.rocketchip.util._
+
+import org.chipsalliance.cde.config._
+import org.chipsalliance.diplomacy.lazymodule._
+
+import freechips.rocketchip.diplomacy.{AddressSet}
+import freechips.rocketchip.resources.{SimpleDevice}
+import freechips.rocketchip.regmapper.{RegField, RegFieldDesc, RegFieldGroup, RegFieldWrType, RegReadFn, RegWriteFn}
+import freechips.rocketchip.tilelink.{TLAdapterNode, TLMessages, TLPermissions, TLRegisterNode}
+
+import freechips.rocketchip.util.DataToAugmentedData
case class DevicePMPParams(addressBits: Int, pageBits: Int)
@@ -235,7 +240,7 @@ class PhysicalFilter(params: PhysicalFilterParams)(implicit p: Parameters) exten
// Frame an appropriate deny message
val denyValid = RegInit(false.B)
- val deny = Reg(in.d.bits)
+ val deny = Reg(chiselTypeOf(in.d.bits))
val d_opcode = TLMessages.adResponse(in.a.bits.opcode)
val d_grant = edgeIn.manager.anySupportAcquireB.B && deny.opcode === TLMessages.Grant
when (in.a.valid && !allow && deny_ready && a_first) {
@@ -257,7 +262,7 @@ class PhysicalFilter(params: PhysicalFilterParams)(implicit p: Parameters) exten
}
}
- val out_d = Wire(in.d.bits)
+ val out_d = Wire(chiselTypeOf(in.d.bits))
out_d := out.d.bits
// Deny can have unconditional priority, because the only out.d message possible is
diff --git a/src/main/scala/devices/tilelink/Plic.scala b/src/main/scala/devices/tilelink/Plic.scala
index 3e6de570423..75cf30edf4b 100644
--- a/src/main/scala/devices/tilelink/Plic.scala
+++ b/src/main/scala/devices/tilelink/Plic.scala
@@ -3,20 +3,25 @@
package freechips.rocketchip.devices.tilelink
import chisel3._
+import chisel3.experimental._
import chisel3.util._
-import org.chipsalliance.cde.config.{Field, Parameters}
-import freechips.rocketchip.subsystem._
-import freechips.rocketchip.diplomacy._
-import freechips.rocketchip.regmapper._
-import freechips.rocketchip.tilelink._
-import freechips.rocketchip.interrupts._
-import freechips.rocketchip.util._
-import freechips.rocketchip.util.property
-import freechips.rocketchip.prci.{ClockSinkDomain}
-import chisel3.experimental.SourceInfo
+
+import org.chipsalliance.cde.config._
+import org.chipsalliance.diplomacy.lazymodule._
+
+import freechips.rocketchip.diplomacy.{AddressSet}
+import freechips.rocketchip.resources.{Description, Resource, ResourceBinding, ResourceBindings, ResourceInt, SimpleDevice}
+import freechips.rocketchip.interrupts.{IntNexusNode, IntSinkParameters, IntSinkPortParameters, IntSourceParameters, IntSourcePortParameters}
+import freechips.rocketchip.regmapper.{RegField, RegFieldDesc, RegFieldRdAction, RegFieldWrType, RegReadFn, RegWriteFn}
+import freechips.rocketchip.subsystem.{BaseSubsystem, CBUS, TLBusWrapperLocation}
+import freechips.rocketchip.tilelink.{TLFragmenter, TLRegisterNode}
+import freechips.rocketchip.util.{Annotated, MuxT, property}
import scala.math.min
+import freechips.rocketchip.util.UIntToAugmentedUInt
+import freechips.rocketchip.util.SeqToAugmentedSeq
+
class GatewayPLICIO extends Bundle {
val valid = Output(Bool())
val ready = Input(Bool())
@@ -355,15 +360,14 @@ class PLICFanIn(nDevices: Int, prioBits: Int) extends Module {
/** Trait that will connect a PLIC to a subsystem */
trait CanHavePeripheryPLIC { this: BaseSubsystem =>
- val plicOpt = p(PLICKey).map { params =>
+ val (plicOpt, plicDomainOpt) = p(PLICKey).map { params =>
val tlbus = locateTLBusWrapper(p(PLICAttachKey).slaveWhere)
- val plicDomainWrapper = LazyModule(new ClockSinkDomain(take = None))
- plicDomainWrapper.clockNode := tlbus.fixedClockNode
+ val plicDomainWrapper = tlbus.generateSynchronousDomain("PLIC").suggestName("plic_domain")
val plic = plicDomainWrapper { LazyModule(new TLPLIC(params, tlbus.beatBytes)) }
- plic.node := tlbus.coupleTo("plic") { TLFragmenter(tlbus) := _ }
- plic.intnode :=* ibus.toPLIC
+ plicDomainWrapper { plic.node := tlbus.coupleTo("plic") { TLFragmenter(tlbus, Some("PLIC")) := _ } }
+ plicDomainWrapper { plic.intnode :=* ibus.toPLIC }
- plic
- }
+ (plic, plicDomainWrapper)
+ }.unzip
}
diff --git a/src/main/scala/devices/tilelink/TestRAM.scala b/src/main/scala/devices/tilelink/TestRAM.scala
index 9fcb9a02d12..368c176a9ee 100644
--- a/src/main/scala/devices/tilelink/TestRAM.scala
+++ b/src/main/scala/devices/tilelink/TestRAM.scala
@@ -4,9 +4,13 @@ package freechips.rocketchip.devices.tilelink
import chisel3._
import chisel3.util._
-import org.chipsalliance.cde.config.Parameters
-import freechips.rocketchip.diplomacy._
-import freechips.rocketchip.tilelink._
+
+import org.chipsalliance.cde.config._
+import org.chipsalliance.diplomacy.lazymodule._
+
+import freechips.rocketchip.diplomacy.{AddressSet, RegionType, TransferSizes}
+import freechips.rocketchip.resources.{MemoryDevice}
+import freechips.rocketchip.tilelink.{TLDelayer, TLFuzzer, TLManagerNode, TLMessages, TLRAMModel, TLSlaveParameters, TLSlavePortParameters}
// Do not use this for synthesis! Only for simulation.
class TLTestRAM(address: AddressSet, executable: Boolean = true, beatBytes: Int = 4, trackCorruption: Boolean = true)(implicit p: Parameters) extends LazyModule
diff --git a/src/main/scala/devices/tilelink/Zero.scala b/src/main/scala/devices/tilelink/Zero.scala
index 2d542b99b86..0e248479f70 100644
--- a/src/main/scala/devices/tilelink/Zero.scala
+++ b/src/main/scala/devices/tilelink/Zero.scala
@@ -4,8 +4,12 @@ package freechips.rocketchip.devices.tilelink
import chisel3._
import chisel3.util._
-import org.chipsalliance.cde.config.Parameters
-import freechips.rocketchip.diplomacy._
+
+import org.chipsalliance.cde.config._
+import org.chipsalliance.diplomacy.lazymodule._
+
+import freechips.rocketchip.diplomacy.{AddressSet, RegionType}
+import freechips.rocketchip.resources.{SimpleDevice}
import freechips.rocketchip.tilelink.TLMessages
/** This /dev/null device accepts single beat gets/puts, as well as atomics.
diff --git a/src/main/scala/diplomacy/AddressRange.scala b/src/main/scala/diplomacy/AddressRange.scala
index c6d55766932..0235d393a50 100644
--- a/src/main/scala/diplomacy/AddressRange.scala
+++ b/src/main/scala/diplomacy/AddressRange.scala
@@ -60,21 +60,3 @@ object AddressRange
def subtract(from: Seq[AddressRange], take: Seq[AddressRange]): Seq[AddressRange] =
take.foldLeft(from) { case (left, r) => left.flatMap { _.subtract(r) } }
}
-
-case class AddressMapEntry(range: AddressRange, permissions: ResourcePermissions, names: Seq[String]) {
- val ResourcePermissions(r, w, x, c, a) = permissions
-
- def toString(aw: Int) = s"\t%${aw}x - %${aw}x %c%c%c%c%c %s".format(
- range.base,
- range.base+range.size,
- if (a) 'A' else ' ',
- if (r) 'R' else ' ',
- if (w) 'W' else ' ',
- if (x) 'X' else ' ',
- if (c) 'C' else ' ',
- names.mkString(", "))
-
- def toJSON = s"""{"base":[${range.base}],"size":[${range.size}],""" +
- s""""r":[$r],"w":[$w],"x":[$x],"c":[$c],"a":[$a],""" +
- s""""names":[${names.map('"'+_+'"').mkString(",")}]}"""
-}
diff --git a/src/main/scala/diplomacy/BundleBridge.scala b/src/main/scala/diplomacy/BundleBridge.scala
deleted file mode 100644
index e02d6f4f966..00000000000
--- a/src/main/scala/diplomacy/BundleBridge.scala
+++ /dev/null
@@ -1,205 +0,0 @@
-// See LICENSE.SiFive for license details.
-
-package freechips.rocketchip.diplomacy
-
-import chisel3._
-import chisel3.experimental.{DataMirror, SourceInfo}
-import chisel3.experimental.DataMirror.internal.chiselTypeClone
-import org.chipsalliance.cde.config.Parameters
-import freechips.rocketchip.util.DataToAugmentedData
-
-case class BundleBridgeParams[T <: Data](genOpt: Option[() => T])
-
-case object BundleBridgeParams {
- def apply[T <: Data](gen: () => T): BundleBridgeParams[T] = BundleBridgeParams(Some(gen))
-}
-
-case class BundleBridgeEdgeParams[T <: Data](source: BundleBridgeParams[T], sink: BundleBridgeParams[T])
-
-class BundleBridgeImp[T <: Data]() extends SimpleNodeImp[BundleBridgeParams[T], BundleBridgeParams[T], BundleBridgeEdgeParams[T], T]
-{
- def edge(pd: BundleBridgeParams[T], pu: BundleBridgeParams[T], p: Parameters, sourceInfo: SourceInfo) = BundleBridgeEdgeParams(pd, pu)
- def bundle(e: BundleBridgeEdgeParams[T]): T = {
- val sourceOpt = e.source.genOpt.map(_())
- val sinkOpt = e.sink.genOpt.map(_())
- (sourceOpt, sinkOpt) match {
- case (None, None) =>
- throw new Exception("BundleBridge needs source or sink to provide bundle generator function")
- case (Some(a), None) => chiselTypeClone(a)
- case (None, Some(b)) => chiselTypeClone(b)
- case (Some(a), Some(b)) => {
- require(DataMirror.checkTypeEquivalence(a, b),
- s"BundleBridge requires doubly-specified source and sink generators to have equivalent Chisel Data types, but got \n$a\n vs\n$b")
- chiselTypeClone(a)
- }
- }
- }
- def render(e: BundleBridgeEdgeParams[T]) = RenderedEdge(colour = "#cccc00" /* yellow */)
-}
-
-case class BundleBridgeSink[T <: Data](genOpt: Option[() => T] = None)
- (implicit valName: ValName)
- extends SinkNode(new BundleBridgeImp[T])(Seq(BundleBridgeParams(genOpt)))
-{
- def bundle: T = in(0)._1
-
- private def inferOutput = bundle.getElements.forall { elt =>
- DataMirror.directionOf(elt) == ActualDirection.Unspecified
- }
-
- def makeIO()(implicit valName: ValName): T = {
- val io: T = IO(if (inferOutput) Output(chiselTypeOf(bundle)) else chiselTypeClone(bundle))
- io.suggestName(valName.name)
- io <> bundle
- io
- }
- def makeIO(name: String): T = makeIO()(ValName(name))
-}
-
-object BundleBridgeSink {
- def apply[T <: Data]()(implicit valName: ValName): BundleBridgeSink[T] = {
- BundleBridgeSink(None)
- }
-}
-
-case class BundleBridgeSource[T <: Data](genOpt: Option[() => T] = None)(implicit valName: ValName) extends SourceNode(new BundleBridgeImp[T])(Seq(BundleBridgeParams(genOpt)))
-{
- def bundle: T = out(0)._1
-
- private def inferInput = bundle.getElements.forall { elt =>
- DataMirror.directionOf(elt) == ActualDirection.Unspecified
- }
-
- def makeIO()(implicit valName: ValName): T = {
- val io: T = IO(if (inferInput) Input(chiselTypeOf(bundle)) else Flipped(chiselTypeClone(bundle)))
- io.suggestName(valName.name)
- bundle <> io
- io
- }
- def makeIO(name: String): T = makeIO()(ValName(name))
-
- private var doneSink = false
- def makeSink()(implicit p: Parameters) = {
- require (!doneSink, "Can only call makeSink() once")
- doneSink = true
- val sink = BundleBridgeSink[T]()
- sink := this
- sink
- }
-}
-
-object BundleBridgeSource {
- def apply[T <: Data]()(implicit valName: ValName): BundleBridgeSource[T] = {
- BundleBridgeSource(None)
- }
- def apply[T <: Data](gen: () => T)(implicit valName: ValName): BundleBridgeSource[T] = {
- BundleBridgeSource(Some(gen))
- }
-}
-
-case class BundleBridgeIdentityNode[T <: Data]()(implicit valName: ValName) extends IdentityNode(new BundleBridgeImp[T])()
-case class BundleBridgeEphemeralNode[T <: Data]()(implicit valName: ValName) extends EphemeralNode(new BundleBridgeImp[T])()
-
-object BundleBridgeNameNode {
- def apply[T <: Data](name: String) = BundleBridgeIdentityNode[T]()(ValName(name))
-}
-
-case class BundleBridgeNexusNode[T <: Data](default: Option[() => T] = None,
- inputRequiresOutput: Boolean = false) // when false, connecting a source does not mandate connecting a sink
- (implicit valName: ValName)
- extends NexusNode(new BundleBridgeImp[T])(
- dFn = seq => seq.headOption.getOrElse(BundleBridgeParams(default)),
- uFn = seq => seq.headOption.getOrElse(BundleBridgeParams(None)),
- inputRequiresOutput = inputRequiresOutput,
- outputRequiresInput = !default.isDefined)
-
-class BundleBridgeNexus[T <: Data](
- inputFn: Seq[T] => T,
- outputFn: (T, Int) => Seq[T],
- default: Option[() => T] = None,
- inputRequiresOutput: Boolean = false,
- override val shouldBeInlined: Boolean = true
-) (implicit p: Parameters) extends LazyModule
-{
- val node = BundleBridgeNexusNode[T](default, inputRequiresOutput)
-
- lazy val module = new Impl
- class Impl extends LazyModuleImp(this) {
- val defaultWireOpt = default.map(_())
- val inputs: Seq[T] = node.in.map(_._1)
- inputs.foreach { i => require(DataMirror.checkTypeEquivalence(i, inputs.head),
- s"${node.context} requires all inputs have equivalent Chisel Data types, but got\n$i\nvs\n${inputs.head}")
- }
- inputs.flatMap(_.getElements).foreach { elt => DataMirror.directionOf(elt) match {
- case ActualDirection.Output => ()
- case ActualDirection.Unspecified => ()
- case _ => require(false, s"${node.context} can only be used with Output-directed Bundles")
- } }
-
- val outputs: Seq[T] = if (node.out.size > 0) {
- val broadcast: T = if (inputs.size >= 1) inputFn(inputs) else defaultWireOpt.get
- outputFn(broadcast, node.out.size)
- } else { Nil }
-
- node.out.map(_._1).foreach { o => require(DataMirror.checkTypeEquivalence(o, outputs.head),
- s"${node.context} requires all outputs have equivalent Chisel Data types, but got\n$o\nvs\n${outputs.head}")
- }
-
- require(outputs.size == node.out.size,
- s"${node.context} outputFn must generate one output wire per edgeOut, but got ${outputs.size} vs ${node.out.size}")
-
- node.out.zip(outputs).foreach { case ((out, _), bcast) => out := bcast }
- }
-}
-
-object BundleBridgeNexus {
- def safeRegNext[T <: Data](x: T): T = {
- val reg = Reg(chiselTypeOf(x))
- reg := x
- reg
- }
-
- def requireOne[T <: Data](registered: Boolean)(seq: Seq[T]): T = {
- require(seq.size == 1, "BundleBroadcast default requires one input")
- if (registered) safeRegNext(seq.head) else seq.head
- }
-
- def orReduction[T <: Data](registered: Boolean)(seq: Seq[T]): T = {
- val x = seq.reduce((a,b) => (a.asUInt | b.asUInt).asTypeOf(seq.head))
- if (registered) safeRegNext(x) else x
- }
-
- def fillN[T <: Data](registered: Boolean)(x: T, n: Int): Seq[T] = Seq.fill(n) {
- if (registered) safeRegNext(x) else x
- }
-
- def apply[T <: Data](
- inputFn: Seq[T] => T = orReduction[T](false) _,
- outputFn: (T, Int) => Seq[T] = fillN[T](false) _,
- default: Option[() => T] = None,
- inputRequiresOutput: Boolean = false,
- shouldBeInlined: Boolean = true
- )(implicit p: Parameters): BundleBridgeNexusNode[T] = {
- val nexus = LazyModule(new BundleBridgeNexus[T](inputFn, outputFn, default, inputRequiresOutput, shouldBeInlined))
- nexus.node
- }
-}
-
-object BundleBroadcast {
- def apply[T <: Data](
- name: Option[String] = None,
- registered: Boolean = false,
- default: Option[() => T] = None,
- inputRequiresOutput: Boolean = false, // when false, connecting a source does not mandate connecting a sink
- shouldBeInlined: Boolean = true
- )(implicit p: Parameters): BundleBridgeNexusNode[T] = {
- val broadcast = LazyModule(new BundleBridgeNexus[T](
- inputFn = BundleBridgeNexus.requireOne[T](registered) _,
- outputFn = BundleBridgeNexus.fillN[T](registered) _,
- default = default,
- inputRequiresOutput = inputRequiresOutput,
- shouldBeInlined = shouldBeInlined))
- name.foreach(broadcast.suggestName(_))
- broadcast.node
- }
-}
diff --git a/src/main/scala/diplomacy/Clone.scala b/src/main/scala/diplomacy/Clone.scala
deleted file mode 100644
index 4e0b9209d65..00000000000
--- a/src/main/scala/diplomacy/Clone.scala
+++ /dev/null
@@ -1,37 +0,0 @@
-// See LICENSE.SiFive for license details.
-
-package freechips.rocketchip.diplomacy
-
-import chisel3._
-import chisel3.experimental.{CloneModuleAsRecord, SourceInfo}
-
-final class CloneLazyModule private (val base: LazyModule)
-{
- // Pay special attention to the .iParams and .oParams of the node, which
- // indicate the parameters a stand-in master must supply.
- def clone[DI, UI, EI, BI <: Data, DO, UO, EO, BO <: Data](node: NodeHandle[DI, UI, EI, BI, DO, UO, EO, BO])(implicit valName: ValName) =
- new MixedTestNode(node, this)
-
- protected[diplomacy] lazy val io = CloneModuleAsRecord(base.module)
-}
-
-object CloneLazyModule
-{
- /** The old API **/
- def apply(base: LazyModule) = new CloneLazyModule(base)
-
-
- /** Constructs a [[LazyModule]], but replaces its [[LazyModuleImp]] with a cloned [[LazyModuleImp]]
- * from another source. The user of [[CloneLazyModule]] must be careful to guarantee that
- * bc and cloneProto have equivalent [[LazyModuleImp]]'s.
- *
- * @param bc [[LazyModule]] instance to wrap, this instance will not evaluate its own [[LazyModuleImp]]
- * @param cloneProto [[LazyModule]] instance which will provide the [[LazyModuleImp]] implementation for bc
- */
- def apply[A <: LazyModule, B <: LazyModule](bc: A, cloneProto: B)(implicit valName: ValName, sourceInfo: SourceInfo): A = {
- require(LazyModule.scope.isDefined, s"CloneLazyModule ${bc.name} ${sourceLine(sourceInfo)} can only exist as the child of a parent LazyModule")
- LazyModule(bc)
- bc.cloneProto = Some(cloneProto)
- bc
- }
-}
diff --git a/src/main/scala/diplomacy/LazyModule.scala b/src/main/scala/diplomacy/LazyModule.scala
deleted file mode 100644
index 5f4da46cb9a..00000000000
--- a/src/main/scala/diplomacy/LazyModule.scala
+++ /dev/null
@@ -1,612 +0,0 @@
-// See LICENSE.SiFive for license details.
-
-package freechips.rocketchip.diplomacy
-
-import chisel3._
-import chisel3.internal.sourceinfo.{SourceInfo, UnlocatableSourceInfo}
-import chisel3.{Module, RawModule, Reset, withClockAndReset}
-import chisel3.experimental.{ChiselAnnotation, CloneModuleAsRecord}
-import firrtl.passes.InlineAnnotation
-import org.chipsalliance.cde.config.Parameters
-
-import scala.collection.immutable.{SeqMap, SortedMap}
-import scala.util.matching._
-
-/** While the [[freechips.rocketchip.diplomacy]] package allows fairly abstract parameter negotiation while constructing a DAG,
- * [[LazyModule]] builds on top of the DAG annotated with the negotiated parameters and leverage's Scala's lazy evaluation property to split Chisel module generation into two phases:
- *
- * - Phase 1 (diplomatic) states parameters, hierarchy, and connections:
- * - [[LazyModule]] and [[BaseNode]] instantiation.
- * - [[BaseNode]] binding.
- * - Phase 2 (lazy) generates [[chisel3]] Modules:
- * - Parameters are negotiated across [[BaseNode]]s.
- * - Concrete [[Bundle]]s are created along [[BaseNode]]s and connected
- * - [[AutoBundle]] are automatically connected along [[Edges]], punching IO as necessary though module hierarchy
- * - [[LazyModuleImpLike]] generates [[chisel3.Module]]s.
- */
-abstract class LazyModule()(implicit val p: Parameters) {
- /** Contains sub-[[LazyModule]]s; can be accessed by [[getChildren]]. */
- protected[diplomacy] var children: List[LazyModule] = List[LazyModule]()
- /** Contains the [[BaseNode]]s instantiated within this instance. */
- protected[diplomacy] var nodes: List[BaseNode] = List[BaseNode]()
- /** Stores [[SourceInfo]] of this instance.
- *
- * The companion object factory method will set this to the correct value.
- */
- protected[diplomacy] var info: SourceInfo = UnlocatableSourceInfo
- /** Parent of this LazyModule. If this instance is at the top of the hierarchy, this will be [[None]]. */
- protected[diplomacy] val parent: Option[LazyModule] = LazyModule.scope
- /** If set, the LazyModule this LazyModule will be a clone of
- * Note that children of a cloned module will also have this set
- */
- protected[diplomacy] var cloneProto: Option[LazyModule] = None
-
- /** Code snippets from [[InModuleBody]] injection. */
- protected[diplomacy] var inModuleBody: List[() => Unit] = List[() => Unit]()
-
- /** Sequence of ancestor LazyModules, starting with [[parent]]. */
- def parents: Seq[LazyModule] = parent match {
- case None => Nil
- case Some(x) => x +: x.parents
- }
-
- // Push this instance onto the [[LazyModule.scope]] stack.
- LazyModule.scope = Some(this)
- parent.foreach(p => p.children = this :: p.children)
-
- /** Accumulates Some(names), taking the final one. `None`s are ignored. */
- private var suggestedNameVar: Option[String] = None
-
- /** Suggests instance name for [[LazyModuleImpLike]] module. */
- def suggestName(x: String): this.type = suggestName(Some(x))
-
- def suggestName(x: Option[String]): this.type = {
- x.foreach { n => suggestedNameVar = Some(n) }
- this
- }
-
- /** Finds the name of the first non-anonymous Scala class while walking up the class hierarchy. */
- private def findClassName(c: Class[_]): String = {
- val n = c.getName.split('.').last
- if (n.contains('$')) findClassName(c.getSuperclass) else n
- }
-
- /** Scala class name of this instance. */
- lazy val className: String = findClassName(getClass)
- /** Suggested instance name. Defaults to [[className]].*/
- lazy val suggestedName: String = suggestedNameVar.getOrElse(className)
- /** Suggested module name. Defaults to [[className]].*/
- lazy val desiredName: String = className // + hashcode?
-
- /** Return instance name. */
- def name: String = suggestedName // className + suggestedName ++ hashcode ?
- /** Return source line that defines this instance. */
- def line: String = sourceLine(info)
-
- // Accessing these names can only be done after circuit elaboration!
- /** Module name in verilog, used in GraphML.
- * For cloned lazyModules, this is the name of the prototype
- */
- lazy val moduleName: String = cloneProto.map(_.module.name).getOrElse(module.name)
- /** Hierarchical path of this instance, used in GraphML.
- * For cloned modules, construct this manually (since this.module should not be evaluated)
- */
- lazy val pathName: String = cloneProto.map(p => s"${parent.get.pathName}.${p.instanceName}")
- .getOrElse(module.pathName)
-
- /** Instance name in verilog. Should only be accessed after circuit elaboration. */
- lazy val instanceName: String = pathName.split('.').last
-
- /** [[chisel3]] hardware implementation of this [[LazyModule]].
- *
- * Subclasses should define this function as `lazy val`s for lazy evaluation.
- * Generally, the evaluation of this marks the beginning of phase 2.
- */
- def module: LazyModuleImpLike
-
- /** Recursively traverse all child LazyModules and Nodes of this LazyModule
- * to construct the set of empty [[Dangle]]'s that are this module's top-level IO
- * This is effectively doing the same thing as [[LazyModuleImp.instantiate]], but
- * without constructing any [[Module]]'s
- */
- protected[diplomacy] def cloneDangles(): List[Dangle] = {
- children.foreach(c => require(c.cloneProto.isDefined, s"${c.info}, ${c.parent.get.info}"))
- val childDangles = children.reverse.flatMap { c => c.cloneDangles() }
- val nodeDangles = nodes.reverse.flatMap(n => n.cloneDangles())
- val allDangles = nodeDangles ++ childDangles
- val pairing = SortedMap(allDangles.groupBy(_.source).toSeq: _*)
- val done = Set() ++ pairing.values.filter(_.size == 2).map {
- case Seq(a, b) =>
- require(a.flipped != b.flipped)
- a.source
- case _ =>
- None
- }
- val forward = allDangles.filter(d => !done(d.source))
- val dangles = forward.map { d =>
- d.copy(name = suggestedName + "_" + d.name)
- }
- dangles
- }
-
- /** Whether to omit generating the GraphML for this [[LazyModule]].
- *
- * Recursively checks whether all [[BaseNode]]s and children [[LazyModule]]s should omit GraphML
- * generation.
- */
- def omitGraphML: Boolean = nodes.forall(_.omitGraphML) && children.forall(_.omitGraphML)
-
- /** Whether this [[LazyModule]]'s module should be marked for in-lining by FIRRTL.
- *
- * The default heuristic is to inline any parents whose children have been inlined
- * and whose nodes all produce identity circuits.
- */
- def shouldBeInlined: Boolean = nodes.forall(_.circuitIdentity) && children.forall(_.shouldBeInlined)
-
- /** GraphML representation for this instance.
- *
- * This is a representation of the Nodes, Edges, LazyModule hierarchy,
- * and any other information that is added in by implementations.
- * It can be converted to an image with various third-party tools.
- */
- lazy val graphML: String = parent.map(_.graphML).getOrElse {
- val buf = new StringBuilder
- buf ++= "\n"
- buf ++= "\n"
- buf ++= " \n"
- buf ++= " \n"
- buf ++= " \n"
- buf ++= " \n"
- nodesGraphML(buf, " ")
- edgesGraphML(buf, " ")
- buf ++= " \n"
- buf ++= "\n"
- buf.toString
- }
-
- /** A globally unique [[LazyModule]] index for this instance. */
- private val index = {
- LazyModule.index = LazyModule.index + 1
- LazyModule.index
- }
-
- /** Generate GraphML fragment for nodes.
- *
- * @param buf String buffer to write to.
- * @param pad Padding as prefix for indentation purposes.
- */
- private def nodesGraphML(buf: StringBuilder, pad: String): Unit = {
- buf ++= s"""$pad\n"""
- buf ++= s"""$pad $instanceName\n"""
- buf ++= s"""$pad $moduleName ($pathName)\n"""
- buf ++= s"""$pad \n"""
- nodes.filter(!_.omitGraphML).foreach { n =>
- buf ++= s"""$pad \n"""
- buf ++= s"""$pad \n"""
- buf ++= s"""$pad ${n.formatNode}, \n${n.nodedebugstring}\n"""
- buf ++= s"""$pad \n"""
- }
- children.filter(!_.omitGraphML).foreach(_.nodesGraphML(buf, pad + " "))
- buf ++= s"""$pad \n"""
- buf ++= s"""$pad\n"""
- }
-
- /** Generate GraphML fragment for edges.
- *
- * @param buf String buffer to write to.
- * @param pad Padding as prefix for indentation purposes.
- */
- private def edgesGraphML(buf: StringBuilder, pad: String): Unit = {
- nodes.filter(!_.omitGraphML) foreach { n =>
- n.outputs.filter(!_._1.omitGraphML).foreach { case (o, edge) =>
- val RenderedEdge(colour, label, flipped) = edge
- buf ++= pad
- buf ++= """"
- } else {
- buf ++= s""" source=\"$index::${n.index}\""""
- buf ++= s""" target=\"${o.lazyModule.index}::${o.index}\">"""
- }
- buf ++= s""""""
- if (flipped) {
- buf ++= s""""""
- } else {
- buf ++= s""""""
- }
- buf ++= s""""""
- buf ++= s"""$label"""
- buf ++= s"""\n"""
- }
- }
- children.filter(!_.omitGraphML).foreach { c => c.edgesGraphML(buf, pad) }
- }
-
- /** Call function on all of this [[LazyModule]]'s [[children]].
- *
- * @param iterfunc Function to call on each descendant.
- */
- def childrenIterator(iterfunc: LazyModule => Unit): Unit = {
- iterfunc(this)
- children.foreach(_.childrenIterator(iterfunc))
- }
-
- /** Call function on all of this [[LazyModule]]'s [[nodes]].
- *
- * @param iterfunc Function to call on each descendant.
- */
- def nodeIterator(iterfunc: BaseNode => Unit): Unit = {
- nodes.foreach(iterfunc)
- childrenIterator(_.nodes.foreach(iterfunc))
- }
-
- /** Accessor for [[children]]. */
- def getChildren: List[LazyModule] = children
-
- /** Accessor for [[nodes]]. */
- def getNodes: List[BaseNode] = nodes
-}
-
-object LazyModule {
- /** Current [[LazyModule]] scope. The scope is a stack of [[LazyModule]]/[[LazyScope]]s.
- *
- * Each call to [[LazyScope.apply]] or [[LazyModule.apply]] will push that item onto the current scope.
- */
- protected[diplomacy] var scope: Option[LazyModule] = None
- /** Global index of [[LazyModule]]. Note that there is no zeroth module. */
- private var index = 0
-
- /** Wraps a [[LazyModule]], handling bookkeeping of scopes.
- *
- * This method manages the scope and index of the [[LazyModule]]s. All [[LazyModule]]s must be
- * wrapped exactly once.
- *
- * @param bc [[LazyModule]] instance to be wrapped.
- * @param valName [[ValName]] used to name this instance,
- * it can be automatically generated by [[ValName]] macro, or specified manually.
- * @param sourceInfo [[SourceInfo]] information about where this [[LazyModule]] is being generated
- */
- def apply[T <: LazyModule](bc: T)(implicit valName: ValName, sourceInfo: SourceInfo): T = {
- // Make sure the user puts [[LazyModule]] around modules in the correct order.
- require(scope.isDefined, s"LazyModule() applied to ${bc.name} twice ${sourceLine(sourceInfo)}. Ensure that descendant LazyModules are instantiated with the LazyModule() wrapper and that you did not call LazyModule() twice.")
- require(scope.get eq bc, s"LazyModule() applied to ${bc.name} before ${scope.get.name} ${sourceLine(sourceInfo)}")
- // Pop from the [[LazyModule.scope]] stack.
- scope = bc.parent
- bc.info = sourceInfo
- if (bc.suggestedNameVar.isEmpty) bc.suggestName(valName.name)
- bc
- }
-}
-
-/** Trait describing the actual [[Module]] implementation wrapped by a [[LazyModule]].
- *
- * This is the actual Chisel module that is lazily-evaluated in the second phase of Diplomacy.
- */
-sealed trait LazyModuleImpLike extends RawModule {
- /** [[LazyModule]] that contains this instance. */
- val wrapper: LazyModule
- /** IOs that will be automatically "punched" for this instance. */
- val auto: AutoBundle
- /** The metadata that describes the [[HalfEdge]]s which generated [[auto]]. */
- protected[diplomacy] val dangles: Seq[Dangle]
-
- // [[wrapper.module]] had better not be accessed while LazyModules are still being built!
- require(LazyModule.scope.isEmpty, s"${wrapper.name}.module was constructed before LazyModule() was run on ${LazyModule.scope.get.name}")
-
- /** Set module name. Defaults to the containing LazyModule's desiredName.*/
- override def desiredName: String = wrapper.desiredName
-
- suggestName(wrapper.suggestedName)
-
- /** [[Parameters]] for chisel [[Module]]s. */
- implicit val p: Parameters = wrapper.p
-
- /** instantiate this [[LazyModule]],
- * return [[AutoBundle]] and a unconnected [[Dangle]]s from this module and submodules. */
- protected[diplomacy] def instantiate(): (AutoBundle, List[Dangle]) = {
- // 1. It will recursively append [[wrapper.children]] into [[chisel3.internal.Builder]],
- // 2. return [[Dangle]]s from each module.
- val childDangles = wrapper.children.reverse.flatMap { c =>
- implicit val sourceInfo: SourceInfo = c.info
- c.cloneProto.map { cp =>
- // If the child is a clone, then recursively set cloneProto of its children as well
- def assignCloneProtos(bases: Seq[LazyModule], clones: Seq[LazyModule]): Unit = {
- require(bases.size == clones.size)
- (bases zip clones).map { case (l,r) =>
- require(l.getClass == r.getClass, s"Cloned children class mismatch ${l.name} != ${r.name}")
- l.cloneProto = Some(r)
- assignCloneProtos(l.children, r.children)
- }
- }
- assignCloneProtos(c.children, cp.children)
- // Clone the child module as a record, and get its [[AutoBundle]]
- val clone = CloneModuleAsRecord(cp.module).suggestName(c.suggestedName)
- val clonedAuto = clone("auto").asInstanceOf[AutoBundle]
- // Get the empty [[Dangle]]'s of the cloned child
- val rawDangles = c.cloneDangles()
- require(rawDangles.size == clonedAuto.elements.size)
- // Assign the [[AutoBundle]] fields of the cloned record to the empty [[Dangle]]'s
- val dangles = (rawDangles zip clonedAuto.elements).map { case (d, (_, io)) =>
- d.copy(dataOpt = Some(io))
- }
- dangles
- } .getOrElse {
- // For non-clones, instantiate the child module
- val mod = try {
- Module(c.module)
- } catch {
- case e: ChiselException => {
- println(s"Chisel exception caught when instantiating ${c.name} within ${this.name} at ${c.line}")
- throw e
- }
- }
- mod.dangles
- }
- }
-
- // Ask each node in this [[LazyModule]] to call [[BaseNode.instantiate]].
- // This will result in a sequence of [[Dangle]] from these [[BaseNode]]s.
- val nodeDangles = wrapper.nodes.reverse.flatMap(_.instantiate())
- // Accumulate all the [[Dangle]]s from this node and any accumulated from its [[wrapper.children]]
- val allDangles = nodeDangles ++ childDangles
- // Group [[allDangles]] by their [[source]].
- val pairing = SortedMap(allDangles.groupBy(_.source).toSeq: _*)
- // For each [[source]] set of [[Dangle]]s of size 2, ensure that these
- // can be connected as a source-sink pair (have opposite flipped value).
- // Make the connection and mark them as [[done]].
- val done = Set() ++ pairing.values.filter(_.size == 2).map {
- case Seq(a, b) =>
- require(a.flipped != b.flipped)
- // @todo <> in chisel3 makes directionless connection.
- if (a.flipped) {
- a.data <> b.data
- } else {
- b.data <> a.data
- }
- a.source
- case _ =>
- None
- }
- // Find all [[Dangle]]s which are still not connected. These will end up as [[AutoBundle]] [[IO]] ports on the module.
- val forward = allDangles.filter(d => !done(d.source))
- // Generate [[AutoBundle]] IO from [[forward]].
- val auto = IO(new AutoBundle(forward.map { d => (d.name, d.data, d.flipped) }: _*))
- // Pass the [[Dangle]]s which remained and were used to generate the [[AutoBundle]] I/O ports up to the [[parent]] [[LazyModule]]
- val dangles = (forward zip auto.elements) map { case (d, (_, io)) =>
- if (d.flipped) {
- d.data <> io
- } else {
- io <> d.data
- }
- d.copy(dataOpt = Some(io), name = wrapper.suggestedName + "_" + d.name)
- }
- // Push all [[LazyModule.inModuleBody]] to [[chisel3.internal.Builder]].
- wrapper.inModuleBody.reverse.foreach {
- _ ()
- }
-
- if (wrapper.shouldBeInlined) {
- chisel3.experimental.annotate(new ChiselAnnotation {
- def toFirrtl = InlineAnnotation(toNamed)
- })
- }
-
- // Return [[IO]] and [[Dangle]] of this [[LazyModuleImp]].
- (auto, dangles)
- }
-}
-
-/** Actual description of a [[Module]] which can be instantiated by a call to [[LazyModule.module]].
- *
- * @param wrapper the [[LazyModule]] from which the `.module` call is being made.
- */
-class LazyModuleImp(val wrapper: LazyModule) extends Module with LazyModuleImpLike {
- /** Instantiate hardware of this `Module`. */
- val (auto, dangles) = instantiate()
-}
-
-/** Actual description of a [[RawModule]] which can be instantiated by a call to [[LazyModule.module]].
- *
- * @param wrapper the [[LazyModule]] from which the `.module` call is being made.
- */
-class LazyRawModuleImp(val wrapper: LazyModule) extends RawModule with LazyModuleImpLike {
- // These wires are the default clock+reset for all LazyModule children.
- // It is recommended to drive these even if you manually drive the [[clock]] and [[reset]] of all of the
- // [[LazyRawModuleImp]] children.
- // Otherwise, anonymous children ([[Monitor]]s for example) will not have their [[clock]] and/or [[reset]] driven properly.
- /** drive clock explicitly. */
- val childClock: Clock = Wire(Clock())
- /** drive reset explicitly. */
- val childReset: Reset = Wire(Reset())
- // the default is that these are disabled
- childClock := false.B.asClock
- childReset := chisel3.DontCare
- val (auto, dangles) = withClockAndReset(childClock, childReset) {
- instantiate()
- }
-}
-
-/** Used for a [[LazyModule]] which does not need to define any [[LazyModuleImp]] implementation.
- *
- * It can be used as wrapper that only instantiates and connects [[LazyModule]]s.
- */
-class SimpleLazyModule(implicit p: Parameters) extends LazyModule {
- lazy val module = new LazyModuleImp(this)
-}
-
-/** Allows dynamic creation of [[Module]] hierarchy and "shoving" logic into a [[LazyModule]]. */
-trait LazyScope {
- this: LazyModule =>
- override def toString: String = s"LazyScope named $name"
-
- /** Evaluate `body` in the current [[LazyModule.scope]] */
- def apply[T](body: => T): T = {
- // Preserve the previous value of the [[LazyModule.scope]], because when calling [[apply]] function,
- // [[LazyModule.scope]] will be altered.
- val saved = LazyModule.scope
- // [[LazyModule.scope]] stack push.
- LazyModule.scope = Some(this)
- // Evaluate [[body]] in the current `scope`, saving the result to [[out]].
- val out = body
- // Check that the `scope` after evaluating `body` is the same as when we started.
- require(LazyModule.scope.isDefined, s"LazyScope $name tried to exit, but scope was empty!")
- require(LazyModule.scope.get eq this, s"LazyScope $name exited before LazyModule ${LazyModule.scope.get.name} was closed")
- // [[LazyModule.scope]] stack pop.
- LazyModule.scope = saved
- out
- }
-}
-
-/** Used to automatically create a level of module hierarchy (a [[SimpleLazyModule]]) within which [[LazyModule]]s can be instantiated and connected.
- *
- * It will instantiate a [[SimpleLazyModule]] to manage evaluation of `body` and evaluate `body` code snippets in this scope.
- */
-object LazyScope {
- /** Create a [[LazyScope]] with an implicit instance name.
- *
- * @param body code executed within the generated [[SimpleLazyModule]].
- * @param valName instance name of generated [[SimpleLazyModule]].
- * @param p [[Parameters]] propagated to [[SimpleLazyModule]].
- */
- def apply[T](body: => T)(implicit valName: ValName, p: Parameters): T = {
- apply(valName.name, "SimpleLazyModule", None)(body)(p)
- }
-
- /** Create a [[LazyScope]] with an explicitly defined instance name.
- *
- * @param name instance name of generated [[SimpleLazyModule]].
- * @param body code executed within the generated `SimpleLazyModule`
- * @param p [[Parameters]] propagated to [[SimpleLazyModule]].
- */
- def apply[T](name: String)(body: => T)(implicit p: Parameters): T = {
- apply(name, "SimpleLazyModule", None)(body)(p)
- }
-
- /** Create a [[LazyScope]] with an explicit instance and class name, and control inlining.
- *
- * @param name instance name of generated [[SimpleLazyModule]].
- * @param desiredModuleName class name of generated [[SimpleLazyModule]].
- * @param overrideInlining tell FIRRTL that this [[SimpleLazyModule]]'s module should be inlined.
- * @param body code executed within the generated `SimpleLazyModule`
- * @param p [[Parameters]] propagated to [[SimpleLazyModule]].
- */
- def apply[T](
- name: String,
- desiredModuleName: String,
- overrideInlining: Option[Boolean] = None)
- (body: => T)
- (implicit p: Parameters): T =
- {
- val scope = LazyModule(new SimpleLazyModule with LazyScope {
- override lazy val desiredName = desiredModuleName
- override def shouldBeInlined = overrideInlining.getOrElse(super.shouldBeInlined)
- }).suggestName(name)
- scope {
- body
- }
- }
-
- /** Create a [[LazyScope]] to temporarily group children for some reason, but tell Firrtl to inline it.
- *
- * For example, we might want to control a set of children's clocks but then not keep the parent wrapper.
- *
- * @param body code executed within the generated `SimpleLazyModule`
- * @param p [[Parameters]] propagated to [[SimpleLazyModule]].
- */
- def inline[T](body: => T)(implicit p: Parameters): T = {
- apply("noname", "ShouldBeInlined", Some(false))(body)(p)
- }
-}
-
-/** One side metadata of a [[Dangle]].
- *
- * Describes one side of an edge going into or out of a [[BaseNode]].
- *
- * @param serial the global [[BaseNode.serial]] number of the [[BaseNode]] that this [[HalfEdge]] connects to.
- * @param index the `index` in the [[BaseNode]]'s input or output port list that this [[HalfEdge]] belongs to.
- */
-case class HalfEdge(serial: Int, index: Int) extends Ordered[HalfEdge] {
-
- import scala.math.Ordered.orderingToOrdered
-
- def compare(that: HalfEdge): Int = HalfEdge.unapply(this) compare HalfEdge.unapply(that)
-}
-
-/** [[Dangle]] captures the `IO` information of a [[LazyModule]] and which two [[BaseNode]]s the [[Edges]]/[[Bundle]] connects.
- *
- * [[Dangle]]s are generated by [[BaseNode.instantiate]]
- * using [[MixedNode.danglesOut]] and [[MixedNode.danglesIn]] ,
- * [[LazyModuleImp.instantiate]] connects those that go to internal or explicit IO connections
- * in a [[LazyModule]].
- *
- * @param source the source [[HalfEdge]] of this [[Dangle]], which captures the source [[BaseNode]] and the port `index` within that [[BaseNode]].
- * @param sink sink [[HalfEdge]] of this [[Dangle]], which captures the sink [[BaseNode]] and the port `index` within that [[BaseNode]].
- * @param flipped flip or not in [[AutoBundle.makeElements]]. If true this corresponds to `danglesOut`, if false it corresponds to `danglesIn`.
- * @param dataOpt actual [[Data]] for the hardware connection. Can be empty if this belongs to a cloned module
- */
-case class Dangle(source: HalfEdge, sink: HalfEdge, flipped: Boolean, name: String, dataOpt: Option[Data]) {
- def data = dataOpt.get
-}
-
-/** [[AutoBundle]] will construct the [[Bundle]]s for a [[LazyModule]] in [[LazyModuleImpLike.instantiate]],
- *
- * @param elts is a sequence of data containing for each IO port a tuple of (name, data, flipped), where
- * name: IO name
- * data: actual data for connection.
- * flipped: flip or not in [[makeElements]]
- */
-final class AutoBundle(elts: (String, Data, Boolean)*) extends Record {
- // We need to preserve the order of elts, despite grouping by name to disambiguate things.
- val elements: SeqMap[String, Data] = SeqMap() ++ elts.zipWithIndex.map(makeElements).groupBy(_._1).values.flatMap {
- // If name is unique, it will return a Seq[index -> (name -> data)].
- case Seq((key, element, i)) => Seq(i -> (key -> element))
- // If name is not unique, name will append with j, and return `Seq[index -> (s"${name}_${j}" -> data)]`.
- case seq => seq.zipWithIndex.map { case ((key, element, i), j) => i -> (key + "_" + j -> element) }
- }.toList.sortBy(_._1).map(_._2)
- require(elements.size == elts.size)
-
- // Trim final "(_[0-9]+)*$" in the name, flip data with flipped.
- private def makeElements(tuple: ((String, Data, Boolean), Int)) = {
- val ((key, data, flip), i) = tuple
- // Trim trailing _0_1_2 stuff so that when we append _# we don't create collisions.
- val regex = new Regex("(_[0-9]+)*$")
- val element = if (flip) Flipped(data.cloneType) else data.cloneType
- (regex.replaceAllIn(key, ""), element, i)
- }
-}
-
-trait ModuleValue[T] {
- def getWrappedValue: T
-}
-
-/** Used to inject code snippets to be evaluated in [[LazyModuleImp.instantiate]] in the current [[LazyModule.scope]].
- *
- * It can be used to create additional hardware outside of the [[LazyModule.children]],
- * connections other than the internal [[BaseNode]] connections,
- * or additional IOs aside from the [[AutoBundle]]
- */
-object InModuleBody {
- def apply[T](body: => T): ModuleValue[T] = {
- require(LazyModule.scope.isDefined, s"InModuleBody invoked outside a LazyModule")
- val scope = LazyModule.scope.get
- // a wrapper to [[body]], being able to extract result after `execute`.
- val out = new ModuleValue[T] {
- var result: Option[T] = None
-
- def execute(): Unit = {
- result = Some(body)
- }
-
- def getWrappedValue: T = {
- require(result.isDefined, s"InModuleBody contents were requested before module was evaluated!")
- result.get
- }
- }
-
- // Prepend [[out.execute]] to [[scope.inModuleBody]],
- // it is a val with type of `() => Unit`, which will be executed in [[LazyModuleImp.instantiate]].
- scope.inModuleBody = out.execute _ +: scope.inModuleBody
- out
- }
-}
diff --git a/src/main/scala/diplomacy/Nodes.scala b/src/main/scala/diplomacy/Nodes.scala
deleted file mode 100644
index 51d3b7e92ad..00000000000
--- a/src/main/scala/diplomacy/Nodes.scala
+++ /dev/null
@@ -1,1800 +0,0 @@
-// See LICENSE.SiFive for license details.
-
-package freechips.rocketchip.diplomacy
-
-import chisel3._
-import chisel3.experimental.SourceInfo
-import org.chipsalliance.cde.config.{Field, Parameters}
-import freechips.rocketchip.util.HeterogeneousBag
-
-import scala.collection.immutable
-import scala.collection.mutable.ListBuffer
-
-/** A field available in [[Parameters]] used to determine whether [[InwardNodeImp.monitor]] will be called. */
-case object MonitorsEnabled extends Field[Boolean](true)
-
-/** When rendering the edge in a graphical format, flip the order in which the edges' source and sink are presented.
- *
- * For example, when rendering graphML, yEd by default tries to put the source node vertically above the sink node, but
- * [[RenderFlipped]] inverts this relationship. When a particular [[LazyModule]] contains both source nodes and sink nodes,
- * flipping the rendering of one node's edge will usual produce a more concise visual layout for the [[LazyModule]].
- */
-case object RenderFlipped extends Field[Boolean](false)
-
-/** [[RenderedEdge]] can set the color and label of the visualization of the DAG. */
-case class RenderedEdge(
- colour: String,
- label: String = "",
- flipped: Boolean = false)
-
-/** [[InwardNodeImp]] defines the types that describe the inward side of the [[BaseNode]].
- *
- * @tparam DI The type of the downward-flowing parameters received on the inner side of the node.
- * @tparam UI The type of the upward-flowing parameters generated by the inner side of the node.
- * @tparam EI The type of the diplomatically-resolved parameters for an Edge connected to the inner side of the node.
- * @tparam BI The type of the [[chisel3.Data]] (usually a [[chisel3.Bundle]]) used when connecting to the inner side of the node,
- * corresponding to the real hardware interface that is emitted along the graph edge,
- * generally parameterized by the [[EI]] type.
- */
-trait InwardNodeImp[DI, UI, EI, BI <: Data]
-{
- /** Creates the inward edge parameters by combining the downward-flowing and upward-flowing parameters for edges
- * that connect to the inward side of this [[BaseNode]].
- *
- * It is left up to a user defining a particular protocol implementation to decide how the parameters flowing through
- * the graph in both directions on this Edge are combined into a single representation.
- *
- * @param pd The downward-flowing parameters into the node along the edge.
- * @param pu The upward-flowing parameters going out of the node along the edge.
- * @param p A view of [[Parameters]] at the point at which the returned edge is being bound.
- * @param sourceInfo [[SourceInfo]] of this edge.
- * @return An inward edge of this node.
- */
- def edgeI(pd: DI, pu: UI, p: Parameters, sourceInfo: SourceInfo): EI
-
- /** Create an inward bundle parameterized by the inward edge.
- *
- * @param ei Inward edge of this node.
- * @return An outward Bundle of this node parameterized by the negotiated Edge parameters.
- */
- def bundleI(ei: EI): BI
-
- /** Defines how input parameters can be "mixed" or negotiated together.
- *
- * The default behavior is to just return `pu`.
- *
- * @param pu The upward-flowing parameters going out of the node along the edge.
- * @param node An inward node to "mix" the upward-flowing parameters into.
- * @return Altered version of the upward-flowing parameters.
- */
- def mixI(pu: UI, node: InwardNode[DI, UI, BI]): UI = pu
-
- /** Function to generate and attach a monitor for this node input.
- *
- * @param bundle Inward bundle of this node to attach the monitor to.
- * @param edge Edge of this node used to parameterize the bundle.
- */
- def monitor(bundle: BI, edge: EI): Unit = {}
-
- /** Define how the edge should be rendered (e.g. in GraphML).
- *
- * @param e Edge to render.
- * @return [[RenderedEdge]] description of how the edge should be generated.
- */
- def render(e: EI): RenderedEdge
-}
-
-/** [[OutwardNodeImp]] defines the types that describe the outwards side of the [[BaseNode]].
- *
- * @tparam DO The type of the downward-flowing parameters generated by the outer side of the node
- * @tparam UO Tye type of the upward-flowing parameters received by the outer side of the node
- * @tparam EO The type of the diplomatically-resolved parameters for an Edge connected to the outer side of the node.
- * @tparam BO The type of the [[chisel3.Data]] (usually a [[chisel3.Bundle]]) used when connecting to the outer side of the node,
- * corresponding to the real hardware interface that is emitted along the graph edge,
- * generally parameterized by the [[EO]] type.
- */
-trait OutwardNodeImp[DO, UO, EO, BO <: Data]
-{
- /** Creates the outward edge parameters by combining the downward-flowing and upward-flowing parameters for edges
- * that connect to the outward side of this [[BaseNode]].
- *
- * It is left up to a user defining a particular protocol implementation to decide how the parameters flowing through
- * the graph in both directions on this Edge are combined into a single representation.
- *
- * @param pd The downward-flowing parameters going out of the node along the edge.
- * @param pu The upward-flowing parameters into the node along the edge.
- * @param p A view of [[Parameters]] at the point at which the returned edge is being bound.
- * @param sourceInfo [[SourceInfo]] of this edge.
- * @return An outward edge of this node.
- */
- def edgeO(pd: DO, pu: UO, p: Parameters, sourceInfo: SourceInfo): EO
-
- /** Create an outward Bundle parameterized by the outward edge.
- *
- * @param eo Outward Edge of this node.
- * @return An outward Bundle of this node parameterized by the negotiated Edge parameters.
- */
- def bundleO(eo: EO): BO
-
- /** Defines how outward parameters can be "mixed" or negotiated together.
- *
- * The default behavior is to just return `pd`.
- *
- * @param pd The downward-flowing parameters into the node along the edge.
- * @param node An outward node to "mix" the downward-flowing parameters into.
- * @return Altered version of the downward-flowing parameters.
- */
- def mixO(pd: DO, node: OutwardNode[DO, UO, BO]): DO = pd
-}
-
-/** The [[NodeImp]] combines an [[InwardNodeImp]] and an [[OutwardNodeImp]].
- *
- * This allows it to define whether it is a protocol-modifying (bridging) sort of node,
- * or whether it is an adapter type node that just modifies the parameters within a protocol.
- *
- * This class has no members and is solely used for holding type information.
- * Applications of diplomacy should extend [[NodeImp]] with a case object that sets concrete type arguments.
- *
- * @tparam D Type of the downward-flowing parameters of the node.
- * @tparam U Type of upward-flowing parameters of the node.
- * @tparam EO Type of the parameters describing an edge on the outer side of the node.
- * @tparam EI Type of the parameters describing an edge on the inner side of the node.
- * @tparam B Bundle type generated on edges connecting to this node.
- */
-abstract class NodeImp[D, U, EO, EI, B <: Data] extends Object
- with InwardNodeImp[D, U, EI, B]
- with OutwardNodeImp[D, U, EO, B]
-
-/** A [[NodeImp]] where the inward and outward edge parameters are of the same type.
- *
- * If, in a given protocol implementation, the parameters visible to the node on the inward side of an edge are
- * the same as the parameters visible to the node on the outward side of an edge,
- * [[SimpleNodeImp]] can be used instead of [[NodeImp]].
- *
- * @tparam D Type of the downward-flowing parameters of the node.
- * @tparam U Type of the upward-flowing parameters of the node.
- * @tparam E Edge Parameters describing the connections on either side of the node.
- * @tparam B Bundle type generated on edges connecting to this node.
- */
-abstract class SimpleNodeImp[D, U, E, B <: Data]
- extends NodeImp[D, U, E, E, B] {
- /** Creates the edge parameters by combining the downward-flowing and upward-flowing parameters for edges that connect to this node.
- *
- * It is left up to a user defining a particular protocol implementation to decide how the parameters flowing through the graph in
- * both directions are combined into a single representation on an Edge.
- *
- * @param pd The downward-flowing parameters into the node along the edge.
- * @param pu The upward-flowing parameters going out of the node along the edge.
- * @param p [[Parameters]]s which can be used during negotiation.
- * @param sourceInfo [[SourceInfo]] of this edge.
- * @return Negotiated edge parameters.
- */
- def edge(pd: D, pu: U, p: Parameters, sourceInfo: SourceInfo): E
-
- def edgeO(pd: D, pu: U, p: Parameters, sourceInfo: SourceInfo): E = edge(pd, pu, p, sourceInfo)
-
- def edgeI(pd: D, pu: U, p: Parameters, sourceInfo: SourceInfo): E = edge(pd, pu, p, sourceInfo)
-
- /** Generate the Bundle from the negotiated Edge parameters.
- *
- * @param e the negotiated Edge parameters
- * @return the corresponding Bundle of this node
- */
- def bundle(e: E): B
-
- def bundleO(e: E): B = bundle(e)
-
- def bundleI(e: E): B = bundle(e)
-}
-
-/** [[BaseNode]] is the abstract base class of the type hierarchy of diplomacy node classes.
- *
- * @param valName [[ValName]] of this node, used by naming inference.
- */
-abstract class BaseNode(implicit val valName: ValName) {
- /** All subclasses of [[BaseNode]]s are expected to be instantiated only within [[LazyModule]]s.
- *
- * Sometimes one wants to view the entire diplomacy graph in a way
- * where you do not care about the specific types of the edges.
- * [[BaseNode]]s are type-erased and provide this view.
- *
- * @return The [[LazyModule]] which contains this Node.
- */
- val scope: Option[LazyModule] = LazyModule.scope
-
- /** @return The index for this node in the containing [[LazyModule]]/[[LazyScope]]'s list of [[BaseNode]]s */
- val index: Int = scope.map(_.nodes.size).getOrElse(0)
-
- /** @return The [[LazyModule]] which contains this [[BaseNode]] */
- def lazyModule: LazyModule = scope.get
-
- // Prepend this node to the current [[LazyModule]]'s list of nodes
- scope.foreach { lm => lm.nodes = this :: lm.nodes }
-
- /** @return The serial number for this node in the global list of [[BaseNode]]s. */
- val serial: Int = BaseNode.serial
-
- BaseNode.serial = BaseNode.serial + 1
-
- /** Instantiate this node.
- *
- * This happens after all nodes connections have been made and we are ready to perform parameter negotiation.
- * This also determines which connections need to leave this node's LazyScope and cross hierarchical boundaries.
- * That information is captured in [[Dangle]]s which are returned from this function.
- *
- * @return A sequence of [[Dangle]]s from this node that leave this [[BaseNode]]'s [[LazyScope]].
- */
- protected[diplomacy] def instantiate(): Seq[Dangle]
- /** Determine the [[Dangle]]'s for connections without instantiating the node, or any child nodes
- *
- * @return A sequence of [[Dangle]]s from this node that leave this [[BaseNode]]'s [[LazyScope]].
- */
- protected[diplomacy] def cloneDangles(): Seq[Dangle]
-
- /** @return name of this node. */
- def name: String = scope.map(_.name).getOrElse("TOP") + "." + valName.name
-
- /** Determines whether or not this node will be excluded from the graph visualization.
- *
- * By default, if this node has neither inputs nor outputs it will be excluded.
- */
- def omitGraphML: Boolean = outputs.isEmpty && inputs.isEmpty
-
- /** Debug string of this node, used in [[LazyModule.graphML]]. */
- lazy val nodedebugstring: String = ""
-
- /** Mark whether this node represents a circuit "identity" that outputs its inputs unchanged.
- *
- * This information may be used to elide monitors or inline the parent module.
- */
- def circuitIdentity: Boolean = false
-
- /** @return A sequence of [[LazyModule]] up to and including Top. */
- def parents: Seq[LazyModule] = scope.map(lm => lm +: lm.parents).getOrElse(Nil)
-
- /** @return The context string for debug. */
- def context: String = {
- s"""$description $name node:
- |parents: ${parents.map(_.name).mkString("/")}
- |locator: ${scope.map(_.line).getOrElse("")}
- |""".stripMargin
- }
-
- /** Determines the name to be used in elements of auto-punched bundles.
- *
- * It takes the name of the node as determined from [[valName]],
- * converts camel case into snake case, and strips "Node" or "NodeOpt" suffixes.
- */
- def wirePrefix: String = {
- val camelCase = "([a-z])([A-Z])".r
- val decamel = camelCase.replaceAllIn(valName.name, _ match { case camelCase(l, h) => l + "_" + h })
- val name = decamel.toLowerCase.stripSuffix("_opt").stripSuffix("node").stripSuffix("_")
- if (name.isEmpty) "" else name + "_"
- }
-
- /** @return [[BaseNode]] description, which should be defined by subclasses and is generally expected to be a constant. */
- def description: String
-
- /** @return [[BaseNode]] instance description, which can be overridden with more detailed information about each node. */
- def formatNode: String = ""
-
- /** @return Metadata to visualize inward edges into this node. */
- def inputs: Seq[(BaseNode, RenderedEdge)]
-
- /** @return Metadata to visualize outward edges from this node. */
- def outputs: Seq[(BaseNode, RenderedEdge)]
-
- /** @return Whether this node can handle [[BIND_FLEX]] type connections on either side.
- *
- * For example, a node `b` will have [[flexibleArityDirection]] be `true` if both are legal:
- * `a :*=* b :*= c`, which resolves to `a :*= b :*= c`
- * or
- * `a :=* b :*=* c`, which resolves to `a :=* b :=* c`
- *
- * If this is `false`, the node can only support `:*=*` if it connects to a node with `flexibleArityDirection = true`
- */
- protected[diplomacy] def flexibleArityDirection: Boolean = false
-
- /** @return The sink cardinality.
- *
- * How many times is this node used as a sink.
- */
- protected[diplomacy] val sinkCard: Int
-
- /** @return The source cardinality.
- *
- * How many times is this node used as a source.
- */
- protected[diplomacy] val sourceCard: Int
-
- /** @return The "flex" cardinality.
- *
- * How many times is this node used in a way that could be either source or sink, depending on final
- * directional determination.
- */
- protected[diplomacy] val flexes: Seq[BaseNode]
-
- /** Resolves the flex to be either source or sink.
- *
- * @return A value >= 0 if it is sink cardinality, a negative value for source cardinality. The magnitude of the value does not matter.
- */
- protected[diplomacy] val flexOffset: Int
-}
-
-/** Companion object for [[BaseNode]], which is only used to hold the the global serial number of all [[BaseNode]]s. */
-object BaseNode {
- protected[diplomacy] var serial = 0
-}
-
-/** Trait that enables a string representation of an edge. */
-trait FormatEdge {
- def formatEdge: String
-}
-
-/** Trait that enables iterating over a [[BaseNode]]'s edges to produce a formatted string representation.
- *
- * In practice this is generally GraphML metadata.
- */
-trait FormatNode[I <: FormatEdge, O <: FormatEdge] extends BaseNode {
- def edges: Edges[I,O]
-
- /** Format the edges of the [[BaseNode]] for emission (generally in GraphML). */
- override def formatNode = if (circuitIdentity) "" else {
- edges.out.map(currEdge =>
- "On Output Edge:\n\n" + currEdge.formatEdge).mkString +
- "\n---------------------------------------------\n\n" +
- edges.in.map(currEdge =>
- "On Input Edge:\n\n" + currEdge.formatEdge).mkString
- }
-}
-
-/** A Handle with no explicitly defined binding functionality.
- *
- * A [[NoHandle]] is at the top of the Handle type hierarchy, but it does not define any binding operators,
- * so by itself a [[NoHandle]] cannot be used on either side of a bind operator.
- *
- * For example, a source node connected directly to a sink node produces a [[NoHandle]],
- * because there are no further bindings that could be applied to either side of the pair of nodes.
- *
- * The other Handle types extend this type and bestow actual binding semantics.
- * They can always be used wherever a [[NoHandle]] is expected because a [[NoHandle]]
- * doesn't provide any guaranteed behavior.
- *
- * Handle algebra:
- *
- * "x---x" [[NoHandle]]
- * "x---<" [[InwardNodeHandle]]
- * "<---x" [[OutwardNodeHandle]]
- * "<---<" (Full) [[NodeHandle]]
- *
- * "<" can be bound to (arrow points in the direction of binding).
- * "x" cannot be bound to.
- *
- * The left side is outer, the right side is inner.
- *
- * Two Handles can be bound if their adjacent ends are both "<".
- */
-trait NoHandle
-case object NoHandleObject extends NoHandle
-
-/** A Handle that can be used on either side of a bind operator. */
-trait NodeHandle[DI, UI, EI, BI <: Data, DO, UO, EO, BO <: Data]
- extends InwardNodeHandle[DI, UI, EI, BI] with OutwardNodeHandle[DO, UO, EO, BO] {
- /** Connects two full nodes handles => full node handle.
- *
- * <---< := <---< == <---<
- * This and that node are both [[BIND_ONCE]].
- *
- * @param h A source node also with sink handle.
- * @return A [[NodeHandle]] with that node as `inwardNode`, this node as `outwardNode`.
- */
- override def := [DX, UX, EX, BX <: Data, EY](h: NodeHandle[DX, UX, EX, BX, DI, UI, EY, BI])(implicit p: Parameters, sourceInfo: SourceInfo): NodeHandle[DX, UX, EX, BX, DO, UO, EO, BO] = { bind(h, BIND_ONCE); NodeHandle(h, this) }
-
- /** Connects two full nodes handles => full node handle.
- *
- * <---< :*= <---< == <---<
- * [[BIND_STAR]] this node as sink, [[BIND_QUERY]] that node as source.
- *
- * @param h A source node also with sink handle.
- * @return A [[NodeHandle]] with that node as `InwardNode`, this node as `OutwardNode`.
- */
- override def :*= [DX, UX, EX, BX <: Data, EY](h: NodeHandle[DX, UX, EX, BX, DI, UI, EY, BI])(implicit p: Parameters, sourceInfo: SourceInfo): NodeHandle[DX, UX, EX, BX, DO, UO, EO, BO] = { bind(h, BIND_STAR); NodeHandle(h, this) }
-
- /** Connects two full nodes handles => full node handle.
- *
- * <---< :=* <---< == <---<
- * [[BIND_QUERY]] this node as sink, [[BIND_STAR]] that node as source.
- *
- * @param h A source node also with sink handle.
- * @return A [[NodeHandle]] with that node as `InwardNode`, this node as `OutwardNode`.
- */
- override def :=* [DX, UX, EX, BX <: Data, EY](h: NodeHandle[DX, UX, EX, BX, DI, UI, EY, BI])(implicit p: Parameters, sourceInfo: SourceInfo): NodeHandle[DX, UX, EX, BX, DO, UO, EO, BO] = { bind(h, BIND_QUERY); NodeHandle(h, this) }
-
- /** Connects two full nodes handles => full node handle.
- *
- * <---< :*=* <---< == <---<
- * [[BIND_FLEX]] this node as sink, [[BIND_FLEX]] that node as source.
- *
- * @param h A source node also with sink handle.
- * @return A [[NodeHandle]] with that node as `inwardNode`, this node as `outwardNode`.
- */
- override def :*=*[DX, UX, EX, BX <: Data, EY](h: NodeHandle[DX, UX, EX, BX, DI, UI, EY, BI])(implicit p: Parameters, sourceInfo: SourceInfo): NodeHandle[DX, UX, EX, BX, DO, UO, EO, BO] = { bind(h, BIND_FLEX); NodeHandle(h, this) }
-
- /** Connects a full node with an output node => an output handle.
- *
- * <---< := <---x == <---x
- * [[BIND_ONCE]] this node as sink, [[BIND_ONCE]] that node as source.
- *
- * @param h A source node also without sink handle.
- * @return A [[OutwardNodeHandle]] with this node as `outwardNode`.
- */
- override def := [EY](h: OutwardNodeHandle[DI, UI, EY, BI])(implicit p: Parameters, sourceInfo: SourceInfo): OutwardNodeHandle[DO, UO, EO, BO] = { bind(h, BIND_ONCE); this }
-
- /** Connects a full node with an output node => an output handle.
- *
- * <---< :*= <---x == <---x
- * [[BIND_STAR]] this node as sink, [[BIND_QUERY]] that node as source.
- *
- * @param h A source node also without sink handle.
- * @return A [[OutwardNodeHandle]] with this node as `outwardNode`.
- */
- override def :*= [EY](h: OutwardNodeHandle[DI, UI, EY, BI])(implicit p: Parameters, sourceInfo: SourceInfo): OutwardNodeHandle[DO, UO, EO, BO] = { bind(h, BIND_STAR); this }
-
- /** Connects a full node with an output => an output.
- *
- * <---< :=* <---x == <---x
- * [[BIND_QUERY]] this node as sink, [[BIND_STAR]] that node as source.
- *
- * @param h A source node also without sink handle.
- * @return A [[OutwardNodeHandle]] with this node as `outwardNode`.
- */
- override def :=* [EY](h: OutwardNodeHandle[DI, UI, EY, BI])(implicit p: Parameters, sourceInfo: SourceInfo): OutwardNodeHandle[DO, UO, EO, BO] = { bind(h, BIND_QUERY); this }
-
- /** Connects a full node with an output => an output.
- *
- * <---< :*=* <---x == <---x
- * [[BIND_FLEX]] this node as sink, [[BIND_FLEX]] that node as source.
- *
- * @param h A source node also without sink handle.
- * @return A [[OutwardNodeHandle]] with this node as `outwardNode`.
- */
- override def :*=*[EY](h: OutwardNodeHandle[DI, UI, EY, BI])(implicit p: Parameters, sourceInfo: SourceInfo): OutwardNodeHandle[DO, UO, EO, BO] = { bind(h, BIND_FLEX); this }
-}
-
-object NodeHandle {
- /** generate a [[NodeHandle]] by combining an [[InwardNodeHandle]] and an [[OutwardNodeHandle]].
- *
- * @param i Inward node handle.
- * @param o Outward node handle.
- * @return [[NodeHandlePair]] with `inwardNode` of `i`, `outwardNode` of `o`.
- */
- def apply[DI, UI, EI, BI <: Data, DO, UO, EO, BO <: Data](i: InwardNodeHandle[DI, UI, EI, BI], o: OutwardNodeHandle[DO, UO, EO, BO]) = new NodeHandlePair(i, o)
-}
-
-/** A data structure that preserves information about the innermost and outermost Nodes in a [[NodeHandle]]. */
-class NodeHandlePair[DI, UI, EI, BI <: Data, DO, UO, EO, BO <: Data]
- (inwardHandle: InwardNodeHandle[DI, UI, EI, BI], outwardHandle: OutwardNodeHandle[DO, UO, EO, BO])
- extends NodeHandle[DI, UI, EI, BI, DO, UO, EO, BO] {
- /** @return [[InwardNode]] of [[inwardHandle]]. */
- val inward: InwardNode[DI, UI, BI] = inwardHandle.inward
-
- /** @return [[OutwardNode]] of [[outwardHandle]]. */
- val outward: OutwardNode[DO, UO, BO] = outwardHandle.outward
-
- /** @return The innermost [[InwardNodeImp]] of this [[NodeHandlePair]]. */
- def inner: InwardNodeImp[DI, UI, EI, BI] = inwardHandle.inner
-
- /** @return The outermost [[OutwardNodeImp]] of [[NodeHandlePair]]. */
- def outer: OutwardNodeImp[DO, UO, EO, BO] = outwardHandle.outer
-}
-
-/** A handle for an [[InwardNode]], which may appear on the left side of a bind operator. */
-trait InwardNodeHandle[DI, UI, EI, BI <: Data] extends NoHandle
-{
- /** @return [[InwardNode]] of `inwardHandle`. */
- def inward: InwardNode[DI, UI, BI]
-
- /** @return [[InwardNodeImp]] of `inwardHandle`. */
- def inner: InwardNodeImp[DI, UI, EI, BI]
-
- /** Bind this node to an [[OutwardNodeHandle]]. */
- protected def bind[EY](h: OutwardNodeHandle[DI, UI, EY, BI], binding: NodeBinding)(implicit p: Parameters, sourceInfo: SourceInfo): Unit = inward.bind(h.outward, binding)
-
- /** Connect an input node with a full node => inward node handle.
- *
- * x---< := <---< == x---<
- * [[BIND_ONCE]] this node as sink, [[BIND_ONCE]] that node as source.
- *
- * @param h A source node also with sink handle.
- * @return A [[NodeHandle]] with that node as `inwardNode`, this node as `outwardNode`.
- */
- def := [DX, UX, EX, BX <: Data, EY](h: NodeHandle[DX, UX, EX, BX, DI, UI, EY, BI])(implicit p: Parameters, sourceInfo: SourceInfo): InwardNodeHandle[DX, UX, EX, BX] = { bind(h, BIND_ONCE); h }
-
- /** Connect an input node with a full node => an input node.
- *
- * x---< :*= <---< == x---<
- * [[BIND_STAR]] this node as sink, [[BIND_QUERY]] that node as source.
- *
- * @param h A Source node also with sink handle.
- * @return A [[NodeHandle]] with that node as `inwardNode`, this node as `outwardNode`.
- */
- def :*= [DX, UX, EX, BX <: Data, EY](h: NodeHandle[DX, UX, EX, BX, DI, UI, EY, BI])(implicit p: Parameters, sourceInfo: SourceInfo): InwardNodeHandle[DX, UX, EX, BX] = { bind(h, BIND_STAR); h }
-
- /** Connect an input node with a full node => an inward node handle.
- *
- * x---< :=* <---< == x---<
- * [[BIND_QUERY]] this node as sink, [[BIND_STAR]] that node as source.
- *
- * @param h A source node also with sink handle.
- * @return A [[NodeHandle]] with that node as `inwardNode`, this node as `outwardNode`.
- */
- def :=* [DX, UX, EX, BX <: Data, EY](h: NodeHandle[DX, UX, EX, BX, DI, UI, EY, BI])(implicit p: Parameters, sourceInfo: SourceInfo): InwardNodeHandle[DX, UX, EX, BX] = { bind(h, BIND_QUERY); h }
-
- /** Connect an input node with a full node => an input node.
- *
- * x---< :*=* <---< == x---<
- * [[BIND_FLEX]] this node as sink, [[BIND_FLEX]] that node as source.
- *
- * @param h A source node also with sink handle.
- * @return A [[NodeHandle]] with that node as `inwardNode`, this node as `outwardNode`.
- */
- def :*=*[DX, UX, EX, BX <: Data, EY](h: NodeHandle[DX, UX, EX, BX, DI, UI, EY, BI])(implicit p: Parameters, sourceInfo: SourceInfo): InwardNodeHandle[DX, UX, EX, BX] = { bind(h, BIND_FLEX); h }
-
- /** Connect an input node with output node => no node.
- *
- * x---< := <---x == x---x
- * [[BIND_ONCE]] this node as sink, [[BIND_ONCE]] that node as source.
- *
- * @param h A source node also without sink handle.
- * @return A [[NoHandle]] since neither side can bind to a node.
- */
- def := [EY](h: OutwardNodeHandle[DI, UI, EY, BI])(implicit p: Parameters, sourceInfo: SourceInfo): NoHandle = { bind(h, BIND_ONCE); NoHandleObject }
-
- /** Connect an input node with output node => no node.
- *
- * x---< :*= <---x == x---x
- * [[BIND_STAR]] this node as sink, [[BIND_QUERY]] that node as source.
- *
- * @param h A source node also without sink handle.
- * @return A [[NoHandle]] since neither side can bind to a node.
- */
- def :*= [EY](h: OutwardNodeHandle[DI, UI, EY, BI])(implicit p: Parameters, sourceInfo: SourceInfo): NoHandle = { bind(h, BIND_STAR); NoHandleObject }
-
- /** Connect an input node with output node => no node.
- *
- * x---< :=* <---x == x---x
- * [[BIND_QUERY]] this node as sink, [[BIND_STAR]] that node as source.
- *
- * @param h A source node also without sink handle.
- * @return A [[NoHandle]] since neither side can bind to another node.
- */
- def :=* [EY](h: OutwardNodeHandle[DI, UI, EY, BI])(implicit p: Parameters, sourceInfo: SourceInfo): NoHandle = { bind(h, BIND_QUERY); NoHandleObject }
-
- /** Connect an input node with output node => no node.
- *
- * x---< :*=* <---x == x---x
- * [[BIND_FLEX]] this node as sink, [[BIND_FLEX]] that node as source.
- *
- * @param h A source node also without sink handle.
- * @return A [[NoHandle]] since neither side can bind to another node.
- */
- def :*=*[EY](h: OutwardNodeHandle[DI, UI, EY, BI])(implicit p: Parameters, sourceInfo: SourceInfo): NoHandle = { bind(h, BIND_FLEX); NoHandleObject }
-}
-
-/** Enumeration of types of binding operations. */
-sealed trait NodeBinding
-
-/** Only connects a single edge. */
-case object BIND_ONCE extends NodeBinding {
- override def toString: String = "once"
-}
-
-/** Connects N (N >= 0) edges.
- *
- * The other side of the edge determines cardinality.
- */
-case object BIND_QUERY extends NodeBinding {
- override def toString: String = "query"
-}
-
-/** Connect N (N >= 0) edges.
- *
- * Our side of the edge determines cardinality.
- */
-case object BIND_STAR extends NodeBinding {
- override def toString: String = "star"
-}
-
-/** Connect N (N >= 0) connections.
- *
- * The number of edges N will be determined by either the right or left side,
- * once the direction ([[BIND_STAR]] or [[BIND_QUERY]]) is determined by the other connections as well.
- */
-case object BIND_FLEX extends NodeBinding {
- override def toString: String = "flex"
-}
-
-/** A Node that defines inward behavior, meaning that it can have edges coming into it and be used on the left side of binding expressions. */
-trait InwardNode[DI, UI, BI <: Data] extends BaseNode {
- /** accumulates input connections. */
- private val accPI = ListBuffer[(Int, OutwardNode[DI, UI, BI], NodeBinding, Parameters, SourceInfo)]()
-
- /** Initially `false`, set to `true` once [[iBindings]] has been evaluated. */
- private var iRealized = false
-
- /** @return debug information of [[iBindings]]. */
- def iBindingInfo: String = s"""${iBindings.size} inward nodes bound: [${iBindings.map(n => s"${n._3}-${n._2.name}").mkString(",")}]"""
-
-
- /** The accumulated number of input connections. */
- protected[diplomacy] def iPushed: Int = accPI.size
-
- /** Accumulate an input connection.
- *
- * Can only be called before [[iBindings]] is accessed.
- *
- * @param index index of this [[InwardNode]] in that [[OutwardNode]].
- * @param node the [[OutwardNode]] to bind to this [[InwardNode]].
- * @param binding [[NodeBinding]] type.
- */
- protected[diplomacy] def iPush(index: Int, node: OutwardNode[DI, UI, BI], binding: NodeBinding)(implicit p: Parameters, sourceInfo: SourceInfo): Unit = {
- val info = sourceLine(sourceInfo, " at ", "")
- require (!iRealized,
- s"""Diplomacy has detected a problem in your code:
- |The following node was incorrectly connected as a sink to ${node.name} after its .module was evaluated at $info.
- |$context
- |$iBindingInfo
- |""".stripMargin)
- accPI += ((index, node, binding, p, sourceInfo))
- }
-
- /** Ends the binding accumulation stage and returns all the input bindings to this node.
- *
- * Evaluating this lazy val will mark the inwards bindings as frozen,
- * preventing subsequent bindings from being created via [[iPush]].
- *
- * The bindings are each a tuple of:
- * - numeric index of this binding in the other end of [[OutwardNode]].
- * - [[OutwardNode]] on the other end of this binding.
- * - [[NodeBinding]] describing the type of binding.
- * - A view of [[Parameters]] where the binding occurred.
- * - [[SourceInfo]] for source-level error reporting.
- */
- protected[diplomacy] lazy val iBindings: immutable.Seq[(Int, OutwardNode[DI, UI, BI], NodeBinding, Parameters, SourceInfo)] = { iRealized = true; accPI.result() }
-
- /** resolved [[BIND_STAR]] binding of inward nodes: how many connections the star represents. */
- protected[diplomacy] val iStar: Int
-
- /** A mapping to convert Node binding index to port range.
- *
- * @return a sequence of tuple of mapping, the item in each a tuple of:
- * - index: the index of connected [[OutwardNode]]
- * - element: port range of connected [[OutwardNode]]
- */
- protected[diplomacy] val iPortMapping: Seq[(Int, Int)]
-
- /** "Forward" an input connection through this node so that the node can be removed from the graph.
- *
- * @return None if no forwarding is needing.
- */
- protected[diplomacy] def iForward(x: Int): Option[(Int, InwardNode[DI, UI, BI])] = None
-
- /** Downward-flowing inward parameters.
- *
- * Generated from the nodes connected to the inward side of this node and sent downstream to this node.
- */
- protected[diplomacy] val diParams: Seq[DI]
-
- /** Upward-flowing inward parameters.
- *
- * Generated by this node and sent upstream to the nodes connected to the inward side of this node.
- */
- protected[diplomacy] val uiParams: Seq[UI]
-
- /** Create a binding from this node to an [[OutwardNode]].
- *
- * @param h The [[OutwardNode]] to bind to.
- * @param binding [[NodeBinding]] the type of binding.
- */
- protected[diplomacy] def bind(h: OutwardNode[DI, UI, BI], binding: NodeBinding)(implicit p: Parameters, sourceInfo: SourceInfo): Unit
-}
-
-/** A Handle for OutwardNodes, which may appear on the right side of a bind operator. */
-trait OutwardNodeHandle[DO, UO, EO, BO <: Data] extends NoHandle {
- /** @return [[OutwardNode]] of `outwardHandle`. */
- def outward: OutwardNode[DO, UO, BO]
-
- /** @return [[OutwardNodeImp]] of `inwardHandle`. */
- def outer: OutwardNodeImp[DO, UO, EO, BO]
-}
-
-/** A Node that defines outward behavior, meaning that it can have edges coming out of it. */
-trait OutwardNode[DO, UO, BO <: Data] extends BaseNode {
- /** Accumulates output connections. */
- private val accPO = ListBuffer[(Int, InwardNode [DO, UO, BO], NodeBinding, Parameters, SourceInfo)]()
-
- /** Initially set to `true`, this is set to false once [[oBindings]] is referenced. */
- private var oRealized = false
-
- /** @return debug information of [[oBindings]]. */
- def oBindingInfo: String = s"""${oBindings.size} outward nodes bound: [${oBindings.map(n => s"${n._3}-${n._2.name}").mkString(",")}]"""
-
- /** The accumulated number of output connections of this node. */
- protected[diplomacy] def oPushed: Int = accPO.size
-
- /** Accumulate an output connection.
- *
- * Can only be called before [[oBindings]] is accessed.
- *
- * @param index Index of this [[OutwardNode]] in that [[InwardNode]].
- * @param node [[InwardNode]] to bind to.
- * @param binding Binding type.
- */
- protected[diplomacy] def oPush(index: Int, node: InwardNode [DO, UO, BO], binding: NodeBinding)(implicit p: Parameters, sourceInfo: SourceInfo): Unit = {
- val info = sourceLine(sourceInfo, " at ", "")
- require (!oRealized,
- s"""Diplomacy has detected a problem in your code:
- |The following node was incorrectly connected as a source to ${node.name} after its .module was evaluated at $info.
- |$context
- |$oBindingInfo
- |""".stripMargin)
- accPO += ((index, node, binding, p, sourceInfo))
- }
-
- /** Ends the binding accumulation stage and returns all the output bindings to this node.
- *
- * Evaluating this lazy val will mark the outward bindings as frozen,
- * preventing subsequent bindings from being created via [[oPush]].
- *
- * The bindings are each a tuple of:
- * - numeric index of this binding in the other end of [[InwardNode]].
- * - [[InwardNode]] on the other end of this binding
- * - [[NodeBinding]] describing the type of binding
- * - A view of [[Parameters]] where the binding occurred.
- * - [[SourceInfo]] for source-level error reporting
- */
- protected[diplomacy] lazy val oBindings: Seq[(Int, InwardNode[DO, UO, BO], NodeBinding, Parameters, SourceInfo)] = { oRealized = true; accPO.result() }
-
- /** resolved [[BIND_STAR]] binding of outward nodes: how many connections the star represents. */
- protected[diplomacy] val oStar: Int
-
- /** A mapping to convert Node binding index to port range.
- *
- * @return a sequence of tuple of mapping, the item in each a tuple of:
- * - index: the index of connected [[InwardNode]]
- * - element: port range of connected [[InwardNode]]
- */
- protected[diplomacy] val oPortMapping: Seq[(Int, Int)]
-
- /** "Forward" an output connection through this node so that the node can be removed from the graph.
- *
- * @return None if no forwarding is needed.
- */
- protected[diplomacy] def oForward(x: Int): Option[(Int, OutwardNode[DO, UO, BO])] = None
-
- /** Upward-flowing outward parameters.
- *
- * Generated from the nodes connected to the outward side of this node and sent upstream to this node.
- */
- protected[diplomacy] val uoParams: Seq[UO]
-
- /** Downward-flowing outward parameters.
- *
- * Generated by this node and sent downstream to the nodes connected to the outward side of this node.
- */
- protected[diplomacy] val doParams: Seq[DO]
-}
-
-abstract class CycleException(kind: String, loop: Seq[String]) extends Exception(s"Diplomatic $kind cycle detected involving $loop")
-case class StarCycleException(loop: Seq[String] = Nil) extends CycleException("star", loop)
-case class DownwardCycleException(loop: Seq[String] = Nil) extends CycleException("downward", loop)
-case class UpwardCycleException(loop: Seq[String] = Nil) extends CycleException("upward", loop)
-
-/** [[Edges]] is a collection of parameters describing the functionality and connection for an interface,
- * which is often derived from the interconnection protocol and can inform the parameterization
- * of the hardware bundles that actually implement the protocol.
- */
-case class Edges[EI, EO](in: Seq[EI], out: Seq[EO])
-
-/** The sealed node class in the package, all node are derived from it.
- *
- * @param inner Sink interface implementation.
- * @param outer Source interface implementation.
- * @param valName val name of this node.
- * @tparam DI Downward-flowing parameters received on the inner side of the node.
- * It is usually a brunch of parameters describing the protocol parameters from a source.
- * For an [[InwardNode]], it is determined by the connected [[OutwardNode]].
- * Since it can be connected to multiple sources, this parameter is always a Seq of source port parameters.
- * @tparam UI Upward-flowing parameters generated by the inner side of the node.
- * It is usually a brunch of parameters describing the protocol parameters of a sink.
- * For an [[InwardNode]], it is determined itself.
- * @tparam EI Edge Parameters describing a connection on the inner side of the node.
- * It is usually a brunch of transfers specified for a sink according to protocol.
- * @tparam BI Bundle type used when connecting to the inner side of the node.
- * It is a hardware interface of this sink interface.
- * It should extends from [[chisel3.Data]], which represents the real hardware.
- * @tparam DO Downward-flowing parameters generated on the outer side of the node.
- * It is usually a brunch of parameters describing the protocol parameters of a source.
- * For an [[OutwardNode]], it is determined itself.
- * @tparam UO Upward-flowing parameters received by the outer side of the node.
- * It is usually a brunch of parameters describing the protocol parameters from a sink.
- * For an [[OutwardNode]], it is determined by the connected [[InwardNode]].
- * Since it can be connected to multiple sinks, this parameter is always a Seq of sink port parameters.
- * @tparam EO Edge Parameters describing a connection on the outer side of the node.
- * It is usually a brunch of transfers specified for a source according to protocol.
- * @tparam BO Bundle type used when connecting to the outer side of the node.
- * It is a hardware interface of this source interface.
- * It should extends from [[chisel3.Data]], which represents the real hardware.
- *
- * @note Call Graph of [[MixedNode]]
- * - line `─`: source is process by a function and generate pass to others
- * - Arrow `→`: target of arrow is generated by source
- *
- * {{{
- * (from the other node)
- * ┌─────────────────────────────────────────────────────────[[InwardNode.uiParams]]─────────────┐
- * ↓ │
- * (binding node when elaboration) [[OutwardNode.uoParams]]────────────────────────[[MixedNode.mapParamsU]]→──────────┐ │
- * [[InwardNode.accPI]] │ │ │
- * │ │ (based on protocol) │
- * │ │ [[MixedNode.inner.edgeI]] │
- * │ │ ↓ │
- * ↓ │ │ │
- * (immobilize after elaboration) (inward port from [[OutwardNode]]) │ ↓ │
- * [[InwardNode.iBindings]]──┐ [[MixedNode.iDirectPorts]]────────────────────→[[MixedNode.iPorts]] [[InwardNode.uiParams]] │
- * │ │ ↑ │ │ │
- * │ │ │ [[OutwardNode.doParams]] │ │
- * │ │ │ (from the other node) │ │
- * │ │ │ │ │ │
- * │ │ │ │ │ │
- * │ │ │ └────────┬──────────────┤ │
- * │ │ │ │ │ │
- * │ │ │ │ (based on protocol) │
- * │ │ │ │ [[MixedNode.inner.edgeI]] │
- * │ │ │ │ │ │
- * │ │ (from the other node) │ ↓ │
- * │ └───[[OutwardNode.oPortMapping]] [[OutwardNode.oStar]] │ [[MixedNode.edgesIn]]───┐ │
- * │ ↑ ↑ │ │ ↓ │
- * │ │ │ │ │ [[MixedNode.in]] │
- * │ │ │ │ ↓ ↑ │
- * │ (solve star connection) │ │ │ [[MixedNode.bundleIn]]──┘ │
- * ├───[[MixedNode.resolveStar]]→─┼─────────────────────────────┤ └────────────────────────────────────┐ │
- * │ │ │ [[MixedNode.bundleOut]]─┐ │ │
- * │ │ │ ↑ ↓ │ │
- * │ │ │ │ [[MixedNode.out]] │ │
- * │ ↓ ↓ │ ↑ │ │
- * │ ┌─────[[InwardNode.iPortMapping]] [[InwardNode.iStar]] [[MixedNode.edgesOut]]──┘ │ │
- * │ │ (from the other node) ↑ │ │
- * │ │ │ │ │ │
- * │ │ │ [[MixedNode.outer.edgeO]] │ │
- * │ │ │ (based on protocol) │ │
- * │ │ │ │ │ │
- * │ │ │ ┌────────────────────────────────────────┤ │ │
- * │ │ │ │ │ │ │
- * │ │ │ │ │ │ │
- * │ │ │ │ │ │ │
- * (immobilize after elaboration)│ ↓ │ │ │ │
- * [[OutwardNode.oBindings]]─┘ [[MixedNode.oDirectPorts]]───→[[MixedNode.oPorts]] [[OutwardNode.doParams]] │ │
- * ↑ (inward port from [[OutwardNode]]) │ │ │ │
- * │ ┌─────────────────────────────────────────┤ │ │ │
- * │ │ │ │ │ │
- * │ │ │ │ │ │
- * [[OutwardNode.accPO]] │ ↓ │ │ │
- * (binding node when elaboration) │ [[InwardNode.diParams]]─────→[[MixedNode.mapParamsD]]────────────────────────────┘ │ │
- * │ ↑ │ │
- * │ └──────────────────────────────────────────────────────────────────────────────────────────┘ │
- * └──────────────────────────────────────────────────────────────────────────────────────────────────────────┘
- * }}}
- */
-sealed abstract class MixedNode[DI, UI, EI, BI <: Data, DO, UO, EO, BO <: Data](
- val inner: InwardNodeImp [DI, UI, EI, BI],
- val outer: OutwardNodeImp[DO, UO, EO, BO])(
- implicit valName: ValName)
- extends BaseNode with NodeHandle[DI, UI, EI, BI, DO, UO, EO, BO] with InwardNode[DI, UI, BI] with OutwardNode[DO, UO, BO] {
- // Generate a [[NodeHandle]] with inward and outward node are both this node.
- val inward = this
- val outward = this
-
- /** Debug info of nodes binding. */
- def bindingInfo: String =
- s"""$iBindingInfo
- |$oBindingInfo
- |""".stripMargin
-
- /** Debug info of ports connecting. */
- def connectedPortsInfo: String =
- s"""${oPorts.size} outward ports connected: [${oPorts.map(_._2.name).mkString(",")}]
- |${iPorts.size} inward ports connected: [${iPorts.map(_._2.name).mkString(",")}]
- |""".stripMargin
-
- /** Debug info of parameters propagations. */
- def parametersInfo: String =
- s"""${doParams.size} downstream outward parameters: [${doParams.mkString(",")}]
- |${uoParams.size} upstream outward parameters: [${uoParams.mkString(",")}]
- |${diParams.size} downstream inward parameters: [${diParams.mkString(",")}]
- |${uiParams.size} upstream inward parameters: [${uiParams.mkString(",")}]
- |""".stripMargin
-
- /** For a given node, converts [[OutwardNode.accPO]] and [[InwardNode.accPI]] to [[MixedNode.oPortMapping]] and [[MixedNode.iPortMapping]].
- *
- * Given counts of known inward and outward binding and inward and outward star bindings, return the resolved inward stars and outward stars.
- *
- * This method will also validate the arguments and throw a runtime error if the values are unsuitable for this type of node.
- *
- * @param iKnown Number of known-size ([[BIND_ONCE]]) input bindings.
- * @param oKnown Number of known-size ([[BIND_ONCE]]) output bindings.
- * @param iStar Number of unknown size ([[BIND_STAR]]) input bindings.
- * @param oStar Number of unknown size ([[BIND_STAR]]) output bindings.
- * @return A Tuple of the resolved number of input and output connections.
- */
- protected[diplomacy] def resolveStar(iKnown: Int, oKnown: Int, iStar: Int, oStar: Int): (Int, Int)
-
- /** Function to generate downward-flowing outward params from the downward-flowing input params and the current output ports.
- *
- * @param n The size of the output sequence to generate.
- * @param p Sequence of downward-flowing input parameters of this node.
- * @return A `n`-sized sequence of downward-flowing output edge parameters.
- */
- protected[diplomacy] def mapParamsD(n: Int, p: Seq[DI]): Seq[DO]
-
- /** Function to generate upward-flowing input parameters from the upward-flowing output parameters [[uiParams]].
- *
- * @param n Size of the output sequence.
- * @param p Upward-flowing output edge parameters.
- * @return A n-sized sequence of upward-flowing input edge parameters.
- */
- protected[diplomacy] def mapParamsU(n: Int, p: Seq[UO]): Seq[UI]
-
- /** @return The sink cardinality of the node, the number of outputs bound with [[BIND_QUERY]] summed with inputs bound with [[BIND_STAR]]. */
- protected[diplomacy] lazy val sinkCard: Int = oBindings.count(_._3 == BIND_QUERY) + iBindings.count(_._3 == BIND_STAR)
-
- /** @return The source cardinality of this node, the number of inputs bound with [[BIND_QUERY]] summed with the number of output bindings bound with [[BIND_STAR]]. */
- protected[diplomacy] lazy val sourceCard: Int = iBindings.count(_._3 == BIND_QUERY) + oBindings.count(_._3 == BIND_STAR)
-
- /** @return list of nodes involved in flex bindings with this node. */
- protected[diplomacy] lazy val flexes: Seq[BaseNode] = oBindings.filter(_._3 == BIND_FLEX).map(_._2) ++ iBindings.filter(_._3 == BIND_FLEX).map(_._2)
-
- /** Resolves the flex to be either source or sink and returns the offset where the [[BIND_STAR]] operators begin greedily taking up the remaining connections.
- *
- * @return A value >= 0 if it is sink cardinality, a negative value for source cardinality. The magnitude of the return value is not relevant.
- */
- protected[diplomacy] lazy val flexOffset: Int = {
- /** Recursively performs a depth-first search of the [[flexes]],
- * [[BaseNode]]s connected to this node with flex operators.
- * The algorithm bottoms out when we either get to a node we have already visited
- * or when we get to a connection that is not a flex and can set the direction for us.
- * Otherwise, recurse by visiting the `flexes` of each node in the current set
- * and decide whether they should be added to the set or not.
- *
- * @return the mapping of [[BaseNode]] indexed by their serial numbers.
- */
- def DFS(v: BaseNode, visited: Map[Int, BaseNode]): Map[Int, BaseNode] = {
- if (visited.contains(v.serial) || !v.flexibleArityDirection) {
- visited
- } else {
- v.flexes.foldLeft(visited + (v.serial -> v))((sum, n) => DFS(n, sum))
- }
- }
-
- /** Determine which [[BaseNode]] are involved in resolving the flex connections to/from this node.
- *
- * @example
- * {{{
- * a :*=* b :*=* c
- * d :*=* b
- * e :*=* f
- * }}}
- *
- * `flexSet` for `a`, `b`, `c`, or `d` will be `Set(a, b, c, d)`
- * `flexSet` for `e` or `f` will be `Set(e,f)`
- */
- val flexSet = DFS(this, Map()).values
-
- /** The total number of :*= operators where we're on the left. */
- val allSink = flexSet.map(_.sinkCard).sum
-
- /** The total number of :=* operators used when we're on the right. */
- val allSource = flexSet.map(_.sourceCard).sum
-
- require (allSink == 0 || allSource == 0,
- s"The nodes ${flexSet.map(_.name)} which are inter-connected by :*=* have ${allSink} :*= operators and ${allSource} :=* operators connected to them, making it impossible to determine cardinality inference direction.")
- allSink - allSource
- }
-
- /** @return A value >= 0 if it is sink cardinality, a negative value for source cardinality. */
- protected[diplomacy] def edgeArityDirection(n: BaseNode): Int = {
- if ( flexibleArityDirection) flexOffset else
- if (n.flexibleArityDirection) n.flexOffset else
- 0
- }
-
- /** For a node which is connected between two nodes, select the one that will influence the direction of the flex resolution. */
- protected[diplomacy] def edgeAritySelect(n: BaseNode, l: => Int, r: => Int): Int = {
- val dir = edgeArityDirection(n)
- if (dir < 0) l else if (dir > 0) r else 1
- }
-
- /** Ensure that the same node is not visited twice in resolving `:*=`, etc operators. */
- private var starCycleGuard = false
-
- /** Resolve all the star operators into concrete indicies.
- * As connections are being made, some may be "star" connections which need to be resolved.
- * In some way to determine how many actual edges they correspond to.
- * We also need to build up the ranges of edges which correspond to each binding operator, so that
- * We can apply the correct edge parameters and later build up correct bundle connections.
- *
- * [[oPortMapping]]: `Seq[(Int, Int)]` where each item is the range of edges corresponding to that oPort (binding operator).
- * [[iPortMapping]]: `Seq[(Int, Int)]` where each item is the range of edges corresponding to that iPort (binding operator).
- * [[oStar]]: `Int` the value to return for this node `N` for any `N :*= foo` or `N :*=* foo :*= bar`
- * [[iStar]]: `Int` the value to return for this node `N` for any `foo :=* N` or `bar :=* foo :*=* N`
- */
- protected[diplomacy] lazy val (oPortMapping: Seq[(Int, Int)], iPortMapping: Seq[(Int, Int)], oStar: Int, iStar: Int) = {
- try {
- if (starCycleGuard) throw StarCycleException()
- starCycleGuard = true
- // For a given node N...
- // Number of foo :=* N
- // + Number of bar :=* foo :*=* N
- val oStars = oBindings.count { case (_,n,b,_,_) => b == BIND_STAR || (b == BIND_FLEX && edgeArityDirection(n) < 0) }
- // Number of N :*= foo
- // + Number of N :*=* foo :*= bar
- val iStars = iBindings.count { case (_,n,b,_,_) => b == BIND_STAR || (b == BIND_FLEX && edgeArityDirection(n) > 0) }
- // 1 for foo := N
- // + bar.iStar for bar :*= foo :*=* N
- // + foo.iStar for foo :*= N
- // + 0 for foo :=* N
- val oKnown = oBindings.map { case (_, n, b, _, _) => b match {
- case BIND_ONCE => 1
- case BIND_FLEX => edgeAritySelect(n, 0, n.iStar)
- case BIND_QUERY => n.iStar
- case BIND_STAR => 0 }}.sum
- // 1 for N := foo
- // + bar.oStar for N :*=* foo :=* bar
- // + foo.oStar for N :=* foo
- // + 0 for N :*= foo
- val iKnown = iBindings.map { case (_, n, b, _, _) => b match {
- case BIND_ONCE => 1
- case BIND_FLEX => edgeAritySelect(n, n.oStar, 0)
- case BIND_QUERY => n.oStar
- case BIND_STAR => 0 }}.sum
- // Resolve star depends on the node subclass to implement the algorithm for this.
- val (iStar, oStar) = resolveStar(iKnown, oKnown, iStars, oStars)
- // Cumulative list of resolved outward binding range starting points
- val oSum = oBindings.map { case (_, n, b, _, _) => b match {
- case BIND_ONCE => 1
- case BIND_FLEX => edgeAritySelect(n, oStar, n.iStar)
- case BIND_QUERY => n.iStar
- case BIND_STAR => oStar }}.scanLeft(0)(_+_)
- // Cumulative list of resolved inward binding range starting points
- val iSum = iBindings.map { case (_, n, b, _, _) => b match {
- case BIND_ONCE => 1
- case BIND_FLEX => edgeAritySelect(n, n.oStar, iStar)
- case BIND_QUERY => n.oStar
- case BIND_STAR => iStar }}.scanLeft(0)(_+_)
- // Create ranges for each binding based on the running sums and return
- // those along with resolved values for the star operations.
- (oSum.init zip oSum.tail, iSum.init zip iSum.tail, oStar, iStar)
- } catch {
- case c: StarCycleException => throw c.copy(loop = context +: c.loop)
- }
- }
-
- /** Sequence of inward ports.
- *
- * This should be called after all star bindings are resolved.
- *
- * Each element is:
- * `j` Port index of this binding in the Node's [[oPortMapping]] on the other side of the binding.
- * `n` Instance of inward node.
- * `p` View of [[Parameters]] where this connection was made.
- * `s` Source info where this connection was made in the source code.
- */
- protected[diplomacy] lazy val oDirectPorts: Seq[(Int, InwardNode[DO, UO, BO], Parameters, SourceInfo)] = oBindings.flatMap { case (i, n, _, p, s) =>
- // for each binding operator in this node, look at what it connects to
- val (start, end) = n.iPortMapping(i)
- (start until end) map { j => (j, n, p, s) }
- }
-
- /** Sequence of outward ports.
- *
- * This should be called after all star bindings are resolved.
- *
- * `j` Port index of this binding in the Node's [[oPortMapping]] on the other side of the binding.
- * `n` Instance of outward node.
- * `p` View of [[Parameters]] where this connection was made.
- * `s` [[SourceInfo]] where this connection was made in the source code.
- */
- protected[diplomacy] lazy val iDirectPorts: Seq[(Int, OutwardNode[DI, UI, BI], Parameters, SourceInfo)] = iBindings.flatMap { case (i, n, _, p, s) =>
- // query this port index range of this node in the other side of node.
- val (start, end) = n.oPortMapping(i)
- (start until end) map { j => (j, n, p, s) }
- }
-
- // Ephemeral nodes ( which have non-None iForward/oForward) have in_degree = out_degree
- // Thus, there must exist an Eulerian path and the below algorithms terminate
- @scala.annotation.tailrec
- private def oTrace(tuple: (Int, InwardNode[DO, UO, BO], Parameters, SourceInfo)): (Int, InwardNode[DO, UO, BO], Parameters, SourceInfo) =
- tuple match { case (i, n, p, s) => n.iForward(i) match {
- case None => (i, n, p, s)
- case Some ((j, m)) => oTrace((j, m, p, s))
- } }
-
- @scala.annotation.tailrec
- private def iTrace(tuple: (Int, OutwardNode[DI, UI, BI], Parameters, SourceInfo)): (Int, OutwardNode[DI, UI, BI], Parameters, SourceInfo) =
- tuple match { case (i, n, p, s) => n.oForward(i) match {
- case None => (i, n, p, s)
- case Some ((j, m)) => iTrace((j, m, p, s))
- } }
-
- /** Final output ports after all stars and port forwarding (e.g. [[EphemeralNode]]s) have been resolved.
- *
- * Each Port is a tuple of:
- * - Numeric index of this binding in the [[InwardNode]] on the other end.
- * - [[InwardNode]] on the other end of this binding.
- * - A view of [[Parameters]] where the binding occurred.
- * - [[SourceInfo]] for source-level error reporting.
- */
- lazy val oPorts: Seq[(Int, InwardNode[DO, UO, BO], Parameters, SourceInfo)] = oDirectPorts.map(oTrace)
-
- /** Final input ports after all stars and port forwarding (e.g. [[EphemeralNode]]s) have been resolved.
- *
- * Each Port is a tuple of:
- * - numeric index of this binding in [[OutwardNode]] on the other end.
- * - [[OutwardNode]] on the other end of this binding.
- * - a view of [[Parameters]] where the binding occurred.
- * - [[SourceInfo]] for source-level error reporting.
- */
- lazy val iPorts: Seq[(Int, OutwardNode[DI, UI, BI], Parameters, SourceInfo)] = iDirectPorts.map(iTrace)
-
- private var oParamsCycleGuard = false
- protected[diplomacy] lazy val diParams: Seq[DI] = iPorts.map { case (i, n, _, _) => n.doParams(i) }
- protected[diplomacy] lazy val doParams: Seq[DO] = {
- try {
- if (oParamsCycleGuard) throw DownwardCycleException()
- oParamsCycleGuard = true
- val o = mapParamsD(oPorts.size, diParams)
- require (o.size == oPorts.size,
- s"""Diplomacy has detected a problem with your graph:
- |At the following node, the number of outward ports should equal the number of produced outward parameters.
- |$context
- |$connectedPortsInfo
- |Downstreamed inward parameters: [${diParams.mkString(",")}]
- |Produced outward parameters: [${o.mkString(",")}]
- |""".stripMargin)
- o.map(outer.mixO(_, this))
- } catch {
- case c: DownwardCycleException => throw c.copy(loop = context +: c.loop)
- }
- }
-
- private var iParamsCycleGuard = false
- protected[diplomacy] lazy val uoParams: Seq[UO] = oPorts.map { case (o, n, _, _) => n.uiParams(o) }
- protected[diplomacy] lazy val uiParams: Seq[UI] = {
- try {
- if (iParamsCycleGuard) throw UpwardCycleException()
- iParamsCycleGuard = true
- val i = mapParamsU(iPorts.size, uoParams)
- require (i.size == iPorts.size,
- s"""Diplomacy has detected a problem with your graph:
- |At the following node, the number of inward ports should equal the number of produced inward parameters.
- |$context
- |$connectedPortsInfo
- |Upstreamed outward parameters: [${uoParams.mkString(",")}]
- |Produced inward parameters: [${i.mkString(",")}]
- |""".stripMargin)
- i.map(inner.mixI(_, this))
- } catch {
- case c: UpwardCycleException => throw c.copy(loop = context +: c.loop)
- }
- }
-
- /** Outward edge parameters. */
- protected[diplomacy] lazy val edgesOut: Seq[EO] = (oPorts zip doParams).map { case ((i, n, p, s), o) => outer.edgeO(o, n.uiParams(i), p, s) }
-
- /** Inward edge parameters. */
- protected[diplomacy] lazy val edgesIn: Seq[EI] = (iPorts zip uiParams).map { case ((o, n, p, s), i) => inner.edgeI(n.doParams(o), i, p, s) }
-
- /** A tuple of the input edge parameters and output edge parameters for the edges bound to this node.
- *
- * If you need to access to the edges of a foreign Node, use this method (in/out create bundles).
- */
- lazy val edges: Edges[EI, EO] = Edges(edgesIn, edgesOut)
-
- /** Create actual Wires corresponding to the Bundles parameterized by the outward edges of this node. */
- protected[diplomacy] lazy val bundleOut: Seq[BO] = edgesOut.map { e =>
- val x = Wire(outer.bundleO(e)).suggestName(s"${valName.name}Out")
- // TODO: Don't care unconnected forwarded diplomatic signals for compatibility issue,
- // In the future, we should add an option to decide whether allowing unconnected in the LazyModule
- x := DontCare
- x
- }
-
- /** Create actual Wires corresponding to the Bundles parameterized by the inward edges of this node. */
- protected[diplomacy] lazy val bundleIn: Seq[BI] = edgesIn .map { e =>
- val x = Wire(inner.bundleI(e)).suggestName(s"${valName.name}In")
- // TODO: Don't care unconnected forwarded diplomatic signals for compatibility issue,
- // In the future, we should add an option to decide whether allowing unconnected in the LazyModule
- x := DontCare
- x
- }
-
- private def emptyDanglesOut: Seq[Dangle] = oPorts.zipWithIndex.map { case ((j, n, _, _), i) =>
- Dangle(
- source = HalfEdge(serial, i),
- sink = HalfEdge(n.serial, j),
- flipped= false,
- name = wirePrefix + "out",
- dataOpt= None)
- }
- private def emptyDanglesIn: Seq[Dangle] = iPorts.zipWithIndex.map { case ((j, n, _, _), i) =>
- Dangle(
- source = HalfEdge(n.serial, j),
- sink = HalfEdge(serial, i),
- flipped= true,
- name = wirePrefix + "in",
- dataOpt=None)
- }
-
-
- /** Create the [[Dangle]]s which describe the connections from this node output to other nodes inputs. */
- protected[diplomacy] def danglesOut: Seq[Dangle] = emptyDanglesOut.zipWithIndex.map {
- case (d,i) => d.copy(dataOpt = Some(bundleOut(i)))
- }
-
- /** Create the [[Dangle]]s which describe the connections from this node input from other nodes outputs. */
- protected[diplomacy] def danglesIn: Seq[Dangle] = emptyDanglesIn.zipWithIndex.map {
- case (d,i) => d.copy(dataOpt = Some(bundleIn(i)))
- }
-
- private[diplomacy] var instantiated = false
-
- /** Gather Bundle and edge parameters of outward ports.
- *
- * Accessors to the result of negotiation to be used within
- * [[LazyModuleImp]] Code. Should only be used within [[LazyModuleImp]] code
- * or after its instantiation has completed.
- */
- def out: Seq[(BO, EO)] = {
- require(instantiated, s"$name.out should not be called until after instantiation of its parent LazyModule.module has begun")
- bundleOut zip edgesOut
- }
-
- /** Gather Bundle and edge parameters of inward ports.
- *
- * Accessors to the result of negotiation to be used within
- * [[LazyModuleImp]] Code. Should only be used within [[LazyModuleImp]] code
- * or after its instantiation has completed.
- */
- def in: Seq[(BI, EI)] = {
- require(instantiated, s"$name.in should not be called until after instantiation of its parent LazyModule.module has begun")
- bundleIn zip edgesIn
- }
-
- /** Actually instantiate this node during [[LazyModuleImp]] evaluation.
- * Mark that it's safe to use the Bundle wires,
- * instantiate monitors on all input ports if appropriate,
- * and return all the dangles of this node.
- */
- protected[diplomacy] def instantiate(): Seq[Dangle] = {
- instantiated = true
- if (!circuitIdentity) {
- (iPorts zip in) foreach {
- case ((_, _, p, _), (b, e)) => if (p(MonitorsEnabled)) inner.monitor(b, e)
- } }
- danglesOut ++ danglesIn
- }
-
- protected[diplomacy] def cloneDangles(): Seq[Dangle] = emptyDanglesOut ++ emptyDanglesIn
-
- /** Connects the outward part of a node with the inward part of this node. */
- protected[diplomacy] def bind(h: OutwardNode[DI, UI, BI], binding: NodeBinding)(implicit p: Parameters, sourceInfo: SourceInfo): Unit = {
- val x = this // x := y
- val y = h
- val info = sourceLine(sourceInfo, " at ", "")
- val i = x.iPushed
- val o = y.oPushed
- y.oPush(i, x, binding match {
- case BIND_ONCE => BIND_ONCE
- case BIND_FLEX => BIND_FLEX
- case BIND_STAR => BIND_QUERY
- case BIND_QUERY => BIND_STAR
- })
- x.iPush(o, y, binding)
- }
-
- /* Metadata for printing the node graph. */
- def inputs: Seq[(OutwardNode[DI, UI, BI], RenderedEdge)] = (iPorts zip edgesIn) map { case ((_, n, p, _), e) =>
- val re = inner.render(e)
- (n, re.copy(flipped = re.flipped != p(RenderFlipped)))
- }
- /** Metadata for printing the node graph */
- def outputs: Seq[(InwardNode[DO, UO, BO], RenderedEdge)] = oPorts map { case (i, n, _, _) => (n, n.inputs(i)._2) }
-}
-
-/** A [[MixedNode]] that may be extended with custom behavior. */
-abstract class MixedCustomNode[DI, UI, EI, BI <: Data, DO, UO, EO, BO <: Data](
- inner: InwardNodeImp [DI, UI, EI, BI],
- outer: OutwardNodeImp[DO, UO, EO, BO])(
- implicit valName: ValName)
- extends MixedNode(inner, outer) {
- override def description = "custom"
- def resolveStar(iKnown: Int, oKnown: Int, iStars: Int, oStars: Int): (Int, Int)
- def mapParamsD(n: Int, p: Seq[DI]): Seq[DO]
- def mapParamsU(n: Int, p: Seq[UO]): Seq[UI]
-}
-
-/** A [[NodeImp]] that may be extended with custom behavior.
- *
- * Different from a [[MixedNode]] in that the inner and outer [[NodeImp]]s are the same.
- */
-abstract class CustomNode[D, U, EO, EI, B <: Data](imp: NodeImp[D, U, EO, EI, B])(
- implicit valName: ValName)
- extends MixedCustomNode(imp, imp)
-
-/** A JunctionNode creates multiple parallel arbiters.
- *
- * @example
- * {{{
- * val jbar = LazyModule(new JBar)
- * slave1.node := jbar.node
- * slave2.node := jbar.node
- * extras.node :=* jbar.node
- * jbar.node :*= masters1.node
- * jbar.node :*= masters2.node
- * }}}
- *
- * In the above example, only the first two connections have their multiplicity specified.
- * All the other connections include a '*' on the JBar's side, so the JBar decides the multiplicity.
- * Thus, in this example, we get 2x crossbars with 2 masters like this:
- * {slave1, extras.1} <= jbar.1 <= {masters1.1, masters2.1}
- * {slave2, extras.2} <= jbar.2 <= {masters1.2, masters2,2}
- *
- * @example
- * {{{
- * val jbar = LazyModule(new JBar)
- * jbar.node :=* masters.node
- * slaves1.node :=* jbar.node
- * slaves2.node :=* jbar.node
- * }}}
- * In the above example, the first connection takes multiplicity (*) from the right (masters).
- * Supposing masters.node had 3 edges, this would result in these three arbiters:
- * {slaves1.1, slaves2.1} <= jbar.1 <= { masters.1 }
- * {slaves1.2, slaves2.2} <= jbar.2 <= { masters.2 }
- * {slaves1.3, slaves2.3} <= jbar.3 <= { masters.3 }
- */
-class MixedJunctionNode[DI, UI, EI, BI <: Data, DO, UO, EO, BO <: Data](
- inner: InwardNodeImp [DI, UI, EI, BI],
- outer: OutwardNodeImp[DO, UO, EO, BO])(
- dFn: Seq[DI] => Seq[DO],
- uFn: Seq[UO] => Seq[UI])(
- implicit valName: ValName)
- extends MixedNode(inner, outer) {
- protected[diplomacy] var multiplicity = 0
-
- def uRatio: Int = iPorts.size / multiplicity
- def dRatio: Int = oPorts.size / multiplicity
-
- override def description = "junction"
- protected[diplomacy] def resolveStar(iKnown: Int, oKnown: Int, iStars: Int, oStars: Int): (Int, Int) = {
- require (iKnown == 0 || oKnown == 0,
- s"""Diplomacy has detected a problem with your graph:
- |The following node appears left of a :=* or a := and right of a :*= or :=. Only one side may drive multiplicity.
- |$context
- |$bindingInfo
- |""".stripMargin)
- multiplicity = iKnown max oKnown
- (multiplicity, multiplicity)
- }
- protected[diplomacy] def mapParamsD(n: Int, p: Seq[DI]): Seq[DO] =
- p.grouped(multiplicity).toList.transpose.map(dFn).transpose.flatten
- protected[diplomacy] def mapParamsU(n: Int, p: Seq[UO]): Seq[UI] =
- p.grouped(multiplicity).toList.transpose.map(uFn).transpose.flatten
-
- def inoutGrouped: Seq[(Seq[(BI, EI)], Seq[(BO, EO)])] = {
- val iGroups = in .grouped(multiplicity).toList.transpose
- val oGroups = out.grouped(multiplicity).toList.transpose
- iGroups zip oGroups
- }
-}
-
-/** A node type which has a fixed ratio between the number of input edges and output edges.
- *
- * The [[NodeImp]] on either side is the same.
- *
- * One example usage would be for putting down a series of 2:1 arbiters.
- *
- * Suppose you had N banks of L2 and wanted to connect those to two different driver crossbars.
- * In that case you can do this:
- * {{{
- * l2banks.node :*= jbar.node
- * jbar.node :*= xbar1.node
- * jbar.node :*= xbar2.node
- * }}}
- * If the L2 has 4 banks, now there are 4 egress ports on both xbar1 and xbar2 and they are arbitrated by the jbar.
- */
-class JunctionNode[D, U, EO, EI, B <: Data](imp: NodeImp[D, U, EO, EI, B])(
- dFn: Seq[D] => Seq[D],
- uFn: Seq[U] => Seq[U])(
- implicit valName: ValName)
- extends MixedJunctionNode[D, U, EI, B, D, U, EO, B](imp, imp)(dFn, uFn)
-
-/** [[MixedAdapterNode]] is used to transform between different diplomacy protocols ([[NodeImp]]), without changing the number of edges passing through it.
- *
- * For example, a [[MixedAdapterNode]] is needed for a TL to AXI bridge (interface).
- * {{{
- * case class TLToAXI4Node(stripBits: Int = 0)(implicit valName: ValName) extends MixedAdapterNode(TLImp, AXI4Imp)
- * }}}
- *
- * @param dFn convert downward parameter from input to output.
- * @param uFn convert upward parameter from output to input.
- */
-class MixedAdapterNode[DI, UI, EI, BI <: Data, DO, UO, EO, BO <: Data](
- inner: InwardNodeImp [DI, UI, EI, BI],
- outer: OutwardNodeImp[DO, UO, EO, BO])(
- dFn: DI => DO,
- uFn: UO => UI)(
- implicit valName: ValName)
- extends MixedNode(inner, outer) {
- override def description = "adapter"
- protected[diplomacy] override def flexibleArityDirection = true
- protected[diplomacy] def resolveStar(iKnown: Int, oKnown: Int, iStars: Int, oStars: Int): (Int, Int) = {
- require (oStars + iStars <= 1,
- s"""Diplomacy has detected a problem with your graph:
- |The following node appears left of a :*= $iStars times and right of a :=* $oStars times, at most once is allowed.
- |$context
- |$bindingInfo
- |""".stripMargin)
- if (oStars > 0) {
- require (iKnown >= oKnown,
- s"""Diplomacy has detected a problem with your graph:
- |After being connected right of :=*, the following node appears left of a := $iKnown times and right of a := $oKnown times.
- |${iKnown - oKnown} additional right of := bindings are required to resolve :=* successfully.
- |$context
- |$bindingInfo
- |""".stripMargin)
- (0, iKnown - oKnown)
- } else if (iStars > 0) {
- require (oKnown >= iKnown,
- s"""Diplomacy has detected a problem with your graph:
- |After being connected left of :*=, the following node appears left of a := $iKnown times and right of a := $oKnown times.
- |${oKnown - iKnown} additional left := bindings are required to resolve :*= successfully.
- |$context
- |$bindingInfo
- |""".stripMargin)
- (oKnown - iKnown, 0)
- } else {
- require (oKnown == iKnown,
- s"""Diplomacy has detected a problem with your graph:
- |The following node appears left of a := $iKnown times and right of a := $oKnown times.
- |Either the number of bindings on both sides of the node match, or connect this node by left-hand side of :*= or right-hand side of :=*
- |$context
- |$bindingInfo
- |""".stripMargin)
- (0, 0)
- }
- }
- protected[diplomacy] def mapParamsD(n: Int, p: Seq[DI]): Seq[DO] = {
- require(n == p.size,
- s"""Diplomacy has detected a problem with your graph:
- |The following node has ${p.size} inputs and $n outputs, they must match.
- |$context
- |$bindingInfo
- |""".stripMargin)
- p.map(dFn)
- }
- protected[diplomacy] def mapParamsU(n: Int, p: Seq[UO]): Seq[UI] = {
- require(n == p.size,
- s"""Diplomacy has detected a problem with your graph:
- |The following node has $n inputs and ${p.size} outputs, they must match
- |$context
- |$bindingInfo
- |""".stripMargin)
- p.map(uFn)
- }
-}
-
-/** A node which modifies the parameters flowing through it, but without changing the number of edges or the diplomatic protocol implementation. */
-class AdapterNode[D, U, EO, EI, B <: Data](imp: NodeImp[D, U, EO, EI, B])(
- dFn: D => D,
- uFn: U => U)(
- implicit valName: ValName)
- extends MixedAdapterNode[D, U, EI, B, D, U, EO, B](imp, imp)(dFn, uFn)
-
-/** A node which does not modify the parameters nor the protocol for edges that pass through it.
- *
- * During hardware generation, [[IdentityNode]]s automatically connect their inputs to outputs.
- */
-class IdentityNode[D, U, EO, EI, B <: Data](imp: NodeImp[D, U, EO, EI, B])()(implicit valName: ValName)
- extends AdapterNode(imp)({ s => s }, { s => s }) {
- override def description = "identity"
- override final def circuitIdentity = true
- override protected[diplomacy] def instantiate(): Seq[Dangle] = {
- val dangles = super.instantiate()
- (out zip in) foreach { case ((o, _), (i, _)) => o :<>= i }
- dangles
- }
- override protected[diplomacy] def cloneDangles(): Seq[Dangle] = super.cloneDangles()
-}
-
-/** [[EphemeralNode]]s are used as temporary connectivity placeholders, but disappear from the final node graph.
- * An ephemeral node provides a mechanism to directly connect two nodes to each other where neither node knows about the other,
- * but both know about an ephemeral node they can use to facilitate the connection.
- */
-class EphemeralNode[D, U, EO, EI, B <: Data](imp: NodeImp[D, U, EO, EI, B])()(implicit valName: ValName)
- extends AdapterNode(imp)({ s => s }, { s => s }) {
- override def description = "ephemeral"
- override final def circuitIdentity = true
- override def omitGraphML = true
- override def oForward(x: Int): Option[(Int, OutwardNode[D, U, B])] = Some(iDirectPorts(x) match { case (i, n, _, _) => (i, n) })
- override def iForward(x: Int): Option[(Int, InwardNode[D, U, B])] = Some(oDirectPorts(x) match { case (i, n, _, _) => (i, n) })
- override protected[diplomacy] def instantiate(): Seq[Dangle] = {
- instantiated = true
- Nil
- }
- override protected[diplomacy] def cloneDangles(): Seq[Dangle] = Nil
-}
-
-/** [[MixedNexusNode]] is used when the number of nodes connecting from either side is unknown (e.g. a Crossbar which also is a protocol adapter).
- *
- * The [[NodeImp]] is different between [[inner]] and [[outer]],
- *
- * @param dFn Function for mapping the parameters flowing downward into new outward flowing down parameters.
- * @param uFn Function for mapping the parameters flowing upward into new inward flowing up parameters.
- * @param inputRequiresOutput True if it is required that if there are input connections, there are output connections (this node can't just be a sink).
- * @param outputRequiresInput True if it is required that if there are output connections, there are input connections (this node can't just be a source).
- */
-class MixedNexusNode[DI, UI, EI, BI <: Data, DO, UO, EO, BO <: Data](
- inner: InwardNodeImp [DI, UI, EI, BI],
- outer: OutwardNodeImp[DO, UO, EO, BO])(
- dFn: Seq[DI] => DO,
- uFn: Seq[UO] => UI,
- // no inputs and no outputs is always allowed
- inputRequiresOutput: Boolean = true,
- outputRequiresInput: Boolean = true)(
- implicit valName: ValName)
- extends MixedNode(inner, outer)
-{
- override def description = "nexus"
- protected[diplomacy] def resolveStar(iKnown: Int, oKnown: Int, iStars: Int, oStars: Int): (Int, Int) = {
- // a nexus treats :=* as a weak pointer
- def resolveStarInfo: String =
- s"""$context
- |$bindingInfo
- |number of known := bindings to inward nodes: $iKnown
- |number of known := bindings to outward nodes: $oKnown
- |number of binding queries from inward nodes: $iStars
- |number of binding queries from outward nodes: $oStars
- |""".stripMargin
- require(!outputRequiresInput || oKnown == 0 || iStars + iKnown != 0,
- s"""Diplomacy has detected a problem with your graph:
- |The following node has $oKnown outward connections and no inward connections. At least one inward connection was required.
- |$resolveStarInfo
- |""".stripMargin)
- require(!inputRequiresOutput || iKnown == 0 || oStars + oKnown != 0,
- s"""Diplomacy has detected a problem with your graph:
- |The following node node has $iKnown inward connections and no outward connections. At least one outward connection was required.
- |$resolveStarInfo
- |""".stripMargin)
- if (iKnown == 0 && oKnown == 0) (0, 0) else (1, 1)
- }
- protected[diplomacy] def mapParamsD(n: Int, p: Seq[DI]): Seq[DO] = { if (n > 0) { val a = dFn(p); Seq.fill(n)(a) } else Nil }
- protected[diplomacy] def mapParamsU(n: Int, p: Seq[UO]): Seq[UI] = { if (n > 0) { val a = uFn(p); Seq.fill(n)(a) } else Nil }
-}
-
-/** [[NexusNode]] is a [[MixedNexusNode]], in which the inward and outward side of the node have the same [[NodeImp]] implementation. */
-class NexusNode[D, U, EO, EI, B <: Data](imp: NodeImp[D, U, EO, EI, B])(
- dFn: Seq[D] => D,
- uFn: Seq[U] => U,
- inputRequiresOutput: Boolean = true,
- outputRequiresInput: Boolean = true)(
- implicit valName: ValName)
- extends MixedNexusNode[D, U, EI, B, D, U, EO, B](imp, imp)(dFn, uFn, inputRequiresOutput, outputRequiresInput)
-
-/** A node which represents a node in the graph which only has outward edges and no inward edges.
- *
- * A [[SourceNode]] cannot appear left of a `:=`, `:*=`, `:=*, or `:*=*`
- * There are no Mixed [[SourceNode]]s, There are no "Mixed" [[SourceNode]]s because each one only has an outward side.
- */
-class SourceNode[D, U, EO, EI, B <: Data](imp: NodeImp[D, U, EO, EI, B])(po: Seq[D])(implicit valName: ValName)
- extends MixedNode(imp, imp)
-{
- override def description = "source"
- protected[diplomacy] def resolveStar(iKnown: Int, oKnown: Int, iStars: Int, oStars: Int): (Int, Int) = {
- def resolveStarInfo: String =
- s"""$context
- |$bindingInfo
- |number of known := bindings to inward nodes: $iKnown
- |number of known := bindings to outward nodes: $oKnown
- |number of binding queries from inward nodes: $iStars
- |number of binding queries from outward nodes: $oStars
- |${po.size} outward parameters: [${po.map(_.toString).mkString(",")}]
- |""".stripMargin
- require(oStars <= 1,
- s"""Diplomacy has detected a problem with your graph:
- |The following node appears right of a :=* $oStars times; at most once is allowed.
- |$resolveStarInfo
- |""".stripMargin)
- require(iStars == 0,
- s"""Diplomacy has detected a problem with your graph:
- |The following node cannot appear left of a :*=
- |$resolveStarInfo
- |""".stripMargin)
- require(iKnown == 0,
- s"""Diplomacy has detected a problem with your graph:
- |The following node cannot appear left of a :=
- |$resolveStarInfo
- |""".stripMargin)
- if (oStars == 0)
- require(po.size == oKnown,
- s"""Diplomacy has detected a problem with your graph:
- |The following node has $oKnown outward bindings connected to it, but ${po.size} sources were specified to the node constructor.
- |Either the number of outward := bindings should be exactly equal to the number of sources, or connect this node on the right-hand side of a :=*
- |$resolveStarInfo
- |""".stripMargin)
- else
- require(po.size >= oKnown,
- s"""Diplomacy has detected a problem with your graph:
- |The following node has $oKnown outward bindings connected to it, but ${po.size} sources were specified to the node constructor.
- |To resolve :=*, size of outward parameters can not be less than bindings.
- |$resolveStarInfo
- |""".stripMargin
- )
- (0, po.size - oKnown)
- }
- protected[diplomacy] def mapParamsD(n: Int, p: Seq[D]): Seq[D] = po
- protected[diplomacy] def mapParamsU(n: Int, p: Seq[U]): Seq[U] = Seq()
-
- def makeIOs()(implicit valName: ValName): HeterogeneousBag[B] = {
- val bundles = this.out.map(_._1)
- val ios = IO(Flipped(new HeterogeneousBag(bundles)))
- ios.suggestName(valName.name)
- bundles.zip(ios).foreach { case (bundle, io) => bundle <> io }
- ios
- }
-}
-
-/** A node which represents a node in the graph which has only inward edges, no outward edges.
- *
- * A [[SinkNode]] cannot appear cannot appear right of a `:=`, `:*=`, `:=*`, or `:*=*`
- *
- * There are no "Mixed" [[SinkNode]]s because each one only has an inward side.
- */
-class SinkNode[D, U, EO, EI, B <: Data](imp: NodeImp[D, U, EO, EI, B])(pi: Seq[U])(implicit valName: ValName)
- extends MixedNode(imp, imp)
-{
- override def description = "sink"
- protected[diplomacy] def resolveStar(iKnown: Int, oKnown: Int, iStars: Int, oStars: Int): (Int, Int) = {
- def resolveStarInfo: String =
- s"""$context
- |$bindingInfo
- |number of known := bindings to inward nodes: $iKnown
- |number of known := bindings to outward nodes: $oKnown
- |number of binding queries from inward nodes: $iStars
- |number of binding queries from outward nodes: $oStars
- |${pi.size} inward parameters: [${pi.map(_.toString).mkString(",")}]
- |""".stripMargin
- require (iStars <= 1,
- s"""Diplomacy has detected a problem with your graph:
- |The following node appears left of a :*= $iStars times; at most once is allowed.
- |$resolveStarInfo
- |""".stripMargin)
- require (oStars == 0,
- s"""Diplomacy has detected a problem with your graph:
- |The following node cannot appear right of a :=*
- |$resolveStarInfo
- |""".stripMargin)
- require (oKnown == 0,
- s"""Diplomacy has detected a problem with your graph:
- |The following node cannot appear right of a :=
- |$resolveStarInfo
- |""".stripMargin)
- if (iStars == 0)
- require(pi.size == iKnown,
- s"""Diplomacy has detected a problem with your graph:
- |The following node has $iKnown inward bindings connected to it, but ${pi.size} sinks were specified to the node constructor.
- |Either the number of inward := bindings should be exactly equal to the number of sink, or connect this node on the left-hand side of a :*=
- |$resolveStarInfo
- |""".stripMargin)
- else
- require(pi.size >= iKnown,
- s"""Diplomacy has detected a problem with your graph:
- |The following node has $iKnown inward bindings connected to it, but ${pi.size} sinks were specified to the node constructor.
- |To resolve :*=, size of inward parameters can not be less than bindings.
- |$resolveStarInfo
- |""".stripMargin
- )
- (pi.size - iKnown, 0)
- }
- protected[diplomacy] def mapParamsD(n: Int, p: Seq[D]): Seq[D] = Seq()
- protected[diplomacy] def mapParamsU(n: Int, p: Seq[U]): Seq[U] = pi
-
- def makeIOs()(implicit valName: ValName): HeterogeneousBag[B] = {
- val bundles = this.in.map(_._1)
- val ios = IO(new HeterogeneousBag(bundles))
- ios.suggestName(valName.name)
- bundles.zip(ios).foreach { case (bundle, io) => io <> bundle }
- ios
- }
-}
-
-/** A node intended to replace a portion of the diplomatic graph in order to test functionality of a copy (cloned) [[LazyModule]]
- *
- * @param node the node to copy
- * @param clone the copy of the LazyModule containing [[node]]
- */
-class MixedTestNode[DI, UI, EI, BI <: Data, DO, UO, EO, BO <: Data] protected[diplomacy](
- node: NodeHandle [DI, UI, EI, BI, DO, UO, EO, BO], clone: CloneLazyModule)(
- implicit valName: ValName)
- extends MixedNode(node.inner, node.outer)
-{
- // The devices connected to this test node must recreate these parameters:
- def iParams: Seq[DI] = node.inward .diParams
- def oParams: Seq[UO] = node.outward.uoParams
-
- override def description = "test"
- protected[diplomacy] def resolveStar(iKnown: Int, oKnown: Int, iStars: Int, oStars: Int): (Int, Int) = {
- def resolveStarInfo: String =
- s"""$context
- |$bindingInfo
- |number of known := bindings to inward nodes: $iKnown
- |number of known := bindings to outward nodes: $oKnown
- |number of binding queries from inward nodes: $iStars
- |number of binding queries from outward nodes: $oStars
- |downstream inward parameters: ${node.inward.diParams}
- |upstream inward parameters: ${node.inward.uiParams}
- |upstream outward parameters: ${node.outward.uoParams}
- |downstream outward parameters: ${node.outward.doParams}
- |node.inward.uiParams.size
- |""".stripMargin
-
- require(oStars <= 1,
- s"""Diplomacy has detected a problem with your graph:
- |The following node appears right of a :=* $oStars times; at most once is allowed.
- |$resolveStarInfo
- |""".stripMargin)
- require(iStars <= 1,
- s"""Diplomacy has detected a problem with your graph:
- |The following node appears left of a :*= $iStars times; at most once is allowed.
- |$resolveStarInfo
- |""".stripMargin)
- require(node.inward .uiParams.size == iKnown || iStars == 1,
- s"""Diplomacy has detected a problem with your graph:
- |The following node has only $iKnown inputs, which should be ${node.inward.uiParams.size}, or connect this node on the left-hand side of :*=
- |$resolveStarInfo
- |""".stripMargin)
- require(node.outward.doParams.size == oKnown || oStars == 1,
- s"""Diplomacy has detected a problem with your graph:
- |The following node has only $oKnown outputs, which should be ${node.outward.doParams.size}, or connect this node on the right-hand side of :=*
- |$resolveStarInfo
- |""".stripMargin)
- (node.inward.uiParams.size - iKnown, node.outward.doParams.size - oKnown)
- }
-
- protected[diplomacy] def mapParamsU(n: Int, p: Seq[UO]): Seq[UI] = node.inward .uiParams
- protected[diplomacy] def mapParamsD(n: Int, p: Seq[DI]): Seq[DO] = node.outward.doParams
-
- override protected[diplomacy] def instantiate(): Seq[Dangle] = {
- val dangles = super.instantiate()
- val orig_module = clone.base.module
- val clone_auto = clone.io("auto").asInstanceOf[AutoBundle]
-
- danglesOut.zipWithIndex.foreach { case (d, i) =>
- val orig = orig_module.dangles.find(_.source == HalfEdge(node.outward.serial, i))
- require (orig.isDefined, s"Cloned node ${node.outward.name} must be connected externally out ${orig_module.name}")
- val io_name = orig_module.auto.elements.find(_._2 eq orig.get.data).get._1
- d.data <> clone_auto.elements(io_name)
- }
- danglesIn.zipWithIndex.foreach { case (d, i) =>
- val orig = orig_module.dangles.find(_.sink == HalfEdge(node.inward.serial, i))
- require (orig.isDefined, s"Cloned node ${node.inward.name} must be connected externally in ${orig_module.name}")
- val io_name = orig_module.auto.elements.find(_._2 eq orig.get.data).get._1
- clone_auto.elements(io_name) <> d.data
- }
-
- dangles
- }
- override protected[diplomacy] def cloneDangles(): Seq[Dangle] = {
- require(false, "Unsupported")
- super.cloneDangles()
- }
-}
diff --git a/src/main/scala/diplomacy/ValName.scala b/src/main/scala/diplomacy/ValName.scala
deleted file mode 100644
index bf0e5812298..00000000000
--- a/src/main/scala/diplomacy/ValName.scala
+++ /dev/null
@@ -1,12 +0,0 @@
-// See LICENSE.SiFive for license details.
-
-package freechips.rocketchip.diplomacy
-
-import freechips.rocketchip.macros.ValNameImpl
-
-case class ValName(name: String)
-
-object ValName
-{
- implicit def materialize(implicit x: ValNameImpl): ValName = ValName(x.name)
-}
diff --git a/src/main/scala/diplomacy/package.scala b/src/main/scala/diplomacy/package.scala
index 5433147fae1..f6f0ed668a8 100644
--- a/src/main/scala/diplomacy/package.scala
+++ b/src/main/scala/diplomacy/package.scala
@@ -2,190 +2,15 @@
package freechips.rocketchip
-import chisel3.experimental.{SourceInfo, SourceLine}
import chisel3.Data
+import chisel3.experimental.{SourceInfo, SourceLine}
import org.chipsalliance.cde.config.Parameters
-import scala.language.implicitConversions
+import scala.language.implicitConversions
-/** Diplomacy is a set of abstractions for describing directed, acyclic graphs
- * where parameters will be negotiated between nodes. These abstractions are
- * expressed in the form of abstract classes, traits, and type parameters, which
- * comprises nearly all of the types defined in this package.
- *
- * The [[NodeImp]] ("node implementation") is the main abstract type that associates
- * the type parameters of all other abstract types. Defining a concrete
- * implementation of [[NodeImp]] will therefore determine concrete types for all
- * type parameters. For example, passing in a concrete instance of NodeImp to a
- * SourceNode will fully determine concrete types for all of a SourceNode's type
- * parameters.
- *
- * Specific applications of Diplomacy are expected to either extend these types
- * or to specify concrete types for the type parameters. This allows for
- * creating and associating application-specific node, edge, parameter, and bundle types.
- *
- *
- * =Concepts, metaphors, and mnemonics to help with understanding Diplomacy code=
- *
- * ==Parameter Types==
- *
- * There are several types of parameters involved in diplomacy code.
- *
- * - Upward-flowing/Downward-flowing Parameters: These parameter types flow along edges and can be considered as the
- * pre-negotiated, unresolved parameters.
- * - Edge Parameters: These parameters are the result of the diplomatic negotiation and that is resolved for each edge.
- * They are metadata, or an abstract concept of the connection represented by their edge, and contain any sort.
- * These are an abstract concept which carry any sort of conceptual information that is useful to pass along the graph edge.
- * For example, the full address map visible from a given edge and the supported access types for each memory region.
- * - "p" Parameters: These are parameters of type [[Parameters]] which are implicit and generally available
- * in various stages of the diplomacy codebase.
- * Often they are captured from the context in which a particular diplomatic node or edge is created or bound.
- * - Bundle Parameters: These parameters are used for actual hardware generation of the [[chisel3.Data]]s which connect
- * diplomatic components. In contrast to edge parameters, this may carry information like the width of an address
- * or opcode field.
- * While they are derived from Edge parameters holding all metadata computed over an edge,
- * Bundle parameters often contain only concrete information required to create the hardware type,
- * such as [[freechips.rocketchip.tilelink.TLBundleParameters]] and [[freechips.rocketchip.amba.axi4.AXI4BundleParameters]]
- *
- * ==Inward/Outward vs. Upward/Downward==
- *
- * Diplomacy defines two dimensions: inward/outward and upward/downward.
- *
- * Inward/outward refer to the direction of edges from the perspective of a given node.
- * For a given node:
- * - Inward refers to edges that point into itself.
- * - Outward refers to edges that point out from itself.
- *
- * Therefore, a given edge is always described as inward to one node and as outward from another.
- *
- * Upward/downward refer to the direction of the overall directed acyclic graph.
- * Because each each edge is directed, we say that the directions flow from sources (nodes that only have outward edges)
- * downwards to sinks (nodes that only have inward edges), or from sinks upwards to sources.
- * These terms are used in parameter negotiation, where parameters flow both
- * upwards and downwards on edges. Note that diplomacy avoids terms like "master/slave",
- * "producer/consumer", though these can be defined by the concrete implementations of diplomatic systems.
- * Such terms imply something about the transactional behavior of agents within a protocol,
- * whereas source/sink and up/down refer only to the structure of the graph and the flow of parameters.
- * - Upward refers to the flow of parameters along edges in the upwards direction.
- * - Downward refers to a flow of parameters along edges in the downwards direction.
- *
- * A useful mnemonic for distinguishing between upward and downward is to imagine
- * a diplomatic graph as a literal network of rivers where water flows in the direction of the edges,
- * and parameters that move in the upstream direction,
- * while downward refers to parameters that move in the downstream direction.
- *
- * ==Acronyms==
- *
- * Diplomacy has some commonly used acronyms described below:
- * D[IO], U[IO], E[IO], B[IO] are the types of parameters which will be propagated.
- * D: Downwards -- parameters passed in the same direction as the edge.
- * U: Upwards -- parameters passed in the opposite direction as the edge.
- * E: Edge -- resolved (negotiated) parameters describing conceptual information on graph edges.
- * B: Bundle should extends from [[chisel3.Data]].
- *
- * {{{
- *
- *
- * Upwards (a.k.a. towards Sources) ↓
- * ↓
- * inward edge of (parameter) type EI ↓
- * created from parameters of type UI and DI ↓
- * will result in a Bundle of type BI ↓
- * ↓
- * ^ ↓ *
- * . ↓ *
- * ┌───────────────────────────────.──↓──*───────────────────────────────┐
- * │ . ↓ * BaseNode │
- * │ . ↓ * (NodeImp) │
- * │ . ↓ * │
- * │ ┌────────────────────────────.──↓──*────────────────────────────┐ │
- * │ │ . ↓ * InwardNode (InwardNodeImp)│ │
- * │ │ (mixI)↓ * │ │
- * │ │ . ↓ * │ │
- * │ │ Upward-flowing inwards . ↓ * Downward-Flowing inwards │ │
- * │ │ parameters of type UI . ↓ * parameters of type DI │ │
- * │ └────────────────────────────.──↓──*────────────────────────────┘ │
- * │ . ↓ * │
- * │ . I v │
- * │ (mapParamsU) (mapParamsD) │
- * │ ^ O + │
- * │ : ↓ + │
- * │ ┌────────────────────────────:──↓──+────────────────────────────┐ │
- * │ │ : ↓ + OutwardNode(OutwardNodeImp)│ │
- * │ │ : ↓ (mixO) │ │
- * │ │ : ↓ + │ │
- * │ │ Upward-flowing outwards : ↓ + Downward-Flowing outward │ │
- * │ │ parameters of type UO : ↓ + parameters of type DO │ │
- * │ └────────────────────────────:──↓──+────────────────────────────┘ │
- * │ : ↓ + │
- * │ : ↓ + │
- * └───────────────────────────────.──↓──*───────────────────────────────┘
- * : ↓ *
- * : ↓ v
- * ↓ outward edge of (parameter) type EO
- * ↓ created from parameters of type UO and DO
- * ↓ will result in a Bundle of type BO
- * ↓
- * ↓ Downwards (a.k.a. towards Sinks)
- *
- * }}}
- *
- * == Handles ==
- *
- * Two Diplomatic nodes can be bound together using the `:=` operator or one of
- * its sibling operators. Binding is asymmetric, and the binding operation will
- * connect the outward of one node to the inward of the other.
- *
- * For example, the expression `a := b` will connect the outward of `b` to the
- * inward of `a`.
- *
- * We would like the `:=` operator to have additional properties that make it
- * intuitive to use:
- *
- * 1. It should be chainable, so that `a := b := c` will have the intuitive effect
- * of binding c to b and b to a. This requires that the return type of `:=` be the
- * same as its arguments, because the result of one `:=` operation must be
- * valid as an argument to other `:=` operations.
- *
- * 2. It should be associative, so that `(a := b) := c` is equivalent to `a := (b := c).`
- * This means that the order in which the bind operations execute does
- * not matter, even if split across multiple files.
- *
- * 3. `a := b` should only be allowed if and only if `b` allows outward edges and `a`
- * allows inward edges. This should be preserved even when chaining
- * operations, and it should ideally be enforced at compile time.
- *
- * [[NodeHandle]] are a way of satisfying all of these properties. A Handle represents
- * the aggregation of a chain of Nodes, and it preserves information about
- * the connectability of the innermost and the outermost sides of the chain.
- *
- * If `b` supports inward edges, then `a := b` returns a [[NodeHandle]] that supports inward
- * edges that go into `b`. If `a` supports outward edges, then `a := b` returns a
- * [[NodeHandle]] that supports outward edges coming out of `a`.
- *
- * ==Node Terms==
- *
- * These are some conventionally used terms for diplomatic Nodes,
- * which describe different common subtypes that certain protocol implementation might utilize:
- * - Mixed: implies that the inward and outward NodeImp are not the same (some sort of protocol conversion is occurring between the two implementations).
- * - Adapter: the number of inward and outward edges must be the same.
- * - Nexus: the number of nodes connecting from either side are unknown until the graph is constructed and can differ from one another.
- * - Identity: modifies neither the parameters nor the protocol-specific circuitry for the edges that pass through it.
- * - Source: cannot have inward edges.
- * - Sink: cannot have outward edges.
- * - Junction: the number of inward and outward edges must have a fixed ratio to one another
- * - Ephemeral: a temporary placeholder used for connectivity operations
+/** Rocketchip Specific Diplomacy code. All other Diplomacy core functionality has been moved to standalone diplomacy
*/
-package object diplomacy
-{
- type SimpleNodeHandle[D, U, E, B <: Data] = NodeHandle[D, U, E, B, D, U, E, B]
- type AnyMixedNode = MixedNode[_, _, _, _ <: Data, _, _, _, _ <: Data]
-
- def sourceLine(sourceInfo: SourceInfo, prefix: String = " (", suffix: String = ")") = sourceInfo match {
- case SourceLine(filename, line, col) => s"$prefix$filename:$line:$col$suffix"
- case _ => ""
- }
-
+package object diplomacy {
def bitIndexes(x: BigInt, tail: Seq[Int] = Nil): Seq[Int] = {
require (x >= 0)
if (x == 0) {
@@ -196,47 +21,290 @@ package object diplomacy
}
}
- implicit class BigIntHexContext(private val sc: StringContext) extends AnyVal {
- def x(args: Any*): BigInt = {
- val orig = sc.s(args: _*)
- BigInt(orig.replace("_", ""), 16)
- }
- }
-
- type PropertyOption = Option[(String, Seq[ResourceValue])]
- type PropertyMap = Iterable[(String, Seq[ResourceValue])]
-
- implicit class IntToProperty(x: Int) {
- def asProperty: Seq[ResourceValue] = Seq(ResourceInt(BigInt(x)))
- }
-
- implicit class BigIntToProperty(x: BigInt) {
- def asProperty: Seq[ResourceValue] = Seq(ResourceInt(x))
+ // TODO - Remove compatibility layer for deprecated diplomacy api once all local references are moved to standalone diplomacy lib.
+ // package.scala
+ @deprecated("Diplomacy has been split to a standalone library", "rocketchip 2.0.0")
+ def sourceLine(sourceInfo: SourceInfo, prefix: String = " (", suffix: String = ")") = sourceInfo match {
+ case SourceLine(filename, line, col) => s"$prefix$filename:$line:$col$suffix"
+ case _ => ""
}
+ @deprecated("Diplomacy has been split to a standalone library", "rocketchip 2.0.0")
+ def EnableMonitors[T](
+ body: Parameters => T
+ )(
+ implicit p: Parameters
+ ) = _root_.org.chipsalliance.diplomacy.EnableMonitors(body)(p)
+ @deprecated("Diplomacy has been split to a standalone library", "rocketchip 2.0.0")
+ def DisableMonitors[T](
+ body: Parameters => T
+ )(
+ implicit p: Parameters
+ ) = _root_.org.chipsalliance.diplomacy.DisableMonitors(body)(p)
+ @deprecated("Diplomacy has been split to a standalone library", "rocketchip 2.0.0")
+ def FlipRendering[T](
+ body: Parameters => T
+ )(
+ implicit p: Parameters
+ ) = _root_.org.chipsalliance.diplomacy.FlipRendering(body)(p)
+ @deprecated("Diplomacy has been split to a standalone library", "rocketchip 2.0.0")
+ implicit def moduleValue[T](value: ModuleValue[T]): T = _root_.org.chipsalliance.diplomacy.moduleValue(value)
- implicit class StringToProperty(x: String) {
- def asProperty: Seq[ResourceValue] = Seq(ResourceString(x))
- }
+// Clone.scala
+ @deprecated("Diplomacy has been split to a standalone library", "rocketchip 2.0.0")
+ val CloneLazyModule = _root_.org.chipsalliance.diplomacy.lazymodule.CloneLazyModule
- implicit class DeviceToProperty(x: Device) {
- def asProperty: Seq[ResourceValue] = Seq(ResourceReference(x.label))
- }
+// ValName.scala
+ @deprecated("Diplomacy has been split to a standalone library", "rocketchip 2.0.0")
+ type ValName = _root_.org.chipsalliance.diplomacy.ValName
+ @deprecated("Diplomacy has been split to a standalone library", "rocketchip 2.0.0")
+ def ValName(value: String) = _root_.org.chipsalliance.diplomacy.ValName(value)
+ @deprecated("Diplomacy has been split to a standalone library", "rocketchip 2.0.0")
+ implicit def SourcecodeNameExt(x: sourcecode.Name) = _root_.org.chipsalliance.diplomacy.SourcecodeNameExt(x)
- def EnableMonitors[T](body: Parameters => T)(implicit p: Parameters) = body(p.alterPartial {
- case MonitorsEnabled => true
- })
- def DisableMonitors[T](body: Parameters => T)(implicit p: Parameters) = body(p.alterPartial {
- case MonitorsEnabled => false
- })
- def FlipRendering[T](body: Parameters => T)(implicit p: Parameters) = body(p.alterPartial {
- case RenderFlipped => !p(RenderFlipped)
- })
+// LazyModule.scala
+ @deprecated("Diplomacy has been split to a standalone library", "rocketchip 2.0.0")
+ type LazyModule = _root_.org.chipsalliance.diplomacy.lazymodule.LazyModule
+ @deprecated("Diplomacy has been split to a standalone library", "rocketchip 2.0.0")
+ val LazyModule = _root_.org.chipsalliance.diplomacy.lazymodule.LazyModule
+ @deprecated("Diplomacy has been split to a standalone library", "rocketchip 2.0.0")
+ type LazyModuleImpLike = _root_.org.chipsalliance.diplomacy.lazymodule.LazyModuleImpLike
+ @deprecated("Diplomacy has been split to a standalone library", "rocketchip 2.0.0")
+ type LazyModuleImp = _root_.org.chipsalliance.diplomacy.lazymodule.LazyModuleImp
+ @deprecated("Diplomacy has been split to a standalone library", "rocketchip 2.0.0")
+ type LazyRawModuleImp = _root_.org.chipsalliance.diplomacy.lazymodule.LazyRawModuleImp
+ @deprecated("Diplomacy has been split to a standalone library", "rocketchip 2.0.0")
+ type SimpleLazyModule = _root_.org.chipsalliance.diplomacy.lazymodule.SimpleLazyModule
+ @deprecated("Diplomacy has been split to a standalone library", "rocketchip 2.0.0")
+ type LazyScope = _root_.org.chipsalliance.diplomacy.lazymodule.LazyScope
+ @deprecated("Diplomacy has been split to a standalone library", "rocketchip 2.0.0")
+ val LazyScope = _root_.org.chipsalliance.diplomacy.lazymodule.LazyScope
+ @deprecated("Diplomacy has been split to a standalone library", "rocketchip 2.0.0")
+ type ModuleValue[T] = _root_.org.chipsalliance.diplomacy.lazymodule.ModuleValue[T]
+ @deprecated("Diplomacy has been split to a standalone library", "rocketchip 2.0.0")
+ val InModuleBody = _root_.org.chipsalliance.diplomacy.lazymodule.InModuleBody
- implicit def moduleValue[T](value: ModuleValue[T]): T = value.getWrappedValue
+// Nodes.scala
+ @deprecated("Diplomacy has been split to a standalone library", "rocketchip 2.0.0")
+ type Dangle = _root_.org.chipsalliance.diplomacy.nodes.Dangle
+ @deprecated("Diplomacy has been split to a standalone library", "rocketchip 2.0.0")
+ val Dangle = _root_.org.chipsalliance.diplomacy.nodes.Dangle
+ @deprecated("Diplomacy has been split to a standalone library", "rocketchip 2.0.0")
+ type HalfEdge = _root_.org.chipsalliance.diplomacy.nodes.HalfEdge
+ @deprecated("Diplomacy has been split to a standalone library", "rocketchip 2.0.0")
+ val HalfEdge = _root_.org.chipsalliance.diplomacy.nodes.HalfEdge
+ @deprecated("Diplomacy has been split to a standalone library", "rocketchip 2.0.0")
+ val MonitorsEnabled = _root_.org.chipsalliance.diplomacy.nodes.MonitorsEnabled
+ @deprecated("Diplomacy has been split to a standalone library", "rocketchip 2.0.0")
+ val RenderFlipped = _root_.org.chipsalliance.diplomacy.nodes.RenderFlipped
+ @deprecated("Diplomacy has been split to a standalone library", "rocketchip 2.0.0")
+ val RenderedEdge = _root_.org.chipsalliance.diplomacy.nodes.RenderedEdge
+ @deprecated("Diplomacy has been split to a standalone library", "rocketchip 2.0.0")
+ type RenderedEdge = _root_.org.chipsalliance.diplomacy.nodes.RenderedEdge
+ @deprecated("Diplomacy has been split to a standalone library", "rocketchip 2.0.0")
+ type InwardNodeImp[DI, UI, EI, BI <: Data] = _root_.org.chipsalliance.diplomacy.nodes.InwardNodeImp[DI, UI, EI, BI]
+ @deprecated("Diplomacy has been split to a standalone library", "rocketchip 2.0.0")
+ type OutwardNodeImp[DO, UO, EO, BO <: Data] = _root_.org.chipsalliance.diplomacy.nodes.OutwardNodeImp[DO, UO, EO, BO]
+ @deprecated("Diplomacy has been split to a standalone library", "rocketchip 2.0.0")
+ type NodeImp[D, U, EO, EI, B <: Data] = _root_.org.chipsalliance.diplomacy.nodes.NodeImp[D, U, EO, EI, B]
+ @deprecated("Diplomacy has been split to a standalone library", "rocketchip 2.0.0")
+ type SimpleNodeImp[D, U, E, B <: Data] = _root_.org.chipsalliance.diplomacy.nodes.SimpleNodeImp[D, U, E, B]
+ @deprecated("Diplomacy has been split to a standalone library", "rocketchip 2.0.0")
+ type BaseNode = _root_.org.chipsalliance.diplomacy.nodes.BaseNode
+ @deprecated("Diplomacy has been split to a standalone library", "rocketchip 2.0.0")
+ val BaseNode = _root_.org.chipsalliance.diplomacy.nodes.BaseNode
+ @deprecated("Diplomacy has been split to a standalone library", "rocketchip 2.0.0")
+ type FormatEdge = _root_.org.chipsalliance.diplomacy.nodes.FormatEdge
+ @deprecated("Diplomacy has been split to a standalone library", "rocketchip 2.0.0")
+ type FormatNode[I <: FormatEdge, O <: FormatEdge] = _root_.org.chipsalliance.diplomacy.nodes.FormatNode[I, O]
+ @deprecated("Diplomacy has been split to a standalone library", "rocketchip 2.0.0")
+ type NoHandle = _root_.org.chipsalliance.diplomacy.nodes.NoHandle
+ @deprecated("Diplomacy has been split to a standalone library", "rocketchip 2.0.0")
+ val NoHandleObject = _root_.org.chipsalliance.diplomacy.nodes.NoHandleObject
+ @deprecated("Diplomacy has been split to a standalone library", "rocketchip 2.0.0")
+ type NodeHandle[DI, UI, EI, BI <: Data, DO, UO, EO, BO <: Data] =
+ _root_.org.chipsalliance.diplomacy.nodes.NodeHandle[DI, UI, EI, BI, DO, UO, EO, BO]
+ @deprecated("Diplomacy has been split to a standalone library", "rocketchip 2.0.0")
+ val NodeHandle = _root_.org.chipsalliance.diplomacy.nodes.NodeHandle
+ @deprecated("Diplomacy has been split to a standalone library", "rocketchip 2.0.0")
+ type NodeHandlePair[DI, UI, EI, BI <: Data, DO, UO, EO, BO <: Data] =
+ _root_.org.chipsalliance.diplomacy.nodes.NodeHandlePair[DI, UI, EI, BI, DO, UO, EO, BO]
+ @deprecated("Diplomacy has been split to a standalone library", "rocketchip 2.0.0")
+ type InwardNodeHandle[DI, UI, EI, BI <: Data] =
+ _root_.org.chipsalliance.diplomacy.nodes.InwardNodeHandle[DI, UI, EI, BI]
+ @deprecated("Diplomacy has been split to a standalone library", "rocketchip 2.0.0")
+ type NodeBinding = _root_.org.chipsalliance.diplomacy.nodes.NodeBinding
+ @deprecated("Diplomacy has been split to a standalone library", "rocketchip 2.0.0")
+ val BIND_ONCE = _root_.org.chipsalliance.diplomacy.nodes.BIND_ONCE
+ @deprecated("Diplomacy has been split to a standalone library", "rocketchip 2.0.0")
+ val BIND_QUERY = _root_.org.chipsalliance.diplomacy.nodes.BIND_QUERY
+ @deprecated("Diplomacy has been split to a standalone library", "rocketchip 2.0.0")
+ val BIND_STAR = _root_.org.chipsalliance.diplomacy.nodes.BIND_STAR
+ @deprecated("Diplomacy has been split to a standalone library", "rocketchip 2.0.0")
+ val BIND_FLEX = _root_.org.chipsalliance.diplomacy.nodes.BIND_FLEX
+ @deprecated("Diplomacy has been split to a standalone library", "rocketchip 2.0.0")
+ type InwardNode[DI, UI, BI <: Data] = _root_.org.chipsalliance.diplomacy.nodes.InwardNode[DI, UI, BI]
+ @deprecated("Diplomacy has been split to a standalone library", "rocketchip 2.0.0")
+ type OutwardNodeHandle[DO, UO, EO, BO <: Data] =
+ _root_.org.chipsalliance.diplomacy.nodes.OutwardNodeHandle[DO, UO, EO, BO]
+ @deprecated("Diplomacy has been split to a standalone library", "rocketchip 2.0.0")
+ type OutwardNode[DO, UO, BO <: Data] = _root_.org.chipsalliance.diplomacy.nodes.OutwardNode[DO, UO, BO]
+ @deprecated("Diplomacy has been split to a standalone library", "rocketchip 2.0.0")
+ type CycleException = _root_.org.chipsalliance.diplomacy.nodes.CycleException
+ @deprecated("Diplomacy has been split to a standalone library", "rocketchip 2.0.0")
+ type StarCycleException = _root_.org.chipsalliance.diplomacy.nodes.StarCycleException
+ @deprecated("Diplomacy has been split to a standalone library", "rocketchip 2.0.0")
+ type DownwardCycleException = _root_.org.chipsalliance.diplomacy.nodes.DownwardCycleException
+ @deprecated("Diplomacy has been split to a standalone library", "rocketchip 2.0.0")
+ type UpwardCycleException = _root_.org.chipsalliance.diplomacy.nodes.UpwardCycleException
+ @deprecated("Diplomacy has been split to a standalone library", "rocketchip 2.0.0")
+ val Edges = _root_.org.chipsalliance.diplomacy.nodes.Edges
+ @deprecated("Diplomacy has been split to a standalone library", "rocketchip 2.0.0")
+ type Edges[EI, EO] = _root_.org.chipsalliance.diplomacy.nodes.Edges[EI, EO]
+ @deprecated("Diplomacy has been split to a standalone library", "rocketchip 2.0.0")
+ type MixedCustomNode[DI, UI, EI, BI <: Data, DO, UO, EO, BO <: Data] =
+ _root_.org.chipsalliance.diplomacy.nodes.MixedCustomNode[DI, UI, EI, BI, DO, UO, EO, BO]
+ @deprecated("Diplomacy has been split to a standalone library", "rocketchip 2.0.0")
+ type CustomNode[D, U, EO, EI, B <: Data] = _root_.org.chipsalliance.diplomacy.nodes.CustomNode[D, U, EO, EI, B]
+ @deprecated("Diplomacy has been split to a standalone library", "rocketchip 2.0.0")
+ type MixedJunctionNode[DI, UI, EI, BI <: Data, DO, UO, EO, BO <: Data] =
+ _root_.org.chipsalliance.diplomacy.nodes.MixedJunctionNode[DI, UI, EI, BI, DO, UO, EO, BO]
+ @deprecated("Diplomacy has been split to a standalone library", "rocketchip 2.0.0")
+ type JunctionNode[D, U, EO, EI, B <: Data] = _root_.org.chipsalliance.diplomacy.nodes.JunctionNode[D, U, EO, EI, B]
+ @deprecated("Diplomacy has been split to a standalone library", "rocketchip 2.0.0")
+ type MixedAdapterNode[DI, UI, EI, BI <: Data, DO, UO, EO, BO <: Data] =
+ _root_.org.chipsalliance.diplomacy.nodes.MixedAdapterNode[DI, UI, EI, BI, DO, UO, EO, BO]
+ @deprecated("Diplomacy has been split to a standalone library", "rocketchip 2.0.0")
+ type AdapterNode[D, U, EO, EI, B <: Data] = _root_.org.chipsalliance.diplomacy.nodes.AdapterNode[D, U, EO, EI, B]
+ @deprecated("Diplomacy has been split to a standalone library", "rocketchip 2.0.0")
+ type IdentityNode[D, U, EO, EI, B <: Data] = _root_.org.chipsalliance.diplomacy.nodes.IdentityNode[D, U, EO, EI, B]
+ @deprecated("Diplomacy has been split to a standalone library", "rocketchip 2.0.0")
+ type EphemeralNode[D, U, EO, EI, B <: Data] = _root_.org.chipsalliance.diplomacy.nodes.EphemeralNode[D, U, EO, EI, B]
+ @deprecated("Diplomacy has been split to a standalone library", "rocketchip 2.0.0")
+ type MixedNexusNode[DI, UI, EI, BI <: Data, DO, UO, EO, BO <: Data] =
+ _root_.org.chipsalliance.diplomacy.nodes.MixedNexusNode[DI, UI, EI, BI, DO, UO, EO, BO]
+ @deprecated("Diplomacy has been split to a standalone library", "rocketchip 2.0.0")
+ type NexusNode[D, U, EO, EI, B <: Data] = _root_.org.chipsalliance.diplomacy.nodes.NexusNode[D, U, EO, EI, B]
+ @deprecated("Diplomacy has been split to a standalone library", "rocketchip 2.0.0")
+ type SourceNode[D, U, EO, EI, B <: Data] = _root_.org.chipsalliance.diplomacy.nodes.SourceNode[D, U, EO, EI, B]
+ @deprecated("Diplomacy has been split to a standalone library", "rocketchip 2.0.0")
+ type SinkNode[D, U, EO, EI, B <: Data] = _root_.org.chipsalliance.diplomacy.nodes.SinkNode[D, U, EO, EI, B]
+ @deprecated("Diplomacy has been split to a standalone library", "rocketchip 2.0.0")
+ type SimpleNodeHandle[D, U, E, B <: Data] = _root_.org.chipsalliance.diplomacy.nodes.SimpleNodeHandle[D, U, E, B]
+ @deprecated("Diplomacy has been split to a standalone library", "rocketchip 2.0.0")
+ type AnyMixedNode = _root_.org.chipsalliance.diplomacy.nodes.AnyMixedNode
- implicit def noCrossing(value: NoCrossing.type): ClockCrossingType = SynchronousCrossing(BufferParams.none)
+// BundleBridge.scala
+ @deprecated("Diplomacy has been split to a standalone library", "rocketchip 2.0.0")
+ type BundleBridgeParams[T <: Data] = _root_.org.chipsalliance.diplomacy.bundlebridge.BundleBridgeParams[T]
+ @deprecated("Diplomacy has been split to a standalone library", "rocketchip 2.0.0")
+ val BundleBridgeParams = _root_.org.chipsalliance.diplomacy.bundlebridge.BundleBridgeParams
+ @deprecated("Diplomacy has been split to a standalone library", "rocketchip 2.0.0")
+ type BundleBridgeEdgeParams[T <: Data] = _root_.org.chipsalliance.diplomacy.bundlebridge.BundleBridgeEdgeParams[T]
+ @deprecated("Diplomacy has been split to a standalone library", "rocketchip 2.0.0")
+ type BundleBridgeImp[T <: Data] = _root_.org.chipsalliance.diplomacy.bundlebridge.BundleBridgeImp[T]
+ @deprecated("Diplomacy has been split to a standalone library", "rocketchip 2.0.0")
+ type BundleBridgeSink[T <: Data] = _root_.org.chipsalliance.diplomacy.bundlebridge.BundleBridgeSink[T]
+ @deprecated("Diplomacy has been split to a standalone library", "rocketchip 2.0.0")
+ val BundleBridgeSink = _root_.org.chipsalliance.diplomacy.bundlebridge.BundleBridgeSink
+ @deprecated("Diplomacy has been split to a standalone library", "rocketchip 2.0.0")
+ type BundleBridgeSource[T <: Data] = _root_.org.chipsalliance.diplomacy.bundlebridge.BundleBridgeSource[T]
+ @deprecated("Diplomacy has been split to a standalone library", "rocketchip 2.0.0")
+ val BundleBridgeSource = _root_.org.chipsalliance.diplomacy.bundlebridge.BundleBridgeSource
+ @deprecated("Diplomacy has been split to a standalone library", "rocketchip 2.0.0")
+ type BundleBridgeIdentityNode[T <: Data] = _root_.org.chipsalliance.diplomacy.bundlebridge.BundleBridgeIdentityNode[T]
+ @deprecated("Diplomacy has been split to a standalone library", "rocketchip 2.0.0")
+ val BundleBridgeIdentityNode = _root_.org.chipsalliance.diplomacy.bundlebridge.BundleBridgeIdentityNode
+ @deprecated("Diplomacy has been split to a standalone library", "rocketchip 2.0.0")
+ type BundleBridgeEphemeralNode[T <: Data] =
+ _root_.org.chipsalliance.diplomacy.bundlebridge.BundleBridgeEphemeralNode[T]
+ @deprecated("Diplomacy has been split to a standalone library", "rocketchip 2.0.0")
+ val BundleBridgeEphemeralNode = _root_.org.chipsalliance.diplomacy.bundlebridge.BundleBridgeEphemeralNode
+ @deprecated("Diplomacy has been split to a standalone library", "rocketchip 2.0.0")
+ def BundleBridgeNameNode[T <: Data](name: String) =
+ _root_.org.chipsalliance.diplomacy.bundlebridge.BundleBridgeNameNode[T](name)
+ @deprecated("Diplomacy has been split to a standalone library", "rocketchip 2.0.0")
+ type BundleBridgeNexusNode[T <: Data] = _root_.org.chipsalliance.diplomacy.bundlebridge.BundleBridgeNexusNode[T]
+ @deprecated("Diplomacy has been split to a standalone library", "rocketchip 2.0.0")
+ type BundleBridgeNexus[T <: Data] = _root_.org.chipsalliance.diplomacy.bundlebridge.BundleBridgeNexus[T]
+ @deprecated("Diplomacy has been split to a standalone library", "rocketchip 2.0.0")
+ val BundleBridgeNexus = _root_.org.chipsalliance.diplomacy.bundlebridge.BundleBridgeNexus
+ @deprecated("Diplomacy has been split to a standalone library", "rocketchip 2.0.0")
+ def BundleBroadcast[T <: Data](
+ name: Option[String] = None,
+ registered: Boolean = false,
+ default: Option[() => T] = None,
+ inputRequiresOutput: Boolean = false, // when false, connecting a source does not mandate connecting a sink
+ shouldBeInlined: Boolean = true
+ )(
+ implicit p: Parameters
+ ) = _root_.org.chipsalliance.diplomacy.bundlebridge
+ .BundleBroadcast[T](name, registered, default, inputRequiresOutput, shouldBeInlined)(p)
+ @deprecated("Diplomacy has been split to a standalone library", "rocketchip 2.0.0")
+ type BundleBridgeInwardNode[T <: Data] = _root_.org.chipsalliance.diplomacy.bundlebridge.BundleBridgeInwardNode[T]
+ @deprecated("Diplomacy has been split to a standalone library", "rocketchip 2.0.0")
+ type BundleBridgeOutwardNode[T <: Data] = _root_.org.chipsalliance.diplomacy.bundlebridge.BundleBridgeOutwardNode[T]
+ @deprecated("Diplomacy has been split to a standalone library", "rocketchip 2.0.0")
+ type BundleBridgeNode[T <: Data] = _root_.org.chipsalliance.diplomacy.bundlebridge.BundleBridgeNode[T]
- type BundleBridgeInwardNode[T <: Data] = InwardNodeHandle[BundleBridgeParams[T], BundleBridgeParams[T], BundleBridgeEdgeParams[T], T]
- type BundleBridgeOutwardNode[T <: Data] = OutwardNodeHandle[BundleBridgeParams[T], BundleBridgeParams[T], BundleBridgeEdgeParams[T], T]
- type BundleBridgeNode[T <: Data] = NodeHandle[BundleBridgeParams[T], BundleBridgeParams[T], BundleBridgeEdgeParams[T], T, BundleBridgeParams[T], BundleBridgeParams[T], BundleBridgeEdgeParams[T], T]
+// Resources.scala
+ @deprecated("Use freechips.rocketchip.resources.ResourcePermissions", "rocketchip 2.0.0")
+ type ResourcePermissions = freechips.rocketchip.resources.ResourcePermissions
+ @deprecated("Use freechips.rocketchip.resources.Resource", "rocketchip 2.0.0")
+ type Resource = freechips.rocketchip.resources.Resource
+ @deprecated("Use freechips.rocketchip.resources.Resource", "rocketchip 2.0.0")
+ val Resource = freechips.rocketchip.resources.Resource
+ @deprecated("Use freechips.rocketchip.resources.ResourceAnchors", "rocketchip 2.0.0")
+ val ResourceAnchors = freechips.rocketchip.resources.ResourceAnchors
+ @deprecated("Use freechips.rocketchip.resources.ResourceAlias", "rocketchip 2.0.0")
+ type ResourceAlias = freechips.rocketchip.resources.ResourceAlias
+ @deprecated("Use freechips.rocketchip.resources.ResourceAlias", "rocketchip 2.0.0")
+ val ResourceAlias = freechips.rocketchip.resources.ResourceAlias
+ @deprecated("Use freechips.rocketchip.resources.ResourceMapping", "rocketchip 2.0.0")
+ type ResourceMapping = freechips.rocketchip.resources.ResourceMapping
+ @deprecated("Use freechips.rocketchip.resources.ResourceMapping", "rocketchip 2.0.0")
+ val ResourceMapping = freechips.rocketchip.resources.ResourceMapping
+ @deprecated("Use freechips.rocketchip.resources.ResourceMap", "rocketchip 2.0.0")
+ type ResourceMap = freechips.rocketchip.resources.ResourceMap
+ @deprecated("Use freechips.rocketchip.resources.ResourceMap", "rocketchip 2.0.0")
+ val ResourceMap = freechips.rocketchip.resources.ResourceMap
+ @deprecated("Use freechips.rocketchip.resources.ResourceReference", "rocketchip 2.0.0")
+ type ResourceReference = freechips.rocketchip.resources.ResourceReference
+ @deprecated("Use freechips.rocketchip.resources.ResourceReference", "rocketchip 2.0.0")
+ val ResourceReference = freechips.rocketchip.resources.ResourceReference
+ @deprecated("Use freechips.rocketchip.resources.ResourceAddress", "rocketchip 2.0.e0")
+ type ResourceAddress = freechips.rocketchip.resources.ResourceAddress
+ @deprecated("Use freechips.rocketchip.resources.ResourceAddress", "rocketchip 2.0.0")
+ val ResourceAddress = freechips.rocketchip.resources.ResourceAddress
+ @deprecated("Use freechips.rocketchip.resources.ResourceValue", "rocketchip 2.0.0")
+ type ResourceValue = freechips.rocketchip.resources.ResourceValue
+ @deprecated("Use freechips.rocketchip.resources.ResourceBinding", "rocketchip 2.0.0")
+ val ResourceBinding = freechips.rocketchip.resources.ResourceBinding
+ @deprecated("Use freechips.rocketchip.resources.ResourceBindings", "rocketchip 2.0.0")
+ type ResourceBindings = freechips.rocketchip.resources.ResourceBindings
+ @deprecated("Use freechips.rocketchip.resources.BindingScope", "rocketchip 2.0.0")
+ type BindingScope = freechips.rocketchip.resources.BindingScope
+ @deprecated("Use freechips.rocketchip.resources.Binding", "rocketchip 2.0.0")
+ type Binding = freechips.rocketchip.resources.Binding
+ @deprecated("Use freechips.rocketchip.resources.Binding", "rocketchip 2.0.0")
+ val Binding = freechips.rocketchip.resources.Binding
+ @deprecated("Use freechips.rocketchip.resources.ResourceInt", "rocketchip 2.0.0")
+ type ResourceInt = freechips.rocketchip.resources.ResourceInt
+ @deprecated("Use freechips.rocketchip.resources.ResourceInt", "rocketchip 2.0.0")
+ val ResourceInt = freechips.rocketchip.resources.ResourceInt
+ @deprecated("Use freechips.rocketchip.resources.ResourceString", "rocketchip 2.0.0")
+ type ResourceString = freechips.rocketchip.resources.ResourceString
+ @deprecated("Use freechips.rocketchip.resources.ResourceString", "rocketchip 2.0.0")
+ val ResourceString = freechips.rocketchip.resources.ResourceString
+ @deprecated("Use freechips.rocketchip.resources.SimpleDevice", "rocketchip 2.0.0")
+ type SimpleDevice = freechips.rocketchip.resources.SimpleDevice
+ @deprecated("Use freechips.rocketchip.resources.MemoryDevice", "rocketchip 2.0.0")
+ type MemoryDevice = freechips.rocketchip.resources.MemoryDevice
+ @deprecated("Use freechips.rocketchip.resources.Device", "rocketchip 2.0.0")
+ type Device = freechips.rocketchip.resources.Device
+ @deprecated("Use freechips.rocketchip.resources.Description", "rocketchip 2.0.0")
+ type Description = freechips.rocketchip.resources.Description
+ @deprecated("Use freechips.rocketchip.resources.Description", "rocketchip 2.0.0")
+ val Description = freechips.rocketchip.resources.Description
+ @deprecated("Use freechips.rocketchip.resources.SimpleBus", "rocketchip 2.0.0")
+ type SimpleBus = freechips.rocketchip.resources.SimpleBus
}
diff --git a/src/main/scala/examples/ExampleDevice.scala b/src/main/scala/examples/ExampleDevice.scala
index ffdb69f8d2c..7358c6bdcdd 100644
--- a/src/main/scala/examples/ExampleDevice.scala
+++ b/src/main/scala/examples/ExampleDevice.scala
@@ -3,10 +3,12 @@
package freechips.rocketchip.examples
import chisel3._
-import org.chipsalliance.cde.config.Parameters
+
+import org.chipsalliance.cde.config._
+import org.chipsalliance.diplomacy.lazymodule._
+
import freechips.rocketchip.amba.ahb.HasAHBControlRegMap
import freechips.rocketchip.amba.axi4.HasAXI4ControlRegMap
-import freechips.rocketchip.diplomacy.LazyModuleImp
import freechips.rocketchip.interrupts.HasInterruptSources
import freechips.rocketchip.tilelink.HasTLControlRegMap
import freechips.rocketchip.regmapper.{IORegisterRouter, RegisterRouterParams, RegField, RegFieldDesc}
diff --git a/src/main/scala/formal/FormalUtils.scala b/src/main/scala/formal/FormalUtils.scala
index 2df69574d58..07922d789fc 100644
--- a/src/main/scala/formal/FormalUtils.scala
+++ b/src/main/scala/formal/FormalUtils.scala
@@ -2,9 +2,10 @@
package freechips.rocketchip.formal
import chisel3._
-import chisel3.util._
import chisel3.experimental.{SourceInfo, SourceLine}
-import org.chipsalliance.cde.config.Field
+import chisel3.util._
+
+import org.chipsalliance.cde.config._
sealed abstract class MonitorDirection(name: String) {
override def toString: String = name
diff --git a/src/main/scala/groundtest/Configs.scala b/src/main/scala/groundtest/Configs.scala
index bb0ccd71ab5..e9b00689aa9 100644
--- a/src/main/scala/groundtest/Configs.scala
+++ b/src/main/scala/groundtest/Configs.scala
@@ -3,13 +3,13 @@
package freechips.rocketchip.groundtest
-import org.chipsalliance.cde.config.Config
+import org.chipsalliance.cde.config._
+
import freechips.rocketchip.devices.tilelink.{CLINTKey, PLICKey}
import freechips.rocketchip.devices.debug.{DebugModuleKey}
import freechips.rocketchip.subsystem._
import freechips.rocketchip.system.BaseConfig
import freechips.rocketchip.rocket.{DCacheParams}
-import freechips.rocketchip.tile.{XLen}
/** Actual testing target Configs */
@@ -30,27 +30,27 @@ class GroundTestBaseConfig extends Config(
case DebugModuleKey => None
case CLINTKey => None
case PLICKey => None
- case SubsystemExternalResetVectorKey => true
+ case HasTilesExternalResetVectorKey => true
})
)
class WithTraceGen(
n: Int = 2,
- overrideIdOffset: Option[Int] = None,
overrideMemOffset: Option[BigInt] = None)(
params: Seq[DCacheParams] = List.fill(n){ DCacheParams(nSets = 16, nWays = 1) },
- nReqs: Int = 8192
+ nReqs: Int = 8192,
+ wordBits: Int = 32
) extends Config((site, here, up) => {
case TilesLocated(InSubsystem) => {
val prev = up(TilesLocated(InSubsystem), site)
- val idOffset = overrideIdOffset.getOrElse(prev.size)
+ val idOffset = up(NumTiles)
val memOffset: BigInt = overrideMemOffset.orElse(site(ExtMem).map(_.master.base)).getOrElse(0x0L)
params.zipWithIndex.map { case (dcp, i) =>
TraceGenTileAttachParams(
tileParams = TraceGenParams(
- hartId = i + idOffset,
+ tileId = i + idOffset,
dcache = Some(dcp),
- wordBits = site(XLen),
+ wordBits = wordBits,
addrBits = 32,
addrBag = {
val nSets = dcp.nSets
@@ -68,4 +68,5 @@ class WithTraceGen(
)
} ++ prev
}
+ case NumTiles => up(NumTiles) + n
})
diff --git a/src/main/scala/groundtest/DummyPTW.scala b/src/main/scala/groundtest/DummyPTW.scala
index ce95b826d83..4dadd95a739 100644
--- a/src/main/scala/groundtest/DummyPTW.scala
+++ b/src/main/scala/groundtest/DummyPTW.scala
@@ -4,9 +4,9 @@
package freechips.rocketchip.groundtest
import chisel3._
-import chisel3.util.{RRArbiter, Valid, log2Up, RegEnable}
+import chisel3.util._
-import org.chipsalliance.cde.config.Parameters
+import org.chipsalliance.cde.config._
import freechips.rocketchip.rocket._
import freechips.rocketchip.tile.CoreModule
import freechips.rocketchip.util.ParameterizedBundle
diff --git a/src/main/scala/groundtest/GroundTestSubsystem.scala b/src/main/scala/groundtest/GroundTestSubsystem.scala
index ba3215f7f53..11263966ebf 100644
--- a/src/main/scala/groundtest/GroundTestSubsystem.scala
+++ b/src/main/scala/groundtest/GroundTestSubsystem.scala
@@ -3,20 +3,30 @@
package freechips.rocketchip.groundtest
import chisel3._
-import org.chipsalliance.cde.config.{Parameters}
-import freechips.rocketchip.diplomacy.{AddressSet, LazyModule}
-import freechips.rocketchip.interrupts.{IntSinkNode, IntSinkPortSimple}
-import freechips.rocketchip.subsystem.{BaseSubsystem, BaseSubsystemModuleImp, HasTiles, CanHaveMasterAXI4MemPort}
+
+import org.chipsalliance.cde.config._
+import org.chipsalliance.diplomacy.lazymodule._
+
+import freechips.rocketchip.diplomacy.AddressSet
+
+import freechips.rocketchip.interrupts._
+import freechips.rocketchip.tile.{NMI}
+import freechips.rocketchip.devices.tilelink.{CLINTConsts}
+import freechips.rocketchip.subsystem._
import freechips.rocketchip.tilelink.{TLRAM, TLFragmenter}
import freechips.rocketchip.interrupts.{NullIntSyncSource}
class GroundTestSubsystem(implicit p: Parameters)
extends BaseSubsystem
- with HasTiles
+ with InstantiatesHierarchicalElements
+ with HasHierarchicalElementsRootContext
+ with HasHierarchicalElements
+ with HasTileNotificationSinks
+ with HasTileInputConstants
with CanHaveMasterAXI4MemPort
{
- val testram = LazyModule(new TLRAM(AddressSet(0x52000000, 0xfff), beatBytes=pbus.beatBytes))
- pbus.coupleTo("TestRAM") { testram.node := TLFragmenter(pbus) := _ }
+ val testram = LazyModule(new TLRAM(AddressSet(0x52000000, 0xfff), beatBytes=tlBusWrapperLocationMap.get(PBUS).getOrElse(tlBusWrapperLocationMap(p(TLManagerViewpointLocated(location)))).beatBytes))
+ tlBusWrapperLocationMap.lift(PBUS).getOrElse(tlBusWrapperLocationMap(p(TLManagerViewpointLocated(location)))).coupleTo("TestRAM") { testram.node := TLFragmenter(tlBusWrapperLocationMap.lift(PBUS).getOrElse(tlBusWrapperLocationMap(p(TLManagerViewpointLocated(location))))) := _ }
// No cores to monitor
def coreMonitorBundles = Nil
@@ -24,16 +34,18 @@ class GroundTestSubsystem(implicit p: Parameters)
// No PLIC in ground test; so just sink the interrupts to nowhere
IntSinkNode(IntSinkPortSimple()) :=* ibus.toPLIC
- val tileStatusNodes = tiles.collect { case t: GroundTestTile => t.statusNode.makeSink() }
-
- // no debug module
- val debugNode = NullIntSyncSource()
+ val tileStatusNodes = totalTiles.values.collect { case t: GroundTestTile => t.statusNode.makeSink() }
+ val clintOpt = None
+ val clintDomainOpt = None
+ val debugOpt = None
+ val plicOpt = None
+ val plicDomainOpt = None
override lazy val module = new GroundTestSubsystemModuleImp(this)
}
class GroundTestSubsystemModuleImp[+L <: GroundTestSubsystem](_outer: L) extends BaseSubsystemModuleImp(_outer) {
val success = IO(Output(Bool()))
- val status = dontTouch(DebugCombiner(outer.tileStatusNodes.map(_.bundle)))
- success := outer.tileCeaseSinkNode.in.head._1.asUInt.andR
+ val status = dontTouch(DebugCombiner(_outer.tileStatusNodes.map(_.bundle).toSeq))
+ success := _outer.tileCeaseSinkNode.in.head._1.asUInt.andR
}
diff --git a/src/main/scala/groundtest/TestHarness.scala b/src/main/scala/groundtest/TestHarness.scala
index 2db67efbee7..348df5beb50 100644
--- a/src/main/scala/groundtest/TestHarness.scala
+++ b/src/main/scala/groundtest/TestHarness.scala
@@ -3,8 +3,10 @@
package freechips.rocketchip.groundtest
import chisel3._
-import org.chipsalliance.cde.config.Parameters
-import freechips.rocketchip.diplomacy.LazyModule
+
+import org.chipsalliance.cde.config._
+import org.chipsalliance.diplomacy.lazymodule._
+
import freechips.rocketchip.system.SimAXIMem
class TestHarness(implicit p: Parameters) extends Module {
diff --git a/src/main/scala/groundtest/Tile.scala b/src/main/scala/groundtest/Tile.scala
index 912016f8ea4..c9516ab4965 100644
--- a/src/main/scala/groundtest/Tile.scala
+++ b/src/main/scala/groundtest/Tile.scala
@@ -4,8 +4,13 @@
package freechips.rocketchip.groundtest
import chisel3._
+
import org.chipsalliance.cde.config._
-import freechips.rocketchip.diplomacy._
+import org.chipsalliance.diplomacy.bundlebridge._
+import org.chipsalliance.diplomacy.lazymodule._
+
+import freechips.rocketchip.resources.{SimpleDevice}
+import freechips.rocketchip.prci.{ClockCrossingType}
import freechips.rocketchip.interrupts._
import freechips.rocketchip.rocket.{BuildHellaCache, DCache, DCacheModule, ICacheParams, NonBlockingDCache, NonBlockingDCacheModule, RocketCoreParams}
import freechips.rocketchip.tile._
@@ -34,7 +39,7 @@ abstract class GroundTestTile(
with SourcesExternalNotifications
{
val cpuDevice: SimpleDevice = new SimpleDevice("groundtest", Nil)
- val intOutwardNode: IntOutwardNode = IntIdentityNode()
+ val intOutwardNode = None
val slaveNode: TLInwardNode = TLIdentityNode()
val statusNode = BundleBridgeSource(() => new GroundTestStatus)
@@ -43,10 +48,7 @@ abstract class GroundTestTile(
dcacheOpt.foreach { m =>
m.hartIdSinkNodeOpt.foreach { _ := hartIdNexusNode }
InModuleBody {
- m.module match {
- case module: DCacheModule => module.tlb_port := DontCare
- case other => other
- }
+ m.module.io.tlb_port := DontCare
}
}
diff --git a/src/main/scala/groundtest/TraceGen.scala b/src/main/scala/groundtest/TraceGen.scala
index 5c5cba9b5f7..588f930978d 100644
--- a/src/main/scala/groundtest/TraceGen.scala
+++ b/src/main/scala/groundtest/TraceGen.scala
@@ -20,15 +20,16 @@
package freechips.rocketchip.groundtest
import chisel3._
-import chisel3.util.{log2Up, MuxLookup, Cat, log2Ceil, Enum}
-import org.chipsalliance.cde.config.{Parameters}
-import freechips.rocketchip.diplomacy.{ClockCrossingType}
+import chisel3.util._
+
+import org.chipsalliance.cde.config._
+
import freechips.rocketchip.rocket._
import freechips.rocketchip.tile._
import freechips.rocketchip.tilelink._
-import freechips.rocketchip.subsystem.{TileCrossingParamsLike, CanAttachTile}
+import freechips.rocketchip.subsystem.{HierarchicalElementCrossingParamsLike, CanAttachTile}
import freechips.rocketchip.util._
-import freechips.rocketchip.prci.{ClockSinkParameters}
+import freechips.rocketchip.prci.{ClockSinkParameters, ClockCrossingType}
// =======
// Outline
@@ -61,22 +62,22 @@ import freechips.rocketchip.prci.{ClockSinkParameters}
// to repeatedly recompile with a different address bag.)
case class TraceGenParams(
- wordBits: Int, // p(XLen)
- addrBits: Int, // p(PAddrBits)
- addrBag: List[BigInt], // p(AddressBag)
+ wordBits: Int,
+ addrBits: Int,
+ addrBag: List[BigInt],
maxRequests: Int,
- memStart: BigInt, //p(ExtMem).base
+ memStart: BigInt,
numGens: Int,
dcache: Option[DCacheParams] = Some(DCacheParams()),
- hartId: Int = 0
+ tileId: Int = 0
) extends InstantiableTileParams[TraceGenTile] with GroundTestTileParams
{
- def instantiate(crossing: TileCrossingParamsLike, lookup: LookupByHartIdImpl)(implicit p: Parameters): TraceGenTile = {
+ def instantiate(crossing: HierarchicalElementCrossingParamsLike, lookup: LookupByHartIdImpl)(implicit p: Parameters): TraceGenTile = {
new TraceGenTile(this, crossing, lookup)
}
- val beuAddr = None
val blockerCtrlAddr = None
- val name = None
+ val baseName = "tracegentile"
+ val uniqueName = s"${baseName}_$tileId"
val clockSinkParams = ClockSinkParameters()
}
@@ -105,7 +106,7 @@ trait HasTraceGenParams {
case class TraceGenTileAttachParams(
tileParams: TraceGenParams,
- crossingParams: TileCrossingParamsLike
+ crossingParams: HierarchicalElementCrossingParamsLike
) extends CanAttachTile {
type TileType = TraceGenTile
val lookup: LookupByHartIdImpl = HartsWontDeduplicate(tileParams)
@@ -186,7 +187,7 @@ class TagMan(val logNumTags : Int) extends Module {
io.tagOut := nextTag
// Is the next tag available?
- io.available := ~MuxLookup(nextTag, true.B, inUseMap)
+ io.available := ~MuxLookup(nextTag, true.B)(inUseMap)
// When user takes a tag
when (io.take) {
@@ -249,7 +250,7 @@ class TraceGenerator(val params: TraceGenParams)(implicit val p: Parameters) ext
val addrBagIndices = (0 to addressBagLen-1).
map(i => i.U(logAddressBagLen.W))
- val randAddrFromBag = MuxLookup(randAddrBagIndex, 0.U,
+ val randAddrFromBag = MuxLookup(randAddrBagIndex, 0.U)(
addrBagIndices.zip(bagOfAddrs))
// Random address from the address bag or the extra addresses.
@@ -268,7 +269,7 @@ class TraceGenerator(val params: TraceGenParams)(implicit val p: Parameters) ext
// A random address from the extra addresses.
val randAddrFromExtra = Cat(0.U,
- MuxLookup(randExtraAddrIndex, 0.U,
+ MuxLookup(randExtraAddrIndex, 0.U)(
extraAddrIndices.zip(extraAddrs)), 0.U(3.W))
Frequency(List(
@@ -279,7 +280,7 @@ class TraceGenerator(val params: TraceGenParams)(implicit val p: Parameters) ext
val allAddrs = extraAddrs ++ bagOfAddrs
val allAddrIndices = (0 until totalNumAddrs)
.map(i => i.U(log2Ceil(totalNumAddrs).W))
- val initAddr = MuxLookup(initCount, 0.U,
+ val initAddr = MuxLookup(initCount, 0.U)(
allAddrIndices.zip(allAddrs))
// Random opcodes
@@ -533,6 +534,7 @@ class TraceGenerator(val params: TraceGenParams)(implicit val p: Parameters) ext
io.mem.req.bits.tag := reqTag
io.mem.req.bits.no_alloc := false.B
io.mem.req.bits.no_xcpt := false.B
+ io.mem.req.bits.no_resp := false.B
io.mem.req.bits.mask := ~(0.U((numBitsInWord / 8).W))
io.mem.req.bits.phys := false.B
io.mem.req.bits.dprv := PRV.M.U
@@ -617,7 +619,7 @@ class TraceGenTile private(
q: Parameters
) extends GroundTestTile(params, crossing, lookup, q)
{
- def this(params: TraceGenParams, crossing: TileCrossingParamsLike, lookup: LookupByHartIdImpl)(implicit p: Parameters) =
+ def this(params: TraceGenParams, crossing: HierarchicalElementCrossingParamsLike, lookup: LookupByHartIdImpl)(implicit p: Parameters) =
this(params, crossing.crossingType, lookup, p)
val masterNode: TLOutwardNode = TLIdentityNode() := visibilityNode := dcacheOpt.map(_.node).getOrElse(TLTempNode())
@@ -644,5 +646,5 @@ class TraceGenTileModuleImp(outer: TraceGenTile) extends GroundTestTileModuleImp
status.timeout.bits := 0.U
status.error.valid := false.B
- assert(!tracegen.io.timeout, s"TraceGen tile ${outer.tileParams.hartId}: request timed out")
+ assert(!tracegen.io.timeout, s"TraceGen tile ${outer.tileParams.tileId}: request timed out")
}
diff --git a/src/main/scala/interrupts/BlockDuringReset.scala b/src/main/scala/interrupts/BlockDuringReset.scala
index 35692c57360..a94c295b062 100644
--- a/src/main/scala/interrupts/BlockDuringReset.scala
+++ b/src/main/scala/interrupts/BlockDuringReset.scala
@@ -2,8 +2,9 @@
package freechips.rocketchip.interrupts
-import org.chipsalliance.cde.config.Parameters
-import freechips.rocketchip.diplomacy.{LazyModule, LazyModuleImp}
+import org.chipsalliance.cde.config._
+import org.chipsalliance.diplomacy.lazymodule._
+
import freechips.rocketchip.util.BlockDuringReset
/** BlockDuringReset ensures that no interrupt is raised while reset is raised. */
diff --git a/src/main/scala/interrupts/Crossing.scala b/src/main/scala/interrupts/Crossing.scala
index 77a15480529..d783e6bbd97 100644
--- a/src/main/scala/interrupts/Crossing.scala
+++ b/src/main/scala/interrupts/Crossing.scala
@@ -4,9 +4,10 @@ package freechips.rocketchip.interrupts
import chisel3._
import chisel3.util._
-import org.chipsalliance.cde.config.Parameters
+import org.chipsalliance.cde.config._
+import org.chipsalliance.diplomacy.lazymodule._
+
import freechips.rocketchip.util.{SynchronizerShiftReg, AsyncResetReg}
-import freechips.rocketchip.diplomacy._
@deprecated("IntXing does not ensure interrupt source is glitch free. Use IntSyncSource and IntSyncSink", "rocket-chip 1.2")
class IntXing(sync: Int = 3)(implicit p: Parameters) extends LazyModule
@@ -35,14 +36,20 @@ class IntSyncCrossingSource(alreadyRegistered: Boolean = false)(implicit p: Para
{
val node = IntSyncSourceNode(alreadyRegistered)
- lazy val module = new Impl
+ lazy val module = if (alreadyRegistered) (new ImplRegistered) else (new Impl)
+
class Impl extends LazyModuleImp(this) {
+ def outSize = node.out.headOption.map(_._1.sync.size).getOrElse(0)
+ override def desiredName = s"IntSyncCrossingSource_n${node.out.size}x${outSize}"
(node.in zip node.out) foreach { case ((in, edgeIn), (out, edgeOut)) =>
- if (alreadyRegistered) {
- out.sync := in
- } else {
- out.sync := AsyncResetReg(Cat(in.reverse)).asBools
- }
+ out.sync := AsyncResetReg(Cat(in.reverse)).asBools
+ }
+ }
+ class ImplRegistered extends LazyRawModuleImp(this) {
+ def outSize = node.out.headOption.map(_._1.sync.size).getOrElse(0)
+ override def desiredName = s"IntSyncCrossingSource_n${node.out.size}x${outSize}_Registered"
+ (node.in zip node.out) foreach { case ((in, edgeIn), (out, edgeOut)) =>
+ out.sync := in
}
}
}
@@ -65,6 +72,7 @@ class IntSyncAsyncCrossingSink(sync: Int = 3)(implicit p: Parameters) extends La
lazy val module = new Impl
class Impl extends LazyModuleImp(this) {
+ override def desiredName = s"IntSyncAsyncCrossingSink_n${node.out.size}x${node.out.head._1.size}"
(node.in zip node.out) foreach { case ((in, edgeIn), (out, edgeOut)) =>
out := SynchronizerShiftReg(in.sync, sync)
}
@@ -85,7 +93,9 @@ class IntSyncSyncCrossingSink()(implicit p: Parameters) extends LazyModule
val node = IntSyncSinkNode(0)
lazy val module = new Impl
- class Impl extends LazyModuleImp(this) {
+ class Impl extends LazyRawModuleImp(this) {
+ def outSize = node.out.headOption.map(_._1.size).getOrElse(0)
+ override def desiredName = s"IntSyncSyncCrossingSink_n${node.out.size}x${outSize}"
(node.in zip node.out) foreach { case ((in, edgeIn), (out, edgeOut)) =>
out := in.sync
}
@@ -107,6 +117,8 @@ class IntSyncRationalCrossingSink()(implicit p: Parameters) extends LazyModule
lazy val module = new Impl
class Impl extends LazyModuleImp(this) {
+ def outSize = node.out.headOption.map(_._1.size).getOrElse(0)
+ override def desiredName = s"IntSyncRationalCrossingSink_n${node.out.size}x${outSize}"
(node.in zip node.out) foreach { case ((in, edgeIn), (out, edgeOut)) =>
out := RegNext(in.sync)
}
diff --git a/src/main/scala/interrupts/CrossingHelper.scala b/src/main/scala/interrupts/CrossingHelper.scala
index 814e13fe39b..d9cdd18b1ee 100644
--- a/src/main/scala/interrupts/CrossingHelper.scala
+++ b/src/main/scala/interrupts/CrossingHelper.scala
@@ -2,9 +2,10 @@
package freechips.rocketchip.interrupts
-import org.chipsalliance.cde.config.Parameters
-import freechips.rocketchip.diplomacy._
-import freechips.rocketchip.prci.{ResetCrossingType, NoResetCrossing, StretchedResetCrossing}
+import org.chipsalliance.cde.config._
+import org.chipsalliance.diplomacy.lazymodule._
+
+import freechips.rocketchip.prci.{ResetCrossingType, NoResetCrossing, StretchedResetCrossing, CrossingType, ClockCrossingType, NoCrossing, AsynchronousCrossing, RationalCrossing, SynchronousCrossing, CreditedCrossing}
import freechips.rocketchip.util.CreditedDelay
trait IntOutwardCrossingHelper {
diff --git a/src/main/scala/interrupts/Nodes.scala b/src/main/scala/interrupts/Nodes.scala
index 25a5cd48354..d2b18122f96 100644
--- a/src/main/scala/interrupts/Nodes.scala
+++ b/src/main/scala/interrupts/Nodes.scala
@@ -4,8 +4,10 @@ package freechips.rocketchip.interrupts
import chisel3._
import chisel3.experimental.SourceInfo
-import org.chipsalliance.cde.config.Parameters
-import freechips.rocketchip.diplomacy._
+
+import org.chipsalliance.cde.config._
+import org.chipsalliance.diplomacy._
+import org.chipsalliance.diplomacy.nodes._
object IntImp extends SimpleNodeImp[IntSourcePortParameters, IntSinkPortParameters, IntEdge, Vec[Bool]]
{
diff --git a/src/main/scala/interrupts/NullIntSource.scala b/src/main/scala/interrupts/NullIntSource.scala
index d906ac36fd9..dc388960313 100644
--- a/src/main/scala/interrupts/NullIntSource.scala
+++ b/src/main/scala/interrupts/NullIntSource.scala
@@ -3,8 +3,9 @@
package freechips.rocketchip.interrupts
import chisel3._
-import org.chipsalliance.cde.config.Parameters
-import freechips.rocketchip.diplomacy._
+
+import org.chipsalliance.cde.config._
+import org.chipsalliance.diplomacy.lazymodule._
/** Useful for stubbing out parts of an interrupt interface where certain devices might be missing */
class NullIntSource(num: Int = 1, ports: Int = 1, sources: Int = 1)(implicit p: Parameters) extends LazyModule
@@ -12,7 +13,7 @@ class NullIntSource(num: Int = 1, ports: Int = 1, sources: Int = 1)(implicit p:
val intnode = IntSourceNode(IntSourcePortSimple(num, ports, sources))
lazy val module = new Impl
- class Impl extends LazyModuleImp(this) {
+ class Impl extends LazyRawModuleImp(this) {
intnode.out.foreach { case (o, _) => o.foreach { _ := false.B } }
}
}
@@ -26,6 +27,6 @@ object NullIntSource {
object NullIntSyncSource {
def apply(num: Int = 1, ports: Int = 1, sources: Int = 1)(implicit p: Parameters): IntSyncOutwardNode = {
- IntSyncCrossingSource() := NullIntSource(num, ports, sources)
+ IntSyncCrossingSource(alreadyRegistered = true) := NullIntSource(num, ports, sources)
}
}
diff --git a/src/main/scala/interrupts/Parameters.scala b/src/main/scala/interrupts/Parameters.scala
index d1c300241cf..e9d90a56e7d 100644
--- a/src/main/scala/interrupts/Parameters.scala
+++ b/src/main/scala/interrupts/Parameters.scala
@@ -3,8 +3,11 @@
package freechips.rocketchip.interrupts
import chisel3.experimental.SourceInfo
-import org.chipsalliance.cde.config.Parameters
-import freechips.rocketchip.diplomacy._
+
+import org.chipsalliance.cde.config._
+import org.chipsalliance.diplomacy.nodes._
+
+import freechips.rocketchip.resources.Resource
// A potentially empty half-open range; [start, end)
case class IntRange(start: Int, end: Int)
diff --git a/src/main/scala/interrupts/RegisterRouter.scala b/src/main/scala/interrupts/RegisterRouter.scala
index 419ec135d27..6e08a2c2c55 100644
--- a/src/main/scala/interrupts/RegisterRouter.scala
+++ b/src/main/scala/interrupts/RegisterRouter.scala
@@ -3,7 +3,11 @@
package freechips.rocketchip.interrupts
import chisel3._
-import freechips.rocketchip.diplomacy._
+
+import org.chipsalliance.diplomacy.lazymodule._
+
+import freechips.rocketchip.resources.Resource
+
import freechips.rocketchip.regmapper._
/** Mix this trait into a RegisterRouter to be able to attach its interrupt sources to an interrupt bus */
diff --git a/src/main/scala/interrupts/Xbar.scala b/src/main/scala/interrupts/Xbar.scala
index 472fead6955..65c3e045ac4 100644
--- a/src/main/scala/interrupts/Xbar.scala
+++ b/src/main/scala/interrupts/Xbar.scala
@@ -2,8 +2,8 @@
package freechips.rocketchip.interrupts
-import org.chipsalliance.cde.config.Parameters
-import freechips.rocketchip.diplomacy._
+import org.chipsalliance.cde.config._
+import org.chipsalliance.diplomacy.lazymodule._
class IntXbar()(implicit p: Parameters) extends LazyModule
{
@@ -19,7 +19,8 @@ class IntXbar()(implicit p: Parameters) extends LazyModule
}
lazy val module = new Impl
- class Impl extends LazyModuleImp(this) {
+ class Impl extends LazyRawModuleImp(this) {
+ override def desiredName = s"IntXbar_i${intnode.in.size}_o${intnode.out.size}"
val cat = intnode.in.map { case (i, e) => i.take(e.source.num) }.flatten
intnode.out.foreach { case (o, _) => o := cat }
}
@@ -40,6 +41,7 @@ class IntSyncXbar()(implicit p: Parameters) extends LazyModule
lazy val module = new Impl
class Impl extends LazyModuleImp(this) {
+ override def desiredName = s"IntSyncXbar_i${intnode.in.size}_o${intnode.out.size}"
val cat = intnode.in.map { case (i, e) => i.sync.take(e.source.num) }.flatten
intnode.out.foreach { case (o, _) => o.sync := cat }
}
diff --git a/src/main/scala/interrupts/package.scala b/src/main/scala/interrupts/package.scala
index a29898210ba..aaa73bf4b3a 100644
--- a/src/main/scala/interrupts/package.scala
+++ b/src/main/scala/interrupts/package.scala
@@ -2,9 +2,12 @@
package freechips.rocketchip
-import chisel3.{Bool, Vec}
-import freechips.rocketchip.diplomacy.{HasClockDomainCrossing, _}
-import freechips.rocketchip.prci.{HasResetDomainCrossing}
+import chisel3._
+
+import org.chipsalliance.diplomacy._
+import org.chipsalliance.diplomacy.nodes._
+
+import freechips.rocketchip.prci.{HasClockDomainCrossing, HasResetDomainCrossing}
package object interrupts
{
diff --git a/src/main/scala/jtag/JtagShifter.scala b/src/main/scala/jtag/JtagShifter.scala
index 69f6d1272fa..cbd001a36f7 100644
--- a/src/main/scala/jtag/JtagShifter.scala
+++ b/src/main/scala/jtag/JtagShifter.scala
@@ -3,7 +3,7 @@
package freechips.rocketchip.jtag
import chisel3._
-import chisel3.experimental.DataMirror
+import chisel3.reflect.DataMirror
import chisel3.internal.firrtl.KnownWidth
import chisel3.util.{Cat, Valid}
@@ -87,6 +87,7 @@ object JtagBypassChain {
* 4.3.2a TDI captured on TCK rising edge, 6.1.2.1b assumed changes on TCK falling edge
*/
class CaptureChain[+T <: Data](gen: T)(implicit val p: Parameters) extends Chain {
+ override def desiredName = s"CaptureChain_${gen.typeName}"
class ModIO extends ChainIO {
val capture = Capture(gen)
}
@@ -134,6 +135,7 @@ object CaptureChain {
* 4.3.2a TDI captured on TCK rising edge, 6.1.2.1b assumed changes on TCK falling edge
*/
class CaptureUpdateChain[+T <: Data, +V <: Data](genCapture: T, genUpdate: V)(implicit val p: Parameters) extends Chain {
+ override def desiredName = s"CaptureUpdateChain_${genCapture.typeName}_To_${genUpdate.typeName}"
class ModIO extends ChainIO {
val capture = Capture(genCapture)
val update = Valid(genUpdate) // valid high when in update state (single cycle), contents may change any time after
diff --git a/src/main/scala/prci/BundleBridgeBlockDuringReset.scala b/src/main/scala/prci/BundleBridgeBlockDuringReset.scala
index 88baf78bfba..7bb37f98ace 100644
--- a/src/main/scala/prci/BundleBridgeBlockDuringReset.scala
+++ b/src/main/scala/prci/BundleBridgeBlockDuringReset.scala
@@ -3,9 +3,13 @@
package freechips.rocketchip.prci
import chisel3._
-import org.chipsalliance.cde.config.{Parameters}
-import freechips.rocketchip.diplomacy._
-import freechips.rocketchip.diplomacy.BundleBridgeNexus.fillN
+
+import org.chipsalliance.cde.config._
+import org.chipsalliance.diplomacy.bundlebridge._
+import org.chipsalliance.diplomacy.lazymodule._
+
+import org.chipsalliance.diplomacy.bundlebridge.BundleBridgeNexus.fillN
+
import freechips.rocketchip.util.{BlockDuringReset, Blockable}
object BundleBridgeBlockDuringReset {
diff --git a/src/main/scala/prci/ClockBundles.scala b/src/main/scala/prci/ClockBundles.scala
index 900e437a5af..0cf06cca6e5 100644
--- a/src/main/scala/prci/ClockBundles.scala
+++ b/src/main/scala/prci/ClockBundles.scala
@@ -5,7 +5,7 @@ import chisel3._
import freechips.rocketchip.util.RecordMap
-class ClockBundle(val params: ClockBundleParameters) extends Bundle
+class ClockBundle(val params: ClockBundleParameters = ClockBundleParameters()) extends Bundle
{
val clock = Output(Clock())
val reset = Output(Reset())
diff --git a/src/main/scala/diplomacy/ClockDomain.scala b/src/main/scala/prci/ClockCrossingType.scala
similarity index 90%
rename from src/main/scala/diplomacy/ClockDomain.scala
rename to src/main/scala/prci/ClockCrossingType.scala
index 89c8a82b3c6..cbb5183a6db 100644
--- a/src/main/scala/diplomacy/ClockDomain.scala
+++ b/src/main/scala/prci/ClockCrossingType.scala
@@ -1,10 +1,10 @@
// See LICENSE.SiFive for license details.
-package freechips.rocketchip.diplomacy
+package freechips.rocketchip.prci
+import org.chipsalliance.diplomacy.lazymodule.{LazyScope, LazyModule}
+import freechips.rocketchip.diplomacy.{BufferParams}
import freechips.rocketchip.util.{RationalDirection, FastToSlow, AsyncQueueParams, CreditedDelay}
-// TODO this should all be moved to package freechips.rocketchip.prci now that it exists
-
trait CrossingType
trait HasDomainCrossing extends LazyScope { this: LazyModule =>
diff --git a/src/main/scala/prci/ClockDivider.scala b/src/main/scala/prci/ClockDivider.scala
index ceb91078f73..8c913f04c8c 100644
--- a/src/main/scala/prci/ClockDivider.scala
+++ b/src/main/scala/prci/ClockDivider.scala
@@ -2,9 +2,11 @@
package freechips.rocketchip.prci
import chisel3._
-import chisel3.util.isPow2
-import org.chipsalliance.cde.config.Parameters
-import freechips.rocketchip.diplomacy._
+import chisel3.util._
+
+import org.chipsalliance.cde.config._
+import org.chipsalliance.diplomacy.lazymodule._
+
import freechips.rocketchip.util.{ClockDivider3, Pow2ClockDivider}
/* An example clock adapter that divides all clocks passed through this node by an integer factor
diff --git a/src/main/scala/prci/ClockDomain.scala b/src/main/scala/prci/ClockDomain.scala
index 665372ca500..9c25284d1d1 100644
--- a/src/main/scala/prci/ClockDomain.scala
+++ b/src/main/scala/prci/ClockDomain.scala
@@ -1,16 +1,20 @@
package freechips.rocketchip.prci
import chisel3._
-import org.chipsalliance.cde.config.Parameters
-import freechips.rocketchip.diplomacy._
-abstract class Domain(implicit p: Parameters) extends LazyModule with HasDomainCrossing {
+import org.chipsalliance.cde.config._
+
+import org.chipsalliance.diplomacy.lazymodule._
+
+abstract class Domain(implicit p: Parameters) extends LazyModule with HasDomainCrossing
+{
def clockBundle: ClockBundle
lazy val module = new Impl
class Impl extends LazyRawModuleImp(this) {
childClock := clockBundle.clock
childReset := clockBundle.reset
+ override def provideImplicitClockToLazyChildren = true
// these are just for backwards compatibility with external devices
// that were manually wiring themselves to the domain's clock/reset input:
@@ -28,6 +32,7 @@ class ClockSinkDomain(val clockSinkParams: ClockSinkParameters)(implicit p: Para
def this(take: Option[ClockParameters] = None, name: Option[String] = None)(implicit p: Parameters) = this(ClockSinkParameters(take = take, name = name))
val clockNode = ClockSinkNode(Seq(clockSinkParams))
def clockBundle = clockNode.in.head._1
+ override lazy val desiredName = (clockSinkParams.name.toSeq :+ "ClockSinkDomain").mkString
}
class ClockSourceDomain(val clockSourceParams: ClockSourceParameters)(implicit p: Parameters) extends ClockDomain
@@ -35,6 +40,7 @@ class ClockSourceDomain(val clockSourceParams: ClockSourceParameters)(implicit p
def this(give: Option[ClockParameters] = None, name: Option[String] = None)(implicit p: Parameters) = this(ClockSourceParameters(give = give, name = name))
val clockNode = ClockSourceNode(Seq(clockSourceParams))
def clockBundle = clockNode.out.head._1
+ override lazy val desiredName = (clockSourceParams.name.toSeq :+ "ClockSourceDomain").mkString
}
abstract class ResetDomain(implicit p: Parameters) extends Domain with HasResetDomainCrossing
diff --git a/src/main/scala/prci/ClockGroup.scala b/src/main/scala/prci/ClockGroup.scala
index ce2b8f98c97..afd113d4e49 100644
--- a/src/main/scala/prci/ClockGroup.scala
+++ b/src/main/scala/prci/ClockGroup.scala
@@ -1,10 +1,14 @@
// See LICENSE.SiFive for license details.
package freechips.rocketchip.prci
-import org.chipsalliance.cde.config.Parameters
-import freechips.rocketchip.diplomacy._
+import org.chipsalliance.cde.config._
+import org.chipsalliance.diplomacy._
+import org.chipsalliance.diplomacy.lazymodule._
+import org.chipsalliance.diplomacy.nodes._
-case class ClockGroupNode(groupName: String)(implicit valName: ValName)
+import freechips.rocketchip.resources.FixedClockResource
+
+case class ClockGroupingNode(groupName: String)(implicit valName: ValName)
extends MixedNexusNode(ClockGroupImp, ClockImp)(
dFn = { _ => ClockSourceParameters() },
uFn = { seq => ClockGroupSinkParameters(name = groupName, members = seq) })
@@ -14,7 +18,7 @@ case class ClockGroupNode(groupName: String)(implicit valName: ValName)
class ClockGroup(groupName: String)(implicit p: Parameters) extends LazyModule
{
- val node = ClockGroupNode(groupName)
+ val node = ClockGroupingNode(groupName)
lazy val module = new Impl
class Impl extends LazyRawModuleImp(this) {
@@ -44,7 +48,7 @@ case class ClockGroupAggregateNode(groupName: String)(implicit valName: ValName)
class ClockGroupAggregator(groupName: String)(implicit p: Parameters) extends LazyModule
{
val node = ClockGroupAggregateNode(groupName)
-
+ override lazy val desiredName = s"ClockGroupAggregator_$groupName"
lazy val module = new Impl
class Impl extends LazyRawModuleImp(this) {
val (in, _) = node.in.unzip
@@ -100,6 +104,7 @@ class FixedClockBroadcast(fixedClockOpt: Option[ClockParameters])(implicit p: Pa
class Impl extends LazyRawModuleImp(this) {
val (in, _) = node.in(0)
val (out, _) = node.out.unzip
+ override def desiredName = s"FixedClockBroadcast_${out.size}"
require (node.in.size == 1, "FixedClockBroadcast can only broadcast a single clock")
out.foreach { _ := in }
}
@@ -107,7 +112,7 @@ class FixedClockBroadcast(fixedClockOpt: Option[ClockParameters])(implicit p: Pa
object FixedClockBroadcast
{
- def apply(fixedClockOpt: Option[ClockParameters])(implicit p: Parameters, valName: ValName) = LazyModule(new FixedClockBroadcast(fixedClockOpt)).node
+ def apply(fixedClockOpt: Option[ClockParameters] = None)(implicit p: Parameters, valName: ValName) = LazyModule(new FixedClockBroadcast(fixedClockOpt)).node
}
case class PRCIClockGroupNode()(implicit valName: ValName)
diff --git a/src/main/scala/prci/ClockGroupDriver.scala b/src/main/scala/prci/ClockGroupDriver.scala
deleted file mode 100644
index 63ff42f1e42..00000000000
--- a/src/main/scala/prci/ClockGroupDriver.scala
+++ /dev/null
@@ -1,46 +0,0 @@
-// See LICENSE.SiFive for license details.
-package freechips.rocketchip.prci
-
-import chisel3._
-import org.chipsalliance.cde.config.Parameters
-import freechips.rocketchip.diplomacy.{InModuleBody, ModuleValue, ValName}
-import freechips.rocketchip.util.{RecordMap}
-
-/** Used to parameterize the creation of simple clock group drivers */
-case class ClockGroupDriverParameters(
- num: Int = 1,
- driveFn: ClockGroupDriver.DriveFn = ClockGroupDriver.driveFromImplicitClock
-) {
- def drive(node: ClockGroupEphemeralNode)(implicit p: Parameters, vn: ValName): ModuleValue[RecordMap[ClockBundle]] = {
- driveFn(node, num, p, vn)
- }
-}
-
-object ClockGroupDriver {
- type DriveFn = (ClockGroupEphemeralNode, Int, Parameters, ValName) => ModuleValue[RecordMap[ClockBundle]]
-
- /** Drive all members of all groups from the Chisel implicit clock */
- def driveFromImplicitClock: DriveFn = { (groups, num, p, vn) =>
- implicit val pp = p
- val dummyClockGroupSourceNode: ClockGroupSourceNode = SimpleClockGroupSource(num)
- groups :*= dummyClockGroupSourceNode
- InModuleBody { RecordMap[ClockBundle]() }
- }
-
- /** Drive all members of all groups from a flattened IO representation */
- def driveFromIOs: DriveFn = { (groups, num, p, vn) =>
- implicit val pp = p
- val ioClockGroupSourceNode = ClockGroupSourceNode(List.fill(num) { ClockGroupSourceParameters() })
- groups :*= ioClockGroupSourceNode
- InModuleBody {
- val bundles = ioClockGroupSourceNode.out.map(_._1)
- val elements = bundles.map(_.member.elements).flatten
- val io = IO(Flipped(RecordMap(elements.map { case (name, data) =>
- name -> data.cloneType
- }:_*)))
-
- elements.foreach { case (name, data) => io(name).foreach { data := _ } }
- io.suggestName(vn.name)
- }
- }
-}
diff --git a/src/main/scala/prci/ClockNodes.scala b/src/main/scala/prci/ClockNodes.scala
index 16a9e01c894..e5c6748fb62 100644
--- a/src/main/scala/prci/ClockNodes.scala
+++ b/src/main/scala/prci/ClockNodes.scala
@@ -2,8 +2,14 @@
package freechips.rocketchip.prci
import chisel3.experimental.SourceInfo
-import org.chipsalliance.cde.config.Parameters
-import freechips.rocketchip.diplomacy._
+
+import org.chipsalliance.cde.config._
+
+import org.chipsalliance.diplomacy._
+import org.chipsalliance.diplomacy.lazymodule._
+import org.chipsalliance.diplomacy.nodes._
+
+import freechips.rocketchip.resources.FixedClockResource
object ClockImp extends SimpleNodeImp[ClockSourceParameters, ClockSinkParameters, ClockEdgeParameters, ClockBundle]
{
diff --git a/src/main/scala/prci/IOHelper.scala b/src/main/scala/prci/IOHelper.scala
index e33e618103b..6b7f75f6c40 100644
--- a/src/main/scala/prci/IOHelper.scala
+++ b/src/main/scala/prci/IOHelper.scala
@@ -3,7 +3,8 @@
package freechips.rocketchip.prci
import chisel3._
-import freechips.rocketchip.diplomacy._
+
+import org.chipsalliance.diplomacy.lazymodule._
object IOHelper {
diff --git a/src/main/scala/prci/ResetCrossingType.scala b/src/main/scala/prci/ResetCrossingType.scala
index dd37db2ee9d..0fdaa3b4d6c 100644
--- a/src/main/scala/prci/ResetCrossingType.scala
+++ b/src/main/scala/prci/ResetCrossingType.scala
@@ -1,8 +1,8 @@
// See LICENSE.SiFive for license details.
package freechips.rocketchip.prci
-import org.chipsalliance.cde.config.Parameters
-import freechips.rocketchip.diplomacy.{CrossingType, HasDomainCrossing, LazyModule}
+import org.chipsalliance.cde.config._
+import org.chipsalliance.diplomacy.lazymodule._
trait HasResetDomainCrossing extends HasDomainCrossing { this: LazyModule =>
type DomainCrossingType = ResetCrossingType
diff --git a/src/main/scala/prci/ResetStretcher.scala b/src/main/scala/prci/ResetStretcher.scala
index 747e93281fa..d9d76ab8e4a 100644
--- a/src/main/scala/prci/ResetStretcher.scala
+++ b/src/main/scala/prci/ResetStretcher.scala
@@ -2,9 +2,10 @@
package freechips.rocketchip.prci
import chisel3._
-import chisel3.util.log2Ceil
-import org.chipsalliance.cde.config.Parameters
-import freechips.rocketchip.diplomacy.{LazyModule, LazyModuleImp, ValName}
+import chisel3.util._
+import org.chipsalliance.cde.config._
+import org.chipsalliance.diplomacy._
+import org.chipsalliance.diplomacy.lazymodule._
/** This adapter takes an input reset and stretches it.
*
@@ -13,7 +14,7 @@ import freechips.rocketchip.diplomacy.{LazyModule, LazyModuleImp, ValName}
class ResetStretcher(cycles: Int)(implicit p: Parameters) extends LazyModule {
val node = ClockAdapterNode()(ValName("reset_stretcher"))
require(cycles > 1, s"ResetStretcher only supports cycles > 1 but got ${cycles}")
-
+ override lazy val desiredName = s"ResetStretcher$cycles"
lazy val module = new Impl
class Impl extends LazyModuleImp(this) {
(node.in zip node.out).foreach { case ((in, _), (out, _)) =>
diff --git a/src/main/scala/prci/ResetSynchronizer.scala b/src/main/scala/prci/ResetSynchronizer.scala
index 9bb6c5aea31..c66ce4576a7 100644
--- a/src/main/scala/prci/ResetSynchronizer.scala
+++ b/src/main/scala/prci/ResetSynchronizer.scala
@@ -1,9 +1,11 @@
// See LICENSE for license details.
package freechips.rocketchip.prci
-import org.chipsalliance.cde.config.{Parameters}
-import freechips.rocketchip.diplomacy._
-import freechips.rocketchip.util.{ResetCatchAndSync}
+import org.chipsalliance.cde.config._
+import org.chipsalliance.diplomacy._
+import org.chipsalliance.diplomacy.lazymodule._
+
+import freechips.rocketchip.util.ResetCatchAndSync
/**
* Synchronizes the reset of a diplomatic clock-reset pair to its accompanying clock.
diff --git a/src/main/scala/prci/ResetWrangler.scala b/src/main/scala/prci/ResetWrangler.scala
index 3f59bc3d183..59b289bc3e6 100644
--- a/src/main/scala/prci/ResetWrangler.scala
+++ b/src/main/scala/prci/ResetWrangler.scala
@@ -4,8 +4,9 @@ package freechips.rocketchip.prci
import chisel3._
import chisel3.util._
import org.chipsalliance.cde.config._
-import freechips.rocketchip.diplomacy._
-import freechips.rocketchip.util._
+import org.chipsalliance.diplomacy.lazymodule._
+
+import freechips.rocketchip.util.{AsyncResetReg, ResetCatchAndSync}
class ResetWrangler(debounceNs: Double = 100000)(implicit p: Parameters) extends LazyModule
{
diff --git a/src/main/scala/prci/TestClockSource.scala b/src/main/scala/prci/TestClockSource.scala
index 440c77f893e..6889908b0d2 100644
--- a/src/main/scala/prci/TestClockSource.scala
+++ b/src/main/scala/prci/TestClockSource.scala
@@ -1,10 +1,11 @@
package freechips.rocketchip.prci
import chisel3._
-import chisel3.util.HasBlackBoxInline
+import chisel3.util._
import chisel3.experimental.DoubleParam
-import org.chipsalliance.cde.config.Parameters
-import freechips.rocketchip.diplomacy._
+
+import org.chipsalliance.cde.config._
+import org.chipsalliance.diplomacy.lazymodule._
class ClockSourceIO extends Bundle {
val power = Input(Bool())
diff --git a/src/main/scala/prci/package.scala b/src/main/scala/prci/package.scala
index e427add8d43..872a05d05d3 100644
--- a/src/main/scala/prci/package.scala
+++ b/src/main/scala/prci/package.scala
@@ -2,15 +2,21 @@
package freechips.rocketchip
-import freechips.rocketchip.diplomacy._
+import org.chipsalliance.diplomacy.nodes._
+import freechips.rocketchip.diplomacy.{BufferParams}
package object prci
{
type ClockInwardNode = InwardNodeHandle[ClockSourceParameters, ClockSinkParameters, ClockEdgeParameters, ClockBundle]
type ClockOutwardNode = OutwardNodeHandle[ClockSourceParameters, ClockSinkParameters, ClockEdgeParameters, ClockBundle]
type ClockNode = NodeHandle[ClockSourceParameters, ClockSinkParameters, ClockEdgeParameters, ClockBundle, ClockSourceParameters, ClockSinkParameters, ClockEdgeParameters, ClockBundle]
+
+ type ClockGroupNode = NodeHandle[ClockGroupSourceParameters, ClockGroupSinkParameters, ClockGroupEdgeParameters, ClockGroupBundle, ClockGroupSourceParameters, ClockGroupSinkParameters, ClockGroupEdgeParameters, ClockGroupBundle]
+
def asyncMux[T](xType: ClockCrossingType, async: T, notasync: T): T = xType match {
case _: AsynchronousCrossing => async
case _ => notasync
}
+
+ implicit def noCrossing(value: NoCrossing.type): ClockCrossingType = SynchronousCrossing(BufferParams.none)
}
diff --git a/src/main/scala/regmapper/RegMapper.scala b/src/main/scala/regmapper/RegMapper.scala
index 78361ef9406..2e00c77005a 100644
--- a/src/main/scala/regmapper/RegMapper.scala
+++ b/src/main/scala/regmapper/RegMapper.scala
@@ -4,13 +4,13 @@ package freechips.rocketchip.regmapper
import chisel3._
import chisel3.experimental.SourceInfo
-import chisel3.util.{DecoupledIO, Decoupled, Queue, Cat, FillInterleaved, UIntToOH}
-import freechips.rocketchip.diplomacy._
-import freechips.rocketchip.util._
-import freechips.rocketchip.util.property
+import chisel3.util._
-// A bus agnostic register interface to a register-based device
+import freechips.rocketchip.diplomacy.AddressDecoder
+
+import freechips.rocketchip.util.{BundleFieldBase, BundleMap, MuxSeq, ReduceOthers, property}
+// A bus agnostic register interface to a register-based device
case class RegMapperParams(indexBits: Int, maskBits: Int, extraFields: Seq[BundleFieldBase] = Nil)
class RegMapperInput(val params: RegMapperParams) extends Bundle
@@ -67,7 +67,13 @@ object RegMapper
val depth = concurrency
require (depth >= 0)
require (!pipelined || depth > 0, "Register-based device with request/response handshaking needs concurrency > 0")
- val back = if (depth > 0) Queue(front, depth) else front
+ val back = if (depth > 0) {
+ val front_q = Module(new Queue(new RegMapperInput(inParams), depth) {
+ override def desiredName = s"Queue${depth}_${front.bits.typeName}_i${inParams.indexBits}_m${inParams.maskBits}"
+ })
+ front_q.io.enq <> front
+ front_q.io.deq
+ } else front
// Convert to and from Bits
def toBits(x: Int, tail: List[Boolean] = List.empty): List[Boolean] =
diff --git a/src/main/scala/regmapper/RegisterRouter.scala b/src/main/scala/regmapper/RegisterRouter.scala
index 0bd43a7fd06..083a1d09dfb 100644
--- a/src/main/scala/regmapper/RegisterRouter.scala
+++ b/src/main/scala/regmapper/RegisterRouter.scala
@@ -3,9 +3,16 @@
package freechips.rocketchip.regmapper
import chisel3._
-import chisel3.util.{isPow2}
-import org.chipsalliance.cde.config.Parameters
-import freechips.rocketchip.diplomacy._
+import chisel3.util._
+
+import org.chipsalliance.cde.config._
+import org.chipsalliance.diplomacy.bundlebridge._
+import org.chipsalliance.diplomacy.lazymodule._
+
+import freechips.rocketchip.diplomacy.{AddressSet}
+import freechips.rocketchip.resources.{Description, Device, SimpleDevice, ResourceBindings, ResourceValue}
+import freechips.rocketchip.prci.{HasClockDomainCrossing}
+
/** Parameters which apply to any RegisterRouter. */
case class RegisterRouterParams(
diff --git a/src/main/scala/regmapper/Test.scala b/src/main/scala/regmapper/Test.scala
index 57c5c7ec583..0faedd84cfb 100644
--- a/src/main/scala/regmapper/Test.scala
+++ b/src/main/scala/regmapper/Test.scala
@@ -3,10 +3,12 @@
package freechips.rocketchip.regmapper
import chisel3._
-import chisel3.util.{Cat, log2Ceil}
-import org.chipsalliance.cde.config.Parameters
-import freechips.rocketchip.diplomacy.LazyModuleImp
-import freechips.rocketchip.util.{Pow2ClockDivider}
+import chisel3.util._
+
+import org.chipsalliance.cde.config._
+import org.chipsalliance.diplomacy.lazymodule._
+
+import freechips.rocketchip.util.Pow2ClockDivider
object LFSR16Seed
{
diff --git a/src/main/scala/resources/AddressMapEntry.scala b/src/main/scala/resources/AddressMapEntry.scala
new file mode 100644
index 00000000000..27ba067ad56
--- /dev/null
+++ b/src/main/scala/resources/AddressMapEntry.scala
@@ -0,0 +1,21 @@
+package freechips.rocketchip.resources
+
+import freechips.rocketchip.diplomacy.{AddressRange}
+
+case class AddressMapEntry(range: AddressRange, permissions: ResourcePermissions, names: Seq[String]) {
+ val ResourcePermissions(r, w, x, c, a) = permissions
+
+ def toString(aw: Int) = s"\t%${aw}x - %${aw}x %c%c%c%c%c %s".format(
+ range.base,
+ range.base+range.size,
+ if (a) 'A' else ' ',
+ if (r) 'R' else ' ',
+ if (w) 'W' else ' ',
+ if (x) 'X' else ' ',
+ if (c) 'C' else ' ',
+ names.mkString(", "))
+
+ def toJSON = s"""{"base":[${range.base}],"size":[${range.size}],""" +
+ s""""r":[$r],"w":[$w],"x":[$x],"c":[$c],"a":[$a],""" +
+ s""""names":[${names.map('"'+_+'"').mkString(",")}]}"""
+}
diff --git a/src/main/scala/diplomacy/DeviceTree.scala b/src/main/scala/resources/DeviceTree.scala
similarity index 98%
rename from src/main/scala/diplomacy/DeviceTree.scala
rename to src/main/scala/resources/DeviceTree.scala
index 05ccdbb5b91..3c9e04384fc 100644
--- a/src/main/scala/diplomacy/DeviceTree.scala
+++ b/src/main/scala/resources/DeviceTree.scala
@@ -1,10 +1,11 @@
// See LICENSE.SiFive for license details.
-package freechips.rocketchip.diplomacy
+package freechips.rocketchip.resources
import org.chipsalliance.cde.config.Field
import sys.process._
import java.io.{ByteArrayInputStream, ByteArrayOutputStream}
+import freechips.rocketchip.diplomacy.{AddressRange}
case object DTSModel extends Field[String]
case object DTSCompat extends Field[Seq[String]] // -dev, -soc
diff --git a/src/main/scala/diplomacy/FixedClockResource.scala b/src/main/scala/resources/FixedClockResource.scala
similarity index 94%
rename from src/main/scala/diplomacy/FixedClockResource.scala
rename to src/main/scala/resources/FixedClockResource.scala
index 2ae3ee9f236..d0c39ef85bd 100644
--- a/src/main/scala/diplomacy/FixedClockResource.scala
+++ b/src/main/scala/resources/FixedClockResource.scala
@@ -1,6 +1,6 @@
// See LICENSE.SiFive for license details.
-package freechips.rocketchip.diplomacy
+package freechips.rocketchip.resources
class FixedClockResource(val name: String, val freqMHz: Double, val prefix: String = "soc/")
{
diff --git a/src/main/scala/diplomacy/JSON.scala b/src/main/scala/resources/JSON.scala
similarity index 95%
rename from src/main/scala/diplomacy/JSON.scala
rename to src/main/scala/resources/JSON.scala
index 0ab4c0a909c..3a656615e6c 100644
--- a/src/main/scala/diplomacy/JSON.scala
+++ b/src/main/scala/resources/JSON.scala
@@ -1,8 +1,9 @@
// See LICENSE.SiFive for license details.
-package freechips.rocketchip.diplomacy
+package freechips.rocketchip.resources
import scala.collection.immutable.SortedMap
+import freechips.rocketchip.diplomacy.{AddressRange}
object JSON
{
diff --git a/src/main/scala/diplomacy/Resources.scala b/src/main/scala/resources/Resources.scala
similarity index 96%
rename from src/main/scala/diplomacy/Resources.scala
rename to src/main/scala/resources/Resources.scala
index 4dc59d95304..41d042f4907 100644
--- a/src/main/scala/diplomacy/Resources.scala
+++ b/src/main/scala/resources/Resources.scala
@@ -1,11 +1,13 @@
// See LICENSE.SiFive for license details.
-package freechips.rocketchip.diplomacy
+package freechips.rocketchip.resources
import chisel3.util.log2Ceil
import scala.collection.immutable.{ListMap, SortedMap}
import scala.collection.mutable.HashMap
+import freechips.rocketchip.diplomacy.{AddressSet, AddressRange}
+import org.chipsalliance.diplomacy.lazymodule.{LazyModule}
sealed trait ResourceValue
@@ -275,12 +277,12 @@ trait BindingScope
BindingScope.add(this)
private val parentScope = BindingScope.find(parent)
- protected[diplomacy] var resourceBindingFns: Seq[() => Unit] = Nil // callback functions to resolve resource binding during elaboration
- protected[diplomacy] var resourceBindings: Seq[(Resource, Option[Device], ResourceValue)] = Nil
+ protected[resources] var resourceBindingFns: Seq[() => Unit] = Nil // callback functions to resolve resource binding during elaboration
+ protected[resources] var resourceBindings: Seq[(Resource, Option[Device], ResourceValue)] = Nil
private case class ExpandedValue(path: Seq[String], labels: Seq[String], value: Seq[ResourceValue])
private lazy val eval: Unit = {
- require (!LazyModule.scope.isDefined, "May not evaluate binding while still constructing LazyModules")
+ require (!LazyModule.getScope.isDefined, "May not evaluate binding while still constructing LazyModules")
parentScope.foreach { _.eval }
resourceBindings = parentScope.map(_.resourceBindings).getOrElse(Nil)
BindingScope.active = Some(this)
@@ -387,10 +389,10 @@ trait BindingScope
object BindingScope
{
- protected[diplomacy] var active: Option[BindingScope] = None
- protected[diplomacy] def find(m: Option[LazyModule] = LazyModule.scope): Option[BindingScope] = m.flatMap {
- case x: BindingScope => find(x.parent).orElse(Some(x))
- case x => find(x.parent)
+ protected[resources] var active: Option[BindingScope] = None
+ protected[resources] def find(m: Option[LazyModule] = LazyModule.getScope): Option[BindingScope] = m.flatMap {
+ case x: BindingScope => find(x.getParent).orElse(Some(x))
+ case x => find(x.getParent)
}
var bindingScopes = new collection.mutable.ArrayBuffer[BindingScope]()
diff --git a/src/main/scala/diplomacy/SRAM.scala b/src/main/scala/resources/SRAM.scala
similarity index 94%
rename from src/main/scala/diplomacy/SRAM.scala
rename to src/main/scala/resources/SRAM.scala
index 205fba914d0..8fc3c16e0d8 100644
--- a/src/main/scala/diplomacy/SRAM.scala
+++ b/src/main/scala/resources/SRAM.scala
@@ -1,11 +1,12 @@
// See LICENSE.SiFive for license details.
-package freechips.rocketchip.diplomacy
+package freechips.rocketchip.resources
import chisel3._
import chisel3.util.log2Ceil
import org.chipsalliance.cde.config.Parameters
import freechips.rocketchip.util.{DescribedSRAM, Code}
+import freechips.rocketchip.diplomacy.{AddressSet, LazyModule}
abstract class DiplomaticSRAM(
val address: AddressSet,
diff --git a/src/main/scala/resources/package.scala b/src/main/scala/resources/package.scala
new file mode 100644
index 00000000000..d2416826427
--- /dev/null
+++ b/src/main/scala/resources/package.scala
@@ -0,0 +1,29 @@
+package freechips.rocketchip
+
+package object resources {
+ type PropertyOption = Option[(String, Seq[ResourceValue])]
+ type PropertyMap = Iterable[(String, Seq[ResourceValue])]
+
+ implicit class BigIntHexContext(private val sc: StringContext) extends AnyVal {
+ def x(args: Any*): BigInt = {
+ val orig = sc.s(args: _*)
+ BigInt(orig.replace("_", ""), 16)
+ }
+ }
+
+ implicit class IntToProperty(x: Int) {
+ def asProperty: Seq[ResourceValue] = Seq(ResourceInt(BigInt(x)))
+ }
+
+ implicit class BigIntToProperty(x: BigInt) {
+ def asProperty: Seq[ResourceValue] = Seq(ResourceInt(x))
+ }
+
+ implicit class StringToProperty(x: String) {
+ def asProperty: Seq[ResourceValue] = Seq(ResourceString(x))
+ }
+
+ implicit class DeviceToProperty(x: Device) {
+ def asProperty: Seq[ResourceValue] = Seq(ResourceReference(x.label))
+ }
+}
diff --git a/src/main/scala/rocket/ALU.scala b/src/main/scala/rocket/ALU.scala
index 20c2bdffeb3..96cbc98aa58 100644
--- a/src/main/scala/rocket/ALU.scala
+++ b/src/main/scala/rocket/ALU.scala
@@ -4,13 +4,14 @@
package freechips.rocketchip.rocket
import chisel3._
-import chisel3.util.{BitPat, Fill, Cat, Reverse}
+import chisel3.util.{BitPat, Fill, Cat, Reverse, PriorityEncoderOH, PopCount, MuxLookup}
import org.chipsalliance.cde.config.Parameters
import freechips.rocketchip.tile.CoreModule
+import freechips.rocketchip.util._
-class ALUFN {
- val SZ_ALU_FN = 4
- def FN_X = BitPat("b????")
+object ALU {
+ val SZ_ALU_FN = 5
+ def FN_X = BitPat("b?????")
def FN_ADD = 0.U
def FN_SL = 1.U
def FN_SEQ = 2.U
@@ -27,6 +28,20 @@ class ALUFN {
def FN_SGE = 13.U
def FN_SLTU = 14.U
def FN_SGEU = 15.U
+ def FN_UNARY = 16.U
+ def FN_ROL = 17.U
+ def FN_ROR = 18.U
+ def FN_BEXT = 19.U
+
+ def FN_ANDN = 24.U
+ def FN_ORN = 25.U
+ def FN_XNOR = 26.U
+
+ def FN_MAX = 28.U
+ def FN_MIN = 29.U
+ def FN_MAXU = 30.U
+ def FN_MINU = 31.U
+ def FN_MAXMIN = BitPat("b111??")
// Mul/div reuse some integer FNs
def FN_DIV = FN_XOR
@@ -41,21 +56,22 @@ class ALUFN {
def isMulFN(fn: UInt, cmp: UInt) = fn(1,0) === cmp(1,0)
def isSub(cmd: UInt) = cmd(3)
- def isCmp(cmd: UInt) = cmd >= FN_SLT
+ def isCmp(cmd: UInt) = (cmd >= FN_SLT && cmd <= FN_SGEU)
+ def isMaxMin(cmd: UInt) = (cmd >= FN_MAX && cmd <= FN_MINU)
def cmpUnsigned(cmd: UInt) = cmd(1)
def cmpInverted(cmd: UInt) = cmd(0)
def cmpEq(cmd: UInt) = !cmd(3)
+ def shiftReverse(cmd: UInt) = !cmd.isOneOf(FN_SR, FN_SRA, FN_ROR, FN_BEXT)
+ def bwInvRs2(cmd: UInt) = cmd.isOneOf(FN_ANDN, FN_ORN, FN_XNOR)
}
-object ALUFN {
- def apply() = new ALUFN
-}
+import ALU._
-abstract class AbstractALU[T <: ALUFN](val aluFn: T)(implicit p: Parameters) extends CoreModule()(p) {
+abstract class AbstractALU(implicit p: Parameters) extends CoreModule()(p) {
val io = IO(new Bundle {
val dw = Input(UInt(SZ_DW.W))
- val fn = Input(UInt(aluFn.SZ_ALU_FN.W))
+ val fn = Input(UInt(SZ_ALU_FN.W))
val in2 = Input(UInt(xLen.W))
val in1 = Input(UInt(xLen.W))
val out = Output(UInt(xLen.W))
@@ -64,50 +80,97 @@ abstract class AbstractALU[T <: ALUFN](val aluFn: T)(implicit p: Parameters) ext
})
}
-class ALU(implicit p: Parameters) extends AbstractALU(new ALUFN)(p) {
+class ALU(implicit p: Parameters) extends AbstractALU()(p) {
// ADD, SUB
- val in2_inv = Mux(aluFn.isSub(io.fn), ~io.in2, io.in2)
+ val in2_inv = Mux(isSub(io.fn), ~io.in2, io.in2)
val in1_xor_in2 = io.in1 ^ in2_inv
- io.adder_out := io.in1 + in2_inv + aluFn.isSub(io.fn)
+ val in1_and_in2 = io.in1 & in2_inv
+ io.adder_out := io.in1 + in2_inv + isSub(io.fn)
// SLT, SLTU
val slt =
Mux(io.in1(xLen-1) === io.in2(xLen-1), io.adder_out(xLen-1),
- Mux(aluFn.cmpUnsigned(io.fn), io.in2(xLen-1), io.in1(xLen-1)))
- io.cmp_out := aluFn.cmpInverted(io.fn) ^ Mux(aluFn.cmpEq(io.fn), in1_xor_in2 === 0.U, slt)
+ Mux(cmpUnsigned(io.fn), io.in2(xLen-1), io.in1(xLen-1)))
+ io.cmp_out := cmpInverted(io.fn) ^ Mux(cmpEq(io.fn), in1_xor_in2 === 0.U, slt)
// SLL, SRL, SRA
val (shamt, shin_r) =
if (xLen == 32) (io.in2(4,0), io.in1)
else {
require(xLen == 64)
- val shin_hi_32 = Fill(32, aluFn.isSub(io.fn) && io.in1(31))
+ val shin_hi_32 = Fill(32, isSub(io.fn) && io.in1(31))
val shin_hi = Mux(io.dw === DW_64, io.in1(63,32), shin_hi_32)
val shamt = Cat(io.in2(5) & (io.dw === DW_64), io.in2(4,0))
(shamt, Cat(shin_hi, io.in1(31,0)))
}
- val shin = Mux(io.fn === aluFn.FN_SR || io.fn === aluFn.FN_SRA, shin_r, Reverse(shin_r))
- val shout_r = (Cat(aluFn.isSub(io.fn) & shin(xLen-1), shin).asSInt >> shamt)(xLen-1,0)
+ val shin = Mux(shiftReverse(io.fn), Reverse(shin_r), shin_r)
+ val shout_r = (Cat(isSub(io.fn) & shin(xLen-1), shin).asSInt >> shamt)(xLen-1,0)
val shout_l = Reverse(shout_r)
- val shout = Mux(io.fn === aluFn.FN_SR || io.fn === aluFn.FN_SRA, shout_r, 0.U) |
- Mux(io.fn === aluFn.FN_SL, shout_l, 0.U)
+ val shout = Mux(io.fn === FN_SR || io.fn === FN_SRA || io.fn === FN_BEXT, shout_r, 0.U) |
+ Mux(io.fn === FN_SL, shout_l, 0.U)
// CZEQZ, CZNEZ
val in2_not_zero = io.in2.orR
val cond_out = Option.when(usingConditionalZero)(
- Mux((io.fn === aluFn.FN_CZEQZ && in2_not_zero) || (io.fn === aluFn.FN_CZNEZ && !in2_not_zero), io.in1, 0.U)
+ Mux((io.fn === FN_CZEQZ && in2_not_zero) || (io.fn === FN_CZNEZ && !in2_not_zero), io.in1, 0.U)
)
// AND, OR, XOR
- val logic = Mux(io.fn === aluFn.FN_XOR || io.fn === aluFn.FN_OR, in1_xor_in2, 0.U) |
- Mux(io.fn === aluFn.FN_OR || io.fn === aluFn.FN_AND, io.in1 & io.in2, 0.U)
+ val logic = Mux(io.fn === FN_XOR || io.fn === FN_OR || io.fn === FN_ORN || io.fn === FN_XNOR, in1_xor_in2, 0.U) |
+ Mux(io.fn === FN_OR || io.fn === FN_AND || io.fn === FN_ORN || io.fn === FN_ANDN, in1_and_in2, 0.U)
- val shift_logic = (aluFn.isCmp (io.fn) && slt) | logic | shout
+ val bext_mask = Mux(coreParams.useZbs.B && io.fn === FN_BEXT, 1.U, ~(0.U(xLen.W)))
+ val shift_logic = (isCmp (io.fn) && slt) | logic | (shout & bext_mask)
val shift_logic_cond = cond_out match {
case Some(co) => shift_logic | co
case _ => shift_logic
}
- val out = Mux(io.fn === aluFn.FN_ADD || io.fn === aluFn.FN_SUB, io.adder_out, shift_logic_cond)
+
+ // CLZ, CTZ, CPOP
+ val tz_in = MuxLookup((io.dw === DW_32) ## !io.in2(0), 0.U)(Seq(
+ 0.U -> io.in1,
+ 1.U -> Reverse(io.in1),
+ 2.U -> 1.U ## io.in1(31,0),
+ 3.U -> 1.U ## Reverse(io.in1(31,0))
+ ))
+ val popc_in = Mux(io.in2(1),
+ Mux(io.dw === DW_32, io.in1(31,0), io.in1),
+ PriorityEncoderOH(1.U ## tz_in) - 1.U)(xLen-1,0)
+ val count = PopCount(popc_in)
+ val in1_bytes = io.in1.asTypeOf(Vec(xLen / 8, UInt(8.W)))
+ val orcb = VecInit(in1_bytes.map(b => Fill(8, b =/= 0.U))).asUInt
+ val rev8 = VecInit(in1_bytes.reverse).asUInt
+ val unary = MuxLookup(io.in2(11,0), count)(Seq(
+ 0x287.U -> orcb,
+ (if (xLen == 32) 0x698 else 0x6b8).U -> rev8,
+ 0x080.U -> io.in1(15,0),
+ 0x604.U -> Fill(xLen-8, io.in1(7)) ## io.in1(7,0),
+ 0x605.U -> Fill(xLen-16, io.in1(15)) ## io.in1(15,0)
+ ))
+
+ // MAX, MIN, MAXU, MINU
+ val maxmin_out = Mux(io.cmp_out, io.in2, io.in1)
+
+ // ROL, ROR
+ val rot_shamt = Mux(io.dw === DW_32, 32.U, xLen.U) - shamt
+ val rotin = Mux(io.fn(0), shin_r, Reverse(shin_r))
+ val rotout_r = (rotin >> rot_shamt)(xLen-1,0)
+ val rotout_l = Reverse(rotout_r)
+ val rotout = Mux(io.fn(0), rotout_r, rotout_l) | Mux(io.fn(0), shout_l, shout_r)
+
+ val out = MuxLookup(io.fn, shift_logic_cond)(Seq(
+ FN_ADD -> io.adder_out,
+ FN_SUB -> io.adder_out
+ ) ++ (if (coreParams.useZbb) Seq(
+ FN_UNARY -> unary,
+ FN_MAX -> maxmin_out,
+ FN_MIN -> maxmin_out,
+ FN_MAXU -> maxmin_out,
+ FN_MINU -> maxmin_out,
+ FN_ROL -> rotout,
+ FN_ROR -> rotout,
+ ) else Nil))
+
io.out := out
if (xLen > 32) {
diff --git a/src/main/scala/rocket/AMOALU.scala b/src/main/scala/rocket/AMOALU.scala
index 0aff648446e..47295d18db0 100644
--- a/src/main/scala/rocket/AMOALU.scala
+++ b/src/main/scala/rocket/AMOALU.scala
@@ -10,6 +10,7 @@ import org.chipsalliance.cde.config.Parameters
class StoreGen(typ: UInt, addr: UInt, dat: UInt, maxSize: Int) {
val size = Wire(UInt(log2Up(log2Up(maxSize)+1).W))
size := typ
+ val dat_padded = dat.pad(maxSize*8)
def misaligned: Bool =
(addr & ((1.U << size) - 1.U)(log2Up(maxSize)-1,0)).orR
@@ -24,8 +25,8 @@ class StoreGen(typ: UInt, addr: UInt, dat: UInt, maxSize: Int) {
}
protected def genData(i: Int): UInt =
- if (i >= log2Up(maxSize)) dat
- else Mux(size === i.U, Fill(1 << (log2Up(maxSize)-i), dat((8 << i)-1,0)), genData(i+1))
+ if (i >= log2Up(maxSize)) dat_padded
+ else Mux(size === i.U, Fill(1 << (log2Up(maxSize)-i), dat_padded((8 << i)-1,0)), genData(i+1))
def data = genData(0)
def wordData = genData(2)
diff --git a/src/main/scala/rocket/BTB.scala b/src/main/scala/rocket/BTB.scala
index 25b5b359ded..75126dd121b 100644
--- a/src/main/scala/rocket/BTB.scala
+++ b/src/main/scala/rocket/BTB.scala
@@ -5,7 +5,6 @@ package freechips.rocketchip.rocket
import chisel3._
import chisel3.util._
-import chisel3.internal.InstanceId
import org.chipsalliance.cde.config.Parameters
import freechips.rocketchip.subsystem.CacheBlockBytes
import freechips.rocketchip.tile.HasCoreParameters
diff --git a/src/main/scala/rocket/CSR.scala b/src/main/scala/rocket/CSR.scala
index 67812022773..407b1e988be 100644
--- a/src/main/scala/rocket/CSR.scala
+++ b/src/main/scala/rocket/CSR.scala
@@ -245,6 +245,7 @@ class CSRDecodeIO(implicit p: Parameters) extends CoreBundle {
val fp_illegal = Output(Bool())
val vector_illegal = Output(Bool())
val fp_csr = Output(Bool())
+ val vector_csr = Output(Bool())
val rocc_illegal = Output(Bool())
val read_illegal = Output(Bool())
val write_illegal = Output(Bool())
@@ -254,10 +255,10 @@ class CSRDecodeIO(implicit p: Parameters) extends CoreBundle {
val virtual_system_illegal = Output(Bool())
}
-class CSRFileIO(implicit p: Parameters) extends CoreBundle
+class CSRFileIO(hasBeu: Boolean)(implicit p: Parameters) extends CoreBundle
with HasCoreParameters {
val ungated_clock = Input(Clock())
- val interrupts = Input(new CoreInterrupts())
+ val interrupts = Input(new CoreInterrupts(hasBeu))
val hartid = Input(UInt(hartIdLen.W))
val rw = new Bundle {
val addr = Input(UInt(CSR.ADDRSZ.W))
@@ -286,6 +287,7 @@ class CSRFileIO(implicit p: Parameters) extends CoreBundle
val pc = Input(UInt(vaddrBitsExtended.W))
val tval = Input(UInt(vaddrBitsExtended.W))
val htval = Input(UInt(((maxSVAddrBits + 1) min xLen).W))
+ val mhtinst_read_pseudo = Input(Bool())
val gva = Input(Bool())
val time = Output(UInt(xLen.W))
val fcsr_rm = Output(Bits(FPConstants.RM_SZ.W))
@@ -375,10 +377,11 @@ class VType(implicit p: Parameters) extends CoreBundle {
class CSRFile(
perfEventSets: EventSets = new EventSets(Seq()),
customCSRs: Seq[CustomCSR] = Nil,
- roccCSRs: Seq[CustomCSR] = Nil)(implicit p: Parameters)
+ roccCSRs: Seq[CustomCSR] = Nil,
+ hasBeu: Boolean = false)(implicit p: Parameters)
extends CoreModule()(p)
with HasCoreParameters {
- val io = IO(new CSRFileIO {
+ val io = IO(new CSRFileIO(hasBeu) {
val customCSRs = Vec(CSRFile.this.customCSRs.size, new CustomCSRIO)
val roccCSRs = Vec(CSRFile.this.roccCSRs.size, new CustomCSRIO)
})
@@ -578,6 +581,12 @@ class CSRFile(
val reg_vxsat = usingVector.option(Reg(Bool()))
val reg_vxrm = usingVector.option(Reg(UInt(io.vector.get.vxrm.getWidth.W)))
+ val reg_mtinst_read_pseudo = Reg(Bool())
+ val reg_htinst_read_pseudo = Reg(Bool())
+ // XLEN=32: 0x00002000
+ // XLEN=64: 0x00003000
+ val Seq(read_mtinst, read_htinst) = Seq(reg_mtinst_read_pseudo, reg_htinst_read_pseudo).map(r => Cat(r, (xLen == 32).option(0.U).getOrElse(r), 0.U(12.W)))
+
val reg_mcountinhibit = RegInit(0.U((CSR.firstHPM + nPerfCounters).W))
io.inhibit_cycle := reg_mcountinhibit(0)
val reg_instret = WideCounter(64, io.retire, inhibit = reg_mcountinhibit(2))
@@ -627,7 +636,7 @@ class CSRFile(
(if (usingAtomics) "A" else "") +
(if (fLen >= 32) "F" else "") +
(if (fLen >= 64) "D" else "") +
- (if (usingVector) "V" else "") +
+ (if (coreParams.hasV) "V" else "") +
(if (usingCompressed) "C" else "")
val isaString = (if (coreParams.useRVE) "E" else "I") +
isaMaskString +
@@ -797,7 +806,7 @@ class CSRFile(
val reg_rocc = roccCSRs.zip(io.roccCSRs).map(t => generateCustomCSR(t._1, t._2))
if (usingHypervisor) {
- read_mapping += CSRs.mtinst -> 0.U
+ read_mapping += CSRs.mtinst -> read_mtinst
read_mapping += CSRs.mtval2 -> reg_mtval2
val read_hstatus = io.hstatus.asUInt.extract(xLen-1,0)
@@ -813,7 +822,7 @@ class CSRFile(
read_mapping += CSRs.hgeie -> 0.U
read_mapping += CSRs.hgeip -> 0.U
read_mapping += CSRs.htval -> reg_htval
- read_mapping += CSRs.htinst -> 0.U
+ read_mapping += CSRs.htinst -> read_htinst
read_mapping += CSRs.henvcfg -> reg_henvcfg.asUInt
if (xLen == 32)
read_mapping += CSRs.henvcfgh -> (reg_henvcfg.asUInt >> 32)
@@ -906,6 +915,7 @@ class CSRFile(
io_dec.fp_illegal := io.status.fs === 0.U || reg_mstatus.v && reg_vsstatus.fs === 0.U || !reg_misa('f'-'a')
io_dec.vector_illegal := io.status.vs === 0.U || reg_mstatus.v && reg_vsstatus.vs === 0.U || !reg_misa('v'-'a')
io_dec.fp_csr := decodeFast(fp_csrs.keys.toList)
+ io_dec.vector_csr := decodeFast(vector_csrs.keys.toList)
io_dec.rocc_illegal := io.status.xs === 0.U || reg_mstatus.v && reg_vsstatus.xs === 0.U || !reg_misa('x'-'a')
val csr_addr_legal = reg_mstatus.prv >= CSR.mode(addr) ||
usingHypervisor.B && !reg_mstatus.v && reg_mstatus.prv === PRV.S.U && CSR.mode(addr) === PRV.H.U
@@ -949,6 +959,7 @@ class CSRFile(
Mux(insn_call, Causes.user_ecall.U + Mux(reg_mstatus.prv(0) && reg_mstatus.v, PRV.H.U, reg_mstatus.prv),
Mux[UInt](insn_break, Causes.breakpoint.U, io.cause))
val cause_lsbs = cause(log2Ceil(1 + CSR.busErrorIntCause)-1, 0)
+ val cause_deleg_lsbs = cause(log2Ceil(xLen)-1,0)
val causeIsDebugInt = cause(xLen-1) && cause_lsbs === CSR.debugIntCause.U
val causeIsDebugTrigger = !cause(xLen-1) && cause_lsbs === CSR.debugTriggerCause.U
val causeIsDebugBreak = !cause(xLen-1) && insn_break && Cat(reg_dcsr.ebreakm, reg_dcsr.ebreakh, reg_dcsr.ebreaks, reg_dcsr.ebreaku)(reg_mstatus.prv)
@@ -956,8 +967,8 @@ class CSRFile(
val debugEntry = p(DebugModuleKey).map(_.debugEntry).getOrElse(BigInt(0x800))
val debugException = p(DebugModuleKey).map(_.debugException).getOrElse(BigInt(0x808))
val debugTVec = Mux(reg_debug, Mux(insn_break, debugEntry.U, debugException.U), debugEntry.U)
- val delegate = usingSupervisor.B && reg_mstatus.prv <= PRV.S.U && Mux(cause(xLen-1), read_mideleg(cause_lsbs), read_medeleg(cause_lsbs))
- val delegateVS = reg_mstatus.v && delegate && Mux(cause(xLen-1), read_hideleg(cause_lsbs), read_hedeleg(cause_lsbs))
+ val delegate = usingSupervisor.B && reg_mstatus.prv <= PRV.S.U && Mux(cause(xLen-1), read_mideleg(cause_deleg_lsbs), read_medeleg(cause_deleg_lsbs))
+ val delegateVS = reg_mstatus.v && delegate && Mux(cause(xLen-1), read_hideleg(cause_deleg_lsbs), read_hedeleg(cause_deleg_lsbs))
def mtvecBaseAlign = 2
def mtvecInterruptAlign = {
require(reg_mip.getWidth <= xLen)
@@ -1060,6 +1071,7 @@ class CSRFile(
reg_scause := cause
reg_stval := tval
reg_htval := io.htval
+ reg_htinst_read_pseudo := io.mhtinst_read_pseudo
reg_mstatus.spie := reg_mstatus.sie
reg_mstatus.spp := reg_mstatus.prv
reg_mstatus.sie := false.B
@@ -1072,6 +1084,7 @@ class CSRFile(
reg_mcause := cause
reg_mtval := tval
reg_mtval2 := io.htval
+ reg_mtinst_read_pseudo := io.mhtinst_read_pseudo
reg_mstatus.mpie := reg_mstatus.mie
reg_mstatus.mpp := trimPrivilege(reg_mstatus.prv)
reg_mstatus.mie := false.B
@@ -1397,6 +1410,10 @@ class CSRFile(
when (decoded_addr(CSRs.htval)) { reg_htval := wdata }
when (decoded_addr(CSRs.mtval2)) { reg_mtval2 := wdata }
+ val write_mhtinst_read_pseudo = wdata(13) && (xLen == 32).option(true.B).getOrElse(wdata(12))
+ when(decoded_addr(CSRs.mtinst)) { reg_mtinst_read_pseudo := write_mhtinst_read_pseudo }
+ when(decoded_addr(CSRs.htinst)) { reg_htinst_read_pseudo := write_mhtinst_read_pseudo }
+
when (decoded_addr(CSRs.vsstatus)) {
val new_vsstatus = wdata.asTypeOf(new MStatus())
reg_vsstatus.sie := new_vsstatus.sie
diff --git a/src/main/scala/rocket/Configs.scala b/src/main/scala/rocket/Configs.scala
new file mode 100644
index 00000000000..a8f18cc2942
--- /dev/null
+++ b/src/main/scala/rocket/Configs.scala
@@ -0,0 +1,334 @@
+package freechips.rocketchip.rocket
+
+import chisel3.util._
+
+import org.chipsalliance.cde.config._
+import org.chipsalliance.diplomacy.lazymodule._
+
+import freechips.rocketchip.prci.{SynchronousCrossing, AsynchronousCrossing, RationalCrossing, ClockCrossingType}
+import freechips.rocketchip.subsystem.{TilesLocated, NumTiles, HierarchicalLocation, RocketCrossingParams, SystemBusKey, CacheBlockBytes, RocketTileAttachParams, InSubsystem, InCluster, HierarchicalElementMasterPortParams, HierarchicalElementSlavePortParams, CBUS, CCBUS, ClustersLocated, TileAttachConfig, CloneTileAttachParams}
+import freechips.rocketchip.tile.{RocketTileParams, RocketTileBoundaryBufferParams, FPUParams}
+import scala.reflect.ClassTag
+
+// All the user-level bells and whistles
+class WithNHugeCores(
+ n: Int,
+ location: HierarchicalLocation,
+ crossing: RocketCrossingParams,
+) extends Config((site, here, up) => {
+ case TilesLocated(`location`) => {
+ val prev = up(TilesLocated(`location`), site)
+ val idOffset = up(NumTiles)
+ val big = RocketTileParams(
+ core = RocketCoreParams(
+ mulDiv = Some(MulDivParams(
+ mulUnroll = 8,
+ mulEarlyOut = true,
+ divEarlyOut = true,
+ )),
+ useZba = true,
+ useZbb = true,
+ useZbs = true,
+ fpu = Some(FPUParams(minFLen = 16))),
+ dcache = Some(DCacheParams(
+ nSets = 64,
+ nWays = 8,
+ rowBits = site(SystemBusKey).beatBits,
+ nMSHRs = 0,
+ blockBytes = site(CacheBlockBytes))),
+ icache = Some(ICacheParams(
+ nSets = 64,
+ nWays = 8,
+ rowBits = site(SystemBusKey).beatBits,
+ blockBytes = site(CacheBlockBytes))))
+ List.tabulate(n)(i => RocketTileAttachParams(
+ big.copy(tileId = i + idOffset),
+ crossing
+ )) ++ prev
+ }
+ case NumTiles => up(NumTiles) + n
+}) {
+ def this(n: Int, location: HierarchicalLocation = InSubsystem) = this(n, location, RocketCrossingParams(
+ master = HierarchicalElementMasterPortParams.locationDefault(location),
+ slave = HierarchicalElementSlavePortParams.locationDefault(location),
+ mmioBaseAddressPrefixWhere = location match {
+ case InSubsystem => CBUS
+ case InCluster(clusterId) => CCBUS(clusterId)
+ }
+ ))
+}
+
+class WithNBigCores(
+ n: Int,
+ location: HierarchicalLocation,
+ crossing: RocketCrossingParams,
+) extends Config((site, here, up) => {
+ case TilesLocated(`location`) => {
+ val prev = up(TilesLocated(`location`), site)
+ val idOffset = up(NumTiles)
+ val big = RocketTileParams(
+ core = RocketCoreParams(mulDiv = Some(MulDivParams(
+ mulUnroll = 8,
+ mulEarlyOut = true,
+ divEarlyOut = true))),
+ dcache = Some(DCacheParams(
+ rowBits = site(SystemBusKey).beatBits,
+ nMSHRs = 0,
+ blockBytes = site(CacheBlockBytes))),
+ icache = Some(ICacheParams(
+ rowBits = site(SystemBusKey).beatBits,
+ blockBytes = site(CacheBlockBytes))))
+ List.tabulate(n)(i => RocketTileAttachParams(
+ big.copy(tileId = i + idOffset),
+ crossing
+ )) ++ prev
+ }
+ case NumTiles => up(NumTiles) + n
+}) {
+ def this(n: Int, location: HierarchicalLocation = InSubsystem) = this(n, location, RocketCrossingParams(
+ master = HierarchicalElementMasterPortParams.locationDefault(location),
+ slave = HierarchicalElementSlavePortParams.locationDefault(location),
+ mmioBaseAddressPrefixWhere = location match {
+ case InSubsystem => CBUS
+ case InCluster(clusterId) => CCBUS(clusterId)
+ }
+ ))
+}
+
+class WithNMedCores(
+ n: Int,
+ crossing: RocketCrossingParams = RocketCrossingParams(),
+) extends Config((site, here, up) => {
+ case TilesLocated(InSubsystem) => {
+ val prev = up(TilesLocated(InSubsystem), site)
+ val idOffset = up(NumTiles)
+ val med = RocketTileParams(
+ core = RocketCoreParams(fpu = None),
+ btb = None,
+ dcache = Some(DCacheParams(
+ rowBits = site(SystemBusKey).beatBits,
+ nSets = 64,
+ nWays = 1,
+ nTLBSets = 1,
+ nTLBWays = 4,
+ nMSHRs = 0,
+ blockBytes = site(CacheBlockBytes))),
+ icache = Some(ICacheParams(
+ rowBits = site(SystemBusKey).beatBits,
+ nSets = 64,
+ nWays = 1,
+ nTLBSets = 1,
+ nTLBWays = 4,
+ blockBytes = site(CacheBlockBytes))))
+ List.tabulate(n)(i => RocketTileAttachParams(
+ med.copy(tileId = i + idOffset),
+ crossing
+ )) ++ prev
+ }
+ case NumTiles => up(NumTiles) + n
+})
+
+class WithNSmallCores(
+ n: Int,
+ crossing: RocketCrossingParams = RocketCrossingParams()
+) extends Config((site, here, up) => {
+ case TilesLocated(InSubsystem) => {
+ val prev = up(TilesLocated(InSubsystem), site)
+ val idOffset = up(NumTiles)
+ val small = RocketTileParams(
+ core = RocketCoreParams(useVM = false, fpu = None),
+ btb = None,
+ dcache = Some(DCacheParams(
+ rowBits = site(SystemBusKey).beatBits,
+ nSets = 64,
+ nWays = 1,
+ nTLBSets = 1,
+ nTLBWays = 4,
+ nMSHRs = 0,
+ blockBytes = site(CacheBlockBytes))),
+ icache = Some(ICacheParams(
+ rowBits = site(SystemBusKey).beatBits,
+ nSets = 64,
+ nWays = 1,
+ nTLBSets = 1,
+ nTLBWays = 4,
+ blockBytes = site(CacheBlockBytes))))
+ List.tabulate(n)(i => RocketTileAttachParams(
+ small.copy(tileId = i + idOffset),
+ crossing
+ )) ++ prev
+ }
+ case NumTiles => up(NumTiles) + n
+})
+
+class With1TinyCore extends Config((site, here, up) => {
+ case TilesLocated(InSubsystem) => {
+ val tiny = RocketTileParams(
+ core = RocketCoreParams(
+ xLen = 32,
+ pgLevels = 2, // sv32
+ useVM = false,
+ fpu = None,
+ mulDiv = Some(MulDivParams(mulUnroll = 8))),
+ btb = None,
+ dcache = Some(DCacheParams(
+ rowBits = site(SystemBusKey).beatBits,
+ nSets = 256, // 16Kb scratchpad
+ nWays = 1,
+ nTLBSets = 1,
+ nTLBWays = 4,
+ nMSHRs = 0,
+ blockBytes = site(CacheBlockBytes),
+ scratch = Some(0x80000000L))),
+ icache = Some(ICacheParams(
+ rowBits = site(SystemBusKey).beatBits,
+ nSets = 64,
+ nWays = 1,
+ nTLBSets = 1,
+ nTLBWays = 4,
+ blockBytes = site(CacheBlockBytes)))
+ )
+ List(RocketTileAttachParams(
+ tiny,
+ RocketCrossingParams(
+ crossingType = SynchronousCrossing(),
+ master = HierarchicalElementMasterPortParams())
+ ))
+ }
+ case NumTiles => 1
+ case ClustersLocated(_) => Nil
+})
+
+class RocketTileAttachConfig(f: RocketTileAttachParams => RocketTileAttachParams) extends TileAttachConfig[RocketTileAttachParams](f)
+
+class RocketTileConfig(f: RocketTileParams => RocketTileParams) extends RocketTileAttachConfig(tp => tp.copy(
+ tileParams = f(tp.tileParams)
+))
+
+class RocketCrossingConfig(f: RocketCrossingParams => RocketCrossingParams) extends RocketTileAttachConfig(tp => tp.copy(
+ crossingParams = f(tp.crossingParams)
+))
+
+class RocketCoreConfig(f: RocketCoreParams => RocketCoreParams) extends RocketTileConfig(tp => tp.copy(
+ core = f(tp.core)
+))
+
+class RocketICacheConfig(f: ICacheParams => ICacheParams) extends RocketTileConfig(tp => tp.copy(
+ icache = tp.icache.map(ic => f(ic))
+))
+
+class RocketDCacheConfig(f: DCacheParams => DCacheParams) extends RocketTileConfig(tp => tp.copy(
+ dcache = tp.dcache.map(dc => f(dc))
+))
+
+class WithL1ICacheSets(sets: Int) extends RocketICacheConfig(_.copy(nSets=sets))
+class WithL1ICacheWays(ways: Int) extends RocketICacheConfig(_.copy(nWays=ways))
+class WithL1ICacheECC(dataECC: String, tagECC: String) extends RocketICacheConfig(_.copy(dataECC = Some(dataECC), tagECC = Some(tagECC)))
+class WithL1ICacheRowBits(n: Int) extends RocketICacheConfig(_.copy(rowBits = n))
+class WithL1ICacheTLBSets(sets: Int) extends RocketICacheConfig(_.copy(nTLBSets = sets))
+class WithL1ICacheTLBWays(ways: Int) extends RocketICacheConfig(_.copy(nTLBWays = ways))
+class WithL1ICacheTLBBasePageSectors(sectors: Int) extends RocketICacheConfig(_.copy(nTLBBasePageSectors = sectors))
+class WithL1ICacheTLBSuperpages(superpages: Int) extends RocketICacheConfig(_.copy(nTLBSuperpages = superpages))
+class WithL1ICacheBlockBytes(bytes: Int = 64) extends RocketICacheConfig(_.copy(blockBytes = bytes))
+
+class WithL1DCacheSets(sets: Int) extends RocketDCacheConfig(_.copy(nSets=sets))
+class WithL1DCacheWays(ways: Int) extends RocketDCacheConfig(_.copy(nWays=ways))
+class WithL1DCacheECC(dataECC: String, tagECC: String) extends RocketDCacheConfig(_.copy(dataECC = Some(dataECC), tagECC = Some(tagECC)))
+class WithL1DCacheRowBits(n: Int) extends RocketDCacheConfig(_.copy(rowBits = n))
+class WithL1DCacheTLBSets(sets: Int) extends RocketDCacheConfig(_.copy(nTLBSets = sets))
+class WithL1DCacheTLBWays(ways: Int) extends RocketDCacheConfig(_.copy(nTLBWays = ways))
+class WithL1DCacheTLBBasePageSectors(sectors: Int) extends RocketDCacheConfig(_.copy(nTLBBasePageSectors = sectors))
+class WithL1DCacheTLBSuperpages(superpages: Int) extends RocketDCacheConfig(_.copy(nTLBSuperpages = superpages))
+class WithL1DCacheBlockBytes(bytes: Int = 64) extends RocketDCacheConfig(_.copy(blockBytes = bytes))
+class WithL1DCacheNonblocking(nMSHRs: Int) extends RocketDCacheConfig(_.copy(nMSHRs = nMSHRs))
+class WithL1DCacheClockGating extends RocketDCacheConfig(_.copy(clockGate = true))
+class WithL1DCacheDTIMAddress(address: BigInt) extends RocketDCacheConfig(_.copy(scratch = Some(address)))
+
+class WithScratchpadsOnly extends RocketTileConfig(tp => tp.copy(
+ core = tp.core.copy(useVM = false),
+ dcache = tp.dcache.map(_.copy(
+ nSets = 256, // 16Kb scratchpad
+ nWays = 1,
+ scratch = Some(0x80000000L)))
+))
+
+class WithCacheRowBits(n: Int) extends RocketTileConfig(tp => tp.copy(
+ dcache = tp.dcache.map(_.copy(rowBits = n)),
+ icache = tp.icache.map(_.copy(rowBits = n))
+))
+
+class WithBEU(addr: BigInt) extends RocketTileConfig(_.copy(beuAddr = Some(addr)))
+class WithBoundaryBuffers(buffers: Option[RocketTileBoundaryBufferParams] = Some(RocketTileBoundaryBufferParams(true))) extends RocketTileConfig(_.copy(boundaryBuffers = buffers))
+
+class WithRV32 extends RocketCoreConfig(c => c.copy(
+ xLen = 32,
+ pgLevels = 2, // sv32
+ fpu = c.fpu.map(_.copy(fLen = 32)),
+ mulDiv = Some(MulDivParams(mulUnroll = 8))
+))
+
+class WithoutVM extends RocketCoreConfig(_.copy(useVM = false))
+class WithCFlushEnabled extends RocketCoreConfig(_.copy(haveCFlush = true))
+class WithNBreakpoints(hwbp: Int) extends RocketCoreConfig(_.copy(nBreakpoints = hwbp))
+class WithHypervisor(hext: Boolean = true) extends RocketCoreConfig(_.copy(useHypervisor = hext))
+class WithCease(enable: Boolean = true) extends RocketCoreConfig(_.copy(haveCease = enable))
+class WithCoreClockGatingEnabled extends RocketCoreConfig(_.copy(clockGate = true))
+class WithPgLevels(n: Int) extends RocketCoreConfig(_.copy(pgLevels = n))
+class WithZba extends RocketCoreConfig(_.copy(useZba = true))
+class WithZbb extends RocketCoreConfig(_.copy(useZbb = true))
+class WithZbs extends RocketCoreConfig(_.copy(useZbs = true))
+class WithB extends RocketCoreConfig(_.copy(useZba = true, useZbb = true, useZbs = true))
+class WithSV48 extends WithPgLevels(4)
+class WithSV39 extends WithPgLevels(3)
+
+// Simulation-only configs
+class WithNoSimulationTimeout extends RocketCoreConfig(_.copy(haveSimTimeout = false))
+class WithDebugROB(enable: Boolean = true, size: Int = 0) extends RocketCoreConfig(_.copy(debugROB = Option.when(enable)(DebugROBParams(size))))
+
+// FPU configs
+class WithoutFPU extends RocketCoreConfig(_.copy(fpu = None))
+class WithFP16 extends RocketCoreConfig(c => c.copy(fpu = c.fpu.map(_.copy(minFLen = 16))))
+class WithFPUWithoutDivSqrt extends RocketCoreConfig(c => c.copy(fpu = c.fpu.map(_.copy(divSqrt = false))))
+
+// mul-div configs
+class WithFastMulDiv extends RocketCoreConfig(c => c.copy(mulDiv = Some(
+ MulDivParams(mulUnroll = 8, mulEarlyOut = c.xLen > 32, divEarlyOut = true)
+)))
+class WithCustomFastMulDiv(mUnroll: Int = 8, mEarlyOut: Boolean = true, dUnroll: Int = 1, dEarlyOut: Boolean = true, dEarlyOutGranularity: Int = 1) extends RocketCoreConfig(_.copy(mulDiv = Some(
+ MulDivParams(mulUnroll = mUnroll, mulEarlyOut = mEarlyOut, divUnroll = dUnroll, divEarlyOut = dEarlyOut, divEarlyOutGranularity = dEarlyOutGranularity)
+)))
+class WithoutMulDiv extends RocketCoreConfig(_.copy(mulDiv = None))
+
+// Branch-prediction configs
+class WithDefaultBtb extends RocketTileConfig(t => t.copy(btb = Some(BTBParams())))
+class WithNoBtb extends RocketTileConfig(_.copy(btb = None))
+
+// Tile CDC configs
+class WithCDC(crossingType: ClockCrossingType = SynchronousCrossing()) extends RocketCrossingConfig(_.copy(crossingType = crossingType))
+class WithSeperateClockReset extends RocketCrossingConfig(_.copy(forceSeparateClockReset = true))
+class WithSynchronousCDCs extends WithCDC(SynchronousCrossing())
+class WithAsynchronousCDCs(depth: Int, sync: Int) extends WithCDC(AsynchronousCrossing(depth, sync))
+class WithRationalCDCs extends WithCDC(RationalCrossing())
+
+
+
+class WithCloneRocketTiles(
+ n: Int = 1,
+ cloneTileId: Int = 0,
+ location: HierarchicalLocation = InSubsystem,
+ cloneLocation: HierarchicalLocation = InSubsystem
+) extends Config((site, here, up) => {
+ case TilesLocated(`location`) => {
+ val prev = up(TilesLocated(location), site)
+ val idOffset = up(NumTiles)
+ val tileAttachParams = up(TilesLocated(cloneLocation)).find(_.tileParams.tileId == cloneTileId)
+ .get.asInstanceOf[RocketTileAttachParams]
+ (0 until n).map { i =>
+ CloneTileAttachParams(cloneTileId, tileAttachParams.copy(
+ tileParams = tileAttachParams.tileParams.copy(tileId = i + idOffset)
+ ))
+ } ++ prev
+ }
+ case NumTiles => up(NumTiles) + n
+})
+
diff --git a/src/main/scala/rocket/Consts.scala b/src/main/scala/rocket/Consts.scala
index 66e45f733ba..10f5201a365 100644
--- a/src/main/scala/rocket/Consts.scala
+++ b/src/main/scala/rocket/Consts.scala
@@ -22,6 +22,7 @@ trait ScalarOpConstants {
def A1_ZERO = 0.U(2.W)
def A1_RS1 = 1.U(2.W)
def A1_PC = 2.U(2.W)
+ def A1_RS1SHL = 3.U(2.W)
def IMM_X = BitPat("b???")
def IMM_S = 0.U(3.W)
@@ -31,11 +32,14 @@ trait ScalarOpConstants {
def IMM_I = 4.U(3.W)
def IMM_Z = 5.U(3.W)
- def A2_X = BitPat("b??")
- def A2_ZERO = 0.U(2.W)
- def A2_SIZE = 1.U(2.W)
- def A2_RS2 = 2.U(2.W)
- def A2_IMM = 3.U(2.W)
+ def A2_X = BitPat("b???")
+ def A2_ZERO = 0.U(3.W)
+ def A2_SIZE = 1.U(3.W)
+ def A2_RS2 = 2.U(3.W)
+ def A2_IMM = 3.U(3.W)
+ def A2_RS2OH = 4.U(3.W)
+ def A2_IMMOH = 5.U(3.W)
+
def X = BitPat("b?")
def N = BitPat("b0")
diff --git a/src/main/scala/rocket/DCache.scala b/src/main/scala/rocket/DCache.scala
index 308392acad1..edbd7328277 100644
--- a/src/main/scala/rocket/DCache.scala
+++ b/src/main/scala/rocket/DCache.scala
@@ -4,16 +4,24 @@ package freechips.rocketchip.rocket
import chisel3._
import chisel3.util._
-import freechips.rocketchip.amba._
-import org.chipsalliance.cde.config.Parameters
-import freechips.rocketchip.diplomacy._
-import freechips.rocketchip.tile.{CoreBundle, LookupByHartId}
-import freechips.rocketchip.tilelink._
-import freechips.rocketchip.util._
-import freechips.rocketchip.util.property
-import chisel3.{DontCare, WireInit, dontTouch, withClock}
import chisel3.experimental.SourceInfo
-import TLMessages._
+
+import org.chipsalliance.cde.config._
+
+import freechips.rocketchip.amba.AMBAProt
+import freechips.rocketchip.diplomacy.{BufferParams}
+import freechips.rocketchip.prci.{ClockCrossingType, RationalCrossing, SynchronousCrossing, AsynchronousCrossing, CreditedCrossing}
+import freechips.rocketchip.tile.{CoreBundle, LookupByHartId}
+import freechips.rocketchip.tilelink.{TLFIFOFixer,ClientMetadata, TLBundleA, TLAtomics, TLBundleB, TLPermissions}
+import freechips.rocketchip.tilelink.TLMessages.{AccessAck, HintAck, AccessAckData, Grant, GrantData, ReleaseAck}
+import freechips.rocketchip.util.{CanHaveErrors, ClockGate, IdentityCode, ReplacementPolicy, DescribedSRAM, property}
+
+import freechips.rocketchip.util.BooleanToAugmentedBoolean
+import freechips.rocketchip.util.UIntToAugmentedUInt
+import freechips.rocketchip.util.UIntIsOneOf
+import freechips.rocketchip.util.IntToAugmentedInt
+import freechips.rocketchip.util.SeqToAugmentedSeq
+import freechips.rocketchip.util.SeqBoolBitwiseOps
// TODO: delete this trait once deduplication is smart enough to avoid globally inlining matching circuits
trait InlineInstance { self: chisel3.experimental.BaseModule =>
@@ -52,7 +60,7 @@ class DCacheDataArray(implicit p: Parameters) extends L1HellaCacheModule()(p) {
val data_arrays = Seq.tabulate(rowBits / subWordBits) {
i =>
DescribedSRAM(
- name = s"data_arrays_${i}",
+ name = s"${tileParams.baseName}_dcache_data_arrays_${i}",
desc = "DCache Data Array",
size = nSets * cacheBlockBytes / rowBytes,
data = Vec(nWays * (subWordBits / eccBits), UInt(encBits.W))
@@ -86,13 +94,11 @@ class DCache(staticIdForMetadataUseOnly: Int, val crossing: ClockCrossingType)(i
class DCacheTLBPort(implicit p: Parameters) extends CoreBundle()(p) {
val req = Flipped(Decoupled(new TLBReq(coreDataBytes.log2)))
- val s1_resp = Output(new TLBResp)
+ val s1_resp = Output(new TLBResp(coreDataBytes.log2))
val s2_kill = Input(Bool())
}
class DCacheModule(outer: DCache) extends HellaCacheModule(outer) {
- val tlb_port = IO(new DCacheTLBPort)
-
val tECC = cacheParams.tagCode
val dECC = cacheParams.dataCode
require(subWordBits % eccBits == 0, "subWordBits must be a multiple of eccBits")
@@ -115,10 +121,21 @@ class DCacheModule(outer: DCache) extends HellaCacheModule(outer) {
// tags
val replacer = ReplacementPolicy.fromString(cacheParams.replacementPolicy, nWays)
+
+ /** Metadata Arbiter:
+ * 0: Tag update on reset
+ * 1: Tag update on ECC error
+ * 2: Tag update on hit
+ * 3: Tag update on refill
+ * 4: Tag update on release
+ * 5: Tag update on flush
+ * 6: Tag update on probe
+ * 7: Tag update on CPU request
+ */
val metaArb = Module(new Arbiter(new DCacheMetadataReq, 8) with InlineInstance)
val tag_array = DescribedSRAM(
- name = "tag_array",
+ name = s"${tileParams.baseName}_dcache_tag_array",
desc = "DCache Tag Array",
size = nSets,
data = Vec(nWays, chiselTypeOf(metaArb.io.out.bits.data))
@@ -126,6 +143,12 @@ class DCacheModule(outer: DCache) extends HellaCacheModule(outer) {
// data
val data = Module(new DCacheDataArray)
+ /** Data Arbiter
+ * 0: data from pending store buffer
+ * 1: data from TL-D refill
+ * 2: release to TL-A
+ * 3: hit path to CPU
+ */
val dataArb = Module(new Arbiter(new DCacheDataReq, 4) with InlineInstance)
dataArb.io.in.tail.foreach(_.bits.wdata := dataArb.io.in.head.bits.wdata) // tie off write ports by default
data.io.req.bits <> dataArb.io.out.bits
@@ -162,7 +185,7 @@ class DCacheModule(outer: DCache) extends HellaCacheModule(outer) {
val s1_nack = WireDefault(false.B)
val s1_valid_masked = s1_valid && !io.cpu.s1_kill
val s1_valid_not_nacked = s1_valid && !s1_nack
- val s1_tlb_req_valid = RegNext(tlb_port.req.fire, false.B)
+ val s1_tlb_req_valid = RegNext(io.tlb_port.req.fire, false.B)
val s2_tlb_req_valid = RegNext(s1_tlb_req_valid, false.B)
val s0_clk_en = metaArb.io.out.valid && !metaArb.io.out.bits.write
@@ -173,8 +196,8 @@ class DCacheModule(outer: DCache) extends HellaCacheModule(outer) {
val s1_req = RegEnable(s0_req, s0_clk_en)
val s1_vaddr = Cat(s1_req.idx.getOrElse(s1_req.addr) >> tagLSB, s1_req.addr(tagLSB-1, 0))
- val s0_tlb_req = WireInit(tlb_port.req.bits)
- when (!tlb_port.req.fire) {
+ val s0_tlb_req = WireInit(io.tlb_port.req.bits)
+ when (!io.tlb_port.req.fire) {
s0_tlb_req.passthrough := s0_req.phys
s0_tlb_req.vaddr := s0_req.addr
s0_tlb_req.size := s0_req.size
@@ -182,7 +205,7 @@ class DCacheModule(outer: DCache) extends HellaCacheModule(outer) {
s0_tlb_req.prv := s0_req.dprv
s0_tlb_req.v := s0_req.dv
}
- val s1_tlb_req = RegEnable(s0_tlb_req, s0_clk_en || tlb_port.req.valid)
+ val s1_tlb_req = RegEnable(s0_tlb_req, s0_clk_en || io.tlb_port.req.valid)
val s1_read = isRead(s1_req.cmd)
val s1_write = isWrite(s1_req.cmd)
@@ -246,7 +269,7 @@ class DCacheModule(outer: DCache) extends HellaCacheModule(outer) {
// address translation
val s1_cmd_uses_tlb = s1_readwrite || s1_flush_line || s1_req.cmd === M_WOK
io.ptw <> tlb.io.ptw
- tlb.io.kill := io.cpu.s2_kill || s2_tlb_req_valid && tlb_port.s2_kill
+ tlb.io.kill := io.cpu.s2_kill || s2_tlb_req_valid && io.tlb_port.s2_kill
tlb.io.req.valid := s1_tlb_req_valid || s1_valid && !io.cpu.s1_kill && s1_cmd_uses_tlb
tlb.io.req.bits := s1_tlb_req
when (!tlb.io.req.ready && !tlb.io.ptw.resp.valid && !io.cpu.req.bits.phys) { io.cpu.req.ready := false.B }
@@ -260,8 +283,8 @@ class DCacheModule(outer: DCache) extends HellaCacheModule(outer) {
tlb.io.sfence.bits.hv := s1_req.cmd === M_HFENCEV
tlb.io.sfence.bits.hg := s1_req.cmd === M_HFENCEG
- tlb_port.req.ready := clock_en_reg
- tlb_port.s1_resp := tlb.io.resp
+ io.tlb_port.req.ready := clock_en_reg
+ io.tlb_port.s1_resp := tlb.io.resp
when (s1_tlb_req_valid && s1_valid && !(s1_req.phys && s1_req.no_xcpt)) { s1_nack := true.B }
pma_checker.io <> DontCare
@@ -561,7 +584,7 @@ class DCacheModule(outer: DCache) extends HellaCacheModule(outer) {
val put = edge.Put(a_source, access_address, a_size, a_data)._2
val putpartial = edge.Put(a_source, access_address, a_size, a_data, a_mask)._2
val atomics = if (edge.manager.anySupportLogical) {
- MuxLookup(s2_req.cmd, WireDefault(0.U.asTypeOf(new TLBundleA(edge.bundle))), Array(
+ MuxLookup(s2_req.cmd, WireDefault(0.U.asTypeOf(new TLBundleA(edge.bundle))))(Array(
M_XA_SWAP -> edge.Logical(a_source, access_address, a_size, a_data, TLAtomics.SWAP)._2,
M_XA_XOR -> edge.Logical(a_source, access_address, a_size, a_data, TLAtomics.XOR) ._2,
M_XA_OR -> edge.Logical(a_source, access_address, a_size, a_data, TLAtomics.OR) ._2,
@@ -904,6 +927,7 @@ class DCacheModule(outer: DCache) extends HellaCacheModule(outer) {
val s1_isSlavePortAccess = s1_req.no_xcpt
val s2_isSlavePortAccess = s2_req.no_xcpt
io.cpu.ordered := !(s1_valid && !s1_isSlavePortAccess || s2_valid && !s2_isSlavePortAccess || cached_grant_wait || uncachedInFlight.asUInt.orR)
+ io.cpu.store_pending := (cached_grant_wait && isWrite(s2_req.cmd)) || uncachedInFlight.asUInt.orR
val s1_xcpt_valid = tlb.io.req.valid && !s1_isSlavePortAccess && !s1_nack
io.cpu.s2_xcpt := Mux(RegNext(s1_xcpt_valid), s2_tlb_xcpt, 0.U.asTypeOf(s2_tlb_xcpt))
@@ -1039,7 +1063,7 @@ class DCacheModule(outer: DCache) extends HellaCacheModule(outer) {
metaArb.io.out.valid || // subsumes resetting || flushing
s1_probe || s2_probe ||
s1_valid || s2_valid ||
- tlb_port.req.valid ||
+ io.tlb_port.req.valid ||
s1_tlb_req_valid || s2_tlb_req_valid ||
pstore1_held || pstore2_valid ||
release_state =/= s_ready ||
diff --git a/src/main/scala/rocket/DebugROB.scala b/src/main/scala/rocket/DebugROB.scala
index 1740b8c073a..39dec03a78c 100644
--- a/src/main/scala/rocket/DebugROB.scala
+++ b/src/main/scala/rocket/DebugROB.scala
@@ -8,7 +8,9 @@ import chisel3.util._
import chisel3.experimental.{IntParam}
import org.chipsalliance.cde.config.{Parameters}
import freechips.rocketchip.tile.{HasCoreParameters}
+import freechips.rocketchip.util.DecoupledHelper
+case class DebugROBParams(size: Int)
class WidenedTracedInstruction extends Bundle {
val valid = Bool()
@@ -27,7 +29,6 @@ class WidenedTracedInstruction extends Bundle {
// These is not synthesizable, they use a C++ blackbox to implement the
// write-back reordering
class DebugROBPushTrace(implicit val p: Parameters) extends BlackBox with HasBlackBoxResource with HasCoreParameters {
- require(traceHasWdata && (vLen max xLen) <= 512)
val io = IO(new Bundle {
val clock = Input(Clock())
val reset = Input(Bool())
@@ -43,7 +44,6 @@ class DebugROBPushTrace(implicit val p: Parameters) extends BlackBox with HasBla
class DebugROBPushWb(implicit val p: Parameters) extends BlackBox
with HasBlackBoxResource with HasCoreParameters {
- require(traceHasWdata && (vLen max xLen) <= 512)
val io = IO(new Bundle {
val clock = Input(Clock())
val reset = Input(Bool())
@@ -57,7 +57,6 @@ class DebugROBPushWb(implicit val p: Parameters) extends BlackBox
}
class DebugROBPopTrace(implicit val p: Parameters) extends BlackBox with HasBlackBoxResource with HasCoreParameters {
- require(traceHasWdata && (vLen max xLen) <= 512)
val io = IO(new Bundle {
val clock = Input(Clock())
val reset = Input(Bool())
@@ -102,3 +101,92 @@ object DebugROB {
debug_rob_push_wb.io.wb_data := data
}
}
+
+class TaggedInstruction(val nXPR: Int)(implicit val p: Parameters) extends Bundle {
+ val insn = new TracedInstruction
+ val tag = UInt(log2Up(nXPR + 1).W)
+ val waiting = Bool()
+}
+
+class TaggedWbData(implicit val p: Parameters) extends Bundle with HasCoreParameters {
+ val valid = Bool()
+ val data = UInt(xLen.W)
+}
+
+class HardDebugROB(val traceRatio: Int, val nXPR: Int)(implicit val p: Parameters)
+ extends Module with HasCoreParameters
+{
+ val io = IO(new Bundle {
+ val i_insn = Input(new TracedInstruction)
+ val should_wb = Input(Bool())
+ val has_wb = Input(Bool())
+ val tag = Input(UInt(log2Up(nXPR + 1).W))
+
+ val wb_val = Input(Bool())
+ val wb_tag = Input(UInt(log2Up(nXPR + 1).W))
+ val wb_data = Input(UInt(xLen.W))
+
+ val o_insn = Output(new TracedInstruction)
+ })
+
+ val iq = Module(new Queue(new TaggedInstruction(nXPR), traceRatio * nXPR, flow = true))
+
+ // No backpressure
+ assert(iq.io.enq.ready)
+
+ iq.io.enq.valid := io.i_insn.valid || io.i_insn.exception || io.i_insn.interrupt
+ iq.io.enq.bits.insn := io.i_insn
+ iq.io.enq.bits.tag := io.tag
+ iq.io.enq.bits.waiting := io.should_wb && !io.has_wb
+
+ val wb_q = Seq.fill(nXPR)(Reg(new TaggedWbData))
+
+ for (i <- 0 until nXPR) {
+ when (io.wb_val && i.U === io.wb_tag) {
+ assert(wb_q(i).valid === false.B)
+ wb_q(i).valid := true.B
+ wb_q(i).data := io.wb_data
+ }
+ }
+
+ val tag_matches = Seq.fill(nXPR)(Wire(Bool()))
+ for (i <- 0 until nXPR) {
+ val is_match = iq.io.deq.bits.waiting &&
+ (iq.io.deq.bits.tag === i.U) &&
+ wb_q(i).valid
+ when (is_match) {
+ tag_matches(i) := true.B
+ } .otherwise {
+ tag_matches(i) := false.B
+ }
+ }
+
+ val tag_match = tag_matches.reduce(_ || _)
+ val vinsn_rdy = !iq.io.deq.bits.waiting ||
+ (iq.io.deq.bits.tag >= nXPR.U) || // not integer instruction
+ tag_match
+ val maybeFire = Mux(iq.io.deq.bits.insn.valid, vinsn_rdy, true.B)
+ val fireTrace = DecoupledHelper(
+ iq.io.deq.valid,
+ maybeFire)
+
+ iq.io.deq.ready := fireTrace.fire(iq.io.deq.valid)
+ io.o_insn := iq.io.deq.bits.insn
+ io.o_insn.valid := iq.io.deq.fire && iq.io.deq.bits.insn.valid
+
+ for (i <- 0 until nXPR) {
+ when (tag_match && fireTrace.fire() && i.U === iq.io.deq.bits.tag) {
+ io.o_insn.wdata.get := wb_q(i).data
+ wb_q(i).valid := false.B
+ }
+ }
+
+ val qcnt = RegInit(0.U(64.W))
+ when (iq.io.enq.fire && !iq.io.deq.fire) {
+ qcnt := qcnt + 1.U
+ } .elsewhen (!iq.io.enq.fire && iq.io.deq.fire) {
+ qcnt := qcnt - 1.U
+ } .otherwise {
+ qcnt := qcnt
+ }
+}
diff --git a/src/main/scala/rocket/Frontend.scala b/src/main/scala/rocket/Frontend.scala
index f6c0ad52b68..8156e51c475 100644
--- a/src/main/scala/rocket/Frontend.scala
+++ b/src/main/scala/rocket/Frontend.scala
@@ -5,14 +5,17 @@ package freechips.rocketchip.rocket
import chisel3._
import chisel3.util._
-import chisel3.{withClock,withReset}
import chisel3.experimental.SourceInfo
+
import org.chipsalliance.cde.config._
-import freechips.rocketchip.diplomacy._
-import freechips.rocketchip.tile._
-import freechips.rocketchip.tilelink.{TLWidthWidget}
-import freechips.rocketchip.util._
-import freechips.rocketchip.util.property
+import org.chipsalliance.diplomacy.bundlebridge._
+import org.chipsalliance.diplomacy.lazymodule._
+
+import freechips.rocketchip.tile.{CoreBundle, BaseTile}
+import freechips.rocketchip.tilelink.{TLWidthWidget, TLEdgeOut}
+import freechips.rocketchip.util.{ClockGate, ShiftQueue, property}
+
+import freechips.rocketchip.util.UIntToAugmentedUInt
class FrontendReq(implicit p: Parameters) extends CoreBundle()(p) {
val pc = UInt(vaddrBitsExtended.W)
@@ -52,6 +55,7 @@ class FrontendIO(implicit p: Parameters) extends CoreBundle()(p) {
val sfence = Valid(new SFenceReq)
val resp = Flipped(Decoupled(new FrontendResp))
val gpa = Flipped(Valid(UInt(vaddrBitsExtended.W)))
+ val gpa_is_pte = Input(Bool())
val btb_update = Valid(new BTBUpdate)
val bht_update = Valid(new BHTUpdate)
val ras_update = Valid(new RASUpdate)
@@ -61,9 +65,9 @@ class FrontendIO(implicit p: Parameters) extends CoreBundle()(p) {
val progress = Output(Bool())
}
-class Frontend(val icacheParams: ICacheParams, staticIdForMetadataUseOnly: Int)(implicit p: Parameters) extends LazyModule {
+class Frontend(val icacheParams: ICacheParams, tileId: Int)(implicit p: Parameters) extends LazyModule {
lazy val module = new FrontendModule(this)
- val icache = LazyModule(new ICache(icacheParams, staticIdForMetadataUseOnly))
+ val icache = LazyModule(new ICache(icacheParams, tileId))
val masterNode = icache.masterNode
val slaveNode = icache.slaveNode
val resetVectorSinkNode = BundleBridgeSink[UInt](Some(() => UInt(masterNode.edges.out.head.bundle.addressBits.W)))
@@ -80,7 +84,7 @@ class FrontendModule(outer: Frontend) extends LazyModuleImp(outer)
with HasL1ICacheParameters {
val io = IO(new FrontendBundle(outer))
val io_reset_vector = outer.resetVectorSinkNode.bundle
- implicit val edge = outer.masterNode.edges.out(0)
+ implicit val edge: TLEdgeOut = outer.masterNode.edges.out(0)
val icache = outer.icache.module
require(fetchWidth*coreInstBytes == outer.icacheParams.fetchBytes)
@@ -240,7 +244,7 @@ class FrontendModule(outer: Frontend) extends LazyModuleImp(outer)
val rvcBranch = bits === Instructions.C_BEQZ || bits === Instructions.C_BNEZ
val rvcJAL = (xLen == 32).B && bits === Instructions32.C_JAL
val rvcJump = bits === Instructions.C_J || rvcJAL
- val rvcImm = Mux(bits(14), new RVCDecoder(bits, xLen).bImm.asSInt, new RVCDecoder(bits, xLen).jImm.asSInt)
+ val rvcImm = Mux(bits(14), new RVCDecoder(bits, xLen, fLen).bImm.asSInt, new RVCDecoder(bits, xLen, fLen).jImm.asSInt)
val rvcJR = bits === Instructions.C_MV && bits(6,2) === 0.U
val rvcReturn = rvcJR && BitPat("b00?01") === bits(11,7)
val rvcJALR = bits === Instructions.C_ADD && bits(6,2) === 0.U
@@ -348,9 +352,11 @@ class FrontendModule(outer: Frontend) extends LazyModuleImp(outer)
// supply guest physical address to commit stage
val gpa_valid = Reg(Bool())
val gpa = Reg(UInt(vaddrBitsExtended.W))
+ val gpa_is_pte = Reg(Bool())
when (fq.io.enq.fire && s2_tlb_resp.gf.inst) {
when (!gpa_valid) {
gpa := s2_tlb_resp.gpa
+ gpa_is_pte := s2_tlb_resp.gpa_is_pte
}
gpa_valid := true.B
}
@@ -359,6 +365,7 @@ class FrontendModule(outer: Frontend) extends LazyModuleImp(outer)
}
io.cpu.gpa.valid := gpa_valid
io.cpu.gpa.bits := gpa
+ io.cpu.gpa_is_pte := gpa_is_pte
// performance events
io.cpu.perf.acquire := icache.io.perf.acquire
@@ -383,7 +390,7 @@ class FrontendModule(outer: Frontend) extends LazyModuleImp(outer)
/** Mix-ins for constructing tiles that have an ICache-based pipeline frontend */
trait HasICacheFrontend extends CanHavePTW { this: BaseTile =>
val module: HasICacheFrontendModule
- val frontend = LazyModule(new Frontend(tileParams.icache.get, staticIdForMetadataUseOnly))
+ val frontend = LazyModule(new Frontend(tileParams.icache.get, tileId))
tlMasterXbar.node := TLWidthWidget(tileParams.icache.get.rowBits/8) := frontend.masterNode
connectTLSlave(frontend.slaveNode, tileParams.core.fetchBytes)
frontend.icache.hartIdSinkNodeOpt.foreach { _ := hartIdNexusNode }
diff --git a/src/main/scala/rocket/HellaCache.scala b/src/main/scala/rocket/HellaCache.scala
index 7360ab89fc0..29333c13fa3 100644
--- a/src/main/scala/rocket/HellaCache.scala
+++ b/src/main/scala/rocket/HellaCache.scala
@@ -3,15 +3,21 @@
package freechips.rocketchip.rocket
-import chisel3._
-import chisel3.util.{isPow2,log2Ceil,log2Up,Decoupled,Valid}
-import chisel3.dontTouch
-import freechips.rocketchip.amba._
-import org.chipsalliance.cde.config.{Parameters, Field}
-import freechips.rocketchip.diplomacy._
-import freechips.rocketchip.tile._
-import freechips.rocketchip.tilelink._
-import freechips.rocketchip.util._
+import chisel3.{dontTouch, _}
+import chisel3.util._
+
+import org.chipsalliance.cde.config._
+import org.chipsalliance.diplomacy.bundlebridge._
+import org.chipsalliance.diplomacy.lazymodule._
+
+import freechips.rocketchip.amba.AMBAProtField
+import freechips.rocketchip.diplomacy.{IdRange, TransferSizes, RegionType}
+import freechips.rocketchip.tile.{L1CacheParams, HasL1CacheParameters, HasCoreParameters, CoreBundle, HasNonDiplomaticTileParameters, BaseTile, HasTileParameters}
+import freechips.rocketchip.tilelink.{TLMasterParameters, TLClientNode, TLMasterPortParameters, TLEdgeOut, TLWidthWidget, TLFIFOFixer, ClientMetadata}
+import freechips.rocketchip.util.{Code, RandomReplacement, ParameterizedBundle}
+
+import freechips.rocketchip.util.{BooleanToAugmentedBoolean, IntToAugmentedInt}
+
import scala.collection.mutable.ListBuffer
case class DCacheParams(
@@ -119,6 +125,7 @@ trait HasCoreData extends HasCoreParameters {
class HellaCacheReqInternal(implicit p: Parameters) extends CoreBundle()(p) with HasCoreMemOp {
val phys = Bool()
+ val no_resp = Bool() // The dcache may omit generating a response for this request
val no_alloc = Bool()
val no_xcpt = Bool()
}
@@ -180,6 +187,7 @@ class HellaCacheIO(implicit p: Parameters) extends CoreBundle()(p) {
val s2_gpa_is_pte = Input(Bool())
val uncached_resp = tileParams.dcache.get.separateUncachedResp.option(Flipped(Decoupled(new HellaCacheResp)))
val ordered = Input(Bool())
+ val store_pending = Input(Bool()) // there is a store in a store buffer somewhere
val perf = Input(new HellaCachePerfEvents())
val keep_clock_enabled = Output(Bool()) // should D$ avoid clock-gating itself?
@@ -188,17 +196,17 @@ class HellaCacheIO(implicit p: Parameters) extends CoreBundle()(p) {
/** Base classes for Diplomatic TL2 HellaCaches */
-abstract class HellaCache(staticIdForMetadataUseOnly: Int)(implicit p: Parameters) extends LazyModule
+abstract class HellaCache(tileId: Int)(implicit p: Parameters) extends LazyModule
with HasNonDiplomaticTileParameters {
protected val cfg = tileParams.dcache.get
protected def cacheClientParameters = cfg.scratch.map(x => Seq()).getOrElse(Seq(TLMasterParameters.v1(
- name = s"Core ${staticIdForMetadataUseOnly} DCache",
+ name = s"Core ${tileId} DCache",
sourceId = IdRange(0, 1 max cfg.nMSHRs),
supportsProbe = TransferSizes(cfg.blockBytes, cfg.blockBytes))))
protected def mmioClientParameters = Seq(TLMasterParameters.v1(
- name = s"Core ${staticIdForMetadataUseOnly} DCache MMIO",
+ name = s"Core ${tileId} DCache MMIO",
sourceId = IdRange(firstMMIO, firstMMIO + cfg.nMMIOs),
requestFifo = true))
@@ -221,17 +229,18 @@ abstract class HellaCache(staticIdForMetadataUseOnly: Int)(implicit p: Parameter
require(!tileParams.core.haveCFlush || cfg.scratch.isEmpty, "CFLUSH_D_L1 instruction requires a D$")
}
-class HellaCacheBundle(val outer: HellaCache)(implicit p: Parameters) extends CoreBundle()(p) {
- val cpu = Flipped((new HellaCacheIO))
+class HellaCacheBundle(implicit p: Parameters) extends CoreBundle()(p) {
+ val cpu = Flipped(new HellaCacheIO)
val ptw = new TLBPTWIO()
val errors = new DCacheErrors
+ val tlb_port = new DCacheTLBPort
}
class HellaCacheModule(outer: HellaCache) extends LazyModuleImp(outer)
with HasL1HellaCacheParameters {
- implicit val edge = outer.node.edges.out(0)
+ implicit val edge: TLEdgeOut = outer.node.edges.out(0)
val (tl_out, _) = outer.node.out(0)
- val io = IO(new HellaCacheBundle(outer))
+ val io = IO(new HellaCacheBundle)
val io_hartid = outer.hartIdSinkNodeOpt.map(_.bundle)
val io_mmio_address_prefix = outer.mmioAddressPrefixSinkNodeOpt.map(_.bundle)
dontTouch(io.cpu.resp) // Users like to monitor these fields even if the core ignores some signals
@@ -254,9 +263,9 @@ case object BuildHellaCache extends Field[BaseTile => Parameters => HellaCache](
object HellaCacheFactory {
def apply(tile: BaseTile)(p: Parameters): HellaCache = {
if (tile.tileParams.dcache.get.nMSHRs == 0)
- new DCache(tile.staticIdForMetadataUseOnly, tile.crossing)(p)
+ new DCache(tile.tileId, tile.crossing)(p)
else
- new NonBlockingDCache(tile.staticIdForMetadataUseOnly)(p)
+ new NonBlockingDCache(tile.tileId)(p)
}
}
@@ -272,10 +281,7 @@ trait HasHellaCache { this: BaseTile =>
dcache.hartIdSinkNodeOpt.map { _ := hartIdNexusNode }
dcache.mmioAddressPrefixSinkNodeOpt.map { _ := mmioAddressPrefixNexusNode }
InModuleBody {
- dcache.module match {
- case module: DCacheModule => module.tlb_port := DontCare
- case other => other
- }
+ dcache.module.io.tlb_port := DontCare
}
}
diff --git a/src/main/scala/rocket/HellaCacheArbiter.scala b/src/main/scala/rocket/HellaCacheArbiter.scala
index 4b9fc08f4cb..cdc287d5043 100644
--- a/src/main/scala/rocket/HellaCacheArbiter.scala
+++ b/src/main/scala/rocket/HellaCacheArbiter.scala
@@ -63,6 +63,7 @@ class HellaCacheArbiter(n: Int)(implicit p: Parameters) extends Module
io.requestor(i).s2_gpa := io.mem.s2_gpa
io.requestor(i).s2_gpa_is_pte := io.mem.s2_gpa_is_pte
io.requestor(i).ordered := io.mem.ordered
+ io.requestor(i).store_pending := io.mem.store_pending
io.requestor(i).perf := io.mem.perf
io.requestor(i).s2_nack := io.mem.s2_nack && s2_id === i.U
io.requestor(i).s2_nack_cause_raw := io.mem.s2_nack_cause_raw
diff --git a/src/main/scala/rocket/ICache.scala b/src/main/scala/rocket/ICache.scala
index 3090ca4f99d..d3bf3c2119f 100644
--- a/src/main/scala/rocket/ICache.scala
+++ b/src/main/scala/rocket/ICache.scala
@@ -3,18 +3,26 @@
package freechips.rocketchip.rocket
-import chisel3._
-import chisel3.util.{Cat, Decoupled, Mux1H, OHToUInt, RegEnable, Valid, isPow2, log2Ceil, log2Up, PopCount}
-import freechips.rocketchip.amba._
-import org.chipsalliance.cde.config.Parameters
-import freechips.rocketchip.diplomacy._
-import freechips.rocketchip.tile._
-import freechips.rocketchip.tilelink._
-import freechips.rocketchip.util.{DescribedSRAM, _}
-import freechips.rocketchip.util.property
-import chisel3.experimental.SourceInfo
-import chisel3.dontTouch
+import chisel3.{dontTouch, _}
+import chisel3.util._
import chisel3.util.random.LFSR
+import chisel3.experimental.SourceInfo
+
+import org.chipsalliance.cde.config._
+import org.chipsalliance.diplomacy.bundlebridge._
+import org.chipsalliance.diplomacy.lazymodule._
+
+import freechips.rocketchip.amba.{AMBAProt, AMBAProtField}
+import freechips.rocketchip.diplomacy.{IdRange, AddressSet, RegionType, TransferSizes}
+import freechips.rocketchip.resources.{SimpleDevice, ResourceBindings, Binding, ResourceAddress, Description, ResourceString, ResourceValue}
+import freechips.rocketchip.tile.{L1CacheParams, HasL1CacheParameters, HasCoreParameters, CoreBundle, TileKey, LookupByHartId}
+import freechips.rocketchip.tilelink.{TLClientNode, TLMasterPortParameters, TLManagerNode, TLSlavePortParameters, TLSlaveParameters, TLMasterParameters, TLHints}
+import freechips.rocketchip.util.{Code, CanHaveErrors, DescribedSRAM, RandomReplacement, Split, IdentityCode, property}
+
+import freechips.rocketchip.util.BooleanToAugmentedBoolean
+import freechips.rocketchip.util.UIntToAugmentedUInt
+import freechips.rocketchip.util.SeqToAugmentedSeq
+import freechips.rocketchip.util.OptionUIntToAugmentedOptionUInt
/** Parameter of [[ICache]].
*
@@ -410,7 +418,7 @@ class ICacheModule(outer: ICache) extends LazyModuleImp(outer)
* content with `refillError ## tag[19:0]` after ECC
* */
val tag_array = DescribedSRAM(
- name = "tag_array",
+ name = s"${tileParams.baseName}_icache_tag_array",
desc = "ICache Tag Array",
size = nSets,
data = Vec(nWays, UInt(tECC.width(1 + tagBits).W))
@@ -497,7 +505,7 @@ class ICacheModule(outer: ICache) extends LazyModuleImp(outer)
// @todo Accessing ITIM correspond address will be able to read cacheline?
// is this desired behavior?
addrInScratchpad(io.s1_paddr) && scratchpadWay(io.s1_paddr) === i.U)
- val s1_vb = vb_array(Cat(i.U, s1_idx)) && !s1_slaveValid
+ val s1_vb = vb_array(Cat(i.U, s1_idx).pad(log2Ceil(nSets*nWays))) && !s1_slaveValid
val enc_tag = tECC.decode(tag_rdata(i))
/** [[tl_error]] ECC error bit.
* [[tag]] of [[tag_array]] access.
@@ -544,7 +552,7 @@ class ICacheModule(outer: ICache) extends LazyModuleImp(outer)
val data_arrays = Seq.tabulate(tl_out.d.bits.data.getWidth / wordBits) {
i =>
DescribedSRAM(
- name = s"data_arrays_${i}",
+ name = s"${tileParams.baseName}_icache_data_arrays_${i}",
desc = "ICache Data Array",
size = nSets * refillCycles,
data = Vec(nWays, UInt(dECC.width(wordBits).W))
diff --git a/src/main/scala/rocket/IDecode.scala b/src/main/scala/rocket/IDecode.scala
index 86ee7eef58a..e61d11dd26a 100644
--- a/src/main/scala/rocket/IDecode.scala
+++ b/src/main/scala/rocket/IDecode.scala
@@ -9,13 +9,14 @@ import org.chipsalliance.cde.config.Parameters
import freechips.rocketchip.util._
import Instructions._
import CustomInstructions._
+import ALU._
abstract trait DecodeConstants
{
val table: Array[(BitPat, List[BitPat])]
}
-class IntCtrlSigs(aluFn: ALUFN = ALUFN())(implicit val p: Parameters) extends Bundle {
+class IntCtrlSigs(implicit val p: Parameters) extends Bundle {
val legal = Bool()
val fp = Bool()
@@ -29,7 +30,7 @@ class IntCtrlSigs(aluFn: ALUFN = ALUFN())(implicit val p: Parameters) extends Bu
val sel_alu1 = Bits(A1_X.getWidth.W)
val sel_imm = Bits(IMM_X.getWidth.W)
val alu_dw = Bool()
- val alu_fn = Bits(aluFn.FN_X.getWidth.W)
+ val alu_fn = Bits(FN_X.getWidth.W)
val mem = Bool()
val mem_cmd = Bits(M_SZ.W)
val rfs1 = Bool()
@@ -44,17 +45,18 @@ class IntCtrlSigs(aluFn: ALUFN = ALUFN())(implicit val p: Parameters) extends Bu
val fence = Bool()
val amo = Bool()
val dp = Bool()
+ val vec = Bool()
def default: List[BitPat] =
- // jal renf1 fence.i
- // val | jalr | renf2 |
- // | fp_val| | renx2 | | renf3 |
- // | | rocc| | | renx1 s_alu1 mem_val | | | wfd |
- // | | | br| | | | s_alu2 | imm dw alu | mem_cmd | | | | mul |
- // | | | | | | | | | | | | | | | | | | | | div | fence
- // | | | | | | | | | | | | | | | | | | | | | wxd | | amo
- // | | | | | | | | | | | | | | | | | | | | | | | | | dp
- List(N,X,X,X,X,X,X,X, A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, X,X,X,X,X,X,X,CSR.X,X,X,X,X)
+ // jal renf1 fence.i
+ // val | jalr | renf2 |
+ // | fp_val| | renx2 | | renf3 |
+ // | | rocc| | | renx1 s_alu1 mem_val | | | wfd |
+ // | | | br| | | | s_alu2 | imm dw alu | mem_cmd | | | | mul |
+ // | | | | | | | | | | | | | | | | | | | | div | fence
+ // | | | | | | | | | | | | | | | | | | | | | wxd | | amo
+ // | | | | | | | | | | | | | | | | | | | | | | | | | dp
+ List(N,X,X,X,X,X,X,X, A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, X,X,X,X,X,X,X,CSR.X,X,X,X,X)
def decode(inst: UInt, table: Iterable[(BitPat, List[BitPat])]) = {
val decoder = DecodeLogic(inst, default, table)
@@ -66,398 +68,486 @@ class IntCtrlSigs(aluFn: ALUFN = ALUFN())(implicit val p: Parameters) extends Bu
}
}
-class IDecode(aluFn: ALUFN = ALUFN())(implicit val p: Parameters) extends DecodeConstants
+class IDecode(implicit val p: Parameters) extends DecodeConstants
{
val table: Array[(BitPat, List[BitPat])] = Array(
- BNE-> List(Y,N,N,Y,N,N,Y,Y,A2_RS2, A1_RS1, IMM_SB,DW_XPR,aluFn.FN_SNE, N,M_X, N,N,N,N,N,N,N,CSR.N,N,N,N,N),
- BEQ-> List(Y,N,N,Y,N,N,Y,Y,A2_RS2, A1_RS1, IMM_SB,DW_XPR,aluFn.FN_SEQ, N,M_X, N,N,N,N,N,N,N,CSR.N,N,N,N,N),
- BLT-> List(Y,N,N,Y,N,N,Y,Y,A2_RS2, A1_RS1, IMM_SB,DW_XPR,aluFn.FN_SLT, N,M_X, N,N,N,N,N,N,N,CSR.N,N,N,N,N),
- BLTU-> List(Y,N,N,Y,N,N,Y,Y,A2_RS2, A1_RS1, IMM_SB,DW_XPR,aluFn.FN_SLTU, N,M_X, N,N,N,N,N,N,N,CSR.N,N,N,N,N),
- BGE-> List(Y,N,N,Y,N,N,Y,Y,A2_RS2, A1_RS1, IMM_SB,DW_XPR,aluFn.FN_SGE, N,M_X, N,N,N,N,N,N,N,CSR.N,N,N,N,N),
- BGEU-> List(Y,N,N,Y,N,N,Y,Y,A2_RS2, A1_RS1, IMM_SB,DW_XPR,aluFn.FN_SGEU, N,M_X, N,N,N,N,N,N,N,CSR.N,N,N,N,N),
-
- JAL-> List(Y,N,N,N,Y,N,N,N,A2_SIZE,A1_PC, IMM_UJ,DW_XPR,aluFn.FN_ADD, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N),
- JALR-> List(Y,N,N,N,N,Y,N,Y,A2_IMM, A1_RS1, IMM_I, DW_XPR,aluFn.FN_ADD, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N),
- AUIPC-> List(Y,N,N,N,N,N,N,N,A2_IMM, A1_PC, IMM_U, DW_XPR,aluFn.FN_ADD, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N),
-
- LB-> List(Y,N,N,N,N,N,N,Y,A2_IMM, A1_RS1, IMM_I, DW_XPR,aluFn.FN_ADD, Y,M_XRD, N,N,N,N,N,N,Y,CSR.N,N,N,N,N),
- LH-> List(Y,N,N,N,N,N,N,Y,A2_IMM, A1_RS1, IMM_I, DW_XPR,aluFn.FN_ADD, Y,M_XRD, N,N,N,N,N,N,Y,CSR.N,N,N,N,N),
- LW-> List(Y,N,N,N,N,N,N,Y,A2_IMM, A1_RS1, IMM_I, DW_XPR,aluFn.FN_ADD, Y,M_XRD, N,N,N,N,N,N,Y,CSR.N,N,N,N,N),
- LBU-> List(Y,N,N,N,N,N,N,Y,A2_IMM, A1_RS1, IMM_I, DW_XPR,aluFn.FN_ADD, Y,M_XRD, N,N,N,N,N,N,Y,CSR.N,N,N,N,N),
- LHU-> List(Y,N,N,N,N,N,N,Y,A2_IMM, A1_RS1, IMM_I, DW_XPR,aluFn.FN_ADD, Y,M_XRD, N,N,N,N,N,N,Y,CSR.N,N,N,N,N),
- SB-> List(Y,N,N,N,N,N,Y,Y,A2_IMM, A1_RS1, IMM_S, DW_XPR,aluFn.FN_ADD, Y,M_XWR, N,N,N,N,N,N,N,CSR.N,N,N,N,N),
- SH-> List(Y,N,N,N,N,N,Y,Y,A2_IMM, A1_RS1, IMM_S, DW_XPR,aluFn.FN_ADD, Y,M_XWR, N,N,N,N,N,N,N,CSR.N,N,N,N,N),
- SW-> List(Y,N,N,N,N,N,Y,Y,A2_IMM, A1_RS1, IMM_S, DW_XPR,aluFn.FN_ADD, Y,M_XWR, N,N,N,N,N,N,N,CSR.N,N,N,N,N),
-
- LUI-> List(Y,N,N,N,N,N,N,N,A2_IMM, A1_ZERO,IMM_U, DW_XPR,aluFn.FN_ADD, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N),
- ADDI-> List(Y,N,N,N,N,N,N,Y,A2_IMM, A1_RS1, IMM_I, DW_XPR,aluFn.FN_ADD, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N),
- SLTI -> List(Y,N,N,N,N,N,N,Y,A2_IMM, A1_RS1, IMM_I, DW_XPR,aluFn.FN_SLT, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N),
- SLTIU-> List(Y,N,N,N,N,N,N,Y,A2_IMM, A1_RS1, IMM_I, DW_XPR,aluFn.FN_SLTU, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N),
- ANDI-> List(Y,N,N,N,N,N,N,Y,A2_IMM, A1_RS1, IMM_I, DW_XPR,aluFn.FN_AND, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N),
- ORI-> List(Y,N,N,N,N,N,N,Y,A2_IMM, A1_RS1, IMM_I, DW_XPR,aluFn.FN_OR, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N),
- XORI-> List(Y,N,N,N,N,N,N,Y,A2_IMM, A1_RS1, IMM_I, DW_XPR,aluFn.FN_XOR, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N),
- ADD-> List(Y,N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_XPR,aluFn.FN_ADD, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N),
- SUB-> List(Y,N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_XPR,aluFn.FN_SUB, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N),
- SLT-> List(Y,N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_XPR,aluFn.FN_SLT, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N),
- SLTU-> List(Y,N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_XPR,aluFn.FN_SLTU, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N),
- AND-> List(Y,N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_XPR,aluFn.FN_AND, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N),
- OR-> List(Y,N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_XPR,aluFn.FN_OR, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N),
- XOR-> List(Y,N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_XPR,aluFn.FN_XOR, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N),
- SLL-> List(Y,N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_XPR,aluFn.FN_SL, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N),
- SRL-> List(Y,N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_XPR,aluFn.FN_SR, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N),
- SRA-> List(Y,N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_XPR,aluFn.FN_SRA, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N),
-
- FENCE-> List(Y,N,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, N,N,N,N,N,N,N,CSR.N,N,Y,N,N),
-
- ECALL-> List(Y,N,N,N,N,N,N,X,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, N,N,N,N,N,N,N,CSR.I,N,N,N,N),
- EBREAK-> List(Y,N,N,N,N,N,N,X,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, N,N,N,N,N,N,N,CSR.I,N,N,N,N),
- MRET-> List(Y,N,N,N,N,N,N,X,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, N,N,N,N,N,N,N,CSR.I,N,N,N,N),
- WFI-> List(Y,N,N,N,N,N,N,X,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, N,N,N,N,N,N,N,CSR.I,N,N,N,N),
- CSRRW-> List(Y,N,N,N,N,N,N,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,aluFn.FN_ADD, N,M_X, N,N,N,N,N,N,Y,CSR.W,N,N,N,N),
- CSRRS-> List(Y,N,N,N,N,N,N,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,aluFn.FN_ADD, N,M_X, N,N,N,N,N,N,Y,CSR.S,N,N,N,N),
- CSRRC-> List(Y,N,N,N,N,N,N,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,aluFn.FN_ADD, N,M_X, N,N,N,N,N,N,Y,CSR.C,N,N,N,N),
- CSRRWI-> List(Y,N,N,N,N,N,N,N,A2_IMM, A1_ZERO,IMM_Z, DW_XPR,aluFn.FN_ADD, N,M_X, N,N,N,N,N,N,Y,CSR.W,N,N,N,N),
- CSRRSI-> List(Y,N,N,N,N,N,N,N,A2_IMM, A1_ZERO,IMM_Z, DW_XPR,aluFn.FN_ADD, N,M_X, N,N,N,N,N,N,Y,CSR.S,N,N,N,N),
- CSRRCI-> List(Y,N,N,N,N,N,N,N,A2_IMM, A1_ZERO,IMM_Z, DW_XPR,aluFn.FN_ADD, N,M_X, N,N,N,N,N,N,Y,CSR.C,N,N,N,N))
+ BNE-> List(Y,N,N,Y,N,N,Y,Y,A2_RS2, A1_RS1, IMM_SB,DW_XPR,FN_SNE, N,M_X, N,N,N,N,N,N,N,CSR.N,N,N,N,N),
+ BEQ-> List(Y,N,N,Y,N,N,Y,Y,A2_RS2, A1_RS1, IMM_SB,DW_XPR,FN_SEQ, N,M_X, N,N,N,N,N,N,N,CSR.N,N,N,N,N),
+ BLT-> List(Y,N,N,Y,N,N,Y,Y,A2_RS2, A1_RS1, IMM_SB,DW_XPR,FN_SLT, N,M_X, N,N,N,N,N,N,N,CSR.N,N,N,N,N),
+ BLTU-> List(Y,N,N,Y,N,N,Y,Y,A2_RS2, A1_RS1, IMM_SB,DW_XPR,FN_SLTU, N,M_X, N,N,N,N,N,N,N,CSR.N,N,N,N,N),
+ BGE-> List(Y,N,N,Y,N,N,Y,Y,A2_RS2, A1_RS1, IMM_SB,DW_XPR,FN_SGE, N,M_X, N,N,N,N,N,N,N,CSR.N,N,N,N,N),
+ BGEU-> List(Y,N,N,Y,N,N,Y,Y,A2_RS2, A1_RS1, IMM_SB,DW_XPR,FN_SGEU, N,M_X, N,N,N,N,N,N,N,CSR.N,N,N,N,N),
+
+ JAL-> List(Y,N,N,N,Y,N,N,N,A2_SIZE,A1_PC, IMM_UJ,DW_XPR,FN_ADD, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N),
+ JALR-> List(Y,N,N,N,N,Y,N,Y,A2_IMM, A1_RS1, IMM_I, DW_XPR,FN_ADD, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N),
+ AUIPC-> List(Y,N,N,N,N,N,N,N,A2_IMM, A1_PC, IMM_U, DW_XPR,FN_ADD, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N),
+
+ LB-> List(Y,N,N,N,N,N,N,Y,A2_IMM, A1_RS1, IMM_I, DW_XPR,FN_ADD, Y,M_XRD, N,N,N,N,N,N,Y,CSR.N,N,N,N,N),
+ LH-> List(Y,N,N,N,N,N,N,Y,A2_IMM, A1_RS1, IMM_I, DW_XPR,FN_ADD, Y,M_XRD, N,N,N,N,N,N,Y,CSR.N,N,N,N,N),
+ LW-> List(Y,N,N,N,N,N,N,Y,A2_IMM, A1_RS1, IMM_I, DW_XPR,FN_ADD, Y,M_XRD, N,N,N,N,N,N,Y,CSR.N,N,N,N,N),
+ LBU-> List(Y,N,N,N,N,N,N,Y,A2_IMM, A1_RS1, IMM_I, DW_XPR,FN_ADD, Y,M_XRD, N,N,N,N,N,N,Y,CSR.N,N,N,N,N),
+ LHU-> List(Y,N,N,N,N,N,N,Y,A2_IMM, A1_RS1, IMM_I, DW_XPR,FN_ADD, Y,M_XRD, N,N,N,N,N,N,Y,CSR.N,N,N,N,N),
+ SB-> List(Y,N,N,N,N,N,Y,Y,A2_IMM, A1_RS1, IMM_S, DW_XPR,FN_ADD, Y,M_XWR, N,N,N,N,N,N,N,CSR.N,N,N,N,N),
+ SH-> List(Y,N,N,N,N,N,Y,Y,A2_IMM, A1_RS1, IMM_S, DW_XPR,FN_ADD, Y,M_XWR, N,N,N,N,N,N,N,CSR.N,N,N,N,N),
+ SW-> List(Y,N,N,N,N,N,Y,Y,A2_IMM, A1_RS1, IMM_S, DW_XPR,FN_ADD, Y,M_XWR, N,N,N,N,N,N,N,CSR.N,N,N,N,N),
+
+ LUI-> List(Y,N,N,N,N,N,N,N,A2_IMM, A1_ZERO,IMM_U, DW_XPR,FN_ADD, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N),
+ ADDI-> List(Y,N,N,N,N,N,N,Y,A2_IMM, A1_RS1, IMM_I, DW_XPR,FN_ADD, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N),
+ SLTI -> List(Y,N,N,N,N,N,N,Y,A2_IMM, A1_RS1, IMM_I, DW_XPR,FN_SLT, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N),
+ SLTIU-> List(Y,N,N,N,N,N,N,Y,A2_IMM, A1_RS1, IMM_I, DW_XPR,FN_SLTU, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N),
+ ANDI-> List(Y,N,N,N,N,N,N,Y,A2_IMM, A1_RS1, IMM_I, DW_XPR,FN_AND, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N),
+ ORI-> List(Y,N,N,N,N,N,N,Y,A2_IMM, A1_RS1, IMM_I, DW_XPR,FN_OR, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N),
+ XORI-> List(Y,N,N,N,N,N,N,Y,A2_IMM, A1_RS1, IMM_I, DW_XPR,FN_XOR, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N),
+ ADD-> List(Y,N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_XPR,FN_ADD, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N),
+ SUB-> List(Y,N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_XPR,FN_SUB, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N),
+ SLT-> List(Y,N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_XPR,FN_SLT, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N),
+ SLTU-> List(Y,N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_XPR,FN_SLTU, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N),
+ AND-> List(Y,N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_XPR,FN_AND, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N),
+ OR-> List(Y,N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_XPR,FN_OR, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N),
+ XOR-> List(Y,N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_XPR,FN_XOR, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N),
+ SLL-> List(Y,N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_XPR,FN_SL, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N),
+ SRL-> List(Y,N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_XPR,FN_SR, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N),
+ SRA-> List(Y,N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_XPR,FN_SRA, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N),
+
+ FENCE-> List(Y,N,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, N,N,N,N,N,N,N,CSR.N,N,Y,N,N),
+
+ ECALL-> List(Y,N,N,N,N,N,N,X,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, N,N,N,N,N,N,N,CSR.I,N,N,N,N),
+ EBREAK-> List(Y,N,N,N,N,N,N,X,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, N,N,N,N,N,N,N,CSR.I,N,N,N,N),
+ MRET-> List(Y,N,N,N,N,N,N,X,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, N,N,N,N,N,N,N,CSR.I,N,N,N,N),
+ WFI-> List(Y,N,N,N,N,N,N,X,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, N,N,N,N,N,N,N,CSR.I,N,N,N,N),
+ CSRRW-> List(Y,N,N,N,N,N,N,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD, N,M_X, N,N,N,N,N,N,Y,CSR.W,N,N,N,N),
+ CSRRS-> List(Y,N,N,N,N,N,N,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD, N,M_X, N,N,N,N,N,N,Y,CSR.S,N,N,N,N),
+ CSRRC-> List(Y,N,N,N,N,N,N,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD, N,M_X, N,N,N,N,N,N,Y,CSR.C,N,N,N,N),
+ CSRRWI-> List(Y,N,N,N,N,N,N,N,A2_IMM, A1_ZERO,IMM_Z, DW_XPR,FN_ADD, N,M_X, N,N,N,N,N,N,Y,CSR.W,N,N,N,N),
+ CSRRSI-> List(Y,N,N,N,N,N,N,N,A2_IMM, A1_ZERO,IMM_Z, DW_XPR,FN_ADD, N,M_X, N,N,N,N,N,N,Y,CSR.S,N,N,N,N),
+ CSRRCI-> List(Y,N,N,N,N,N,N,N,A2_IMM, A1_ZERO,IMM_Z, DW_XPR,FN_ADD, N,M_X, N,N,N,N,N,N,Y,CSR.C,N,N,N,N))
}
-class CeaseDecode(aluFn: ALUFN = ALUFN())(implicit val p: Parameters) extends DecodeConstants
+class CeaseDecode(implicit val p: Parameters) extends DecodeConstants
{
val table: Array[(BitPat, List[BitPat])] = Array(
- CEASE-> List(Y,N,N,N,N,N,N,X,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, N,N,N,N,N,N,N,CSR.I,N,N,N,N))
+ CEASE-> List(Y,N,N,N,N,N,N,X,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, N,N,N,N,N,N,N,CSR.I,N,N,N,N))
}
-class FenceIDecode(flushDCache: Boolean, aluFn: ALUFN = ALUFN())(implicit val p: Parameters) extends DecodeConstants
+class FenceIDecode(flushDCache: Boolean)(implicit val p: Parameters) extends DecodeConstants
{
private val (v, cmd) = if (flushDCache) (Y, BitPat(M_FLUSH_ALL)) else (N, M_X)
val table: Array[(BitPat, List[BitPat])] = Array(
- FENCE_I-> List(Y,N,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, v,cmd, N,N,N,N,N,N,N,CSR.N,Y,Y,N,N))
+ FENCE_I-> List(Y,N,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, FN_X, v,cmd, N,N,N,N,N,N,N,CSR.N,Y,Y,N,N))
}
-class ConditionalZeroDecode(aluFn: ALUFN = ALUFN())(implicit val p: Parameters) extends DecodeConstants
+class ConditionalZeroDecode(implicit val p: Parameters) extends DecodeConstants
{
val table: Array[(BitPat, List[BitPat])] = Array(
- CZERO_EQZ-> List(Y,N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_XPR,aluFn.FN_CZEQZ, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N),
- CZERO_NEZ-> List(Y,N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_XPR,aluFn.FN_CZNEZ, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N))
+ CZERO_EQZ-> List(Y,N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_XPR,FN_CZEQZ, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N),
+ CZERO_NEZ-> List(Y,N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_XPR,FN_CZNEZ, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N))
}
-class CFlushDecode(supportsFlushLine: Boolean, aluFn: ALUFN = ALUFN())(implicit val p: Parameters) extends DecodeConstants
+class CFlushDecode(supportsFlushLine: Boolean)(implicit val p: Parameters) extends DecodeConstants
{
private def zapRs1(x: BitPat) = if (supportsFlushLine) x else BitPat(x.value.U)
val table: Array[(BitPat, List[BitPat])] = Array(
zapRs1(CFLUSH_D_L1)->
- List(Y,N,N,N,N,N,N,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,aluFn.FN_ADD, Y,M_FLUSH_ALL,N,N,N,N,N,N,N,CSR.I,N,N,N,N),
+ List(Y,N,N,N,N,N,N,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD, Y,M_FLUSH_ALL,N,N,N,N,N,N,N,CSR.I,N,N,N,N),
zapRs1(CDISCARD_D_L1)->
- List(Y,N,N,N,N,N,N,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,aluFn.FN_ADD, Y,M_FLUSH_ALL,N,N,N,N,N,N,N,CSR.I,N,N,N,N))
+ List(Y,N,N,N,N,N,N,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD, Y,M_FLUSH_ALL,N,N,N,N,N,N,N,CSR.I,N,N,N,N))
}
-class SVMDecode(aluFn: ALUFN = ALUFN())(implicit val p: Parameters) extends DecodeConstants
+class SVMDecode(implicit val p: Parameters) extends DecodeConstants
{
val table: Array[(BitPat, List[BitPat])] = Array(
- SFENCE_VMA->List(Y,N,N,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,aluFn.FN_ADD, Y,M_SFENCE, N,N,N,N,N,N,N,CSR.I,N,N,N,N))
+ SFENCE_VMA->List(Y,N,N,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD, Y,M_SFENCE, N,N,N,N,N,N,N,CSR.I,N,N,N,N))
}
-class SDecode(aluFn: ALUFN = ALUFN())(implicit val p: Parameters) extends DecodeConstants
+class SDecode(implicit val p: Parameters) extends DecodeConstants
{
val table: Array[(BitPat, List[BitPat])] = Array(
- SRET-> List(Y,N,N,N,N,N,N,X,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, N,N,N,N,N,N,N,CSR.I,N,N,N,N))
+ SRET-> List(Y,N,N,N,N,N,N,X,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, N,N,N,N,N,N,N,CSR.I,N,N,N,N))
}
-class HypervisorDecode(aluFn: ALUFN = ALUFN())(implicit val p: Parameters) extends DecodeConstants
+class HypervisorDecode(implicit val p: Parameters) extends DecodeConstants
{
val table: Array[(BitPat, List[BitPat])] = Array(
- HFENCE_VVMA->List(Y,N,N,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR, aluFn.FN_ADD, Y,M_HFENCEV, N,N,N,N,N,N,N,CSR.I,N,N,N,N),
- HFENCE_GVMA->List(Y,N,N,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR, aluFn.FN_ADD, Y,M_HFENCEG, N,N,N,N,N,N,N,CSR.I,N,N,N,N),
+ HFENCE_VVMA->List(Y,N,N,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR, FN_ADD, Y,M_HFENCEV, N,N,N,N,N,N,N,CSR.I,N,N,N,N),
+ HFENCE_GVMA->List(Y,N,N,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR, FN_ADD, Y,M_HFENCEG, N,N,N,N,N,N,N,CSR.I,N,N,N,N),
- HLV_B -> List(Y,N,N,N,N,N,N,Y,A2_ZERO, A1_RS1, IMM_X, DW_XPR, aluFn.FN_ADD, Y,M_XRD, N,N,N,N,N,N,Y,CSR.I,N,N,N,N),
- HLV_BU-> List(Y,N,N,N,N,N,N,Y,A2_ZERO, A1_RS1, IMM_X, DW_XPR, aluFn.FN_ADD, Y,M_XRD, N,N,N,N,N,N,Y,CSR.I,N,N,N,N),
- HLV_H -> List(Y,N,N,N,N,N,N,Y,A2_ZERO, A1_RS1, IMM_X, DW_XPR, aluFn.FN_ADD, Y,M_XRD, N,N,N,N,N,N,Y,CSR.I,N,N,N,N),
- HLV_HU-> List(Y,N,N,N,N,N,N,Y,A2_ZERO, A1_RS1, IMM_X, DW_XPR, aluFn.FN_ADD, Y,M_XRD, N,N,N,N,N,N,Y,CSR.I,N,N,N,N),
- HLVX_HU-> List(Y,N,N,N,N,N,N,Y,A2_ZERO, A1_RS1, IMM_X, DW_XPR, aluFn.FN_ADD, Y,M_HLVX, N,N,N,N,N,N,Y,CSR.I,N,N,N,N),
- HLV_W-> List(Y,N,N,N,N,N,N,Y,A2_ZERO, A1_RS1, IMM_X, DW_XPR, aluFn.FN_ADD, Y,M_XRD, N,N,N,N,N,N,Y,CSR.I,N,N,N,N),
- HLVX_WU-> List(Y,N,N,N,N,N,N,Y,A2_ZERO, A1_RS1, IMM_X, DW_XPR, aluFn.FN_ADD, Y,M_HLVX, N,N,N,N,N,N,Y,CSR.I,N,N,N,N),
+ HLV_B -> List(Y,N,N,N,N,N,N,Y,A2_ZERO, A1_RS1, IMM_X, DW_XPR, FN_ADD, Y,M_XRD, N,N,N,N,N,N,Y,CSR.I,N,N,N,N),
+ HLV_BU-> List(Y,N,N,N,N,N,N,Y,A2_ZERO, A1_RS1, IMM_X, DW_XPR, FN_ADD, Y,M_XRD, N,N,N,N,N,N,Y,CSR.I,N,N,N,N),
+ HLV_H -> List(Y,N,N,N,N,N,N,Y,A2_ZERO, A1_RS1, IMM_X, DW_XPR, FN_ADD, Y,M_XRD, N,N,N,N,N,N,Y,CSR.I,N,N,N,N),
+ HLV_HU-> List(Y,N,N,N,N,N,N,Y,A2_ZERO, A1_RS1, IMM_X, DW_XPR, FN_ADD, Y,M_XRD, N,N,N,N,N,N,Y,CSR.I,N,N,N,N),
+ HLVX_HU-> List(Y,N,N,N,N,N,N,Y,A2_ZERO, A1_RS1, IMM_X, DW_XPR, FN_ADD, Y,M_HLVX, N,N,N,N,N,N,Y,CSR.I,N,N,N,N),
+ HLV_W-> List(Y,N,N,N,N,N,N,Y,A2_ZERO, A1_RS1, IMM_X, DW_XPR, FN_ADD, Y,M_XRD, N,N,N,N,N,N,Y,CSR.I,N,N,N,N),
+ HLVX_WU-> List(Y,N,N,N,N,N,N,Y,A2_ZERO, A1_RS1, IMM_X, DW_XPR, FN_ADD, Y,M_HLVX, N,N,N,N,N,N,Y,CSR.I,N,N,N,N),
- HSV_B-> List(Y,N,N,N,N,N,Y,Y,A2_ZERO, A1_RS1, IMM_I, DW_XPR, aluFn.FN_ADD, Y,M_XWR, N,N,N,N,N,N,N,CSR.I,N,N,N,N),
- HSV_H-> List(Y,N,N,N,N,N,Y,Y,A2_ZERO, A1_RS1, IMM_I, DW_XPR, aluFn.FN_ADD, Y,M_XWR, N,N,N,N,N,N,N,CSR.I,N,N,N,N),
- HSV_W-> List(Y,N,N,N,N,N,Y,Y,A2_ZERO, A1_RS1, IMM_I, DW_XPR, aluFn.FN_ADD, Y,M_XWR, N,N,N,N,N,N,N,CSR.I,N,N,N,N))
+ HSV_B-> List(Y,N,N,N,N,N,Y,Y,A2_ZERO, A1_RS1, IMM_I, DW_XPR, FN_ADD, Y,M_XWR, N,N,N,N,N,N,N,CSR.I,N,N,N,N),
+ HSV_H-> List(Y,N,N,N,N,N,Y,Y,A2_ZERO, A1_RS1, IMM_I, DW_XPR, FN_ADD, Y,M_XWR, N,N,N,N,N,N,N,CSR.I,N,N,N,N),
+ HSV_W-> List(Y,N,N,N,N,N,Y,Y,A2_ZERO, A1_RS1, IMM_I, DW_XPR, FN_ADD, Y,M_XWR, N,N,N,N,N,N,N,CSR.I,N,N,N,N))
}
-class DebugDecode(aluFn: ALUFN = ALUFN())(implicit val p: Parameters) extends DecodeConstants
+class DebugDecode(implicit val p: Parameters) extends DecodeConstants
{
val table: Array[(BitPat, List[BitPat])] = Array(
- DRET-> List(Y,N,N,N,N,N,N,X,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, N,N,N,N,N,N,N,CSR.I,N,N,N,N))
+ DRET-> List(Y,N,N,N,N,N,N,X,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, N,N,N,N,N,N,N,CSR.I,N,N,N,N))
}
-class NMIDecode(aluFn: ALUFN = ALUFN())(implicit val p: Parameters) extends DecodeConstants
+class NMIDecode(implicit val p: Parameters) extends DecodeConstants
{
val table: Array[(BitPat, List[BitPat])] = Array(
- MNRET-> List(Y,N,N,N,N,N,N,X,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, N,N,N,N,N,N,N,CSR.I,N,N,N,N))
+ MNRET-> List(Y,N,N,N,N,N,N,X,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, N,N,N,N,N,N,N,CSR.I,N,N,N,N))
}
-class I32Decode(aluFn: ALUFN = ALUFN())(implicit val p: Parameters) extends DecodeConstants
+class I32Decode(implicit val p: Parameters) extends DecodeConstants
{
val table: Array[(BitPat, List[BitPat])] = Array(
Instructions32.SLLI->
- List(Y,N,N,N,N,N,N,Y,A2_IMM, A1_RS1, IMM_I, DW_XPR,aluFn.FN_SL, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N),
+ List(Y,N,N,N,N,N,N,Y,A2_IMM, A1_RS1, IMM_I, DW_XPR,FN_SL, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N),
Instructions32.SRLI->
- List(Y,N,N,N,N,N,N,Y,A2_IMM, A1_RS1, IMM_I, DW_XPR,aluFn.FN_SR, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N),
+ List(Y,N,N,N,N,N,N,Y,A2_IMM, A1_RS1, IMM_I, DW_XPR,FN_SR, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N),
Instructions32.SRAI->
- List(Y,N,N,N,N,N,N,Y,A2_IMM, A1_RS1, IMM_I, DW_XPR,aluFn.FN_SRA, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N))
+ List(Y,N,N,N,N,N,N,Y,A2_IMM, A1_RS1, IMM_I, DW_XPR,FN_SRA, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N))
}
-class I64Decode(aluFn: ALUFN = ALUFN())(implicit val p: Parameters) extends DecodeConstants
+class I64Decode(implicit val p: Parameters) extends DecodeConstants
{
val table: Array[(BitPat, List[BitPat])] = Array(
- LD-> List(Y,N,N,N,N,N,N,Y,A2_IMM, A1_RS1, IMM_I, DW_XPR,aluFn.FN_ADD, Y,M_XRD, N,N,N,N,N,N,Y,CSR.N,N,N,N,N),
- LWU-> List(Y,N,N,N,N,N,N,Y,A2_IMM, A1_RS1, IMM_I, DW_XPR,aluFn.FN_ADD, Y,M_XRD, N,N,N,N,N,N,Y,CSR.N,N,N,N,N),
- SD-> List(Y,N,N,N,N,N,Y,Y,A2_IMM, A1_RS1, IMM_S, DW_XPR,aluFn.FN_ADD, Y,M_XWR, N,N,N,N,N,N,N,CSR.N,N,N,N,N),
-
- SLLI-> List(Y,N,N,N,N,N,N,Y,A2_IMM, A1_RS1, IMM_I, DW_XPR,aluFn.FN_SL, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N),
- SRLI-> List(Y,N,N,N,N,N,N,Y,A2_IMM, A1_RS1, IMM_I, DW_XPR,aluFn.FN_SR, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N),
- SRAI-> List(Y,N,N,N,N,N,N,Y,A2_IMM, A1_RS1, IMM_I, DW_XPR,aluFn.FN_SRA, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N),
-
- ADDIW-> List(Y,N,N,N,N,N,N,Y,A2_IMM, A1_RS1, IMM_I, DW_32,aluFn.FN_ADD, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N),
- SLLIW-> List(Y,N,N,N,N,N,N,Y,A2_IMM, A1_RS1, IMM_I, DW_32,aluFn.FN_SL, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N),
- SRLIW-> List(Y,N,N,N,N,N,N,Y,A2_IMM, A1_RS1, IMM_I, DW_32,aluFn.FN_SR, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N),
- SRAIW-> List(Y,N,N,N,N,N,N,Y,A2_IMM, A1_RS1, IMM_I, DW_32,aluFn.FN_SRA, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N),
- ADDW-> List(Y,N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_32,aluFn.FN_ADD, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N),
- SUBW-> List(Y,N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_32,aluFn.FN_SUB, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N),
- SLLW-> List(Y,N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_32,aluFn.FN_SL, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N),
- SRLW-> List(Y,N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_32,aluFn.FN_SR, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N),
- SRAW-> List(Y,N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_32,aluFn.FN_SRA, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N))
+ LD-> List(Y,N,N,N,N,N,N,Y,A2_IMM, A1_RS1, IMM_I, DW_XPR,FN_ADD, Y,M_XRD, N,N,N,N,N,N,Y,CSR.N,N,N,N,N),
+ LWU-> List(Y,N,N,N,N,N,N,Y,A2_IMM, A1_RS1, IMM_I, DW_XPR,FN_ADD, Y,M_XRD, N,N,N,N,N,N,Y,CSR.N,N,N,N,N),
+ SD-> List(Y,N,N,N,N,N,Y,Y,A2_IMM, A1_RS1, IMM_S, DW_XPR,FN_ADD, Y,M_XWR, N,N,N,N,N,N,N,CSR.N,N,N,N,N),
+
+ SLLI-> List(Y,N,N,N,N,N,N,Y,A2_IMM, A1_RS1, IMM_I, DW_XPR,FN_SL, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N),
+ SRLI-> List(Y,N,N,N,N,N,N,Y,A2_IMM, A1_RS1, IMM_I, DW_XPR,FN_SR, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N),
+ SRAI-> List(Y,N,N,N,N,N,N,Y,A2_IMM, A1_RS1, IMM_I, DW_XPR,FN_SRA, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N),
+
+ ADDIW-> List(Y,N,N,N,N,N,N,Y,A2_IMM, A1_RS1, IMM_I, DW_32,FN_ADD, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N),
+ SLLIW-> List(Y,N,N,N,N,N,N,Y,A2_IMM, A1_RS1, IMM_I, DW_32,FN_SL, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N),
+ SRLIW-> List(Y,N,N,N,N,N,N,Y,A2_IMM, A1_RS1, IMM_I, DW_32,FN_SR, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N),
+ SRAIW-> List(Y,N,N,N,N,N,N,Y,A2_IMM, A1_RS1, IMM_I, DW_32,FN_SRA, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N),
+ ADDW-> List(Y,N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_32,FN_ADD, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N),
+ SUBW-> List(Y,N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_32,FN_SUB, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N),
+ SLLW-> List(Y,N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_32,FN_SL, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N),
+ SRLW-> List(Y,N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_32,FN_SR, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N),
+ SRAW-> List(Y,N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_32,FN_SRA, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N))
}
-class Hypervisor64Decode(aluFn: ALUFN = ALUFN())(implicit val p: Parameters) extends DecodeConstants
+class Hypervisor64Decode(implicit val p: Parameters) extends DecodeConstants
{
val table: Array[(BitPat, List[BitPat])] = Array(
- HLV_D-> List(Y,N,N,N,N,N,N,Y,A2_ZERO, A1_RS1, IMM_X, DW_XPR, aluFn.FN_ADD, Y,M_XRD, N,N,N,N,N,N,Y,CSR.I,N,N,N,N),
- HSV_D-> List(Y,N,N,N,N,N,Y,Y,A2_ZERO, A1_RS1, IMM_I, DW_XPR, aluFn.FN_ADD, Y,M_XWR, N,N,N,N,N,N,N,CSR.I,N,N,N,N),
- HLV_WU-> List(Y,N,N,N,N,N,N,Y,A2_ZERO, A1_RS1, IMM_X, DW_XPR, aluFn.FN_ADD, Y,M_XRD, N,N,N,N,N,N,Y,CSR.I,N,N,N,N))
+ HLV_D-> List(Y,N,N,N,N,N,N,Y,A2_ZERO, A1_RS1, IMM_X, DW_XPR, FN_ADD, Y,M_XRD, N,N,N,N,N,N,Y,CSR.I,N,N,N,N),
+ HSV_D-> List(Y,N,N,N,N,N,Y,Y,A2_ZERO, A1_RS1, IMM_I, DW_XPR, FN_ADD, Y,M_XWR, N,N,N,N,N,N,N,CSR.I,N,N,N,N),
+ HLV_WU-> List(Y,N,N,N,N,N,N,Y,A2_ZERO, A1_RS1, IMM_X, DW_XPR, FN_ADD, Y,M_XRD, N,N,N,N,N,N,Y,CSR.I,N,N,N,N))
}
-class MDecode(pipelinedMul: Boolean, aluFn: ALUFN = ALUFN())(implicit val p: Parameters) extends DecodeConstants
+class MDecode(pipelinedMul: Boolean)(implicit val p: Parameters) extends DecodeConstants
{
val M = if (pipelinedMul) Y else N
val D = if (pipelinedMul) N else Y
val table: Array[(BitPat, List[BitPat])] = Array(
- MUL-> List(Y,N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_XPR,aluFn.FN_MUL, N,M_X, N,N,N,N,M,D,Y,CSR.N,N,N,N,N),
- MULH-> List(Y,N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_XPR,aluFn.FN_MULH, N,M_X, N,N,N,N,M,D,Y,CSR.N,N,N,N,N),
- MULHU-> List(Y,N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_XPR,aluFn.FN_MULHU, N,M_X, N,N,N,N,M,D,Y,CSR.N,N,N,N,N),
- MULHSU-> List(Y,N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_XPR,aluFn.FN_MULHSU,N,M_X, N,N,N,N,M,D,Y,CSR.N,N,N,N,N),
-
- DIV-> List(Y,N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_XPR,aluFn.FN_DIV, N,M_X, N,N,N,N,N,Y,Y,CSR.N,N,N,N,N),
- DIVU-> List(Y,N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_XPR,aluFn.FN_DIVU, N,M_X, N,N,N,N,N,Y,Y,CSR.N,N,N,N,N),
- REM-> List(Y,N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_XPR,aluFn.FN_REM, N,M_X, N,N,N,N,N,Y,Y,CSR.N,N,N,N,N),
- REMU-> List(Y,N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_XPR,aluFn.FN_REMU, N,M_X, N,N,N,N,N,Y,Y,CSR.N,N,N,N,N))
+ MUL-> List(Y,N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_XPR,FN_MUL, N,M_X, N,N,N,N,M,D,Y,CSR.N,N,N,N,N),
+ MULH-> List(Y,N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_XPR,FN_MULH, N,M_X, N,N,N,N,M,D,Y,CSR.N,N,N,N,N),
+ MULHU-> List(Y,N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_XPR,FN_MULHU, N,M_X, N,N,N,N,M,D,Y,CSR.N,N,N,N,N),
+ MULHSU-> List(Y,N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_XPR,FN_MULHSU,N,M_X, N,N,N,N,M,D,Y,CSR.N,N,N,N,N),
+
+ DIV-> List(Y,N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_XPR,FN_DIV, N,M_X, N,N,N,N,N,Y,Y,CSR.N,N,N,N,N),
+ DIVU-> List(Y,N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_XPR,FN_DIVU, N,M_X, N,N,N,N,N,Y,Y,CSR.N,N,N,N,N),
+ REM-> List(Y,N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_XPR,FN_REM, N,M_X, N,N,N,N,N,Y,Y,CSR.N,N,N,N,N),
+ REMU-> List(Y,N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_XPR,FN_REMU, N,M_X, N,N,N,N,N,Y,Y,CSR.N,N,N,N,N))
}
-class M64Decode(pipelinedMul: Boolean, aluFn: ALUFN = ALUFN())(implicit val p: Parameters) extends DecodeConstants
+class M64Decode(pipelinedMul: Boolean)(implicit val p: Parameters) extends DecodeConstants
{
val M = if (pipelinedMul) Y else N
val D = if (pipelinedMul) N else Y
val table: Array[(BitPat, List[BitPat])] = Array(
- MULW-> List(Y,N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_32, aluFn.FN_MUL, N,M_X, N,N,N,N,M,D,Y,CSR.N,N,N,N,N),
-
- DIVW-> List(Y,N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_32, aluFn.FN_DIV, N,M_X, N,N,N,N,N,Y,Y,CSR.N,N,N,N,N),
- DIVUW-> List(Y,N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_32, aluFn.FN_DIVU, N,M_X, N,N,N,N,N,Y,Y,CSR.N,N,N,N,N),
- REMW-> List(Y,N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_32, aluFn.FN_REM, N,M_X, N,N,N,N,N,Y,Y,CSR.N,N,N,N,N),
- REMUW-> List(Y,N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_32, aluFn.FN_REMU, N,M_X, N,N,N,N,N,Y,Y,CSR.N,N,N,N,N))
-}
-
-class ADecode(aluFn: ALUFN = ALUFN())(implicit val p: Parameters) extends DecodeConstants
-{
- val table: Array[(BitPat, List[BitPat])] = Array(
- AMOADD_W-> List(Y,N,N,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,aluFn.FN_ADD, Y,M_XA_ADD, N,N,N,N,N,N,Y,CSR.N,N,N,Y,N),
- AMOXOR_W-> List(Y,N,N,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,aluFn.FN_ADD, Y,M_XA_XOR, N,N,N,N,N,N,Y,CSR.N,N,N,Y,N),
- AMOSWAP_W-> List(Y,N,N,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,aluFn.FN_ADD, Y,M_XA_SWAP, N,N,N,N,N,N,Y,CSR.N,N,N,Y,N),
- AMOAND_W-> List(Y,N,N,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,aluFn.FN_ADD, Y,M_XA_AND, N,N,N,N,N,N,Y,CSR.N,N,N,Y,N),
- AMOOR_W-> List(Y,N,N,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,aluFn.FN_ADD, Y,M_XA_OR, N,N,N,N,N,N,Y,CSR.N,N,N,Y,N),
- AMOMIN_W-> List(Y,N,N,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,aluFn.FN_ADD, Y,M_XA_MIN, N,N,N,N,N,N,Y,CSR.N,N,N,Y,N),
- AMOMINU_W-> List(Y,N,N,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,aluFn.FN_ADD, Y,M_XA_MINU, N,N,N,N,N,N,Y,CSR.N,N,N,Y,N),
- AMOMAX_W-> List(Y,N,N,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,aluFn.FN_ADD, Y,M_XA_MAX, N,N,N,N,N,N,Y,CSR.N,N,N,Y,N),
- AMOMAXU_W-> List(Y,N,N,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,aluFn.FN_ADD, Y,M_XA_MAXU, N,N,N,N,N,N,Y,CSR.N,N,N,Y,N),
-
- LR_W-> List(Y,N,N,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,aluFn.FN_ADD, Y,M_XLR, N,N,N,N,N,N,Y,CSR.N,N,N,Y,N),
- SC_W-> List(Y,N,N,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,aluFn.FN_ADD, Y,M_XSC, N,N,N,N,N,N,Y,CSR.N,N,N,Y,N))
-}
-
-class A64Decode(aluFn: ALUFN = ALUFN())(implicit val p: Parameters) extends DecodeConstants
-{
- val table: Array[(BitPat, List[BitPat])] = Array(
- AMOADD_D-> List(Y,N,N,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,aluFn.FN_ADD, Y,M_XA_ADD, N,N,N,N,N,N,Y,CSR.N,N,N,Y,N),
- AMOSWAP_D-> List(Y,N,N,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,aluFn.FN_ADD, Y,M_XA_SWAP, N,N,N,N,N,N,Y,CSR.N,N,N,Y,N),
- AMOXOR_D-> List(Y,N,N,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,aluFn.FN_ADD, Y,M_XA_XOR, N,N,N,N,N,N,Y,CSR.N,N,N,Y,N),
- AMOAND_D-> List(Y,N,N,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,aluFn.FN_ADD, Y,M_XA_AND, N,N,N,N,N,N,Y,CSR.N,N,N,Y,N),
- AMOOR_D-> List(Y,N,N,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,aluFn.FN_ADD, Y,M_XA_OR, N,N,N,N,N,N,Y,CSR.N,N,N,Y,N),
- AMOMIN_D-> List(Y,N,N,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,aluFn.FN_ADD, Y,M_XA_MIN, N,N,N,N,N,N,Y,CSR.N,N,N,Y,N),
- AMOMINU_D-> List(Y,N,N,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,aluFn.FN_ADD, Y,M_XA_MINU, N,N,N,N,N,N,Y,CSR.N,N,N,Y,N),
- AMOMAX_D-> List(Y,N,N,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,aluFn.FN_ADD, Y,M_XA_MAX, N,N,N,N,N,N,Y,CSR.N,N,N,Y,N),
- AMOMAXU_D-> List(Y,N,N,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,aluFn.FN_ADD, Y,M_XA_MAXU, N,N,N,N,N,N,Y,CSR.N,N,N,Y,N),
-
- LR_D-> List(Y,N,N,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,aluFn.FN_ADD, Y,M_XLR, N,N,N,N,N,N,Y,CSR.N,N,N,Y,N),
- SC_D-> List(Y,N,N,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,aluFn.FN_ADD, Y,M_XSC, N,N,N,N,N,N,Y,CSR.N,N,N,Y,N))
-}
-
-class HDecode(aluFn: ALUFN = ALUFN())(implicit val p: Parameters) extends DecodeConstants
-{
- val table: Array[(BitPat, List[BitPat])] = Array(
- FCVT_S_H-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,N,N,Y,N,N,N,CSR.N,N,N,N,N),
- FCVT_H_S-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,N,N,Y,N,N,N,CSR.N,N,N,N,N),
- FSGNJ_H-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,Y,N,Y,N,N,N,CSR.N,N,N,N,N),
- FSGNJX_H-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,Y,N,Y,N,N,N,CSR.N,N,N,N,N),
- FSGNJN_H-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,Y,N,Y,N,N,N,CSR.N,N,N,N,N),
- FMIN_H-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,Y,N,Y,N,N,N,CSR.N,N,N,N,N),
- FMAX_H-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,Y,N,Y,N,N,N,CSR.N,N,N,N,N),
- FADD_H-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,Y,N,Y,N,N,N,CSR.N,N,N,N,N),
- FSUB_H-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,Y,N,Y,N,N,N,CSR.N,N,N,N,N),
- FMUL_H-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,Y,N,Y,N,N,N,CSR.N,N,N,N,N),
- FMADD_H-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,Y,Y,Y,N,N,N,CSR.N,N,N,N,N),
- FMSUB_H-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,Y,Y,Y,N,N,N,CSR.N,N,N,N,N),
- FNMADD_H-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,Y,Y,Y,N,N,N,CSR.N,N,N,N,N),
- FNMSUB_H-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,Y,Y,Y,N,N,N,CSR.N,N,N,N,N),
- FCLASS_H-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,N,N,N,N,N,Y,CSR.N,N,N,N,N),
- FMV_X_H-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,N,N,N,N,N,Y,CSR.N,N,N,N,N),
- FCVT_W_H-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,N,N,N,N,N,Y,CSR.N,N,N,N,N),
- FCVT_WU_H-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,N,N,N,N,N,Y,CSR.N,N,N,N,N),
- FEQ_H-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,Y,N,N,N,N,Y,CSR.N,N,N,N,N),
- FLT_H-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,Y,N,N,N,N,Y,CSR.N,N,N,N,N),
- FLE_H-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,Y,N,N,N,N,Y,CSR.N,N,N,N,N),
- FMV_H_X-> List(Y,Y,N,N,N,N,N,Y,A2_X, A1_RS1, IMM_X, DW_X, aluFn.FN_X, N,M_X, N,N,N,Y,N,N,N,CSR.N,N,N,N,N),
- FCVT_H_W-> List(Y,Y,N,N,N,N,N,Y,A2_X, A1_RS1, IMM_X, DW_X, aluFn.FN_X, N,M_X, N,N,N,Y,N,N,N,CSR.N,N,N,N,N),
- FCVT_H_WU-> List(Y,Y,N,N,N,N,N,Y,A2_X, A1_RS1, IMM_X, DW_X, aluFn.FN_X, N,M_X, N,N,N,Y,N,N,N,CSR.N,N,N,N,N),
- FLH-> List(Y,Y,N,N,N,N,N,Y,A2_IMM, A1_RS1, IMM_I, DW_XPR,aluFn.FN_ADD, Y,M_XRD, N,N,N,Y,N,N,N,CSR.N,N,N,N,N),
- FSH-> List(Y,Y,N,N,N,N,N,Y,A2_IMM, A1_RS1, IMM_S, DW_XPR,aluFn.FN_ADD, Y,M_XWR, N,Y,N,N,N,N,N,CSR.N,N,N,N,N),
- FDIV_H-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,Y,N,Y,N,N,N,CSR.N,N,N,N,N),
- FSQRT_H-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,Y,N,Y,N,N,N,CSR.N,N,N,N,N))
-}
-
-class FDecode(aluFn: ALUFN = ALUFN())(implicit val p: Parameters) extends DecodeConstants
+ MULW-> List(Y,N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_32, FN_MUL, N,M_X, N,N,N,N,M,D,Y,CSR.N,N,N,N,N),
+
+ DIVW-> List(Y,N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_32, FN_DIV, N,M_X, N,N,N,N,N,Y,Y,CSR.N,N,N,N,N),
+ DIVUW-> List(Y,N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_32, FN_DIVU, N,M_X, N,N,N,N,N,Y,Y,CSR.N,N,N,N,N),
+ REMW-> List(Y,N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_32, FN_REM, N,M_X, N,N,N,N,N,Y,Y,CSR.N,N,N,N,N),
+ REMUW-> List(Y,N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_32, FN_REMU, N,M_X, N,N,N,N,N,Y,Y,CSR.N,N,N,N,N))
+}
+
+class ADecode(implicit val p: Parameters) extends DecodeConstants
+{
+ val table: Array[(BitPat, List[BitPat])] = Array(
+ AMOADD_W-> List(Y,N,N,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD, Y,M_XA_ADD, N,N,N,N,N,N,Y,CSR.N,N,N,Y,N),
+ AMOXOR_W-> List(Y,N,N,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD, Y,M_XA_XOR, N,N,N,N,N,N,Y,CSR.N,N,N,Y,N),
+ AMOSWAP_W-> List(Y,N,N,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD, Y,M_XA_SWAP, N,N,N,N,N,N,Y,CSR.N,N,N,Y,N),
+ AMOAND_W-> List(Y,N,N,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD, Y,M_XA_AND, N,N,N,N,N,N,Y,CSR.N,N,N,Y,N),
+ AMOOR_W-> List(Y,N,N,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD, Y,M_XA_OR, N,N,N,N,N,N,Y,CSR.N,N,N,Y,N),
+ AMOMIN_W-> List(Y,N,N,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD, Y,M_XA_MIN, N,N,N,N,N,N,Y,CSR.N,N,N,Y,N),
+ AMOMINU_W-> List(Y,N,N,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD, Y,M_XA_MINU, N,N,N,N,N,N,Y,CSR.N,N,N,Y,N),
+ AMOMAX_W-> List(Y,N,N,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD, Y,M_XA_MAX, N,N,N,N,N,N,Y,CSR.N,N,N,Y,N),
+ AMOMAXU_W-> List(Y,N,N,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD, Y,M_XA_MAXU, N,N,N,N,N,N,Y,CSR.N,N,N,Y,N),
+
+ LR_W-> List(Y,N,N,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD, Y,M_XLR, N,N,N,N,N,N,Y,CSR.N,N,N,Y,N),
+ SC_W-> List(Y,N,N,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD, Y,M_XSC, N,N,N,N,N,N,Y,CSR.N,N,N,Y,N))
+}
+
+class A64Decode(implicit val p: Parameters) extends DecodeConstants
+{
+ val table: Array[(BitPat, List[BitPat])] = Array(
+ AMOADD_D-> List(Y,N,N,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD, Y,M_XA_ADD, N,N,N,N,N,N,Y,CSR.N,N,N,Y,N),
+ AMOSWAP_D-> List(Y,N,N,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD, Y,M_XA_SWAP, N,N,N,N,N,N,Y,CSR.N,N,N,Y,N),
+ AMOXOR_D-> List(Y,N,N,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD, Y,M_XA_XOR, N,N,N,N,N,N,Y,CSR.N,N,N,Y,N),
+ AMOAND_D-> List(Y,N,N,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD, Y,M_XA_AND, N,N,N,N,N,N,Y,CSR.N,N,N,Y,N),
+ AMOOR_D-> List(Y,N,N,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD, Y,M_XA_OR, N,N,N,N,N,N,Y,CSR.N,N,N,Y,N),
+ AMOMIN_D-> List(Y,N,N,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD, Y,M_XA_MIN, N,N,N,N,N,N,Y,CSR.N,N,N,Y,N),
+ AMOMINU_D-> List(Y,N,N,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD, Y,M_XA_MINU, N,N,N,N,N,N,Y,CSR.N,N,N,Y,N),
+ AMOMAX_D-> List(Y,N,N,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD, Y,M_XA_MAX, N,N,N,N,N,N,Y,CSR.N,N,N,Y,N),
+ AMOMAXU_D-> List(Y,N,N,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD, Y,M_XA_MAXU, N,N,N,N,N,N,Y,CSR.N,N,N,Y,N),
+
+ LR_D-> List(Y,N,N,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD, Y,M_XLR, N,N,N,N,N,N,Y,CSR.N,N,N,Y,N),
+ SC_D-> List(Y,N,N,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD, Y,M_XSC, N,N,N,N,N,N,Y,CSR.N,N,N,Y,N))
+}
+
+class HDecode(implicit val p: Parameters) extends DecodeConstants
+{
+ val table: Array[(BitPat, List[BitPat])] = Array(
+ FCVT_S_H-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, Y,N,N,Y,N,N,N,CSR.N,N,N,N,N),
+ FCVT_H_S-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, Y,N,N,Y,N,N,N,CSR.N,N,N,N,N),
+ FSGNJ_H-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, Y,Y,N,Y,N,N,N,CSR.N,N,N,N,N),
+ FSGNJX_H-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, Y,Y,N,Y,N,N,N,CSR.N,N,N,N,N),
+ FSGNJN_H-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, Y,Y,N,Y,N,N,N,CSR.N,N,N,N,N),
+ FMIN_H-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, Y,Y,N,Y,N,N,N,CSR.N,N,N,N,N),
+ FMAX_H-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, Y,Y,N,Y,N,N,N,CSR.N,N,N,N,N),
+ FADD_H-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, Y,Y,N,Y,N,N,N,CSR.N,N,N,N,N),
+ FSUB_H-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, Y,Y,N,Y,N,N,N,CSR.N,N,N,N,N),
+ FMUL_H-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, Y,Y,N,Y,N,N,N,CSR.N,N,N,N,N),
+ FMADD_H-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, Y,Y,Y,Y,N,N,N,CSR.N,N,N,N,N),
+ FMSUB_H-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, Y,Y,Y,Y,N,N,N,CSR.N,N,N,N,N),
+ FNMADD_H-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, Y,Y,Y,Y,N,N,N,CSR.N,N,N,N,N),
+ FNMSUB_H-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, Y,Y,Y,Y,N,N,N,CSR.N,N,N,N,N),
+ FCLASS_H-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, Y,N,N,N,N,N,Y,CSR.N,N,N,N,N),
+ FMV_X_H-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, Y,N,N,N,N,N,Y,CSR.N,N,N,N,N),
+ FCVT_W_H-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, Y,N,N,N,N,N,Y,CSR.N,N,N,N,N),
+ FCVT_WU_H-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, Y,N,N,N,N,N,Y,CSR.N,N,N,N,N),
+ FEQ_H-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, Y,Y,N,N,N,N,Y,CSR.N,N,N,N,N),
+ FLT_H-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, Y,Y,N,N,N,N,Y,CSR.N,N,N,N,N),
+ FLE_H-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, Y,Y,N,N,N,N,Y,CSR.N,N,N,N,N),
+ FMV_H_X-> List(Y,Y,N,N,N,N,N,Y,A2_X, A1_RS1, IMM_X, DW_X, FN_X, N,M_X, N,N,N,Y,N,N,N,CSR.N,N,N,N,N),
+ FCVT_H_W-> List(Y,Y,N,N,N,N,N,Y,A2_X, A1_RS1, IMM_X, DW_X, FN_X, N,M_X, N,N,N,Y,N,N,N,CSR.N,N,N,N,N),
+ FCVT_H_WU-> List(Y,Y,N,N,N,N,N,Y,A2_X, A1_RS1, IMM_X, DW_X, FN_X, N,M_X, N,N,N,Y,N,N,N,CSR.N,N,N,N,N),
+ FLH-> List(Y,Y,N,N,N,N,N,Y,A2_IMM, A1_RS1, IMM_I, DW_XPR,FN_ADD, Y,M_XRD, N,N,N,Y,N,N,N,CSR.N,N,N,N,N),
+ FSH-> List(Y,Y,N,N,N,N,N,Y,A2_IMM, A1_RS1, IMM_S, DW_XPR,FN_ADD, Y,M_XWR, N,Y,N,N,N,N,N,CSR.N,N,N,N,N),
+ FDIV_H-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, Y,Y,N,Y,N,N,N,CSR.N,N,N,N,N),
+ FSQRT_H-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, Y,Y,N,Y,N,N,N,CSR.N,N,N,N,N))
+}
+
+class FDecode(implicit val p: Parameters) extends DecodeConstants
+{
+ val table: Array[(BitPat, List[BitPat])] = Array(
+ FSGNJ_S-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, Y,Y,N,Y,N,N,N,CSR.N,N,N,N,N),
+ FSGNJX_S-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, Y,Y,N,Y,N,N,N,CSR.N,N,N,N,N),
+ FSGNJN_S-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, Y,Y,N,Y,N,N,N,CSR.N,N,N,N,N),
+ FMIN_S-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, Y,Y,N,Y,N,N,N,CSR.N,N,N,N,N),
+ FMAX_S-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, Y,Y,N,Y,N,N,N,CSR.N,N,N,N,N),
+ FADD_S-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, Y,Y,N,Y,N,N,N,CSR.N,N,N,N,N),
+ FSUB_S-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, Y,Y,N,Y,N,N,N,CSR.N,N,N,N,N),
+ FMUL_S-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, Y,Y,N,Y,N,N,N,CSR.N,N,N,N,N),
+ FMADD_S-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, Y,Y,Y,Y,N,N,N,CSR.N,N,N,N,N),
+ FMSUB_S-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, Y,Y,Y,Y,N,N,N,CSR.N,N,N,N,N),
+ FNMADD_S-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, Y,Y,Y,Y,N,N,N,CSR.N,N,N,N,N),
+ FNMSUB_S-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, Y,Y,Y,Y,N,N,N,CSR.N,N,N,N,N),
+ FCLASS_S-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, Y,N,N,N,N,N,Y,CSR.N,N,N,N,N),
+ FMV_X_W-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, Y,N,N,N,N,N,Y,CSR.N,N,N,N,N),
+ FCVT_W_S-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, Y,N,N,N,N,N,Y,CSR.N,N,N,N,N),
+ FCVT_WU_S-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, Y,N,N,N,N,N,Y,CSR.N,N,N,N,N),
+ FEQ_S-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, Y,Y,N,N,N,N,Y,CSR.N,N,N,N,N),
+ FLT_S-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, Y,Y,N,N,N,N,Y,CSR.N,N,N,N,N),
+ FLE_S-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, Y,Y,N,N,N,N,Y,CSR.N,N,N,N,N),
+ FMV_W_X-> List(Y,Y,N,N,N,N,N,Y,A2_X, A1_RS1, IMM_X, DW_X, FN_X, N,M_X, N,N,N,Y,N,N,N,CSR.N,N,N,N,N),
+ FCVT_S_W-> List(Y,Y,N,N,N,N,N,Y,A2_X, A1_RS1, IMM_X, DW_X, FN_X, N,M_X, N,N,N,Y,N,N,N,CSR.N,N,N,N,N),
+ FCVT_S_WU-> List(Y,Y,N,N,N,N,N,Y,A2_X, A1_RS1, IMM_X, DW_X, FN_X, N,M_X, N,N,N,Y,N,N,N,CSR.N,N,N,N,N),
+ FLW-> List(Y,Y,N,N,N,N,N,Y,A2_IMM, A1_RS1, IMM_I, DW_XPR,FN_ADD, Y,M_XRD, N,N,N,Y,N,N,N,CSR.N,N,N,N,N),
+ FSW-> List(Y,Y,N,N,N,N,N,Y,A2_IMM, A1_RS1, IMM_S, DW_XPR,FN_ADD, Y,M_XWR, N,Y,N,N,N,N,N,CSR.N,N,N,N,N),
+ FDIV_S-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, Y,Y,N,Y,N,N,N,CSR.N,N,N,N,N),
+ FSQRT_S-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, Y,Y,N,Y,N,N,N,CSR.N,N,N,N,N))
+}
+
+class DDecode(implicit val p: Parameters) extends DecodeConstants
+{
+ val table: Array[(BitPat, List[BitPat])] = Array(
+ FCVT_S_D-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, Y,N,N,Y,N,N,N,CSR.N,N,N,N,Y),
+ FCVT_D_S-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, Y,N,N,Y,N,N,N,CSR.N,N,N,N,Y),
+ FSGNJ_D-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, Y,Y,N,Y,N,N,N,CSR.N,N,N,N,Y),
+ FSGNJX_D-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, Y,Y,N,Y,N,N,N,CSR.N,N,N,N,Y),
+ FSGNJN_D-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, Y,Y,N,Y,N,N,N,CSR.N,N,N,N,Y),
+ FMIN_D-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, Y,Y,N,Y,N,N,N,CSR.N,N,N,N,Y),
+ FMAX_D-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, Y,Y,N,Y,N,N,N,CSR.N,N,N,N,Y),
+ FADD_D-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, Y,Y,N,Y,N,N,N,CSR.N,N,N,N,Y),
+ FSUB_D-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, Y,Y,N,Y,N,N,N,CSR.N,N,N,N,Y),
+ FMUL_D-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, Y,Y,N,Y,N,N,N,CSR.N,N,N,N,Y),
+ FMADD_D-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, Y,Y,Y,Y,N,N,N,CSR.N,N,N,N,Y),
+ FMSUB_D-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, Y,Y,Y,Y,N,N,N,CSR.N,N,N,N,Y),
+ FNMADD_D-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, Y,Y,Y,Y,N,N,N,CSR.N,N,N,N,Y),
+ FNMSUB_D-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, Y,Y,Y,Y,N,N,N,CSR.N,N,N,N,Y),
+ FCLASS_D-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, Y,N,N,N,N,N,Y,CSR.N,N,N,N,Y),
+ FCVT_W_D-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, Y,N,N,N,N,N,Y,CSR.N,N,N,N,Y),
+ FCVT_WU_D-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, Y,N,N,N,N,N,Y,CSR.N,N,N,N,Y),
+ FEQ_D-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, Y,Y,N,N,N,N,Y,CSR.N,N,N,N,Y),
+ FLT_D-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, Y,Y,N,N,N,N,Y,CSR.N,N,N,N,Y),
+ FLE_D-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, Y,Y,N,N,N,N,Y,CSR.N,N,N,N,Y),
+ FCVT_D_W-> List(Y,Y,N,N,N,N,N,Y,A2_X, A1_RS1, IMM_X, DW_X, FN_X, N,M_X, N,N,N,Y,N,N,N,CSR.N,N,N,N,Y),
+ FCVT_D_WU-> List(Y,Y,N,N,N,N,N,Y,A2_X, A1_RS1, IMM_X, DW_X, FN_X, N,M_X, N,N,N,Y,N,N,N,CSR.N,N,N,N,Y),
+ FLD-> List(Y,Y,N,N,N,N,N,Y,A2_IMM, A1_RS1, IMM_I, DW_XPR,FN_ADD, Y,M_XRD, N,N,N,Y,N,N,N,CSR.N,N,N,N,Y),
+ FSD-> List(Y,Y,N,N,N,N,N,Y,A2_IMM, A1_RS1, IMM_S, DW_XPR,FN_ADD, Y,M_XWR, N,Y,N,N,N,N,N,CSR.N,N,N,N,Y),
+ FDIV_D-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, Y,Y,N,Y,N,N,N,CSR.N,N,N,N,Y),
+ FSQRT_D-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, Y,Y,N,Y,N,N,N,CSR.N,N,N,N,Y))
+}
+
+class HDDecode(implicit val p: Parameters) extends DecodeConstants
+{
+ val table: Array[(BitPat, List[BitPat])] = Array(
+ FCVT_D_H-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, Y,N,N,Y,N,N,N,CSR.N,N,N,N,Y),
+ FCVT_H_D-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, Y,N,N,Y,N,N,N,CSR.N,N,N,N,Y))
+}
+
+class H64Decode(implicit val p: Parameters) extends DecodeConstants
+{
+ val table: Array[(BitPat, List[BitPat])] = Array(
+ FCVT_L_H-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, Y,N,N,N,N,N,Y,CSR.N,N,N,N,N),
+ FCVT_LU_H-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, Y,N,N,N,N,N,Y,CSR.N,N,N,N,N),
+ FCVT_H_L-> List(Y,Y,N,N,N,N,N,Y,A2_X, A1_RS1, IMM_X, DW_X, FN_X, N,M_X, N,N,N,Y,N,N,N,CSR.N,N,N,N,N),
+ FCVT_H_LU-> List(Y,Y,N,N,N,N,N,Y,A2_X, A1_RS1, IMM_X, DW_X, FN_X, N,M_X, N,N,N,Y,N,N,N,CSR.N,N,N,N,N))
+}
+
+class F64Decode(implicit val p: Parameters) extends DecodeConstants
+{
+ val table: Array[(BitPat, List[BitPat])] = Array(
+ FCVT_L_S-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, Y,N,N,N,N,N,Y,CSR.N,N,N,N,N),
+ FCVT_LU_S-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, Y,N,N,N,N,N,Y,CSR.N,N,N,N,N),
+ FCVT_S_L-> List(Y,Y,N,N,N,N,N,Y,A2_X, A1_RS1, IMM_X, DW_X, FN_X, N,M_X, N,N,N,Y,N,N,N,CSR.N,N,N,N,N),
+ FCVT_S_LU-> List(Y,Y,N,N,N,N,N,Y,A2_X, A1_RS1, IMM_X, DW_X, FN_X, N,M_X, N,N,N,Y,N,N,N,CSR.N,N,N,N,N))
+}
+
+class D64Decode(implicit val p: Parameters) extends DecodeConstants
+{
+ val table: Array[(BitPat, List[BitPat])] = Array(
+ FMV_X_D-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, Y,N,N,N,N,N,Y,CSR.N,N,N,N,Y),
+ FCVT_L_D-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, Y,N,N,N,N,N,Y,CSR.N,N,N,N,Y),
+ FCVT_LU_D-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, Y,N,N,N,N,N,Y,CSR.N,N,N,N,Y),
+ FMV_D_X-> List(Y,Y,N,N,N,N,N,Y,A2_X, A1_RS1, IMM_X, DW_X, FN_X, N,M_X, N,N,N,Y,N,N,N,CSR.N,N,N,N,Y),
+ FCVT_D_L-> List(Y,Y,N,N,N,N,N,Y,A2_X, A1_RS1, IMM_X, DW_X, FN_X, N,M_X, N,N,N,Y,N,N,N,CSR.N,N,N,N,Y),
+ FCVT_D_LU-> List(Y,Y,N,N,N,N,N,Y,A2_X, A1_RS1, IMM_X, DW_X, FN_X, N,M_X, N,N,N,Y,N,N,N,CSR.N,N,N,N,Y))
+}
+
+class VCFGDecode(implicit val p: Parameters) extends DecodeConstants
+{
+ val table: Array[(BitPat, List[BitPat])] = Array(
+ VSETVLI -> List(Y,N,N,N,N,N,N,Y,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N),
+ VSETIVLI -> List(Y,N,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N),
+ VSETVL -> List(Y,N,N,N,N,N,Y,Y,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N))
+}
+
+class ZbaDecode(implicit val p: Parameters) extends DecodeConstants
+{
+ val table: Array[(BitPat, List[BitPat])] = Array(
+ SH1ADD -> List(Y,N,N,N,N,N,Y,Y,A2_RS2,A1_RS1SHL,IMM_X,DW_XPR,FN_ADD, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N),
+ SH2ADD -> List(Y,N,N,N,N,N,Y,Y,A2_RS2,A1_RS1SHL,IMM_X,DW_XPR,FN_ADD, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N),
+ SH3ADD -> List(Y,N,N,N,N,N,Y,Y,A2_RS2,A1_RS1SHL,IMM_X,DW_XPR,FN_ADD, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N),
+ )
+}
+
+class Zba64Decode(implicit val p: Parameters) extends DecodeConstants
+{
+ val table: Array[(BitPat, List[BitPat])] = Array(
+ SH1ADD_UW-> List(Y,N,N,N,N,N,Y,Y,A2_RS2,A1_RS1SHL,IMM_X, DW_64,FN_ADD, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N),
+ SH2ADD_UW-> List(Y,N,N,N,N,N,Y,Y,A2_RS2,A1_RS1SHL,IMM_X, DW_64,FN_ADD, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N),
+ SH3ADD_UW-> List(Y,N,N,N,N,N,Y,Y,A2_RS2,A1_RS1SHL,IMM_X, DW_64,FN_ADD, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N),
+ ADD_UW -> List(Y,N,N,N,N,N,Y,Y,A2_RS2,A1_RS1SHL,IMM_X, DW_64,FN_ADD, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N),
+ SLLI_UW -> List(Y,N,N,N,N,N,Y,Y,A2_IMM,A1_RS1SHL,IMM_I, DW_64,FN_SL , N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N),
+ )
+}
+
+class ZbbDecode(implicit val p: Parameters) extends DecodeConstants
+{
+ val table: Array[(BitPat, List[BitPat])] = Array(
+ ANDN -> List(Y,N,N,N,N,N,Y,Y,A2_RS2 ,A1_RS1,IMM_X,DW_XPR,FN_ANDN, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N),
+ ORN -> List(Y,N,N,N,N,N,Y,Y,A2_RS2 ,A1_RS1,IMM_X,DW_XPR,FN_ORN, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N),
+ XNOR -> List(Y,N,N,N,N,N,Y,Y,A2_RS2 ,A1_RS1,IMM_X,DW_XPR,FN_XNOR, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N),
+ CLZ -> List(Y,N,N,N,N,N,N,Y,A2_IMM ,A1_RS1,IMM_I,DW_XPR,FN_UNARY, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N),
+ CPOP -> List(Y,N,N,N,N,N,N,Y,A2_IMM ,A1_RS1,IMM_I,DW_XPR,FN_UNARY, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N),
+ CTZ -> List(Y,N,N,N,N,N,N,Y,A2_IMM ,A1_RS1,IMM_I,DW_XPR,FN_UNARY, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N),
+ MAX -> List(Y,N,N,N,N,N,Y,Y,A2_RS2 ,A1_RS1,IMM_X,DW_XPR,FN_MAX, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N),
+ MAXU -> List(Y,N,N,N,N,N,Y,Y,A2_RS2 ,A1_RS1,IMM_X,DW_XPR,FN_MAXU, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N),
+ MIN -> List(Y,N,N,N,N,N,Y,Y,A2_RS2 ,A1_RS1,IMM_X,DW_XPR,FN_MIN, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N),
+ MINU -> List(Y,N,N,N,N,N,Y,Y,A2_RS2 ,A1_RS1,IMM_X,DW_XPR,FN_MINU, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N),
+ ORC_B -> List(Y,N,N,N,N,N,N,Y,A2_IMM ,A1_RS1,IMM_I,DW_XPR,FN_UNARY, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N),
+ ROL -> List(Y,N,N,N,N,N,Y,Y,A2_RS2 ,A1_RS1,IMM_X,DW_XPR,FN_ROL, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N),
+ ROR -> List(Y,N,N,N,N,N,Y,Y,A2_RS2 ,A1_RS1,IMM_X,DW_XPR,FN_ROR, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N),
+ RORI -> List(Y,N,N,N,N,N,N,Y,A2_IMM ,A1_RS1,IMM_I,DW_XPR,FN_ROR, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N),
+ SEXT_B -> List(Y,N,N,N,N,N,N,Y,A2_IMM ,A1_RS1,IMM_I,DW_XPR,FN_UNARY, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N),
+ SEXT_H -> List(Y,N,N,N,N,N,N,Y,A2_IMM ,A1_RS1,IMM_I,DW_XPR,FN_UNARY, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N),
+ )
+}
+
+class Zbb64Decode(implicit val p: Parameters) extends DecodeConstants
+{
+ val table: Array[(BitPat, List[BitPat])] = Array(
+ REV8 -> List(Y,N,N,N,N,N,N,Y,A2_IMM ,A1_RS1,IMM_I,DW_XPR,FN_UNARY, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N),
+ CTZW -> List(Y,N,N,N,N,N,N,Y,A2_IMM ,A1_RS1,IMM_I,DW_32 ,FN_UNARY, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N),
+ CLZW -> List(Y,N,N,N,N,N,N,Y,A2_IMM ,A1_RS1,IMM_I,DW_32 ,FN_UNARY, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N),
+ CPOPW -> List(Y,N,N,N,N,N,N,Y,A2_IMM ,A1_RS1,IMM_I,DW_32 ,FN_UNARY, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N),
+ ROLW -> List(Y,N,N,N,N,N,Y,Y,A2_RS2 ,A1_RS1,IMM_X,DW_32 ,FN_ROL, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N),
+ RORW -> List(Y,N,N,N,N,N,Y,Y,A2_RS2 ,A1_RS1,IMM_X,DW_32 ,FN_ROR, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N),
+ RORIW -> List(Y,N,N,N,N,N,N,Y,A2_IMM ,A1_RS1,IMM_I,DW_32 ,FN_ROR, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N),
+ ZEXT_H -> List(Y,N,N,N,N,N,N,Y,A2_IMM ,A1_RS1,IMM_I,DW_XPR,FN_UNARY, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N),
+ )
+}
+
+class Zbb32Decode(implicit val p: Parameters) extends DecodeConstants
+{
+ val table: Array[(BitPat, List[BitPat])] = Array(
+ Instructions32.REV8 ->
+ List(Y,N,N,N,N,N,N,Y,A2_IMM ,A1_RS1,IMM_I,DW_XPR,FN_UNARY, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N),
+ Instructions32.ZEXT_H ->
+ List(Y,N,N,N,N,N,N,Y,A2_IMM ,A1_RS1,IMM_I,DW_XPR,FN_UNARY, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N),
+ )
+}
+
+class ZbsDecode(implicit val p: Parameters) extends DecodeConstants
+{
+ val table: Array[(BitPat, List[BitPat])] = Array(
+ BCLR -> List(Y,N,N,N,N,N,Y,Y,A2_RS2OH ,A1_RS1,IMM_X,DW_XPR,FN_ANDN, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N),
+ BCLRI -> List(Y,N,N,N,N,N,N,Y,A2_IMMOH ,A1_RS1,IMM_I,DW_XPR,FN_ANDN, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N),
+ BEXT -> List(Y,N,N,N,N,N,Y,Y,A2_RS2 ,A1_RS1,IMM_X,DW_XPR,FN_BEXT, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N),
+ BEXTI -> List(Y,N,N,N,N,N,N,Y,A2_IMM ,A1_RS1,IMM_I,DW_XPR,FN_BEXT, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N),
+ BINV -> List(Y,N,N,N,N,N,Y,Y,A2_RS2OH ,A1_RS1,IMM_X,DW_XPR,FN_XOR , N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N),
+ BINVI -> List(Y,N,N,N,N,N,N,Y,A2_IMMOH ,A1_RS1,IMM_I,DW_XPR,FN_XOR , N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N),
+ BSET -> List(Y,N,N,N,N,N,Y,Y,A2_RS2OH ,A1_RS1,IMM_X,DW_XPR,FN_OR , N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N),
+ BSETI -> List(Y,N,N,N,N,N,N,Y,A2_IMMOH ,A1_RS1,IMM_I,DW_XPR,FN_OR , N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N),
+ )
+}
+
+class RoCCDecode(implicit val p: Parameters) extends DecodeConstants
{
val table: Array[(BitPat, List[BitPat])] = Array(
- FSGNJ_S-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,Y,N,Y,N,N,N,CSR.N,N,N,N,N),
- FSGNJX_S-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,Y,N,Y,N,N,N,CSR.N,N,N,N,N),
- FSGNJN_S-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,Y,N,Y,N,N,N,CSR.N,N,N,N,N),
- FMIN_S-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,Y,N,Y,N,N,N,CSR.N,N,N,N,N),
- FMAX_S-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,Y,N,Y,N,N,N,CSR.N,N,N,N,N),
- FADD_S-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,Y,N,Y,N,N,N,CSR.N,N,N,N,N),
- FSUB_S-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,Y,N,Y,N,N,N,CSR.N,N,N,N,N),
- FMUL_S-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,Y,N,Y,N,N,N,CSR.N,N,N,N,N),
- FMADD_S-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,Y,Y,Y,N,N,N,CSR.N,N,N,N,N),
- FMSUB_S-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,Y,Y,Y,N,N,N,CSR.N,N,N,N,N),
- FNMADD_S-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,Y,Y,Y,N,N,N,CSR.N,N,N,N,N),
- FNMSUB_S-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,Y,Y,Y,N,N,N,CSR.N,N,N,N,N),
- FCLASS_S-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,N,N,N,N,N,Y,CSR.N,N,N,N,N),
- FMV_X_W-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,N,N,N,N,N,Y,CSR.N,N,N,N,N),
- FCVT_W_S-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,N,N,N,N,N,Y,CSR.N,N,N,N,N),
- FCVT_WU_S-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,N,N,N,N,N,Y,CSR.N,N,N,N,N),
- FEQ_S-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,Y,N,N,N,N,Y,CSR.N,N,N,N,N),
- FLT_S-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,Y,N,N,N,N,Y,CSR.N,N,N,N,N),
- FLE_S-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,Y,N,N,N,N,Y,CSR.N,N,N,N,N),
- FMV_W_X-> List(Y,Y,N,N,N,N,N,Y,A2_X, A1_RS1, IMM_X, DW_X, aluFn.FN_X, N,M_X, N,N,N,Y,N,N,N,CSR.N,N,N,N,N),
- FCVT_S_W-> List(Y,Y,N,N,N,N,N,Y,A2_X, A1_RS1, IMM_X, DW_X, aluFn.FN_X, N,M_X, N,N,N,Y,N,N,N,CSR.N,N,N,N,N),
- FCVT_S_WU-> List(Y,Y,N,N,N,N,N,Y,A2_X, A1_RS1, IMM_X, DW_X, aluFn.FN_X, N,M_X, N,N,N,Y,N,N,N,CSR.N,N,N,N,N),
- FLW-> List(Y,Y,N,N,N,N,N,Y,A2_IMM, A1_RS1, IMM_I, DW_XPR,aluFn.FN_ADD, Y,M_XRD, N,N,N,Y,N,N,N,CSR.N,N,N,N,N),
- FSW-> List(Y,Y,N,N,N,N,N,Y,A2_IMM, A1_RS1, IMM_S, DW_XPR,aluFn.FN_ADD, Y,M_XWR, N,Y,N,N,N,N,N,CSR.N,N,N,N,N),
- FDIV_S-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,Y,N,Y,N,N,N,CSR.N,N,N,N,N),
- FSQRT_S-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,Y,N,Y,N,N,N,CSR.N,N,N,N,N))
-}
-
-class DDecode(aluFn: ALUFN = ALUFN())(implicit val p: Parameters) extends DecodeConstants
-{
- val table: Array[(BitPat, List[BitPat])] = Array(
- FCVT_S_D-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,N,N,Y,N,N,N,CSR.N,N,N,N,Y),
- FCVT_D_S-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,N,N,Y,N,N,N,CSR.N,N,N,N,Y),
- FSGNJ_D-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,Y,N,Y,N,N,N,CSR.N,N,N,N,Y),
- FSGNJX_D-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,Y,N,Y,N,N,N,CSR.N,N,N,N,Y),
- FSGNJN_D-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,Y,N,Y,N,N,N,CSR.N,N,N,N,Y),
- FMIN_D-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,Y,N,Y,N,N,N,CSR.N,N,N,N,Y),
- FMAX_D-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,Y,N,Y,N,N,N,CSR.N,N,N,N,Y),
- FADD_D-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,Y,N,Y,N,N,N,CSR.N,N,N,N,Y),
- FSUB_D-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,Y,N,Y,N,N,N,CSR.N,N,N,N,Y),
- FMUL_D-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,Y,N,Y,N,N,N,CSR.N,N,N,N,Y),
- FMADD_D-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,Y,Y,Y,N,N,N,CSR.N,N,N,N,Y),
- FMSUB_D-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,Y,Y,Y,N,N,N,CSR.N,N,N,N,Y),
- FNMADD_D-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,Y,Y,Y,N,N,N,CSR.N,N,N,N,Y),
- FNMSUB_D-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,Y,Y,Y,N,N,N,CSR.N,N,N,N,Y),
- FCLASS_D-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,N,N,N,N,N,Y,CSR.N,N,N,N,Y),
- FCVT_W_D-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,N,N,N,N,N,Y,CSR.N,N,N,N,Y),
- FCVT_WU_D-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,N,N,N,N,N,Y,CSR.N,N,N,N,Y),
- FEQ_D-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,Y,N,N,N,N,Y,CSR.N,N,N,N,Y),
- FLT_D-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,Y,N,N,N,N,Y,CSR.N,N,N,N,Y),
- FLE_D-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,Y,N,N,N,N,Y,CSR.N,N,N,N,Y),
- FCVT_D_W-> List(Y,Y,N,N,N,N,N,Y,A2_X, A1_RS1, IMM_X, DW_X, aluFn.FN_X, N,M_X, N,N,N,Y,N,N,N,CSR.N,N,N,N,Y),
- FCVT_D_WU-> List(Y,Y,N,N,N,N,N,Y,A2_X, A1_RS1, IMM_X, DW_X, aluFn.FN_X, N,M_X, N,N,N,Y,N,N,N,CSR.N,N,N,N,Y),
- FLD-> List(Y,Y,N,N,N,N,N,Y,A2_IMM, A1_RS1, IMM_I, DW_XPR,aluFn.FN_ADD, Y,M_XRD, N,N,N,Y,N,N,N,CSR.N,N,N,N,Y),
- FSD-> List(Y,Y,N,N,N,N,N,Y,A2_IMM, A1_RS1, IMM_S, DW_XPR,aluFn.FN_ADD, Y,M_XWR, N,Y,N,N,N,N,N,CSR.N,N,N,N,Y),
- FDIV_D-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,Y,N,Y,N,N,N,CSR.N,N,N,N,Y),
- FSQRT_D-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,Y,N,Y,N,N,N,CSR.N,N,N,N,Y))
-}
-
-class HDDecode(aluFn: ALUFN = ALUFN())(implicit val p: Parameters) extends DecodeConstants
-{
- val table: Array[(BitPat, List[BitPat])] = Array(
- FCVT_D_H-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,N,N,Y,N,N,N,CSR.N,N,N,N,Y),
- FCVT_H_D-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,N,N,Y,N,N,N,CSR.N,N,N,N,Y))
-}
-
-class H64Decode(aluFn: ALUFN = ALUFN())(implicit val p: Parameters) extends DecodeConstants
-{
- val table: Array[(BitPat, List[BitPat])] = Array(
- FCVT_L_H-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,N,N,N,N,N,Y,CSR.N,N,N,N,N),
- FCVT_LU_H-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,N,N,N,N,N,Y,CSR.N,N,N,N,N),
- FCVT_H_L-> List(Y,Y,N,N,N,N,N,Y,A2_X, A1_RS1, IMM_X, DW_X, aluFn.FN_X, N,M_X, N,N,N,Y,N,N,N,CSR.N,N,N,N,N),
- FCVT_H_LU-> List(Y,Y,N,N,N,N,N,Y,A2_X, A1_RS1, IMM_X, DW_X, aluFn.FN_X, N,M_X, N,N,N,Y,N,N,N,CSR.N,N,N,N,N))
-}
-
-class F64Decode(aluFn: ALUFN = ALUFN())(implicit val p: Parameters) extends DecodeConstants
-{
- val table: Array[(BitPat, List[BitPat])] = Array(
- FCVT_L_S-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,N,N,N,N,N,Y,CSR.N,N,N,N,N),
- FCVT_LU_S-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,N,N,N,N,N,Y,CSR.N,N,N,N,N),
- FCVT_S_L-> List(Y,Y,N,N,N,N,N,Y,A2_X, A1_RS1, IMM_X, DW_X, aluFn.FN_X, N,M_X, N,N,N,Y,N,N,N,CSR.N,N,N,N,N),
- FCVT_S_LU-> List(Y,Y,N,N,N,N,N,Y,A2_X, A1_RS1, IMM_X, DW_X, aluFn.FN_X, N,M_X, N,N,N,Y,N,N,N,CSR.N,N,N,N,N))
-}
-
-class D64Decode(aluFn: ALUFN = ALUFN())(implicit val p: Parameters) extends DecodeConstants
-{
- val table: Array[(BitPat, List[BitPat])] = Array(
- FMV_X_D-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,N,N,N,N,N,Y,CSR.N,N,N,N,Y),
- FCVT_L_D-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,N,N,N,N,N,Y,CSR.N,N,N,N,Y),
- FCVT_LU_D-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,N,N,N,N,N,Y,CSR.N,N,N,N,Y),
- FMV_D_X-> List(Y,Y,N,N,N,N,N,Y,A2_X, A1_RS1, IMM_X, DW_X, aluFn.FN_X, N,M_X, N,N,N,Y,N,N,N,CSR.N,N,N,N,Y),
- FCVT_D_L-> List(Y,Y,N,N,N,N,N,Y,A2_X, A1_RS1, IMM_X, DW_X, aluFn.FN_X, N,M_X, N,N,N,Y,N,N,N,CSR.N,N,N,N,Y),
- FCVT_D_LU-> List(Y,Y,N,N,N,N,N,Y,A2_X, A1_RS1, IMM_X, DW_X, aluFn.FN_X, N,M_X, N,N,N,Y,N,N,N,CSR.N,N,N,N,Y))
-}
-
-class RoCCDecode(aluFn: ALUFN = ALUFN())(implicit val p: Parameters) extends DecodeConstants
-{
- val table: Array[(BitPat, List[BitPat])] = Array(
- CUSTOM0-> List(Y,N,Y,N,N,N,N,N,A2_ZERO,A1_RS1, IMM_X, DW_XPR,aluFn.FN_ADD, N,M_X,N,N,N,N,N,N,N,CSR.N,N,N,N,N),
- CUSTOM0_RS1-> List(Y,N,Y,N,N,N,N,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,aluFn.FN_ADD, N,M_X,N,N,N,N,N,N,N,CSR.N,N,N,N,N),
- CUSTOM0_RS1_RS2-> List(Y,N,Y,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,aluFn.FN_ADD, N,M_X,N,N,N,N,N,N,N,CSR.N,N,N,N,N),
- CUSTOM0_RD-> List(Y,N,Y,N,N,N,N,N,A2_ZERO,A1_RS1, IMM_X, DW_XPR,aluFn.FN_ADD, N,M_X,N,N,N,N,N,N,Y,CSR.N,N,N,N,N),
- CUSTOM0_RD_RS1-> List(Y,N,Y,N,N,N,N,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,aluFn.FN_ADD, N,M_X,N,N,N,N,N,N,Y,CSR.N,N,N,N,N),
- CUSTOM0_RD_RS1_RS2->List(Y,N,Y,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,aluFn.FN_ADD, N,M_X,N,N,N,N,N,N,Y,CSR.N,N,N,N,N),
- CUSTOM1-> List(Y,N,Y,N,N,N,N,N,A2_ZERO,A1_RS1, IMM_X, DW_XPR,aluFn.FN_ADD, N,M_X,N,N,N,N,N,N,N,CSR.N,N,N,N,N),
- CUSTOM1_RS1-> List(Y,N,Y,N,N,N,N,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,aluFn.FN_ADD, N,M_X,N,N,N,N,N,N,N,CSR.N,N,N,N,N),
- CUSTOM1_RS1_RS2-> List(Y,N,Y,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,aluFn.FN_ADD, N,M_X,N,N,N,N,N,N,N,CSR.N,N,N,N,N),
- CUSTOM1_RD-> List(Y,N,Y,N,N,N,N,N,A2_ZERO,A1_RS1, IMM_X, DW_XPR,aluFn.FN_ADD, N,M_X,N,N,N,N,N,N,Y,CSR.N,N,N,N,N),
- CUSTOM1_RD_RS1-> List(Y,N,Y,N,N,N,N,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,aluFn.FN_ADD, N,M_X,N,N,N,N,N,N,Y,CSR.N,N,N,N,N),
- CUSTOM1_RD_RS1_RS2->List(Y,N,Y,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,aluFn.FN_ADD, N,M_X,N,N,N,N,N,N,Y,CSR.N,N,N,N,N),
- CUSTOM2-> List(Y,N,Y,N,N,N,N,N,A2_ZERO,A1_RS1, IMM_X, DW_XPR,aluFn.FN_ADD, N,M_X,N,N,N,N,N,N,N,CSR.N,N,N,N,N),
- CUSTOM2_RS1-> List(Y,N,Y,N,N,N,N,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,aluFn.FN_ADD, N,M_X,N,N,N,N,N,N,N,CSR.N,N,N,N,N),
- CUSTOM2_RS1_RS2-> List(Y,N,Y,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,aluFn.FN_ADD, N,M_X,N,N,N,N,N,N,N,CSR.N,N,N,N,N),
- CUSTOM2_RD-> List(Y,N,Y,N,N,N,N,N,A2_ZERO,A1_RS1, IMM_X, DW_XPR,aluFn.FN_ADD, N,M_X,N,N,N,N,N,N,Y,CSR.N,N,N,N,N),
- CUSTOM2_RD_RS1-> List(Y,N,Y,N,N,N,N,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,aluFn.FN_ADD, N,M_X,N,N,N,N,N,N,Y,CSR.N,N,N,N,N),
- CUSTOM2_RD_RS1_RS2->List(Y,N,Y,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,aluFn.FN_ADD, N,M_X,N,N,N,N,N,N,Y,CSR.N,N,N,N,N),
- CUSTOM3-> List(Y,N,Y,N,N,N,N,N,A2_ZERO,A1_RS1, IMM_X, DW_XPR,aluFn.FN_ADD, N,M_X,N,N,N,N,N,N,N,CSR.N,N,N,N,N),
- CUSTOM3_RS1-> List(Y,N,Y,N,N,N,N,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,aluFn.FN_ADD, N,M_X,N,N,N,N,N,N,N,CSR.N,N,N,N,N),
- CUSTOM3_RS1_RS2-> List(Y,N,Y,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,aluFn.FN_ADD, N,M_X,N,N,N,N,N,N,N,CSR.N,N,N,N,N),
- CUSTOM3_RD-> List(Y,N,Y,N,N,N,N,N,A2_ZERO,A1_RS1, IMM_X, DW_XPR,aluFn.FN_ADD, N,M_X,N,N,N,N,N,N,Y,CSR.N,N,N,N,N),
- CUSTOM3_RD_RS1-> List(Y,N,Y,N,N,N,N,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,aluFn.FN_ADD, N,M_X,N,N,N,N,N,N,Y,CSR.N,N,N,N,N),
- CUSTOM3_RD_RS1_RS2->List(Y,N,Y,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,aluFn.FN_ADD, N,M_X,N,N,N,N,N,N,Y,CSR.N,N,N,N,N))
+ CUSTOM0-> List(Y,N,Y,N,N,N,N,N,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD, N,M_X,N,N,N,N,N,N,N,CSR.N,N,N,N,N),
+ CUSTOM0_RS1-> List(Y,N,Y,N,N,N,N,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD, N,M_X,N,N,N,N,N,N,N,CSR.N,N,N,N,N),
+ CUSTOM0_RS1_RS2-> List(Y,N,Y,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD, N,M_X,N,N,N,N,N,N,N,CSR.N,N,N,N,N),
+ CUSTOM0_RD-> List(Y,N,Y,N,N,N,N,N,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD, N,M_X,N,N,N,N,N,N,Y,CSR.N,N,N,N,N),
+ CUSTOM0_RD_RS1-> List(Y,N,Y,N,N,N,N,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD, N,M_X,N,N,N,N,N,N,Y,CSR.N,N,N,N,N),
+ CUSTOM0_RD_RS1_RS2->List(Y,N,Y,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD, N,M_X,N,N,N,N,N,N,Y,CSR.N,N,N,N,N),
+ CUSTOM1-> List(Y,N,Y,N,N,N,N,N,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD, N,M_X,N,N,N,N,N,N,N,CSR.N,N,N,N,N),
+ CUSTOM1_RS1-> List(Y,N,Y,N,N,N,N,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD, N,M_X,N,N,N,N,N,N,N,CSR.N,N,N,N,N),
+ CUSTOM1_RS1_RS2-> List(Y,N,Y,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD, N,M_X,N,N,N,N,N,N,N,CSR.N,N,N,N,N),
+ CUSTOM1_RD-> List(Y,N,Y,N,N,N,N,N,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD, N,M_X,N,N,N,N,N,N,Y,CSR.N,N,N,N,N),
+ CUSTOM1_RD_RS1-> List(Y,N,Y,N,N,N,N,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD, N,M_X,N,N,N,N,N,N,Y,CSR.N,N,N,N,N),
+ CUSTOM1_RD_RS1_RS2->List(Y,N,Y,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD, N,M_X,N,N,N,N,N,N,Y,CSR.N,N,N,N,N),
+ CUSTOM2-> List(Y,N,Y,N,N,N,N,N,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD, N,M_X,N,N,N,N,N,N,N,CSR.N,N,N,N,N),
+ CUSTOM2_RS1-> List(Y,N,Y,N,N,N,N,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD, N,M_X,N,N,N,N,N,N,N,CSR.N,N,N,N,N),
+ CUSTOM2_RS1_RS2-> List(Y,N,Y,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD, N,M_X,N,N,N,N,N,N,N,CSR.N,N,N,N,N),
+ CUSTOM2_RD-> List(Y,N,Y,N,N,N,N,N,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD, N,M_X,N,N,N,N,N,N,Y,CSR.N,N,N,N,N),
+ CUSTOM2_RD_RS1-> List(Y,N,Y,N,N,N,N,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD, N,M_X,N,N,N,N,N,N,Y,CSR.N,N,N,N,N),
+ CUSTOM2_RD_RS1_RS2->List(Y,N,Y,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD, N,M_X,N,N,N,N,N,N,Y,CSR.N,N,N,N,N),
+ CUSTOM3-> List(Y,N,Y,N,N,N,N,N,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD, N,M_X,N,N,N,N,N,N,N,CSR.N,N,N,N,N),
+ CUSTOM3_RS1-> List(Y,N,Y,N,N,N,N,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD, N,M_X,N,N,N,N,N,N,N,CSR.N,N,N,N,N),
+ CUSTOM3_RS1_RS2-> List(Y,N,Y,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD, N,M_X,N,N,N,N,N,N,N,CSR.N,N,N,N,N),
+ CUSTOM3_RD-> List(Y,N,Y,N,N,N,N,N,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD, N,M_X,N,N,N,N,N,N,Y,CSR.N,N,N,N,N),
+ CUSTOM3_RD_RS1-> List(Y,N,Y,N,N,N,N,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD, N,M_X,N,N,N,N,N,N,Y,CSR.N,N,N,N,N),
+ CUSTOM3_RD_RS1_RS2->List(Y,N,Y,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD, N,M_X,N,N,N,N,N,N,Y,CSR.N,N,N,N,N))
}
diff --git a/src/main/scala/rocket/Multiplier.scala b/src/main/scala/rocket/Multiplier.scala
index fd571024d63..081dd0c841f 100644
--- a/src/main/scala/rocket/Multiplier.scala
+++ b/src/main/scala/rocket/Multiplier.scala
@@ -7,8 +7,10 @@ import chisel3._
import chisel3.util.{Cat, log2Up, log2Ceil, log2Floor, Log2, Decoupled, Enum, Fill, Valid, Pipe}
import freechips.rocketchip.util._
-class MultiplierReq(dataBits: Int, tagBits: Int, aluFn: ALUFN = new ALUFN) extends Bundle {
- val fn = Bits(aluFn.SZ_ALU_FN.W)
+import ALU._
+
+class MultiplierReq(dataBits: Int, tagBits: Int) extends Bundle {
+ val fn = Bits(SZ_ALU_FN.W)
val dw = Bits(SZ_DW.W)
val in1 = Bits(dataBits.W)
val in2 = Bits(dataBits.W)
@@ -17,11 +19,12 @@ class MultiplierReq(dataBits: Int, tagBits: Int, aluFn: ALUFN = new ALUFN) exten
class MultiplierResp(dataBits: Int, tagBits: Int) extends Bundle {
val data = Bits(dataBits.W)
+ val full_data = Bits((2*dataBits).W)
val tag = UInt(tagBits.W)
}
-class MultiplierIO(val dataBits: Int, val tagBits: Int, aluFn: ALUFN = new ALUFN) extends Bundle {
- val req = Flipped(Decoupled(new MultiplierReq(dataBits, tagBits, aluFn)))
+class MultiplierIO(val dataBits: Int, val tagBits: Int) extends Bundle {
+ val req = Flipped(Decoupled(new MultiplierReq(dataBits, tagBits)))
val kill = Input(Bool())
val resp = Decoupled(new MultiplierResp(dataBits, tagBits))
}
@@ -34,12 +37,12 @@ case class MulDivParams(
divEarlyOutGranularity: Int = 1
)
-class MulDiv(cfg: MulDivParams, width: Int, nXpr: Int = 32, aluFn: ALUFN = new ALUFN) extends Module {
+class MulDiv(cfg: MulDivParams, width: Int, nXpr: Int = 32) extends Module {
private def minDivLatency = (cfg.divUnroll > 0).option(if (cfg.divEarlyOut) 3 else 1 + w/cfg.divUnroll)
private def minMulLatency = (cfg.mulUnroll > 0).option(if (cfg.mulEarlyOut) 2 else w/cfg.mulUnroll)
def minLatency: Int = (minDivLatency ++ minMulLatency).min
- val io = IO(new MultiplierIO(width, log2Up(nXpr), aluFn))
+ val io = IO(new MultiplierIO(width, log2Up(nXpr)))
val w = io.req.bits.in1.getWidth
val mulw = if (cfg.mulUnroll == 0) w else (w + cfg.mulUnroll - 1) / cfg.mulUnroll * cfg.mulUnroll
val fastMulW = if (cfg.mulUnroll == 0) false else w/2 > cfg.mulUnroll && w % (2*cfg.mulUnroll) == 0
@@ -58,15 +61,15 @@ class MulDiv(cfg: MulDivParams, width: Int, nXpr: Int = 32, aluFn: ALUFN = new A
val remainder = Reg(Bits((2*mulw+2).W)) // div only needs 2*w+1 bits
val mulDecode = List(
- aluFn.FN_MUL -> List(Y, N, X, X),
- aluFn.FN_MULH -> List(Y, Y, Y, Y),
- aluFn.FN_MULHU -> List(Y, Y, N, N),
- aluFn.FN_MULHSU -> List(Y, Y, Y, N))
+ FN_MUL -> List(Y, N, X, X),
+ FN_MULH -> List(Y, Y, Y, Y),
+ FN_MULHU -> List(Y, Y, N, N),
+ FN_MULHSU -> List(Y, Y, Y, N))
val divDecode = List(
- aluFn.FN_DIV -> List(N, N, Y, Y),
- aluFn.FN_REM -> List(N, Y, Y, Y),
- aluFn.FN_DIVU -> List(N, N, N, N),
- aluFn.FN_REMU -> List(N, Y, N, N))
+ FN_DIV -> List(N, N, Y, Y),
+ FN_REM -> List(N, Y, Y, Y),
+ FN_DIVU -> List(N, N, N, N),
+ FN_REMU -> List(N, Y, N, N))
val cmdMul :: cmdHi :: lhsSigned :: rhsSigned :: Nil =
DecodeLogic(io.req.bits.fn, List(X, X, X, X),
(if (cfg.divUnroll != 0) divDecode else Nil) ++ (if (cfg.mulUnroll != 0) mulDecode else Nil)).map(_.asBool)
@@ -175,23 +178,24 @@ class MulDiv(cfg: MulDivParams, width: Int, nXpr: Int = 32, aluFn: ALUFN = new A
io.resp.bits.tag := req.tag
io.resp.bits.data := Cat(hiOut, loOut)
+ io.resp.bits.full_data := Cat(remainder(2*w, w+1), remainder(w-1, 0))
io.resp.valid := (state === s_done_mul || state === s_done_div)
io.req.ready := state === s_ready
}
-class PipelinedMultiplier(width: Int, latency: Int, nXpr: Int = 32, aluFn: ALUFN = new ALUFN) extends Module with ShouldBeRetimed {
+class PipelinedMultiplier(width: Int, latency: Int, nXpr: Int = 32) extends Module with ShouldBeRetimed {
val io = IO(new Bundle {
- val req = Flipped(Valid(new MultiplierReq(width, log2Ceil(nXpr), aluFn)))
+ val req = Flipped(Valid(new MultiplierReq(width, log2Ceil(nXpr))))
val resp = Valid(new MultiplierResp(width, log2Ceil(nXpr)))
})
val in = Pipe(io.req)
val decode = List(
- aluFn.FN_MUL -> List(N, X, X),
- aluFn.FN_MULH -> List(Y, Y, Y),
- aluFn.FN_MULHU -> List(Y, N, N),
- aluFn.FN_MULHSU -> List(Y, Y, N))
+ FN_MUL -> List(N, X, X),
+ FN_MULH -> List(Y, Y, Y),
+ FN_MULHU -> List(Y, N, N),
+ FN_MULHSU -> List(Y, Y, N))
val cmdHi :: lhsSigned :: rhsSigned :: Nil =
DecodeLogic(in.bits.fn, List(X, X, X), decode).map(_.asBool)
val cmdHalf = (width > 32).B && in.bits.dw === DW_32
@@ -205,4 +209,5 @@ class PipelinedMultiplier(width: Int, latency: Int, nXpr: Int = 32, aluFn: ALUFN
io.resp.valid := resp.valid
io.resp.bits.tag := resp.bits.tag
io.resp.bits.data := Pipe(in.valid, muxed, latency-1).bits
+ io.resp.bits.full_data := Pipe(in.valid, prod, latency-1).bits.asUInt
}
diff --git a/src/main/scala/rocket/NBDcache.scala b/src/main/scala/rocket/NBDcache.scala
index f9161dd5d51..a0f9f72b91b 100644
--- a/src/main/scala/rocket/NBDcache.scala
+++ b/src/main/scala/rocket/NBDcache.scala
@@ -56,6 +56,7 @@ class IOMSHR(id: Int)(implicit edge: TLEdgeOut, p: Parameters) extends L1HellaCa
val mem_access = Decoupled(new TLBundleA(edge.bundle))
val mem_ack = Flipped(Valid(new TLBundleD(edge.bundle)))
val replay_next = Output(Bool())
+ val store_pending = Output(Bool())
})
def beatOffset(addr: UInt) = addr.extract(beatOffBits - 1, wordOffBits)
@@ -68,7 +69,7 @@ class IOMSHR(id: Int)(implicit edge: TLEdgeOut, p: Parameters) extends L1HellaCa
val req = Reg(new HellaCacheReq)
val grant_word = Reg(UInt(wordBits.W))
- val s_idle :: s_mem_access :: s_mem_ack :: s_resp :: Nil = Enum(4)
+ val s_idle :: s_mem_access :: s_mem_ack :: s_resp_1 :: s_resp_2 :: Nil = Enum(5)
val state = RegInit(s_idle)
io.req.ready := (state === s_idle)
@@ -82,7 +83,7 @@ class IOMSHR(id: Int)(implicit edge: TLEdgeOut, p: Parameters) extends L1HellaCa
val get = edge.Get(a_source, a_address, a_size)._2
val put = edge.Put(a_source, a_address, a_size, a_data)._2
val atomics = if (edge.manager.anySupportLogical) {
- MuxLookup(req.cmd, (0.U).asTypeOf(new TLBundleA(edge.bundle)), Array(
+ MuxLookup(req.cmd, (0.U).asTypeOf(new TLBundleA(edge.bundle)))(Array(
M_XA_SWAP -> edge.Logical(a_source, a_address, a_size, a_data, TLAtomics.SWAP)._2,
M_XA_XOR -> edge.Logical(a_source, a_address, a_size, a_data, TLAtomics.XOR) ._2,
M_XA_OR -> edge.Logical(a_source, a_address, a_size, a_data, TLAtomics.OR) ._2,
@@ -102,8 +103,8 @@ class IOMSHR(id: Int)(implicit edge: TLEdgeOut, p: Parameters) extends L1HellaCa
io.mem_access.valid := (state === s_mem_access)
io.mem_access.bits := Mux(isAMO(req.cmd), atomics, Mux(isRead(req.cmd), get, put))
- io.replay_next := (state === s_mem_ack) || io.resp.valid && !io.resp.ready
- io.resp.valid := (state === s_resp)
+ io.replay_next := state === s_resp_1 || (state === s_resp_2 && !io.resp.ready)
+ io.resp.valid := state === s_resp_2
io.resp.bits.addr := req.addr
io.resp.bits.idx.foreach(_ := req.idx.get)
io.resp.bits.tag := req.tag
@@ -119,6 +120,7 @@ class IOMSHR(id: Int)(implicit edge: TLEdgeOut, p: Parameters) extends L1HellaCa
io.resp.bits.data_word_bypass := loadgen.wordData
io.resp.bits.store_data := req.data
io.resp.bits.replay := true.B
+ io.store_pending := state =/= s_idle && isWrite(req.cmd)
when (io.req.fire) {
req := io.req.bits
@@ -130,12 +132,16 @@ class IOMSHR(id: Int)(implicit edge: TLEdgeOut, p: Parameters) extends L1HellaCa
}
when (state === s_mem_ack && io.mem_ack.valid) {
- state := s_resp
+ state := Mux(req.no_resp || !isRead(req.cmd), s_idle, s_resp_1)
when (isRead(req.cmd)) {
grant_word := wordFromBeat(req.addr, io.mem_ack.bits.data)
}
}
+ when (state === s_resp_1) {
+ state := s_resp_2
+ }
+
when (io.resp.fire) {
state := s_idle
}
@@ -331,6 +337,7 @@ class MSHRFile(implicit edge: TLEdgeOut, p: Parameters) extends L1HellaCacheModu
val probe_rdy = Output(Bool())
val fence_rdy = Output(Bool())
val replay_next = Output(Bool())
+ val store_pending = Output(Bool())
})
// determine if the request is cacheable or not
@@ -439,6 +446,8 @@ class MSHRFile(implicit edge: TLEdgeOut, p: Parameters) extends L1HellaCacheModu
TLArbiter.lowestFromSeq(edge, io.mem_acquire, mshrs.map(_.io.mem_acquire) ++ mmios.map(_.io.mem_access))
TLArbiter.lowestFromSeq(edge, io.mem_finish, mshrs.map(_.io.mem_finish))
+ io.store_pending := sdq_val =/= 0.U || mmios.map(_.io.store_pending).orR
+
io.resp <> resp_arb.io.out
io.req.ready := Mux(!cacheable,
mmio_rdy,
@@ -716,8 +725,11 @@ class NonBlockingDCacheModule(outer: NonBlockingDCache) extends HellaCacheModule
val prober = Module(new ProbeUnit)
val mshrs = Module(new MSHRFile)
+ io.tlb_port.req.ready := true.B
io.cpu.req.ready := true.B
val s1_valid = RegNext(io.cpu.req.fire, false.B)
+ val s1_tlb_req_valid = RegNext(io.tlb_port.req.fire, false.B)
+ val s1_tlb_req = RegEnable(io.tlb_port.req.bits, io.tlb_port.req.fire)
val s1_req = Reg(new HellaCacheReq)
val s1_valid_masked = s1_valid && !io.cpu.s1_kill
val s1_replay = RegInit(false.B)
@@ -725,6 +737,7 @@ class NonBlockingDCacheModule(outer: NonBlockingDCache) extends HellaCacheModule
val s1_sfence = s1_req.cmd === M_SFENCE
val s2_valid = RegNext(s1_valid_masked && !s1_sfence, false.B) && !io.cpu.s2_xcpt.asUInt.orR
+ val s2_tlb_req_valid = RegNext(s1_tlb_req_valid, false.B)
val s2_req = Reg(new HellaCacheReq)
val s2_replay = RegNext(s1_replay, false.B) && s2_req.cmd =/= M_FLUSH_ALL
val s2_recycle = Wire(Bool())
@@ -751,6 +764,7 @@ class NonBlockingDCacheModule(outer: NonBlockingDCache) extends HellaCacheModule
dtlb.io.req.bits.cmd := s1_req.cmd
dtlb.io.req.bits.prv := s1_req.dprv
dtlb.io.req.bits.v := s1_req.dv
+ when (s1_tlb_req_valid) { dtlb.io.req.bits := s1_tlb_req }
when (!dtlb.io.req.ready && !io.cpu.req.bits.phys) { io.cpu.req.ready := false.B }
dtlb.io.sfence.valid := s1_valid && !io.cpu.s1_kill && s1_sfence
@@ -778,13 +792,16 @@ class NonBlockingDCacheModule(outer: NonBlockingDCache) extends HellaCacheModule
when (s2_recycle) {
s1_req := s2_req
}
- val s1_addr = dtlb.io.resp.paddr
+ val s1_addr = Mux(s1_req.phys, s1_req.addr, dtlb.io.resp.paddr)
+
+ io.tlb_port.s1_resp := dtlb.io.resp
when (s1_clk_en) {
s2_req.size := s1_req.size
s2_req.signed := s1_req.signed
s2_req.phys := s1_req.phys
s2_req.addr := s1_addr
+ s2_req.no_resp := s1_req.no_resp
when (s1_write) {
s2_req.data := Mux(s1_replay, mshrs.io.replay.bits.data, io.cpu.s1_data.data)
}
@@ -990,7 +1007,7 @@ class NonBlockingDCacheModule(outer: NonBlockingDCache) extends HellaCacheModule
amoalu.io.rhs := s2_req.data
// nack it like it's hot
- val s1_nack = dtlb.io.req.valid && dtlb.io.resp.miss || io.cpu.s2_nack ||
+ val s1_nack = dtlb.io.req.valid && dtlb.io.resp.miss || io.cpu.s2_nack || s1_tlb_req_valid ||
s1_req.addr(idxMSB,idxLSB) === prober.io.meta_write.bits.idx && !prober.io.req.ready
val s2_nack_hit = RegEnable(s1_nack, s1_valid || s1_replay)
when (s2_nack_hit) { mshrs.io.req.valid := false.B }
@@ -1039,6 +1056,7 @@ class NonBlockingDCacheModule(outer: NonBlockingDCache) extends HellaCacheModule
io.cpu.resp.bits.data_word_bypass := loadgen.wordData
io.cpu.resp.bits.data_raw := s2_data_word
io.cpu.ordered := mshrs.io.fence_rdy && !s1_valid && !s2_valid
+ io.cpu.store_pending := mshrs.io.store_pending
io.cpu.replay_next := (s1_replay && s1_read) || mshrs.io.replay_next
val s1_xcpt_valid = dtlb.io.req.valid && !s1_nack
diff --git a/src/main/scala/rocket/PMA.scala b/src/main/scala/rocket/PMA.scala
new file mode 100644
index 00000000000..b2144e6b38a
--- /dev/null
+++ b/src/main/scala/rocket/PMA.scala
@@ -0,0 +1,49 @@
+// See LICENSE.SiFive for license details.
+// See LICENSE.Berkeley for license details.
+
+package freechips.rocketchip.rocket
+
+import chisel3._
+import chisel3.util._
+import chisel3.experimental.SourceInfo
+
+import org.chipsalliance.cde.config._
+
+import freechips.rocketchip.devices.debug.DebugModuleKey
+import freechips.rocketchip.diplomacy.RegionType
+import freechips.rocketchip.subsystem.CacheBlockBytes
+import freechips.rocketchip.tile.{CoreModule, CoreBundle}
+import freechips.rocketchip.tilelink.{TLSlavePortParameters, TLManagerParameters}
+
+class PMAChecker(manager: TLSlavePortParameters)(implicit p: Parameters) extends CoreModule()(p) {
+ val io = IO(new Bundle {
+ val paddr = Input(UInt())
+
+ val resp = Output(new Bundle {
+ val cacheable = Bool()
+ val r = Bool()
+ val w = Bool()
+ val pp = Bool()
+ val al = Bool()
+ val aa = Bool()
+ val x = Bool()
+ val eff = Bool()
+ })
+ })
+
+ // PMA
+ // check exist a slave can consume this address.
+ val legal_address = manager.findSafe(io.paddr).reduce(_||_)
+ // check utility to help check SoC property.
+ def fastCheck(member: TLManagerParameters => Boolean) =
+ legal_address && manager.fastProperty(io.paddr, member, (b:Boolean) => b.B)
+
+ io.resp.cacheable := fastCheck(_.supportsAcquireB)
+ io.resp.r := fastCheck(_.supportsGet)
+ io.resp.w := fastCheck(_.supportsPutFull)
+ io.resp.pp := fastCheck(_.supportsPutPartial)
+ io.resp.al := fastCheck(_.supportsLogical)
+ io.resp.aa := fastCheck(_.supportsArithmetic)
+ io.resp.x := fastCheck(_.executable)
+ io.resp.eff := fastCheck(Seq(RegionType.PUT_EFFECTS, RegionType.GET_EFFECTS) contains _.regionType)
+}
diff --git a/src/main/scala/rocket/PMP.scala b/src/main/scala/rocket/PMP.scala
index 11fe95d9e0b..2ccd58ce822 100644
--- a/src/main/scala/rocket/PMP.scala
+++ b/src/main/scala/rocket/PMP.scala
@@ -142,6 +142,7 @@ class PMPHomogeneityChecker(pmps: Seq[PMP])(implicit p: Parameters) {
class PMPChecker(lgMaxSize: Int)(implicit val p: Parameters) extends Module
with HasCoreParameters {
+ override def desiredName = s"PMPChecker_s${lgMaxSize}"
val io = IO(new Bundle {
val prv = Input(UInt(PRV.SZ.W))
val pmp = Input(Vec(nPMPs, new PMP))
diff --git a/src/main/scala/rocket/PTW.scala b/src/main/scala/rocket/PTW.scala
index 91b9a7bb2f1..872b143e24c 100644
--- a/src/main/scala/rocket/PTW.scala
+++ b/src/main/scala/rocket/PTW.scala
@@ -522,6 +522,7 @@ class PTW(n: Int)(implicit edge: TLEdgeOut, p: Parameters) extends CoreModule()(
io.mem.req.bits.dprv := PRV.S.U // PTW accesses are S-mode by definition
io.mem.req.bits.dv := do_both_stages && !stage2
io.mem.req.bits.tag := DontCare
+ io.mem.req.bits.no_resp := false.B
io.mem.req.bits.no_alloc := DontCare
io.mem.req.bits.no_xcpt := DontCare
io.mem.req.bits.data := DontCare
@@ -540,7 +541,7 @@ class PTW(n: Int)(implicit edge: TLEdgeOut, p: Parameters) extends CoreModule()(
require(TLBPageLookup.homogeneous(edge.manager.managers, pgSize), s"All memory regions must be $pgSize-byte aligned")
true.B
} else {
- TLBPageLookup(edge.manager.managers, xLen, p(CacheBlockBytes), pgSize)(r_pte.ppn << pgIdxBits).homogeneous
+ TLBPageLookup(edge.manager.managers, xLen, p(CacheBlockBytes), pgSize, xLen/8)(r_pte.ppn << pgIdxBits).homogeneous
}
}
val pmaHomogeneous = pmaPgLevelHomogeneous(count)
@@ -694,7 +695,7 @@ class PTW(n: Int)(implicit edge: TLEdgeOut, p: Parameters) extends CoreModule()(
when (do_both_stages && !stage2) { do_switch := true.B }
count := count + 1.U
}.otherwise {
- val gf = stage2 && !stage2_final && !pte.ur()
+ val gf = (stage2 && !stage2_final && !pte.ur()) || (pte.leaf() && pte.reserved_for_future === 0.U && invalid_gpa)
val ae = pte.v && invalid_paddr
val pf = pte.v && pte.reserved_for_future =/= 0.U
val success = pte.v && !ae && !pf && !gf
@@ -722,7 +723,7 @@ class PTW(n: Int)(implicit edge: TLEdgeOut, p: Parameters) extends CoreModule()(
}
resp_ae_ptw := ae && count < (pgLevels-1).U && pte.table()
- resp_ae_final := ae
+ resp_ae_final := ae && pte.leaf()
resp_pf := pf && !stage2
resp_gf := gf || (pf && stage2)
resp_hr := !stage2 || (!pf && !gf && pte.ur())
diff --git a/src/main/scala/rocket/RVC.scala b/src/main/scala/rocket/RVC.scala
index cc54c293558..c9252c086cf 100644
--- a/src/main/scala/rocket/RVC.scala
+++ b/src/main/scala/rocket/RVC.scala
@@ -16,7 +16,7 @@ class ExpandedInstruction extends Bundle {
val rs3 = UInt(5.W)
}
-class RVCDecoder(x: UInt, xLen: Int, useAddiForMv: Boolean = false) {
+class RVCDecoder(x: UInt, xLen: Int, fLen: Int, useAddiForMv: Boolean = false) {
def inst(bits: UInt, rd: UInt = x(11,7), rs1: UInt = x(19,15), rs2: UInt = x(24,20), rs3: UInt = x(31,27)) = {
val res = Wire(new ExpandedInstruction)
res.bits := bits
@@ -153,6 +153,38 @@ class RVCDecoder(x: UInt, xLen: Int, useAddiForMv: Boolean = false) {
val s = q0 ++ q1 ++ q2 ++ q3
s(Cat(x(1,0), x(15,13)))
}
+
+ def q0_ill = {
+ def allz = !(x(12, 2).orR)
+ def fld = if (fLen >= 64) false.B else true.B
+ def flw32 = if (xLen == 64 || fLen >= 32) false.B else true.B
+ def fsd = if (fLen >= 64) false.B else true.B
+ def fsw32 = if (xLen == 64 || fLen >= 32) false.B else true.B
+ Seq(allz, fld, false.B, flw32, true.B, fsd, false.B, fsw32)
+ }
+
+ def q1_ill = {
+ def rd0 = if (xLen == 32) false.B else rd === 0.U
+ def immz = !(x(12) | x(6, 2).orR)
+ def arith_res = x(12, 10).andR && (if (xLen == 32) true.B else x(6) === 1.U)
+ Seq(false.B, rd0, false.B, immz, arith_res, false.B, false.B, false.B)
+ }
+
+ def q2_ill = {
+ def fldsp = if (fLen >= 64) false.B else true.B
+ def rd0 = rd === 0.U
+ def flwsp = if (xLen == 64) rd0 else if (fLen >= 32) false.B else true.B
+ def jr_res = !(x(12 ,2).orR)
+ def fsdsp = if (fLen >= 64) false.B else true.B
+ def fswsp32 = if (xLen == 64) false.B else if (fLen >= 32) false.B else true.B
+ Seq(false.B, fldsp, rd0, flwsp, jr_res, fsdsp, false.B, fswsp32)
+ }
+ def q3_ill = Seq.fill(8)(false.B)
+
+ def ill = {
+ val s = q0_ill ++ q1_ill ++ q2_ill ++ q3_ill
+ s(Cat(x(1,0), x(15,13)))
+ }
}
class RVCExpander(useAddiForMv: Boolean = false)(implicit val p: Parameters) extends Module with HasCoreParameters {
@@ -160,13 +192,17 @@ class RVCExpander(useAddiForMv: Boolean = false)(implicit val p: Parameters) ext
val in = Input(UInt(32.W))
val out = Output(new ExpandedInstruction)
val rvc = Output(Bool())
+ val ill = Output(Bool())
})
if (usingCompressed) {
io.rvc := io.in(1,0) =/= 3.U
- io.out := new RVCDecoder(io.in, p(XLen), useAddiForMv).decode
+ val decoder = new RVCDecoder(io.in, xLen, fLen, useAddiForMv)
+ io.out := decoder.decode
+ io.ill := decoder.ill
} else {
io.rvc := false.B
- io.out := new RVCDecoder(io.in, p(XLen), useAddiForMv).passthrough
+ io.out := new RVCDecoder(io.in, xLen, fLen, useAddiForMv).passthrough
+ io.ill := false.B // only used for RVC
}
}
diff --git a/src/main/scala/rocket/RocketCore.scala b/src/main/scala/rocket/RocketCore.scala
index 65f8c73234a..1491a4143e1 100644
--- a/src/main/scala/rocket/RocketCore.scala
+++ b/src/main/scala/rocket/RocketCore.scala
@@ -13,6 +13,8 @@ import freechips.rocketchip.util.property
import scala.collection.mutable.ArrayBuffer
case class RocketCoreParams(
+ xLen: Int = 64,
+ pgLevels: Int = 3, // sv39 default
bootFreqHz: BigInt = 0,
useVM: Boolean = true,
useUser: Boolean = false,
@@ -24,6 +26,9 @@ case class RocketCoreParams(
useCompressed: Boolean = true,
useRVE: Boolean = false,
useConditionalZero: Boolean = false,
+ useZba: Boolean = false,
+ useZbb: Boolean = false,
+ useZbs: Boolean = false,
nLocalInterrupts: Int = 0,
useNMI: Boolean = false,
nBreakpoints: Int = 1,
@@ -48,9 +53,10 @@ case class RocketCoreParams(
mimpid: Int = 0x20181004, // release date in BCD
mulDiv: Option[MulDivParams] = Some(MulDivParams()),
fpu: Option[FPUParams] = Some(FPUParams()),
- debugROB: Boolean = false, // if enabled, uses a C++ debug ROB to generate trace-with-wdata
+ debugROB: Option[DebugROBParams] = None, // if size < 1, SW ROB, else HW ROB
haveCease: Boolean = true, // non-standard CEASE instruction
- haveSimTimeout: Boolean = true // add plusarg for simulation timeout
+ haveSimTimeout: Boolean = true, // add plusarg for simulation timeout
+ vector: Option[RocketCoreVectorParams] = None
) extends CoreParams {
val lgPauseCycles = 5
val haveFSDirty = false
@@ -61,7 +67,15 @@ case class RocketCoreParams(
val retireWidth: Int = 1
val instBits: Int = if (useCompressed) 16 else 32
val lrscCycles: Int = 80 // worst case is 14 mispredicted branches + slop
- val traceHasWdata: Boolean = false // ooo wb, so no wdata in trace
+ val traceHasWdata: Boolean = debugROB.isDefined // ooo wb, so no wdata in trace
+ override val useVector = vector.isDefined
+ override val vectorUseDCache = vector.map(_.useDCache).getOrElse(false)
+ override def vLen = vector.map(_.vLen).getOrElse(0)
+ override def eLen = vector.map(_.eLen).getOrElse(0)
+ override def vfLen = vector.map(_.vfLen).getOrElse(0)
+ override def vfh = vector.map(_.vfh).getOrElse(false)
+ override def vExts = vector.map(_.vExts).getOrElse(Nil)
+ override def vMemDataBits = vector.map(_.vMemDataBits).getOrElse(0)
override val customIsaExt = Option.when(haveCease)("xrocket") // CEASE instruction
override def minFLen: Int = fpu.map(_.minFLen).getOrElse(32)
override def customCSRs(implicit p: Parameters) = new RocketCustomCSRs
@@ -75,8 +89,6 @@ trait HasRocketCoreParameters extends HasCoreParameters {
val mulDivParams = rocketParams.mulDiv.getOrElse(MulDivParams()) // TODO ask andrew about this
- val aluFn = new ALUFN
-
require(!fastLoadByte || fastLoadWord)
require(!rocketParams.haveFSDirty, "rocket doesn't support setting fs dirty from outside, please disable haveFSDirty")
}
@@ -112,10 +124,37 @@ class RocketCustomCSRs(implicit p: Parameters) extends CustomCSRs with HasRocket
override def decls = super.decls :+ marchid :+ mvendorid :+ mimpid
}
+class CoreInterrupts(val hasBeu: Boolean)(implicit p: Parameters) extends TileInterrupts()(p) {
+ val buserror = Option.when(hasBeu)(Bool())
+}
+
+trait HasRocketCoreIO extends HasRocketCoreParameters {
+ implicit val p: Parameters
+ def nTotalRoCCCSRs: Int
+ val io = IO(new CoreBundle()(p) {
+ val hartid = Input(UInt(hartIdLen.W))
+ val reset_vector = Input(UInt(resetVectorLen.W))
+ val interrupts = Input(new CoreInterrupts(tileParams.asInstanceOf[RocketTileParams].beuAddr.isDefined))
+ val imem = new FrontendIO
+ val dmem = new HellaCacheIO
+ val ptw = Flipped(new DatapathPTWIO())
+ val fpu = Flipped(new FPUCoreIO())
+ val rocc = Flipped(new RoCCCoreIO(nTotalRoCCCSRs))
+ val trace = Output(new TraceBundle)
+ val bpwatch = Output(Vec(coreParams.nBreakpoints, new BPWatch(coreParams.retireWidth)))
+ val cease = Output(Bool())
+ val wfi = Output(Bool())
+ val traceStall = Input(Bool())
+ val vector = if (usingVector) Some(Flipped(new VectorCoreIO)) else None
+ })
+}
+
+
class Rocket(tile: RocketTile)(implicit p: Parameters) extends CoreModule()(p)
with HasRocketCoreParameters
- with HasCoreIO {
+ with HasRocketCoreIO {
def nTotalRoCCCSRs = tile.roccCSRs.flatten.size
+ import ALU._
val clock_en_reg = RegInit(true.B)
val long_latency_stall = Reg(Bool())
@@ -143,8 +182,8 @@ class Rocket(tile: RocketTile)(implicit p: Parameters) extends CoreModule()(p)
("jal", () => id_ctrl.jal),
("jalr", () => id_ctrl.jalr))
++ (if (!usingMulDiv) Seq() else Seq(
- ("mul", () => if (pipelinedMul) id_ctrl.mul else id_ctrl.div && (id_ctrl.alu_fn & aluFn.FN_DIV) =/= aluFn.FN_DIV),
- ("div", () => if (pipelinedMul) id_ctrl.div else id_ctrl.div && (id_ctrl.alu_fn & aluFn.FN_DIV) === aluFn.FN_DIV)))
+ ("mul", () => if (pipelinedMul) id_ctrl.mul else id_ctrl.div && (id_ctrl.alu_fn & FN_DIV) =/= FN_DIV),
+ ("div", () => if (pipelinedMul) id_ctrl.div else id_ctrl.div && (id_ctrl.alu_fn & FN_DIV) === FN_DIV)))
++ (if (!usingFPU) Seq() else Seq(
("fp load", () => id_ctrl.fp && io.fpu.dec.ldst && io.fpu.dec.wen),
("fp store", () => id_ctrl.fp && io.fpu.dec.ldst && !io.fpu.dec.wen),
@@ -177,29 +216,33 @@ class Rocket(tile: RocketTile)(implicit p: Parameters) extends CoreModule()(p)
val pipelinedMul = usingMulDiv && mulDivParams.mulUnroll == xLen
val decode_table = {
- (if (usingMulDiv) new MDecode(pipelinedMul, aluFn) +: (xLen > 32).option(new M64Decode(pipelinedMul, aluFn)).toSeq else Nil) ++:
- (if (usingAtomics) new ADecode(aluFn) +: (xLen > 32).option(new A64Decode(aluFn)).toSeq else Nil) ++:
- (if (fLen >= 32) new FDecode(aluFn) +: (xLen > 32).option(new F64Decode(aluFn)).toSeq else Nil) ++:
- (if (fLen >= 64) new DDecode(aluFn) +: (xLen > 32).option(new D64Decode(aluFn)).toSeq else Nil) ++:
- (if (minFLen == 16) new HDecode(aluFn) +: (xLen > 32).option(new H64Decode(aluFn)).toSeq ++: (fLen >= 64).option(new HDDecode(aluFn)).toSeq else Nil) ++:
- (usingRoCC.option(new RoCCDecode(aluFn))) ++:
- (if (xLen == 32) new I32Decode(aluFn) else new I64Decode(aluFn)) +:
- (usingVM.option(new SVMDecode(aluFn))) ++:
- (usingSupervisor.option(new SDecode(aluFn))) ++:
- (usingHypervisor.option(new HypervisorDecode(aluFn))) ++:
- ((usingHypervisor && (xLen == 64)).option(new Hypervisor64Decode(aluFn))) ++:
- (usingDebug.option(new DebugDecode(aluFn))) ++:
- (usingNMI.option(new NMIDecode(aluFn))) ++:
- (usingConditionalZero.option(new ConditionalZeroDecode(aluFn))) ++:
- Seq(new FenceIDecode(tile.dcache.flushOnFenceI, aluFn)) ++:
- coreParams.haveCFlush.option(new CFlushDecode(tile.dcache.canSupportCFlushLine, aluFn)) ++:
- rocketParams.haveCease.option(new CeaseDecode(aluFn)) ++:
- Seq(new IDecode(aluFn))
+ (if (usingMulDiv) new MDecode(pipelinedMul) +: (xLen > 32).option(new M64Decode(pipelinedMul)).toSeq else Nil) ++:
+ (if (usingAtomics) new ADecode +: (xLen > 32).option(new A64Decode).toSeq else Nil) ++:
+ (if (fLen >= 32) new FDecode +: (xLen > 32).option(new F64Decode).toSeq else Nil) ++:
+ (if (fLen >= 64) new DDecode +: (xLen > 32).option(new D64Decode).toSeq else Nil) ++:
+ (if (minFLen == 16) new HDecode +: (xLen > 32).option(new H64Decode).toSeq ++: (fLen >= 64).option(new HDDecode).toSeq else Nil) ++:
+ (usingRoCC.option(new RoCCDecode)) ++:
+ (if (xLen == 32) new I32Decode else new I64Decode) +:
+ (usingVM.option(new SVMDecode)) ++:
+ (usingSupervisor.option(new SDecode)) ++:
+ (usingHypervisor.option(new HypervisorDecode)) ++:
+ ((usingHypervisor && (xLen == 64)).option(new Hypervisor64Decode)) ++:
+ (usingDebug.option(new DebugDecode)) ++:
+ (usingNMI.option(new NMIDecode)) ++:
+ (usingConditionalZero.option(new ConditionalZeroDecode)) ++:
+ Seq(new FenceIDecode(tile.dcache.flushOnFenceI)) ++:
+ coreParams.haveCFlush.option(new CFlushDecode(tile.dcache.canSupportCFlushLine)) ++:
+ rocketParams.haveCease.option(new CeaseDecode) ++:
+ usingVector.option(new VCFGDecode) ++:
+ (if (coreParams.useZba) new ZbaDecode +: (xLen > 32).option(new Zba64Decode).toSeq else Nil) ++:
+ (if (coreParams.useZbb) Seq(new ZbbDecode, if (xLen == 32) new Zbb32Decode else new Zbb64Decode) else Nil) ++:
+ coreParams.useZbs.option(new ZbsDecode) ++:
+ Seq(new IDecode)
} flatMap(_.table)
- val ex_ctrl = Reg(new IntCtrlSigs(aluFn))
- val mem_ctrl = Reg(new IntCtrlSigs(aluFn))
- val wb_ctrl = Reg(new IntCtrlSigs(aluFn))
+ val ex_ctrl = Reg(new IntCtrlSigs)
+ val mem_ctrl = Reg(new IntCtrlSigs)
+ val wb_ctrl = Reg(new IntCtrlSigs)
val ex_reg_xcpt_interrupt = Reg(Bool())
val ex_reg_valid = Reg(Bool())
@@ -216,6 +259,7 @@ class Rocket(tile: RocketTile)(implicit p: Parameters) extends CoreModule()(p)
val ex_reg_inst = Reg(Bits())
val ex_reg_raw_inst = Reg(UInt())
val ex_reg_wphit = Reg(Vec(nBreakpoints, Bool()))
+ val ex_reg_set_vconfig = Reg(Bool())
val mem_reg_xcpt_interrupt = Reg(Bool())
val mem_reg_valid = Reg(Bool())
@@ -228,6 +272,7 @@ class Rocket(tile: RocketTile)(implicit p: Parameters) extends CoreModule()(p)
val mem_reg_slow_bypass = Reg(Bool())
val mem_reg_load = Reg(Bool())
val mem_reg_store = Reg(Bool())
+ val mem_reg_set_vconfig = Reg(Bool())
val mem_reg_sfence = Reg(Bool())
val mem_reg_pc = Reg(UInt())
val mem_reg_inst = Reg(Bits())
@@ -245,6 +290,7 @@ class Rocket(tile: RocketTile)(implicit p: Parameters) extends CoreModule()(p)
val wb_reg_replay = Reg(Bool())
val wb_reg_flush_pipe = Reg(Bool())
val wb_reg_cause = Reg(UInt())
+ val wb_reg_set_vconfig = Reg(Bool())
val wb_reg_sfence = Reg(Bool())
val wb_reg_pc = Reg(UInt())
val wb_reg_mem_size = Reg(UInt())
@@ -272,7 +318,8 @@ class Rocket(tile: RocketTile)(implicit p: Parameters) extends CoreModule()(p)
require(decodeWidth == 1 /* TODO */ && retireWidth == decodeWidth)
require(!(coreParams.useRVE && coreParams.fpu.nonEmpty), "Can't select both RVE and floating-point")
require(!(coreParams.useRVE && coreParams.useHypervisor), "Can't select both RVE and Hypervisor")
- val id_ctrl = Wire(new IntCtrlSigs(aluFn)).decode(id_inst(0), decode_table)
+ val id_ctrl = Wire(new IntCtrlSigs).decode(id_inst(0), decode_table)
+
val lgNXRegs = if (coreParams.useRVE) 4 else 5
val regAddrMask = (1 << lgNXRegs) - 1
@@ -291,17 +338,51 @@ class Rocket(tile: RocketTile)(implicit p: Parameters) extends CoreModule()(p)
val ctrl_killd = Wire(Bool())
val id_npc = (ibuf.io.pc.asSInt + ImmGen(IMM_UJ, id_inst(0))).asUInt
- val csr = Module(new CSRFile(perfEvents, coreParams.customCSRs.decls, tile.roccCSRs.flatten))
+ val csr = Module(new CSRFile(perfEvents, coreParams.customCSRs.decls, tile.roccCSRs.flatten, tile.rocketParams.beuAddr.isDefined))
val id_csr_en = id_ctrl.csr.isOneOf(CSR.S, CSR.C, CSR.W)
val id_system_insn = id_ctrl.csr === CSR.I
val id_csr_ren = id_ctrl.csr.isOneOf(CSR.S, CSR.C) && id_expanded_inst(0).rs1 === 0.U
val id_csr = Mux(id_system_insn && id_ctrl.mem, CSR.N, Mux(id_csr_ren, CSR.R, id_ctrl.csr))
val id_csr_flush = id_system_insn || (id_csr_en && !id_csr_ren && csr.io.decode(0).write_flush)
+ val id_set_vconfig = Seq(Instructions.VSETVLI, Instructions.VSETIVLI, Instructions.VSETVL).map(_ === id_inst(0)).orR && usingVector.B
+
+ id_ctrl.vec := false.B
+ if (usingVector) {
+ val v_decode = rocketParams.vector.get.decoder(p)
+ v_decode.io.inst := id_inst(0)
+ v_decode.io.vconfig := csr.io.vector.get.vconfig
+ when (v_decode.io.legal) {
+ id_ctrl.legal := !csr.io.vector.get.vconfig.vtype.vill
+ id_ctrl.fp := v_decode.io.fp
+ id_ctrl.rocc := false.B
+ id_ctrl.branch := false.B
+ id_ctrl.jal := false.B
+ id_ctrl.jalr := false.B
+ id_ctrl.rxs2 := v_decode.io.read_rs2
+ id_ctrl.rxs1 := v_decode.io.read_rs1
+ id_ctrl.mem := false.B
+ id_ctrl.rfs1 := v_decode.io.read_frs1
+ id_ctrl.rfs2 := false.B
+ id_ctrl.rfs3 := false.B
+ id_ctrl.wfd := v_decode.io.write_frd
+ id_ctrl.mul := false.B
+ id_ctrl.div := false.B
+ id_ctrl.wxd := v_decode.io.write_rd
+ id_ctrl.csr := CSR.N
+ id_ctrl.fence_i := false.B
+ id_ctrl.fence := false.B
+ id_ctrl.amo := false.B
+ id_ctrl.dp := false.B
+ id_ctrl.vec := true.B
+ }
+ }
+
val id_illegal_insn = !id_ctrl.legal ||
(id_ctrl.mul || id_ctrl.div) && !csr.io.status.isa('m'-'a') ||
id_ctrl.amo && !csr.io.status.isa('a'-'a') ||
- id_ctrl.fp && (csr.io.decode(0).fp_illegal || io.fpu.illegal_rm) ||
+ id_ctrl.fp && (csr.io.decode(0).fp_illegal || (io.fpu.illegal_rm && !id_ctrl.vec)) ||
+ (id_ctrl.vec) && (csr.io.decode(0).vector_illegal || csr.io.vector.map(_.vconfig.vtype.vill).getOrElse(false.B)) ||
id_ctrl.dp && !csr.io.status.isa('d'-'a') ||
ibuf.io.inst(0).bits.rvc && !csr.io.status.isa('c'-'a') ||
id_raddr2_illegal && id_ctrl.rxs2 ||
@@ -324,7 +405,10 @@ class Rocket(tile: RocketTile)(implicit p: Parameters) extends CoreModule()(p)
val id_rocc_busy = usingRoCC.B &&
(io.rocc.busy || ex_reg_valid && ex_ctrl.rocc ||
mem_reg_valid && mem_ctrl.rocc || wb_reg_valid && wb_ctrl.rocc)
- val id_do_fence = WireDefault(id_rocc_busy && id_ctrl.fence ||
+ val id_csr_rocc_write = tile.roccCSRs.flatten.map(_.id.U === id_inst(0)(31,20)).orR && id_csr_en && !id_csr_ren
+ val id_vec_busy = io.vector.map(v => v.backend_busy || v.trap_check_busy).getOrElse(false.B)
+ val id_do_fence = WireDefault(id_rocc_busy && (id_ctrl.fence || id_csr_rocc_write) ||
+ id_vec_busy && id_ctrl.fence ||
id_mem_busy && (id_ctrl.amo && id_amo_rl || id_ctrl.fence_i || id_reg_fence && (id_ctrl.mem || id_ctrl.rocc)))
val bpu = Module(new BreakpointUnit(nBreakpoints))
@@ -384,24 +468,47 @@ class Rocket(tile: RocketTile)(implicit p: Parameters) extends CoreModule()(p)
val ex_rs = for (i <- 0 until id_raddr.size)
yield Mux(ex_reg_rs_bypass(i), bypass_mux(ex_reg_rs_lsb(i)), Cat(ex_reg_rs_msb(i), ex_reg_rs_lsb(i)))
val ex_imm = ImmGen(ex_ctrl.sel_imm, ex_reg_inst)
- val ex_op1 = MuxLookup(ex_ctrl.sel_alu1, 0.S, Seq(
+ val ex_rs1shl = Mux(ex_reg_inst(3), ex_rs(0)(31,0), ex_rs(0)) << ex_reg_inst(14,13)
+ val ex_op1 = MuxLookup(ex_ctrl.sel_alu1, 0.S)(Seq(
A1_RS1 -> ex_rs(0).asSInt,
- A1_PC -> ex_reg_pc.asSInt))
- val ex_op2 = MuxLookup(ex_ctrl.sel_alu2, 0.S, Seq(
+ A1_PC -> ex_reg_pc.asSInt,
+ A1_RS1SHL -> (if (rocketParams.useZba) ex_rs1shl.asSInt else 0.S)
+ ))
+ val ex_op2_oh = UIntToOH(Mux(ex_ctrl.sel_alu2(0), (ex_reg_inst >> 20).asUInt, ex_rs(1))(log2Ceil(xLen)-1,0)).asSInt
+ val ex_op2 = MuxLookup(ex_ctrl.sel_alu2, 0.S)(Seq(
A2_RS2 -> ex_rs(1).asSInt,
A2_IMM -> ex_imm,
- A2_SIZE -> Mux(ex_reg_rvc, 2.S, 4.S)))
-
- val alu = Module(aluFn match {
- case _: ALUFN => new ALU
- })
+ A2_SIZE -> Mux(ex_reg_rvc, 2.S, 4.S),
+ ) ++ (if (coreParams.useZbs) Seq(
+ A2_RS2OH -> ex_op2_oh,
+ A2_IMMOH -> ex_op2_oh,
+ ) else Nil))
+
+ val (ex_new_vl, ex_new_vconfig) = if (usingVector) {
+ val ex_new_vtype = VType.fromUInt(MuxCase(ex_rs(1), Seq(
+ ex_reg_inst(31,30).andR -> ex_reg_inst(29,20),
+ !ex_reg_inst(31) -> ex_reg_inst(30,20))))
+ val ex_avl = Mux(ex_ctrl.rxs1,
+ Mux(ex_reg_inst(19,15) === 0.U,
+ Mux(ex_reg_inst(11,7) === 0.U, csr.io.vector.get.vconfig.vl, ex_new_vtype.vlMax),
+ ex_rs(0)
+ ),
+ ex_reg_inst(19,15))
+ val ex_new_vl = ex_new_vtype.vl(ex_avl, csr.io.vector.get.vconfig.vl, false.B, false.B, false.B)
+ val ex_new_vconfig = Wire(new VConfig)
+ ex_new_vconfig.vtype := ex_new_vtype
+ ex_new_vconfig.vl := ex_new_vl
+ (Some(ex_new_vl), Some(ex_new_vconfig))
+ } else { (None, None) }
+
+ val alu = Module(new ALU)
alu.io.dw := ex_ctrl.alu_dw
alu.io.fn := ex_ctrl.alu_fn
alu.io.in2 := ex_op2.asUInt
alu.io.in1 := ex_op1.asUInt
// multiplier and divider
- val div = Module(new MulDiv(if (pipelinedMul) mulDivParams.copy(mulUnroll = 0) else mulDivParams, width = xLen, aluFn = aluFn))
+ val div = Module(new MulDiv(if (pipelinedMul) mulDivParams.copy(mulUnroll = 0) else mulDivParams, width = xLen))
div.io.req.valid := ex_reg_valid && ex_ctrl.div
div.io.req.bits.dw := ex_ctrl.alu_dw
div.io.req.bits.fn := ex_ctrl.alu_fn
@@ -409,7 +516,7 @@ class Rocket(tile: RocketTile)(implicit p: Parameters) extends CoreModule()(p)
div.io.req.bits.in2 := ex_rs(1)
div.io.req.bits.tag := ex_waddr
val mul = pipelinedMul.option {
- val m = Module(new PipelinedMultiplier(xLen, 2, aluFn = aluFn))
+ val m = Module(new PipelinedMultiplier(xLen, 2))
m.io.req.valid := ex_reg_valid && ex_ctrl.mul
m.io.req.bits := div.io.req.bits
m
@@ -427,7 +534,7 @@ class Rocket(tile: RocketTile)(implicit p: Parameters) extends CoreModule()(p)
when (id_ctrl.fence && id_fence_succ === 0.U) { id_reg_pause := true.B }
when (id_fence_next) { id_reg_fence := true.B }
when (id_xcpt) { // pass PC down ALU writeback pipeline for badaddr
- ex_ctrl.alu_fn := aluFn.FN_ADD
+ ex_ctrl.alu_fn := FN_ADD
ex_ctrl.alu_dw := DW_XPR
ex_ctrl.sel_alu1 := A1_RS1 // badaddr := instruction
ex_ctrl.sel_alu2 := A2_ZERO
@@ -481,13 +588,15 @@ class Rocket(tile: RocketTile)(implicit p: Parameters) extends CoreModule()(p)
ex_reg_pc := ibuf.io.pc
ex_reg_btb_resp := ibuf.io.btb_resp
ex_reg_wphit := bpu.io.bpwatch.map { bpw => bpw.ivalid(0) }
+ ex_reg_set_vconfig := id_set_vconfig && !id_xcpt
}
// replay inst in ex stage?
val ex_pc_valid = ex_reg_valid || ex_reg_replay || ex_reg_xcpt_interrupt
val wb_dcache_miss = wb_ctrl.mem && !io.dmem.resp.valid
val replay_ex_structural = ex_ctrl.mem && !io.dmem.req.ready ||
- ex_ctrl.div && !div.io.req.ready
+ ex_ctrl.div && !div.io.req.ready ||
+ ex_ctrl.vec && !io.vector.map(_.ex.ready).getOrElse(true.B)
val replay_ex_load_use = wb_dcache_miss && ex_reg_load_use
val replay_ex = ex_reg_replay || (ex_reg_valid && (replay_ex_structural || replay_ex_load_use))
val ctrl_killx = take_pc_mem_wb || replay_ex || !ex_reg_valid
@@ -538,6 +647,7 @@ class Rocket(tile: RocketTile)(implicit p: Parameters) extends CoreModule()(p)
mem_reg_flush_pipe := ex_reg_flush_pipe
mem_reg_slow_bypass := ex_slow_bypass
mem_reg_wphit := ex_reg_wphit
+ mem_reg_set_vconfig := ex_reg_set_vconfig
mem_reg_cause := ex_cause
mem_reg_inst := ex_reg_inst
@@ -546,13 +656,17 @@ class Rocket(tile: RocketTile)(implicit p: Parameters) extends CoreModule()(p)
mem_reg_hls_or_dv := io.dmem.req.bits.dv
mem_reg_pc := ex_reg_pc
// IDecode ensured they are 1H
- mem_reg_wdata := alu.io.out
+ mem_reg_wdata := Mux(ex_reg_set_vconfig, ex_new_vl.getOrElse(alu.io.out), alu.io.out)
mem_br_taken := alu.io.cmp_out
+
when (ex_ctrl.rxs2 && (ex_ctrl.mem || ex_ctrl.rocc || ex_sfence)) {
val size = Mux(ex_ctrl.rocc, log2Ceil(xLen/8).U, ex_reg_mem_size)
mem_reg_rs2 := new StoreGen(size, 0.U, ex_rs(1), coreDataBytes).data
}
+ if (usingVector) { when (ex_reg_set_vconfig) {
+ mem_reg_rs2 := ex_new_vconfig.get.asUInt
+ } }
when (ex_ctrl.jalr && csr.io.status.debug) {
// flush I$ on D-mode JALR to effect uncached fetch without D$ flush
mem_ctrl.fence_i := true.B
@@ -580,21 +694,23 @@ class Rocket(tile: RocketTile)(implicit p: Parameters) extends CoreModule()(p)
val dcache_kill_mem = mem_reg_valid && mem_ctrl.wxd && io.dmem.replay_next // structural hazard on writeback port
val fpu_kill_mem = mem_reg_valid && mem_ctrl.fp && io.fpu.nack_mem
- val replay_mem = dcache_kill_mem || mem_reg_replay || fpu_kill_mem
+ val vec_kill_mem = mem_reg_valid && mem_ctrl.mem && io.vector.map(_.mem.block_mem).getOrElse(false.B)
+ val vec_kill_all = mem_reg_valid && io.vector.map(_.mem.block_all).getOrElse(false.B)
+ val replay_mem = dcache_kill_mem || mem_reg_replay || fpu_kill_mem || vec_kill_mem || vec_kill_all
val killm_common = dcache_kill_mem || take_pc_wb || mem_reg_xcpt || !mem_reg_valid
div.io.kill := killm_common && RegNext(div.io.req.fire)
- val ctrl_killm = killm_common || mem_xcpt || fpu_kill_mem
+ val ctrl_killm = killm_common || mem_xcpt || fpu_kill_mem || vec_kill_mem
// writeback stage
wb_reg_valid := !ctrl_killm
wb_reg_replay := replay_mem && !take_pc_wb
- wb_reg_xcpt := mem_xcpt && !take_pc_wb
+ wb_reg_xcpt := mem_xcpt && !take_pc_wb && !io.vector.map(_.mem.block_all).getOrElse(false.B)
wb_reg_flush_pipe := !ctrl_killm && mem_reg_flush_pipe
when (mem_pc_valid) {
wb_ctrl := mem_ctrl
wb_reg_sfence := mem_reg_sfence
wb_reg_wdata := Mux(!mem_reg_xcpt && mem_ctrl.fp && mem_ctrl.wxd, io.fpu.toint_data, mem_int_wdata)
- when (mem_ctrl.rocc || mem_reg_sfence) {
+ when (mem_ctrl.rocc || mem_reg_sfence || mem_reg_set_vconfig) {
wb_reg_rs2 := mem_reg_rs2
}
wb_reg_cause := mem_cause
@@ -606,7 +722,7 @@ class Rocket(tile: RocketTile)(implicit p: Parameters) extends CoreModule()(p)
wb_reg_hfence_g := mem_ctrl.mem_cmd === M_HFENCEG
wb_reg_pc := mem_reg_pc
wb_reg_wphit := mem_reg_wphit | bpu.io.bpwatch.map { bpw => (bpw.rvalid(0) && mem_reg_load) || (bpw.wvalid(0) && mem_reg_store) }
-
+ wb_reg_set_vconfig := mem_reg_set_vconfig
}
val (wb_xcpt, wb_cause) = checkExceptions(List(
@@ -637,11 +753,12 @@ class Rocket(tile: RocketTile)(implicit p: Parameters) extends CoreModule()(p)
val wb_pc_valid = wb_reg_valid || wb_reg_replay || wb_reg_xcpt
val wb_wxd = wb_reg_valid && wb_ctrl.wxd
- val wb_set_sboard = wb_ctrl.div || wb_dcache_miss || wb_ctrl.rocc
+ val wb_set_sboard = wb_ctrl.div || wb_dcache_miss || wb_ctrl.rocc || wb_ctrl.vec
val replay_wb_common = io.dmem.s2_nack || wb_reg_replay
val replay_wb_rocc = wb_reg_valid && wb_ctrl.rocc && !io.rocc.cmd.ready
val replay_wb_csr: Bool = wb_reg_valid && csr.io.rw_stall
- val replay_wb = replay_wb_common || replay_wb_rocc || replay_wb_csr
+ val replay_wb_vec = wb_reg_valid && io.vector.map(_.wb.replay).getOrElse(false.B)
+ val replay_wb = replay_wb_common || replay_wb_rocc || replay_wb_csr || replay_wb_vec
take_pc_wb := replay_wb || wb_xcpt || csr.io.eret || wb_reg_flush_pipe
// writeback arbitration
@@ -651,30 +768,46 @@ class Rocket(tile: RocketTile)(implicit p: Parameters) extends CoreModule()(p)
val dmem_resp_valid = io.dmem.resp.valid && io.dmem.resp.bits.has_data
val dmem_resp_replay = dmem_resp_valid && io.dmem.resp.bits.replay
- div.io.resp.ready := !wb_wxd
- val ll_wdata = WireDefault(div.io.resp.bits.data)
- val ll_waddr = WireDefault(div.io.resp.bits.tag)
- val ll_wen = WireDefault(div.io.resp.fire)
+ class LLWB extends Bundle {
+ val data = UInt(xLen.W)
+ val tag = UInt(5.W)
+ }
+
+ val ll_arb = Module(new Arbiter(new LLWB, 3)) // div, rocc, vec
+ ll_arb.io.in.foreach(_.valid := false.B)
+ ll_arb.io.in.foreach(_.bits := DontCare)
+ val ll_wdata = WireInit(ll_arb.io.out.bits.data)
+ val ll_waddr = WireInit(ll_arb.io.out.bits.tag)
+ val ll_wen = WireInit(ll_arb.io.out.fire)
+ ll_arb.io.out.ready := !wb_wxd
+
+ div.io.resp.ready := ll_arb.io.in(0).ready
+ ll_arb.io.in(0).valid := div.io.resp.valid
+ ll_arb.io.in(0).bits.data := div.io.resp.bits.data
+ ll_arb.io.in(0).bits.tag := div.io.resp.bits.tag
+
if (usingRoCC) {
- io.rocc.resp.ready := !wb_wxd
- when (io.rocc.resp.fire) {
- div.io.resp.ready := false.B
- ll_wdata := io.rocc.resp.bits.data
- ll_waddr := io.rocc.resp.bits.rd
- ll_wen := true.B
- }
+ io.rocc.resp.ready := ll_arb.io.in(1).ready
+ ll_arb.io.in(1).valid := io.rocc.resp.valid
+ ll_arb.io.in(1).bits.data := io.rocc.resp.bits.data
+ ll_arb.io.in(1).bits.tag := io.rocc.resp.bits.rd
} else {
// tie off RoCC
io.rocc.resp.ready := false.B
io.rocc.mem.req.ready := false.B
}
+
+ io.vector.map { v =>
+ v.resp.ready := Mux(v.resp.bits.fp, !(dmem_resp_valid && dmem_resp_fpu), ll_arb.io.in(2).ready)
+ ll_arb.io.in(2).valid := v.resp.valid && !v.resp.bits.fp
+ ll_arb.io.in(2).bits.data := v.resp.bits.data
+ ll_arb.io.in(2).bits.tag := v.resp.bits.rd
+ }
// Dont care mem since not all RoCC need accessing memory
io.rocc.mem := DontCare
when (dmem_resp_replay && dmem_resp_xpu) {
- div.io.resp.ready := false.B
- if (usingRoCC)
- io.rocc.resp.ready := false.B
+ ll_arb.io.out.ready := false.B
ll_waddr := dmem_resp_waddr
ll_wen := true.B
}
@@ -700,11 +833,15 @@ class Rocket(tile: RocketTile)(implicit p: Parameters) extends CoreModule()(p)
csr.io.interrupts := io.interrupts
csr.io.hartid := io.hartid
io.fpu.fcsr_rm := csr.io.fcsr_rm
- csr.io.fcsr_flags := io.fpu.fcsr_flags
+ val vector_fcsr_flags = io.vector.map(_.set_fflags.bits).getOrElse(0.U(5.W))
+ val vector_fcsr_flags_valid = io.vector.map(_.set_fflags.valid).getOrElse(false.B)
+ csr.io.fcsr_flags.valid := io.fpu.fcsr_flags.valid | vector_fcsr_flags_valid
+ csr.io.fcsr_flags.bits := (io.fpu.fcsr_flags.bits & Fill(5, io.fpu.fcsr_flags.valid)) | (vector_fcsr_flags & Fill(5, vector_fcsr_flags_valid))
io.fpu.time := csr.io.time(31,0)
io.fpu.hartid := io.hartid
csr.io.rocc_interrupt := io.rocc.interrupt
csr.io.pc := wb_reg_pc
+
val tval_dmem_addr = !wb_reg_xcpt
val tval_any_addr = tval_dmem_addr ||
wb_reg_cause.isOneOf(Causes.breakpoint.U, Causes.fetch_access.U, Causes.fetch_page_fault.U, Causes.fetch_guest_page_fault.U)
@@ -712,7 +849,7 @@ class Rocket(tile: RocketTile)(implicit p: Parameters) extends CoreModule()(p)
val tval_valid = wb_xcpt && (tval_any_addr || tval_inst)
csr.io.gva := wb_xcpt && (tval_any_addr && csr.io.status.v || tval_dmem_addr && wb_reg_hls_or_dv)
csr.io.tval := Mux(tval_valid, encodeVirtualAddress(wb_reg_wdata, wb_reg_wdata), 0.U)
- csr.io.htval := {
+ val (htval, mhtinst_read_pseudo) = {
val htval_valid_imem = wb_reg_xcpt && wb_reg_cause === Causes.fetch_guest_page_fault.U
val htval_imem = Mux(htval_valid_imem, io.imem.gpa.bits, 0.U)
assert(!htval_valid_imem || io.imem.gpa.valid)
@@ -720,8 +857,47 @@ class Rocket(tile: RocketTile)(implicit p: Parameters) extends CoreModule()(p)
val htval_valid_dmem = wb_xcpt && tval_dmem_addr && io.dmem.s2_xcpt.gf.asUInt.orR && !io.dmem.s2_xcpt.pf.asUInt.orR
val htval_dmem = Mux(htval_valid_dmem, io.dmem.s2_gpa, 0.U)
- (htval_dmem | htval_imem) >> hypervisorExtraAddrBits
+ val htval = (htval_dmem | htval_imem) >> hypervisorExtraAddrBits
+ // read pseudoinstruction if a guest-page fault is caused by an implicit memory access for VS-stage address translation
+ val mhtinst_read_pseudo = (io.imem.gpa_is_pte && htval_valid_imem) || (io.dmem.s2_gpa_is_pte && htval_valid_dmem)
+ (htval, mhtinst_read_pseudo)
+ }
+
+ csr.io.vector.foreach { v =>
+ v.set_vconfig.valid := wb_reg_set_vconfig && wb_reg_valid
+ v.set_vconfig.bits := wb_reg_rs2.asTypeOf(new VConfig)
+ v.set_vs_dirty := wb_valid && wb_ctrl.vec
+ v.set_vstart.valid := wb_valid && wb_reg_set_vconfig
+ v.set_vstart.bits := 0.U
}
+
+ io.vector.foreach { v =>
+ when (v.wb.retire || v.wb.xcpt || wb_ctrl.vec) {
+ csr.io.pc := v.wb.pc
+ csr.io.retire := v.wb.retire
+ csr.io.inst(0) := v.wb.inst
+ when (v.wb.xcpt && !wb_reg_xcpt) {
+ wb_xcpt := true.B
+ wb_cause := v.wb.cause
+ csr.io.tval := v.wb.tval
+ }
+ }
+ v.wb.store_pending := io.dmem.store_pending
+ v.wb.vxrm := csr.io.vector.get.vxrm
+ v.wb.frm := csr.io.fcsr_rm
+ csr.io.vector.get.set_vxsat := v.set_vxsat
+ when (v.set_vconfig.valid) {
+ csr.io.vector.get.set_vconfig.valid := true.B
+ csr.io.vector.get.set_vconfig.bits := v.set_vconfig.bits
+ }
+ when (v.set_vstart.valid) {
+ csr.io.vector.get.set_vstart.valid := true.B
+ csr.io.vector.get.set_vstart.bits := v.set_vstart.bits
+ }
+ }
+
+ csr.io.htval := htval
+ csr.io.mhtinst_read_pseudo := mhtinst_read_pseudo
io.ptw.ptbr := csr.io.ptbr
io.ptw.hgatp := csr.io.hgatp
io.ptw.vsatp := csr.io.vsatp
@@ -733,21 +909,51 @@ class Rocket(tile: RocketTile)(implicit p: Parameters) extends CoreModule()(p)
csr.io.rw.addr := wb_reg_inst(31,20)
csr.io.rw.cmd := CSR.maskCmd(wb_reg_valid, wb_ctrl.csr)
csr.io.rw.wdata := wb_reg_wdata
+
+
io.rocc.csrs <> csr.io.roccCSRs
io.trace.time := csr.io.time
io.trace.insns := csr.io.trace
- if (rocketParams.debugROB) {
- val csr_trace_with_wdata = WireInit(csr.io.trace(0))
- csr_trace_with_wdata.wdata.get := rf_wdata
- DebugROB.pushTrace(clock, reset,
- io.hartid, csr_trace_with_wdata,
- (wb_ctrl.wfd || (wb_ctrl.wxd && wb_waddr =/= 0.U)) && !csr.io.trace(0).exception,
- wb_ctrl.wxd && wb_wen && !wb_set_sboard,
- wb_waddr + Mux(wb_ctrl.wfd, 32.U, 0.U))
-
- io.trace.insns(0) := DebugROB.popTrace(clock, reset, io.hartid)
-
- DebugROB.pushWb(clock, reset, io.hartid, ll_wen, rf_waddr, rf_wdata)
+ if (rocketParams.debugROB.isDefined) {
+ val sz = rocketParams.debugROB.get.size
+ if (sz < 1) { // use unsynthesizable ROB
+ val csr_trace_with_wdata = WireInit(csr.io.trace(0))
+ csr_trace_with_wdata.wdata.get := rf_wdata
+ val should_wb = WireInit((wb_ctrl.wfd || (wb_ctrl.wxd && wb_waddr =/= 0.U)) && !csr.io.trace(0).exception)
+ val has_wb = WireInit(wb_ctrl.wxd && wb_wen && !wb_set_sboard)
+ val wb_addr = WireInit(wb_waddr + Mux(wb_ctrl.wfd, 32.U, 0.U))
+
+ io.vector.foreach { v => when (v.wb.retire) {
+ should_wb := v.wb.rob_should_wb
+ has_wb := false.B
+ wb_addr := Cat(v.wb.rob_should_wb_fp, csr_trace_with_wdata.insn(11,7))
+ }}
+
+ DebugROB.pushTrace(clock, reset,
+ io.hartid, csr_trace_with_wdata,
+ should_wb, has_wb, wb_addr)
+
+ io.trace.insns(0) := DebugROB.popTrace(clock, reset, io.hartid)
+
+ DebugROB.pushWb(clock, reset, io.hartid, ll_wen, rf_waddr, rf_wdata)
+ } else { // synthesizable ROB (no FPRs)
+ require(!usingVector, "Synthesizable ROB does not support vector implementations")
+ val csr_trace_with_wdata = WireInit(csr.io.trace(0))
+ csr_trace_with_wdata.wdata.get := rf_wdata
+
+ val debug_rob = Module(new HardDebugROB(sz, 32))
+ debug_rob.io.i_insn := csr_trace_with_wdata
+ debug_rob.io.should_wb := (wb_ctrl.wfd || (wb_ctrl.wxd && wb_waddr =/= 0.U)) &&
+ !csr.io.trace(0).exception
+ debug_rob.io.has_wb := wb_ctrl.wxd && wb_wen && !wb_set_sboard
+ debug_rob.io.tag := wb_waddr + Mux(wb_ctrl.wfd, 32.U, 0.U)
+
+ debug_rob.io.wb_val := ll_wen
+ debug_rob.io.wb_tag := rf_waddr
+ debug_rob.io.wb_data := rf_wdata
+
+ io.trace.insns(0) := debug_rob.io.o_insn
+ }
} else {
io.trace.insns := csr.io.trace
}
@@ -779,7 +985,7 @@ class Rocket(tile: RocketTile)(implicit p: Parameters) extends CoreModule()(p)
sboard.set(wb_set_sboard && wb_wen, wb_waddr)
// stall for RAW/WAW hazards on CSRs, loads, AMOs, and mul/div in execute stage.
- val ex_cannot_bypass = ex_ctrl.csr =/= CSR.N || ex_ctrl.jalr || ex_ctrl.mem || ex_ctrl.mul || ex_ctrl.div || ex_ctrl.fp || ex_ctrl.rocc
+ val ex_cannot_bypass = ex_ctrl.csr =/= CSR.N || ex_ctrl.jalr || ex_ctrl.mem || ex_ctrl.mul || ex_ctrl.div || ex_ctrl.fp || ex_ctrl.rocc || ex_ctrl.vec
val data_hazard_ex = ex_ctrl.wxd && checkHazards(hazard_targets, _ === ex_waddr)
val fp_data_hazard_ex = id_ctrl.fp && ex_ctrl.wfd && checkHazards(fp_hazard_targets, _ === ex_waddr)
val id_ex_hazard = ex_reg_valid && (data_hazard_ex && ex_cannot_bypass || fp_data_hazard_ex)
@@ -788,11 +994,15 @@ class Rocket(tile: RocketTile)(implicit p: Parameters) extends CoreModule()(p)
val mem_mem_cmd_bh =
if (fastLoadWord) (!fastLoadByte).B && mem_reg_slow_bypass
else true.B
- val mem_cannot_bypass = mem_ctrl.csr =/= CSR.N || mem_ctrl.mem && mem_mem_cmd_bh || mem_ctrl.mul || mem_ctrl.div || mem_ctrl.fp || mem_ctrl.rocc
+ val mem_cannot_bypass = mem_ctrl.csr =/= CSR.N || mem_ctrl.mem && mem_mem_cmd_bh || mem_ctrl.mul || mem_ctrl.div || mem_ctrl.fp || mem_ctrl.rocc || mem_ctrl.vec
val data_hazard_mem = mem_ctrl.wxd && checkHazards(hazard_targets, _ === mem_waddr)
val fp_data_hazard_mem = id_ctrl.fp && mem_ctrl.wfd && checkHazards(fp_hazard_targets, _ === mem_waddr)
val id_mem_hazard = mem_reg_valid && (data_hazard_mem && mem_cannot_bypass || fp_data_hazard_mem)
id_load_use := mem_reg_valid && data_hazard_mem && mem_ctrl.mem
+ val id_vconfig_hazard = id_ctrl.vec && (
+ (ex_reg_valid && ex_reg_set_vconfig) ||
+ (mem_reg_valid && mem_reg_set_vconfig) ||
+ (wb_reg_valid && wb_reg_set_vconfig))
// stall for RAW/WAW hazards on load/AMO misses and mul/div in writeback.
val data_hazard_wb = wb_ctrl.wxd && checkHazards(hazard_targets, _ === wb_waddr)
@@ -801,8 +1011,9 @@ class Rocket(tile: RocketTile)(implicit p: Parameters) extends CoreModule()(p)
val id_stall_fpu = if (usingFPU) {
val fp_sboard = new Scoreboard(32)
- fp_sboard.set((wb_dcache_miss && wb_ctrl.wfd || io.fpu.sboard_set) && wb_valid, wb_waddr)
- fp_sboard.clear(dmem_resp_replay && dmem_resp_fpu, dmem_resp_waddr)
+ fp_sboard.set(((wb_dcache_miss || wb_ctrl.vec) && wb_ctrl.wfd || io.fpu.sboard_set) && wb_valid, wb_waddr)
+ val v_ll = io.vector.map(v => v.resp.fire && v.resp.bits.fp).getOrElse(false.B)
+ fp_sboard.clear((dmem_resp_replay && dmem_resp_fpu) || v_ll, io.fpu.ll_resp_tag)
fp_sboard.clear(io.fpu.sboard_clr, io.fpu.sboard_clra)
checkHazards(fp_hazard_targets, fp_sboard.read _)
@@ -819,8 +1030,10 @@ class Rocket(tile: RocketTile)(implicit p: Parameters) extends CoreModule()(p)
val ctrl_stalld =
id_ex_hazard || id_mem_hazard || id_wb_hazard || id_sboard_hazard ||
+ id_vconfig_hazard ||
csr.io.singleStep && (ex_reg_valid || mem_reg_valid || wb_reg_valid) ||
id_csr_en && csr.io.decode(0).fp_csr && !io.fpu.fcsr_rdy ||
+ id_csr_en && csr.io.decode(0).vector_csr && id_vec_busy ||
id_ctrl.fp && id_stall_fpu ||
id_ctrl.mem && dcache_blocked || // reduce activity during D$ misses
id_ctrl.rocc && rocc_blocked || // reduce activity while RoCC is busy
@@ -840,7 +1053,7 @@ class Rocket(tile: RocketTile)(implicit p: Parameters) extends CoreModule()(p)
mem_npc)) // flush or branch misprediction
io.imem.flush_icache := wb_reg_valid && wb_ctrl.fence_i && !io.dmem.s2_nack
io.imem.might_request := {
- imem_might_request_reg := ex_pc_valid || mem_pc_valid || io.ptw.customCSRs.disableICacheClockGate
+ imem_might_request_reg := ex_pc_valid || mem_pc_valid || io.ptw.customCSRs.disableICacheClockGate || io.vector.map(_.trap_check_busy).getOrElse(false.B)
imem_might_request_reg
}
io.imem.progress := RegNext(wb_reg_valid && !replay_wb_common)
@@ -883,12 +1096,37 @@ class Rocket(tile: RocketTile)(implicit p: Parameters) extends CoreModule()(p)
io.fpu.killm := killm_common
io.fpu.inst := id_inst(0)
io.fpu.fromint_data := ex_rs(0)
- io.fpu.dmem_resp_val := dmem_resp_valid && dmem_resp_fpu
- io.fpu.dmem_resp_data := (if (minFLen == 32) io.dmem.resp.bits.data_word_bypass else io.dmem.resp.bits.data)
- io.fpu.dmem_resp_type := io.dmem.resp.bits.size
- io.fpu.dmem_resp_tag := dmem_resp_waddr
+ io.fpu.ll_resp_val := dmem_resp_valid && dmem_resp_fpu
+ io.fpu.ll_resp_data := (if (minFLen == 32) io.dmem.resp.bits.data_word_bypass else io.dmem.resp.bits.data)
+ io.fpu.ll_resp_type := io.dmem.resp.bits.size
+ io.fpu.ll_resp_tag := dmem_resp_waddr
io.fpu.keep_clock_enabled := io.ptw.customCSRs.disableCoreClockGate
+ io.fpu.v_sew := csr.io.vector.map(_.vconfig.vtype.vsew).getOrElse(0.U)
+
+ io.vector.map { v =>
+ when (!(dmem_resp_valid && dmem_resp_fpu)) {
+ io.fpu.ll_resp_val := v.resp.valid && v.resp.bits.fp
+ io.fpu.ll_resp_data := v.resp.bits.data
+ io.fpu.ll_resp_type := v.resp.bits.size
+ io.fpu.ll_resp_tag := v.resp.bits.rd
+ }
+ }
+
+ io.vector.foreach { v =>
+ v.ex.valid := ex_reg_valid && (ex_ctrl.vec || rocketParams.vector.get.issueVConfig.B && ex_reg_set_vconfig) && !ctrl_killx
+ v.ex.inst := ex_reg_inst
+ v.ex.vconfig := csr.io.vector.get.vconfig
+ v.ex.vstart := Mux(mem_reg_valid && mem_ctrl.vec || wb_reg_valid && wb_ctrl.vec, 0.U, csr.io.vector.get.vstart)
+ v.ex.rs1 := ex_rs(0)
+ v.ex.rs2 := ex_rs(1)
+ v.ex.pc := ex_reg_pc
+ v.mem.frs1 := io.fpu.store_data
+ v.killm := killm_common
+ v.status := csr.io.status
+ }
+
+
io.dmem.req.valid := ex_reg_valid && ex_ctrl.mem
val ex_dcache_tag = Cat(ex_waddr, ex_ctrl.fp)
require(coreParams.dcacheReqTagBits >= ex_dcache_tag.getWidth)
@@ -901,15 +1139,16 @@ class Rocket(tile: RocketTile)(implicit p: Parameters) extends CoreModule()(p)
io.dmem.req.bits.idx.foreach(_ := io.dmem.req.bits.addr)
io.dmem.req.bits.dprv := Mux(ex_reg_hls, csr.io.hstatus.spvp, csr.io.status.dprv)
io.dmem.req.bits.dv := ex_reg_hls || csr.io.status.dv
+ io.dmem.req.bits.no_resp := !isRead(ex_ctrl.mem_cmd) || (!ex_ctrl.fp && ex_waddr === 0.U)
io.dmem.req.bits.no_alloc := DontCare
io.dmem.req.bits.no_xcpt := DontCare
io.dmem.req.bits.data := DontCare
io.dmem.req.bits.mask := DontCare
- io.dmem.s1_data.data := (if (fLen == 0) mem_reg_rs2 else Mux(mem_ctrl.fp, Fill((xLen max fLen) / fLen, io.fpu.store_data), mem_reg_rs2))
+ io.dmem.s1_data.data := (if (fLen == 0) mem_reg_rs2 else Mux(mem_ctrl.fp, Fill(coreDataBits / fLen, io.fpu.store_data), mem_reg_rs2))
io.dmem.s1_data.mask := DontCare
- io.dmem.s1_kill := killm_common || mem_ldst_xcpt || fpu_kill_mem
+ io.dmem.s1_kill := killm_common || mem_ldst_xcpt || fpu_kill_mem || vec_kill_mem
io.dmem.s2_kill := false.B
// don't let D$ go to sleep if we're probably going to use it soon
io.dmem.keep_clock_enabled := ibuf.io.inst(0).valid && id_ctrl.mem && !csr.io.csr_stall
@@ -1036,7 +1275,7 @@ class Rocket(tile: RocketTile)(implicit p: Parameters) extends CoreModule()(p)
val rocketImpl = withClock (gated_clock) { new RocketImpl }
def checkExceptions(x: Seq[(Bool, UInt)]) =
- (x.map(_._1).reduce(_||_), PriorityMux(x))
+ (WireInit(x.map(_._1).reduce(_||_)), WireInit(PriorityMux(x)))
def coverExceptions(exceptionValid: Bool, cause: UInt, labelPrefix: String, coverCausesLabels: Seq[(Int, String)]): Unit = {
for ((coverCause, label) <- coverCausesLabels) {
diff --git a/src/main/scala/rocket/ScratchpadSlavePort.scala b/src/main/scala/rocket/ScratchpadSlavePort.scala
index c5b5632f583..8b613aa09de 100644
--- a/src/main/scala/rocket/ScratchpadSlavePort.scala
+++ b/src/main/scala/rocket/ScratchpadSlavePort.scala
@@ -4,10 +4,17 @@ package freechips.rocketchip.rocket
import chisel3._
import chisel3.util._
-import org.chipsalliance.cde.config.Parameters
-import freechips.rocketchip.diplomacy._
-import freechips.rocketchip.tilelink._
-import freechips.rocketchip.util._
+
+import org.chipsalliance.cde.config._
+import org.chipsalliance.diplomacy.lazymodule._
+
+import freechips.rocketchip.diplomacy.{AddressSet, RegionType, TransferSizes}
+import freechips.rocketchip.resources.{SimpleDevice}
+
+import freechips.rocketchip.tilelink.{TLManagerNode, TLSlavePortParameters, TLSlaveParameters, TLBundleA, TLMessages, TLAtomics}
+
+import freechips.rocketchip.util.UIntIsOneOf
+import freechips.rocketchip.util.DataToAugmentedData
/* This adapter converts between diplomatic TileLink and non-diplomatic HellaCacheIO */
class ScratchpadSlavePort(address: Seq[AddressSet], coreDataBytes: Int, usingAtomics: Boolean)(implicit p: Parameters) extends LazyModule {
@@ -57,16 +64,16 @@ class ScratchpadSlavePort(address: Seq[AddressSet], coreDataBytes: Int, usingAto
def formCacheReq(a: TLBundleA) = {
val req = Wire(new HellaCacheReq)
- req.cmd := MuxLookup(a.opcode, M_XRD, Array(
+ req.cmd := MuxLookup(a.opcode, M_XRD)(Array(
TLMessages.PutFullData -> M_XWR,
TLMessages.PutPartialData -> M_PWR,
- TLMessages.ArithmeticData -> MuxLookup(a.param, M_XRD, Array(
+ TLMessages.ArithmeticData -> MuxLookup(a.param, M_XRD)(Array(
TLAtomics.MIN -> M_XA_MIN,
TLAtomics.MAX -> M_XA_MAX,
TLAtomics.MINU -> M_XA_MINU,
TLAtomics.MAXU -> M_XA_MAXU,
TLAtomics.ADD -> M_XA_ADD)),
- TLMessages.LogicalData -> MuxLookup(a.param, M_XRD, Array(
+ TLMessages.LogicalData -> MuxLookup(a.param, M_XRD)(Array(
TLAtomics.XOR -> M_XA_XOR,
TLAtomics.OR -> M_XA_OR,
TLAtomics.AND -> M_XA_AND,
@@ -89,6 +96,7 @@ class ScratchpadSlavePort(address: Seq[AddressSet], coreDataBytes: Int, usingAto
req.tag := 0.U
req.phys := true.B
req.no_xcpt := true.B
+ req.no_resp := false.B
req.data := 0.U
req.no_alloc := false.B
req.mask := 0.U
diff --git a/src/main/scala/rocket/TLB.scala b/src/main/scala/rocket/TLB.scala
index c1f04aef73a..8cc4a2c67c9 100644
--- a/src/main/scala/rocket/TLB.scala
+++ b/src/main/scala/rocket/TLB.scala
@@ -5,18 +5,24 @@ package freechips.rocketchip.rocket
import chisel3._
import chisel3.util._
+import chisel3.experimental.SourceInfo
-import org.chipsalliance.cde.config.{Field, Parameters}
-import freechips.rocketchip.subsystem.CacheBlockBytes
+import org.chipsalliance.cde.config._
+
+import freechips.rocketchip.devices.debug.DebugModuleKey
import freechips.rocketchip.diplomacy.RegionType
+import freechips.rocketchip.subsystem.CacheBlockBytes
import freechips.rocketchip.tile.{CoreModule, CoreBundle}
import freechips.rocketchip.tilelink._
-import freechips.rocketchip.util._
-import freechips.rocketchip.util.property
-import freechips.rocketchip.devices.debug.DebugModuleKey
-import chisel3.experimental.SourceInfo
+import freechips.rocketchip.util.{OptimizationBarrier, SetAssocLRU, PseudoLRU, PopCountAtLeast, property}
+
+import freechips.rocketchip.util.BooleanToAugmentedBoolean
+import freechips.rocketchip.util.IntToAugmentedInt
+import freechips.rocketchip.util.UIntToAugmentedUInt
+import freechips.rocketchip.util.UIntIsOneOf
+import freechips.rocketchip.util.SeqToAugmentedSeq
+import freechips.rocketchip.util.SeqBoolBitwiseOps
-case object PgLevels extends Field[Int](2)
case object ASIdBits extends Field[Int](0)
case object VMIdBits extends Field[Int](0)
@@ -65,7 +71,7 @@ class TLBExceptions extends Bundle {
val inst = Bool()
}
-class TLBResp(implicit p: Parameters) extends CoreBundle()(p) {
+class TLBResp(lgMaxSize: Int = 3)(implicit p: Parameters) extends CoreBundle()(p) {
// lookup responses
val miss = Bool()
/** physical address */
@@ -86,6 +92,10 @@ class TLBResp(implicit p: Parameters) extends CoreBundle()(p) {
val must_alloc = Bool()
/** if this address is prefetchable for caches*/
val prefetchable = Bool()
+ /** size/cmd of request that generated this response*/
+ val size = UInt(log2Ceil(lgMaxSize + 1).W)
+ val cmd = UInt(M_SZ.W)
+
}
class TLBEntryData(implicit p: Parameters) extends CoreBundle()(p) {
@@ -306,11 +316,12 @@ case class TLBConfig(
* @param edge collect SoC metadata.
*/
class TLB(instruction: Boolean, lgMaxSize: Int, cfg: TLBConfig)(implicit edge: TLEdgeOut, p: Parameters) extends CoreModule()(p) {
+ override def desiredName = if (instruction) "ITLB" else "DTLB"
val io = IO(new Bundle {
/** request from Core */
val req = Flipped(Decoupled(new TLBReq(lgMaxSize)))
/** response to Core */
- val resp = Output(new TLBResp())
+ val resp = Output(new TLBResp(lgMaxSize))
/** SFence Input */
val sfence = Flipped(Valid(new SFenceReq))
/** IO to PTW */
@@ -407,24 +418,21 @@ class TLB(instruction: Boolean, lgMaxSize: Int, cfg: TLBConfig)(implicit edge: T
pmp.io.size := io.req.bits.size
pmp.io.pmp := (io.ptw.pmp: Seq[PMP])
pmp.io.prv := mpu_priv
- // PMA
- // check exist a slave can consume this address.
- val legal_address = edge.manager.findSafe(mpu_physaddr).reduce(_||_)
- // check utility to help check SoC property.
- def fastCheck(member: TLManagerParameters => Boolean) =
- legal_address && edge.manager.fastProperty(mpu_physaddr, member, (b:Boolean) => b.B)
+
+ val pma = Module(new PMAChecker(edge.manager)(p))
+ pma.io.paddr := mpu_physaddr
// todo: using DataScratchpad doesn't support cacheable.
- val cacheable = fastCheck(_.supportsAcquireB) && (instruction || !usingDataScratchpad).B
- val homogeneous = TLBPageLookup(edge.manager.managers, xLen, p(CacheBlockBytes), BigInt(1) << pgIdxBits)(mpu_physaddr).homogeneous
+ val cacheable = pma.io.resp.cacheable && (instruction || !usingDataScratchpad).B
+ val homogeneous = TLBPageLookup(edge.manager.managers, xLen, p(CacheBlockBytes), BigInt(1) << pgIdxBits, 1 << lgMaxSize)(mpu_physaddr).homogeneous
// In M mode, if access DM address(debug module program buffer)
val deny_access_to_debug = mpu_priv <= PRV.M.U && p(DebugModuleKey).map(dmp => dmp.address.contains(mpu_physaddr)).getOrElse(false.B)
- val prot_r = fastCheck(_.supportsGet) && !deny_access_to_debug && pmp.io.r
- val prot_w = fastCheck(_.supportsPutFull) && !deny_access_to_debug && pmp.io.w
- val prot_pp = fastCheck(_.supportsPutPartial)
- val prot_al = fastCheck(_.supportsLogical)
- val prot_aa = fastCheck(_.supportsArithmetic)
- val prot_x = fastCheck(_.executable) && !deny_access_to_debug && pmp.io.x
- val prot_eff = fastCheck(Seq(RegionType.PUT_EFFECTS, RegionType.GET_EFFECTS) contains _.regionType)
+ val prot_r = pma.io.resp.r && !deny_access_to_debug && pmp.io.r
+ val prot_w = pma.io.resp.w && !deny_access_to_debug && pmp.io.w
+ val prot_pp = pma.io.resp.pp
+ val prot_al = pma.io.resp.al
+ val prot_aa = pma.io.resp.aa
+ val prot_x = pma.io.resp.x && !deny_access_to_debug && pmp.io.x
+ val prot_eff = pma.io.resp.eff
// hit check
val sector_hits = sectored_entries(memIdx).map(_.sectorHit(vpn, priv_v))
@@ -642,6 +650,8 @@ class TLB(instruction: Boolean, lgMaxSize: Int, cfg: TLBConfig)(implicit edge: T
io.resp.prefetchable := (prefetchable_array & hits).orR && edge.manager.managers.forall(m => !m.supportsAcquireB || m.supportsHint).B
io.resp.miss := do_refill || vsatp_mode_mismatch || tlb_miss || multipleHits
io.resp.paddr := Cat(ppn, io.req.bits.vaddr(pgIdxBits-1, 0))
+ io.resp.size := io.req.bits.size
+ io.resp.cmd := io.req.bits.cmd
io.resp.gpa_is_pte := vstage1_en && r_gpa_is_pte
io.resp.gpa := {
val page = Mux(!vstage1_en, Cat(bad_gpa, vpn), r_gpa >> pgIdxBits)
diff --git a/src/main/scala/rocket/TLBPermissions.scala b/src/main/scala/rocket/TLBPermissions.scala
index e35b85f528a..899bc7c33ca 100644
--- a/src/main/scala/rocket/TLBPermissions.scala
+++ b/src/main/scala/rocket/TLBPermissions.scala
@@ -3,10 +3,10 @@
package freechips.rocketchip.rocket
import chisel3._
-import chisel3.util.isPow2
+import chisel3.util._
-import freechips.rocketchip.diplomacy._
-import freechips.rocketchip.tilelink._
+import freechips.rocketchip.diplomacy.{AddressSet, TransferSizes, RegionType, AddressDecoder}
+import freechips.rocketchip.tilelink.TLManagerParameters
case class TLBPermissions(
homogeneous: Bool, // if false, the below are undefined
@@ -51,13 +51,13 @@ object TLBPageLookup
}
// Unmapped memory is considered to be inhomogeneous
- def apply(managers: Seq[TLManagerParameters], xLen: Int, cacheBlockBytes: Int, pageSize: BigInt): UInt => TLBPermissions = {
+ def apply(managers: Seq[TLManagerParameters], xLen: Int, cacheBlockBytes: Int, pageSize: BigInt, maxRequestBytes: Int): UInt => TLBPermissions = {
require (isPow2(xLen) && xLen >= 8)
require (isPow2(cacheBlockBytes) && cacheBlockBytes >= xLen/8)
require (isPow2(pageSize) && pageSize >= cacheBlockBytes)
val xferSizes = TransferSizes(cacheBlockBytes, cacheBlockBytes)
- val allSizes = TransferSizes(1, cacheBlockBytes)
+ val allSizes = TransferSizes(1, maxRequestBytes)
val amoSizes = TransferSizes(4, xLen/8)
val permissions = managers.foreach { m =>
diff --git a/src/main/scala/rocket/VectorUnit.scala b/src/main/scala/rocket/VectorUnit.scala
new file mode 100644
index 00000000000..636c0f21332
--- /dev/null
+++ b/src/main/scala/rocket/VectorUnit.scala
@@ -0,0 +1,102 @@
+package freechips.rocketchip.rocket
+
+import chisel3._
+import chisel3.util._
+import org.chipsalliance.cde.config._
+import freechips.rocketchip.tile._
+import freechips.rocketchip.diplomacy._
+import freechips.rocketchip.tilelink._
+
+case class RocketCoreVectorParams(
+ build: Parameters => RocketVectorUnit,
+ vLen: Int,
+ eLen: Int,
+ vfLen: Int,
+ vfh: Boolean,
+ vMemDataBits: Int,
+ decoder: Parameters => RocketVectorDecoder,
+ useDCache: Boolean,
+ issueVConfig: Boolean,
+ vExts: Seq[String]
+)
+
+class VectorCoreIO(implicit p: Parameters) extends CoreBundle()(p) {
+ val status = Input(new MStatus)
+ val ex = new Bundle {
+ val valid = Input(Bool())
+ val ready = Output(Bool())
+ val inst = Input(UInt(32.W))
+ val pc = Input(UInt(vaddrBitsExtended.W))
+ val vconfig = Input(new VConfig)
+ val vstart = Input(UInt(log2Ceil(maxVLMax).W))
+ val rs1 = Input(UInt(xLen.W))
+ val rs2 = Input(UInt(xLen.W))
+ }
+ val killm = Input(Bool())
+ val mem = new Bundle {
+ val frs1 = Input(UInt(fLen.W))
+ val block_mem = Output(Bool())
+ val block_all = Output(Bool())
+ }
+
+ val wb = new Bundle {
+ val store_pending = Input(Bool())
+ val replay = Output(Bool())
+ val retire = Output(Bool())
+ val inst = Output(UInt(32.W))
+ val rob_should_wb = Output(Bool()) // debug
+ val rob_should_wb_fp = Output(Bool()) // debug
+ val pc = Output(UInt(vaddrBitsExtended.W))
+ val xcpt = Output(Bool())
+ val cause = Output(UInt(log2Ceil(Causes.all.max).W))
+ val tval = Output(UInt(coreMaxAddrBits.W))
+ val vxrm = Input(UInt(2.W))
+ val frm = Input(UInt(3.W))
+ }
+
+ val resp = Decoupled(new Bundle {
+ val fp = Bool()
+ val size = UInt(2.W)
+ val rd = UInt(5.W)
+ val data = UInt((xLen max fLen).W)
+ })
+
+ val set_vstart = Valid(UInt(log2Ceil(maxVLMax).W))
+ val set_vxsat = Output(Bool())
+ val set_vconfig = Valid(new VConfig)
+ val set_fflags = Valid(UInt(5.W))
+
+ val trap_check_busy = Output(Bool())
+ val backend_busy = Output(Bool())
+}
+
+abstract class RocketVectorUnit(implicit p: Parameters) extends LazyModule {
+ val module: RocketVectorUnitModuleImp
+ val tlNode: TLNode = TLIdentityNode()
+ val atlNode: TLNode = TLIdentityNode()
+}
+
+class RocketVectorUnitModuleImp(outer: RocketVectorUnit) extends LazyModuleImp(outer) {
+ val io = IO(new Bundle {
+ val core = new VectorCoreIO
+ val tlb = Flipped(new DCacheTLBPort)
+ val dmem = new HellaCacheIO
+
+ val fp_req = Decoupled(new FPInput())
+ val fp_resp = Flipped(Decoupled(new FPResult()))
+ })
+}
+
+abstract class RocketVectorDecoder(implicit p: Parameters) extends CoreModule()(p) {
+ val io = IO(new Bundle {
+ val inst = Input(UInt(32.W))
+ val vconfig = Input(new VConfig)
+ val legal = Output(Bool())
+ val fp = Output(Bool())
+ val read_rs1 = Output(Bool())
+ val read_rs2 = Output(Bool())
+ val read_frs1 = Output(Bool())
+ val write_rd = Output(Bool())
+ val write_frd = Output(Bool())
+ })
+}
diff --git a/src/main/scala/subsystem/Attachable.scala b/src/main/scala/subsystem/Attachable.scala
index 7809280a110..9f3f720a04a 100644
--- a/src/main/scala/subsystem/Attachable.scala
+++ b/src/main/scala/subsystem/Attachable.scala
@@ -2,9 +2,10 @@
package freechips.rocketchip.subsystem
-import org.chipsalliance.cde.config.Parameters
-import freechips.rocketchip.diplomacy.{LazyModule, LazyScope}
-import freechips.rocketchip.prci.ClockGroupEphemeralNode
+import org.chipsalliance.cde.config._
+import org.chipsalliance.diplomacy.lazymodule._
+
+import freechips.rocketchip.prci.ClockGroupNode
import freechips.rocketchip.tilelink.TLBusWrapper
import freechips.rocketchip.util.{Location, LocationMap}
@@ -23,13 +24,14 @@ trait LazyScopeWithParameters extends LazyScope { this: LazyModule =>
/** Layers of hierarchy with this trait contain attachment points for neworks of power, clock, reset, and interrupt resources */
trait HasPRCILocations extends LazyScopeWithParameters { this: LazyModule =>
- implicit val asyncClockGroupsNode: ClockGroupEphemeralNode
+ val allClockGroupsNode: ClockGroupNode
val ibus: InterruptBusWrapper
val anyLocationMap = LocationMap.empty[Any]
}
/** Layers of hierarchy with this trait contain attachment points for TileLink interfaces */
trait HasTileLinkLocations extends HasPRCILocations { this: LazyModule =>
+ val busContextName: String
val tlBusWrapperLocationMap = LocationMap.empty[TLBusWrapper]
def locateTLBusWrapper(location: Location[TLBusWrapper]): TLBusWrapper = locateTLBusWrapper(location.name)
def locateTLBusWrapper(name: String): TLBusWrapper = tlBusWrapperLocationMap(Location[TLBusWrapper](name))
diff --git a/src/main/scala/subsystem/BankedL2Params.scala b/src/main/scala/subsystem/BankedCoherenceParams.scala
similarity index 81%
rename from src/main/scala/subsystem/BankedL2Params.scala
rename to src/main/scala/subsystem/BankedCoherenceParams.scala
index 402dd537804..235cd1eebbd 100644
--- a/src/main/scala/subsystem/BankedL2Params.scala
+++ b/src/main/scala/subsystem/BankedCoherenceParams.scala
@@ -2,19 +2,27 @@
package freechips.rocketchip.subsystem
-import chisel3.util.isPow2
+import chisel3.util._
+
import org.chipsalliance.cde.config._
+import org.chipsalliance.diplomacy.lazymodule._
+
import freechips.rocketchip.devices.tilelink.BuiltInDevices
-import freechips.rocketchip.diplomacy._
-import freechips.rocketchip.interrupts._
-import freechips.rocketchip.tilelink._
-import freechips.rocketchip.util._
+import freechips.rocketchip.diplomacy.AddressSet
+import freechips.rocketchip.interrupts.IntOutwardNode
+import freechips.rocketchip.tilelink.{
+ TLBroadcast, HasTLBusParams, BroadcastFilter, TLBusWrapper, TLBusWrapperInstantiationLike,
+ TLJbar, TLEdge, TLOutwardNode, TLTempNode, TLInwardNode, BankBinder, TLBroadcastParams,
+ TLBroadcastControlParams, TLBuffer, TLFragmenter, TLNameNode
+}
+import freechips.rocketchip.util.Location
+
import CoherenceManagerWrapper._
/** Global cache coherence granularity, which applies to all caches, for now. */
case object CacheBlockBytes extends Field[Int](64)
-/** L2 Broadcast Hub configuration */
+/** LLC Broadcast Hub configuration */
case object BroadcastKey extends Field(BroadcastParams())
case class BroadcastParams(
@@ -23,10 +31,11 @@ case class BroadcastParams(
controlAddress: Option[BigInt] = None,
filterFactory: TLBroadcast.ProbeFilterFactory = BroadcastFilter.factory)
-/** L2 memory subsystem configuration */
-case object BankedL2Key extends Field(BankedL2Params())
+/** Coherence manager configuration */
+case object SubsystemBankedCoherenceKey extends Field(BankedCoherenceParams())
+case class ClusterBankedCoherenceKey(clusterId: Int) extends Field(BankedCoherenceParams(nBanks=0))
-case class BankedL2Params(
+case class BankedCoherenceParams(
nBanks: Int = 1,
coherenceManager: CoherenceManagerInstantiationFn = broadcastManager
) {
diff --git a/src/main/scala/subsystem/BaseSubsystem.scala b/src/main/scala/subsystem/BaseSubsystem.scala
index 926e1d22923..e5aaa6242aa 100644
--- a/src/main/scala/subsystem/BaseSubsystem.scala
+++ b/src/main/scala/subsystem/BaseSubsystem.scala
@@ -2,15 +2,22 @@
package freechips.rocketchip.subsystem
+import chisel3._
import chisel3.util._
-import org.chipsalliance.cde.config.{Field, Parameters}
-import freechips.rocketchip.diplomacy._
-import freechips.rocketchip.prci._
+
+import org.chipsalliance.cde.config._
+import org.chipsalliance.diplomacy.lazymodule._
+
+import freechips.rocketchip.diplomacy.{AddressRange}
+import freechips.rocketchip.resources.{
+ BindingScope, DTS, DTB, ResourceBinding, JSON, ResourceInt,
+ DTSModel, DTSCompat, DTSTimebase, ResourceString, Resource,
+ ResourceAnchors, AddressMapEntry}
+import freechips.rocketchip.prci.{ClockGroupIdentityNode, ClockGroupAggregator, ClockGroupSourceNode, ClockGroupSourceParameters}
import freechips.rocketchip.tilelink.TLBusWrapper
-import freechips.rocketchip.util._
+import freechips.rocketchip.util.{Location, ElaborationArtefacts, PlusArgArtefacts, RecordMap, Annotated}
-case object SubsystemDriveAsyncClockGroupsKey extends Field[Option[ClockGroupDriverParameters]](Some(ClockGroupDriverParameters(1)))
-case object AsyncClockGroupsKey extends Field[() => ClockGroupEphemeralNode](() => ClockGroupEphemeralNode()(ValName("clock_sources")))
+case object SubsystemDriveClockGroupsFromIO extends Field[Boolean](true)
case class TLNetworkTopologyLocated(where: HierarchicalLocation) extends Field[Seq[CanInstantiateWithinContextThatHasTileLinkLocations with CanConnectWithinContextThatHasTileLinkLocations]]
case class TLManagerViewpointLocated(where: HierarchicalLocation) extends Field[Location[TLBusWrapper]](SBUS)
@@ -19,22 +26,29 @@ case object InTile extends HierarchicalLocation("InTile")
case object InSubsystem extends HierarchicalLocation("InSubsystem")
case object InSystem extends HierarchicalLocation("InSystem")
-/** BareSubsystem is the root class for creating a subsystem */
-abstract class BareSubsystem(implicit p: Parameters) extends LazyModule with BindingScope {
+// HasDts is generating metadatas from Scala, which is not the target for new diplomacy and Property.
+// It will be deprecated and removed after we migrate all metadata handling logic to OM Dialect.
+trait HasDTS extends LazyModule with BindingScope {
lazy val dts = DTS(bindingTree)
lazy val dtb = DTB(dts)
lazy val json = JSON(bindingTree)
}
-abstract class BareSubsystemModuleImp[+L <: BareSubsystem](_outer: L) extends LazyModuleImp(_outer) {
- val outer = _outer
- ElaborationArtefacts.add("graphml", outer.graphML)
- ElaborationArtefacts.add("dts", outer.dts)
- ElaborationArtefacts.add("json", outer.json)
+trait HasDTSImp[+L <: HasDTS] { this: LazyRawModuleImp =>
+ def dtsLM: L
+ // GraphML should live outside form this trait, but we keep it here until we find an appropriate way to handle metadata
+ ElaborationArtefacts.add("graphml", dtsLM.graphML)
+ // PlusArg should be purged out from rocket-chip in a near feature.
ElaborationArtefacts.add("plusArgs", PlusArgArtefacts.serialize_cHeader())
- println(outer.dts)
+ ElaborationArtefacts.add("dts", dtsLM.dts)
+ ElaborationArtefacts.add("json", dtsLM.json)
+ println(dtsLM.dts)
}
+/** BareSubsystem is the root class for creating a subsystem */
+abstract class BareSubsystem(implicit p: Parameters) extends LazyModule
+abstract class BareSubsystemModuleImp[+L <: BareSubsystem](_outer: L) extends LazyRawModuleImp(_outer)
+
trait SubsystemResetScheme
case object ResetSynchronous extends SubsystemResetScheme
case object ResetAsynchronous extends SubsystemResetScheme
@@ -47,11 +61,22 @@ case object SubsystemResetSchemeKey extends Field[SubsystemResetScheme](ResetSyn
*/
trait HasConfigurablePRCILocations { this: HasPRCILocations =>
val ibus = LazyModule(new InterruptBusWrapper)
- implicit val asyncClockGroupsNode = p(AsyncClockGroupsKey)()
- val clock_sources: ModuleValue[RecordMap[ClockBundle]] =
- p(SubsystemDriveAsyncClockGroupsKey)
- .map(_.drive(asyncClockGroupsNode))
- .getOrElse(InModuleBody { RecordMap[ClockBundle]() })
+ val allClockGroupsNode = ClockGroupIdentityNode()
+ val io_clocks = if (p(SubsystemDriveClockGroupsFromIO)) {
+ val aggregator = ClockGroupAggregator()
+ val source = ClockGroupSourceNode(Seq(ClockGroupSourceParameters()))
+ allClockGroupsNode :*= aggregator := source
+ Some(InModuleBody {
+ val elements = source.out.map(_._1.member.elements).flatten
+ val io = IO(Flipped(RecordMap(elements.map { case (name, data) =>
+ name -> data.cloneType
+ }:_*)))
+ elements.foreach { case (name, data) => io(name).foreach { data := _ } }
+ io
+ })
+ } else {
+ None
+ }
}
/** Look up the topology configuration for the TL buses located within this layer of the hierarchy */
@@ -60,36 +85,32 @@ trait HasConfigurableTLNetworkTopology { this: HasTileLinkLocations =>
// Calling these functions populates tlBusWrapperLocationMap and connects the locations to each other.
val topology = p(TLNetworkTopologyLocated(location))
- topology.map(_.instantiate(this))
+ topology.foreach(_.instantiate(this))
topology.foreach(_.connect(this))
+ def viewpointBus: TLBusWrapper = tlBusWrapperLocationMap(p(TLManagerViewpointLocated(location)))
// This is used lazily at DTS binding time to get a view of the network
- lazy val topManagers = tlBusWrapperLocationMap(p(TLManagerViewpointLocated(location))).unifyManagers
+ lazy val topManagers = viewpointBus.unifyManagers
}
/** Base Subsystem class with no peripheral devices, ports or cores added yet */
abstract class BaseSubsystem(val location: HierarchicalLocation = InSubsystem)
(implicit p: Parameters)
extends BareSubsystem
+ with HasDTS
with Attachable
with HasConfigurablePRCILocations
with HasConfigurableTLNetworkTopology
{
override val module: BaseSubsystemModuleImp[BaseSubsystem]
- // TODO must there really always be an "sbus"?
- val sbus = tlBusWrapperLocationMap(SBUS)
- tlBusWrapperLocationMap.lift(SBUS).map { _.clockGroupNode := asyncClockGroupsNode }
+ val busContextName = "subsystem"
- // TODO: Preserve legacy implicit-clock behavior for IBUS for now. If binding
- // a PLIC to the CBUS, ensure it is synchronously coupled to the SBUS.
- ibus.clockNode := sbus.fixedClockNode
+ viewpointBus.clockGroupNode := allClockGroupsNode
- // TODO deprecate these public members to see where users are manually hardcoding a particular bus that might actually not exist in a certain dynamic topology
- val pbus = tlBusWrapperLocationMap.lift(PBUS).getOrElse(sbus)
- val fbus = tlBusWrapperLocationMap.lift(FBUS).getOrElse(sbus)
- val mbus = tlBusWrapperLocationMap.lift(MBUS).getOrElse(sbus)
- val cbus = tlBusWrapperLocationMap.lift(CBUS).getOrElse(sbus)
+ // TODO: Preserve legacy implicit-clock behavior for IBUS for now. If binding
+ // a PLIC to the CBUS, ensure it is synchronously coupled to the SBUS.
+ ibus.clockNode := viewpointBus.fixedClockNode
// Collect information for use in DTS
ResourceBinding {
@@ -119,9 +140,10 @@ abstract class BaseSubsystem(val location: HierarchicalLocation = InSubsystem)
}
-abstract class BaseSubsystemModuleImp[+L <: BaseSubsystem](_outer: L) extends BareSubsystemModuleImp(_outer) {
+abstract class BaseSubsystemModuleImp[+L <: BaseSubsystem](_outer: L) extends BareSubsystemModuleImp(_outer) with HasDTSImp[L] {
+ def dtsLM: L = _outer
private val mapping: Seq[AddressMapEntry] = Annotated.addressMapping(this, {
- outer.collectResourceAddresses.groupBy(_._2).toList.flatMap { case (key, seq) =>
+ dtsLM.collectResourceAddresses.groupBy(_._2).toList.flatMap { case (key, seq) =>
AddressRange.fromSets(key.address).map { r => AddressMapEntry(r, key.permissions, seq.map(_._1)) }
}.sortBy(_.range)
})
@@ -129,14 +151,14 @@ abstract class BaseSubsystemModuleImp[+L <: BaseSubsystem](_outer: L) extends Ba
Annotated.addressMapping(this, mapping)
println("Generated Address Map")
- mapping.map(entry => println(entry.toString((outer.sbus.busView.bundle.addressBits-1)/4 + 1)))
+ mapping.foreach(entry => println(entry.toString((dtsLM.tlBusWrapperLocationMap(p(TLManagerViewpointLocated(dtsLM.location))).busView.bundle.addressBits-1)/4 + 1)))
println("")
ElaborationArtefacts.add("memmap.json", s"""{"mapping":[${mapping.map(_.toJSON).mkString(",")}]}""")
// Confirm that all of memory was described by DTS
private val dtsRanges = AddressRange.unify(mapping.map(_.range))
- private val allRanges = AddressRange.unify(outer.topManagers.flatMap { m => AddressRange.fromSets(m.address) })
+ private val allRanges = AddressRange.unify(dtsLM.topManagers.flatMap { m => AddressRange.fromSets(m.address) })
if (dtsRanges != allRanges) {
println("Address map described by DTS differs from physical implementation:")
diff --git a/src/main/scala/subsystem/BusTopology.scala b/src/main/scala/subsystem/BusTopology.scala
index 239a016647e..5b3dd7c452a 100644
--- a/src/main/scala/subsystem/BusTopology.scala
+++ b/src/main/scala/subsystem/BusTopology.scala
@@ -2,9 +2,11 @@
package freechips.rocketchip.subsystem
-import org.chipsalliance.cde.config.Field
-import freechips.rocketchip.diplomacy._
-import freechips.rocketchip.tilelink._
+import org.chipsalliance.cde.config._
+import org.chipsalliance.diplomacy.nodes._
+
+import freechips.rocketchip.prci.{ClockCrossingType, NoCrossing, SynchronousCrossing}
+import freechips.rocketchip.tilelink.{TLBusWrapper, TLBusWrapperTopology, TLBusWrapperConnection}
import freechips.rocketchip.util.Location
// These fields control parameters of the five traditional tilelink bus wrappers.
@@ -23,12 +25,16 @@ case object MemoryBusKey extends Field[MemoryBusParams]
// dynamically-configured topologies.
class TLBusWrapperLocation(name: String) extends Location[TLBusWrapper](name)
-case object SBUS extends TLBusWrapperLocation("subsystem_sbus")
-case object PBUS extends TLBusWrapperLocation("subsystem_pbus")
-case object FBUS extends TLBusWrapperLocation("subsystem_fbus")
-case object MBUS extends TLBusWrapperLocation("subsystem_mbus")
-case object CBUS extends TLBusWrapperLocation("subsystem_cbus")
-case object L2 extends TLBusWrapperLocation("subsystem_l2")
+case object SBUS extends TLBusWrapperLocation("sbus")
+case object PBUS extends TLBusWrapperLocation("pbus")
+case object FBUS extends TLBusWrapperLocation("fbus")
+case object MBUS extends TLBusWrapperLocation("mbus")
+case object CBUS extends TLBusWrapperLocation("cbus")
+case object COH extends TLBusWrapperLocation("coh")
+case class CSBUS(clusterId: Int) extends TLBusWrapperLocation(s"csbus$clusterId")
+case class CMBUS(clusterId: Int) extends TLBusWrapperLocation(s"cmbus$clusterId")
+case class CCBUS(clusterId: Int) extends TLBusWrapperLocation(s"ccbus$clusterId")
+case class CCOH (clusterId: Int) extends TLBusWrapperLocation(s"ccoh$clusterId")
/** Parameterizes the subsystem in terms of optional clock-crossings
* that are insertable between some of the five traditional tilelink bus wrappers.
@@ -89,20 +95,40 @@ case class HierarchicalBusTopologyParams(
/** Parameterization of a topology containing a banked coherence manager and a bus for attaching memory devices. */
case class CoherentBusTopologyParams(
- sbus: SystemBusParams, // TODO remove this after better width propagation
mbus: MemoryBusParams,
- l2: BankedL2Params,
+ coherence: BankedCoherenceParams,
sbusToMbusXType: ClockCrossingType = NoCrossing,
driveMBusClockFromSBus: Boolean = true
) extends TLBusWrapperTopology(
- instantiations = (if (l2.nBanks == 0) Nil else List(
+ instantiations = (if (coherence.nBanks == 0) Nil else List(
(MBUS, mbus),
- (L2, CoherenceManagerWrapperParams(mbus.blockBytes, mbus.beatBytes, l2.nBanks, L2.name, sbus.dtsFrequency)(l2.coherenceManager)))),
- connections = if (l2.nBanks == 0) Nil else List(
- (SBUS, L2, TLBusWrapperConnection(driveClockFromMaster = Some(true), nodeBinding = BIND_STAR)()),
- (L2, MBUS, TLBusWrapperConnection.crossTo(
+ (COH, CoherenceManagerWrapperParams(mbus.blockBytes, mbus.beatBytes, coherence.nBanks, COH.name)(coherence.coherenceManager)))),
+ connections = if (coherence.nBanks == 0) Nil else List(
+ (SBUS, COH, TLBusWrapperConnection(driveClockFromMaster = Some(true), nodeBinding = BIND_STAR)()),
+ (COH, MBUS, TLBusWrapperConnection.crossTo(
xType = sbusToMbusXType,
driveClockFromMaster = if (driveMBusClockFromSBus) Some(true) else None,
nodeBinding = BIND_QUERY))
)
)
+
+case class ClusterBusTopologyParams(
+ clusterId: Int,
+ csbus: SystemBusParams,
+ ccbus: PeripheryBusParams,
+ coherence: BankedCoherenceParams
+) extends TLBusWrapperTopology(
+ instantiations = List(
+ (CSBUS(clusterId), csbus),
+ (CCBUS(clusterId), ccbus)) ++ (if (coherence.nBanks == 0) Nil else List(
+ (CMBUS(clusterId), csbus),
+ (CCOH (clusterId), CoherenceManagerWrapperParams(csbus.blockBytes, csbus.beatBytes, coherence.nBanks, CCOH(clusterId).name)(coherence.coherenceManager)))),
+ connections = if (coherence.nBanks == 0) Nil else List(
+ (CSBUS(clusterId), CCOH (clusterId), TLBusWrapperConnection(driveClockFromMaster = Some(true), nodeBinding = BIND_STAR)()),
+ (CCOH (clusterId), CMBUS(clusterId), TLBusWrapperConnection.crossTo(
+ xType = NoCrossing,
+ driveClockFromMaster = Some(true),
+ nodeBinding = BIND_QUERY))
+ )
+)
+
diff --git a/src/main/scala/subsystem/Cluster.scala b/src/main/scala/subsystem/Cluster.scala
new file mode 100644
index 00000000000..9d82ad616ca
--- /dev/null
+++ b/src/main/scala/subsystem/Cluster.scala
@@ -0,0 +1,236 @@
+package freechips.rocketchip.subsystem
+
+import chisel3._
+import chisel3.util._
+
+import org.chipsalliance.cde.config._
+import org.chipsalliance.diplomacy.bundlebridge._
+import org.chipsalliance.diplomacy.lazymodule._
+
+import freechips.rocketchip.devices.debug.{TLDebugModule}
+import freechips.rocketchip.diplomacy.{FlipRendering}
+import freechips.rocketchip.interrupts.{IntIdentityNode, IntSyncIdentityNode, NullIntSource}
+import freechips.rocketchip.prci.{ClockCrossingType, NoCrossing, ClockSinkParameters, ClockGroupIdentityNode, BundleBridgeBlockDuringReset}
+import freechips.rocketchip.tile.{RocketTile, NMI, TraceBundle}
+import freechips.rocketchip.tilelink.TLWidthWidget
+import freechips.rocketchip.util.TraceCoreInterface
+
+import scala.collection.immutable.SortedMap
+
+case class ClustersLocated(loc: HierarchicalLocation) extends Field[Seq[CanAttachCluster]](Nil)
+
+case class ClusterParams(
+ val clusterId: Int,
+ val clockSinkParams: ClockSinkParameters = ClockSinkParameters()
+) extends HierarchicalElementParams {
+ val baseName = "cluster"
+ val uniqueName = s"${baseName}_$clusterId"
+ def instantiate(crossing: HierarchicalElementCrossingParamsLike, lookup: LookupByClusterIdImpl)(implicit p: Parameters): Cluster = {
+ new Cluster(this, crossing.crossingType, lookup)
+ }
+}
+
+class Cluster(
+ val thisClusterParams: ClusterParams,
+ crossing: ClockCrossingType,
+ lookup: LookupByClusterIdImpl)(implicit p: Parameters) extends BaseHierarchicalElement(crossing)(p)
+ with Attachable
+ with HasConfigurableTLNetworkTopology
+ with InstantiatesHierarchicalElements
+ with HasHierarchicalElements
+{
+ val busContextName = thisClusterParams.baseName
+ lazy val clusterId = thisClusterParams.clusterId
+ lazy val location = InCluster(clusterId)
+
+ lazy val allClockGroupsNode = ClockGroupIdentityNode()
+
+ val csbus = tlBusWrapperLocationMap(CSBUS(clusterId)) // like the sbus in the base subsystem
+ val ccbus = tlBusWrapperLocationMap(CCBUS(clusterId)) // like the cbus in the base subsystem
+ val cmbus = tlBusWrapperLocationMap.lift(CMBUS(clusterId)).getOrElse(csbus)
+
+ csbus.clockGroupNode := allClockGroupsNode
+ ccbus.clockGroupNode := allClockGroupsNode
+
+ val slaveNode = ccbus.inwardNode
+ val masterNode = cmbus.outwardNode
+
+
+
+ lazy val ibus = LazyModule(new InterruptBusWrapper)
+ ibus.clockNode := csbus.fixedClockNode
+
+ def msipDomain = this
+ def meipDomain = this
+ def seipDomain = this
+ def toPlicDomain = this
+ lazy val msipNodes = totalTileIdList.map { i => (i, IntIdentityNode()) }.to(SortedMap)
+ lazy val meipNodes = totalTileIdList.map { i => (i, IntIdentityNode()) }.to(SortedMap)
+ lazy val seipNodes = totalTileIdList.map { i => (i, IntIdentityNode()) }.to(SortedMap)
+ lazy val tileToPlicNodes = totalTileIdList.map { i => (i, IntIdentityNode()) }.to(SortedMap)
+ lazy val debugNodes = totalTileIdList.map { i => (i, IntSyncIdentityNode()) }.to(SortedMap)
+ lazy val nmiNodes = totalTiles.filter { case (i,t) => t.tileParams.core.useNMI }
+ .mapValues(_ => BundleBridgeIdentityNode[NMI]()).to(SortedMap)
+ lazy val tileHartIdNodes = totalTileIdList.map { i => (i, BundleBridgeIdentityNode[UInt]()) }.to(SortedMap)
+ lazy val tileResetVectorNodes = totalTileIdList.map { i => (i, BundleBridgeIdentityNode[UInt]()) }.to(SortedMap)
+ lazy val traceCoreNodes = totalTileIdList.map { i => (i, BundleBridgeIdentityNode[TraceCoreInterface]()) }.to(SortedMap)
+ lazy val traceNodes = totalTileIdList.map { i => (i, BundleBridgeIdentityNode[TraceBundle]()) }.to(SortedMap)
+
+ // TODO fix: shouldn't need to connect dummy notifications
+ tileHaltXbarNode := NullIntSource()
+ tileWFIXbarNode := NullIntSource()
+ tileCeaseXbarNode := NullIntSource()
+
+ override lazy val module = new ClusterModuleImp(this)
+}
+
+class ClusterModuleImp(outer: Cluster) extends BaseHierarchicalElementModuleImp[Cluster](outer)
+
+case class InCluster(id: Int) extends HierarchicalLocation(s"Cluster$id")
+
+class ClusterPRCIDomain(
+ clockSinkParams: ClockSinkParameters,
+ crossingParams: HierarchicalElementCrossingParamsLike,
+ clusterParams: ClusterParams,
+ lookup: LookupByClusterIdImpl)
+ (implicit p: Parameters) extends HierarchicalElementPRCIDomain[Cluster](clockSinkParams, crossingParams)
+{
+ val element = element_reset_domain {
+ LazyModule(clusterParams.instantiate(crossingParams, lookup))
+ }
+ // Nothing should depend on the clocks coming from clockNode anyways
+ clockNode := element.csbus.fixedClockNode
+}
+
+
+trait CanAttachCluster {
+ type ClusterContextType <: DefaultHierarchicalElementContextType
+
+ def clusterParams: ClusterParams
+ def crossingParams: HierarchicalElementCrossingParamsLike
+
+ def instantiate(allClusterParams: Seq[ClusterParams], instantiatedClusters: SortedMap[Int, ClusterPRCIDomain])(implicit p: Parameters): ClusterPRCIDomain = {
+ val clockSinkParams = clusterParams.clockSinkParams.copy(name = Some(clusterParams.uniqueName))
+ val cluster_prci_domain = LazyModule(new ClusterPRCIDomain(
+ clockSinkParams, crossingParams, clusterParams, PriorityMuxClusterIdFromSeq(allClusterParams)))
+ cluster_prci_domain
+ }
+
+ def connect(domain: ClusterPRCIDomain, context: ClusterContextType): Unit = {
+ connectMasterPorts(domain, context)
+ connectSlavePorts(domain, context)
+ connectInterrupts(domain, context)
+ connectPRC(domain, context)
+ connectOutputNotifications(domain, context)
+ connectInputConstants(domain, context)
+ connectTrace(domain, context)
+ }
+
+ def connectMasterPorts(domain: ClusterPRCIDomain, context: Attachable): Unit = {
+ implicit val p = context.p
+ val dataBus = context.locateTLBusWrapper(crossingParams.master.where)
+ dataBus.coupleFrom(clusterParams.baseName) { bus =>
+ bus :=* crossingParams.master.injectNode(context) :=* domain.crossMasterPort(crossingParams.crossingType)
+ }
+ }
+ def connectSlavePorts(domain: ClusterPRCIDomain, context: Attachable): Unit = {
+ implicit val p = context.p
+ val controlBus = context.locateTLBusWrapper(crossingParams.slave.where)
+ controlBus.coupleTo(clusterParams.baseName) { bus =>
+ domain.crossSlavePort(crossingParams.crossingType) :*= crossingParams.slave.injectNode(context) :*= TLWidthWidget(controlBus.beatBytes) :*= bus
+ }
+ }
+ def connectInterrupts(domain: ClusterPRCIDomain, context: ClusterContextType): Unit = {
+ implicit val p = context.p
+
+ domain.element.debugNodes.foreach { case (hartid, node) =>
+ node := context.debugNodes(hartid)
+ }
+
+ domain.element.msipNodes.foreach { case (hartid, node) => context.msipDomain {
+ domain.crossIntIn(crossingParams.crossingType, node) := context.msipNodes(hartid)
+ }}
+
+ domain.element.meipNodes.foreach { case (hartid, node) => context.meipDomain {
+ domain.crossIntIn(crossingParams.crossingType, node) := context.meipNodes(hartid)
+ }}
+
+ domain.element.seipNodes.foreach { case (hartid, node) => context.seipDomain {
+ domain.crossIntIn(crossingParams.crossingType, node) := context.seipNodes(hartid)
+ }}
+
+ domain.element.tileToPlicNodes.foreach { case (hartid, node) =>
+ FlipRendering { implicit p =>
+ context.tileToPlicNodes(hartid) :=* domain.crossIntOut(crossingParams.crossingType, node) }
+ }
+ context.ibus.fromSync :=* domain.crossIntOut(crossingParams.crossingType, domain.element.ibus.toPLIC)
+
+ domain.element.nmiNodes.foreach { case (hartid, node) =>
+ node := context.nmiNodes(hartid)
+ }
+ }
+
+ def connectPRC(domain: ClusterPRCIDomain, context: ClusterContextType): Unit = {
+ implicit val p = context.p
+ domain.element.allClockGroupsNode :*= context.allClockGroupsNode
+ domain {
+ domain.element_reset_domain.clockNode := crossingParams.resetCrossingType.injectClockNode := domain.clockNode
+ }
+ }
+
+ def connectOutputNotifications(domain: ClusterPRCIDomain, context: ClusterContextType): Unit = {
+ implicit val p = context.p
+ context.tileHaltXbarNode :=* domain.crossIntOut(NoCrossing, domain.element.tileHaltXbarNode)
+ context.tileWFIXbarNode :=* domain.crossIntOut(NoCrossing, domain.element.tileWFIXbarNode)
+ context.tileCeaseXbarNode :=* domain.crossIntOut(NoCrossing, domain.element.tileCeaseXbarNode)
+
+ }
+
+ def connectInputConstants(domain: ClusterPRCIDomain, context: ClusterContextType): Unit = {
+ implicit val p = context.p
+ val tlBusToGetPrefixFrom = context.locateTLBusWrapper(crossingParams.mmioBaseAddressPrefixWhere)
+ domain.element.tileHartIdNodes.foreach { case (hartid, node) =>
+ node := context.tileHartIdNodes(hartid)
+ }
+ domain.element.tileResetVectorNodes.foreach { case (hartid, node) =>
+ node := context.tileResetVectorNodes(hartid)
+ }
+ }
+
+ def connectTrace(domain: ClusterPRCIDomain, context: ClusterContextType): Unit = {
+ implicit val p = context.p
+ domain.element.traceNodes.foreach { case (hartid, node) =>
+ val traceNexusNode = BundleBridgeBlockDuringReset[TraceBundle](
+ resetCrossingType = crossingParams.resetCrossingType)
+ context.traceNodes(hartid) := traceNexusNode := node
+ }
+ domain.element.traceCoreNodes.foreach { case (hartid, node) =>
+ val traceCoreNexusNode = BundleBridgeBlockDuringReset[TraceCoreInterface](
+ resetCrossingType = crossingParams.resetCrossingType)
+ context.traceCoreNodes(hartid) :*= traceCoreNexusNode := node
+ }
+ }
+}
+
+case class ClusterAttachParams(
+ clusterParams: ClusterParams,
+ crossingParams: HierarchicalElementCrossingParamsLike
+) extends CanAttachCluster
+
+case class CloneClusterAttachParams(
+ sourceClusterId: Int,
+ cloneParams: CanAttachCluster
+) extends CanAttachCluster {
+ def clusterParams = cloneParams.clusterParams
+ def crossingParams = cloneParams.crossingParams
+
+ override def instantiate(allClusterParams: Seq[ClusterParams], instantiatedClusters: SortedMap[Int, ClusterPRCIDomain])(implicit p: Parameters): ClusterPRCIDomain = {
+ require(instantiatedClusters.contains(sourceClusterId))
+ val clockSinkParams = clusterParams.clockSinkParams.copy(name = Some(clusterParams.uniqueName))
+ val cluster_prci_domain = CloneLazyModule(
+ new ClusterPRCIDomain(clockSinkParams, crossingParams, clusterParams, PriorityMuxClusterIdFromSeq(allClusterParams)),
+ instantiatedClusters(sourceClusterId)
+ )
+ cluster_prci_domain
+ }
+}
diff --git a/src/main/scala/subsystem/Configs.scala b/src/main/scala/subsystem/Configs.scala
index a9dbf4307bb..37001b39fd3 100644
--- a/src/main/scala/subsystem/Configs.scala
+++ b/src/main/scala/subsystem/Configs.scala
@@ -4,45 +4,63 @@
package freechips.rocketchip.subsystem
import chisel3.util._
+
import org.chipsalliance.cde.config._
-import freechips.rocketchip.devices.debug._
-import freechips.rocketchip.devices.tilelink._
-import freechips.rocketchip.diplomacy._
-import freechips.rocketchip.rocket._
-import freechips.rocketchip.tile._
-import freechips.rocketchip.util._
+import org.chipsalliance.diplomacy.lazymodule._
+
+import freechips.rocketchip.devices.debug.{DebugModuleKey, DefaultDebugModuleParams, ExportDebug, JTAG, APB}
+import freechips.rocketchip.devices.tilelink.{
+ BuiltInErrorDeviceParams, BootROMLocated, BootROMParams, CLINTKey, DevNullDevice, CLINTParams, PLICKey, PLICParams, DevNullParams
+}
+import freechips.rocketchip.prci.{SynchronousCrossing, AsynchronousCrossing, RationalCrossing, ClockCrossingType}
+import freechips.rocketchip.diplomacy.{
+ AddressSet, MonitorsEnabled,
+}
+import freechips.rocketchip.resources.{
+ DTSModel, DTSCompat, DTSTimebase, BigIntHexContext
+}
+import freechips.rocketchip.tile.{
+ MaxHartIdBits, RocketTileParams, BuildRoCC, AccumulatorExample, OpcodeSet, TranslatorExample, CharacterCountExample, BlackBoxExample
+}
+import freechips.rocketchip.util.ClockGateModelFile
+import scala.reflect.ClassTag
+
+case object MaxXLen extends Field[Int]
class BaseSubsystemConfig extends Config ((site, here, up) => {
// Tile parameters
- case PgLevels => if (site(XLen) == 64) 3 /* Sv39 */ else 2 /* Sv32 */
- case XLen => 64 // Applies to all cores
- case MaxHartIdBits => log2Up((site(TilesLocated(InSubsystem)).map(_.tileParams.hartId) :+ 0).max+1)
+ case MaxXLen => (site(PossibleTileLocations).flatMap(loc => site(TilesLocated(loc)))
+ .map(_.tileParams.core.xLen) :+ 32).max
+ case MaxHartIdBits => log2Up((site(PossibleTileLocations).flatMap(loc => site(TilesLocated(loc)))
+ .map(_.tileParams.tileId) :+ 0).max+1)
// Interconnect parameters
case SystemBusKey => SystemBusParams(
- beatBytes = site(XLen)/8,
+ beatBytes = 8,
blockBytes = site(CacheBlockBytes))
case ControlBusKey => PeripheryBusParams(
- beatBytes = site(XLen)/8,
+ beatBytes = 8,
blockBytes = site(CacheBlockBytes),
+ dtsFrequency = Some(100000000), // Default to 100 MHz cbus clock
errorDevice = Some(BuiltInErrorDeviceParams(
- errorParams = DevNullParams(List(AddressSet(0x3000, 0xfff)), maxAtomic=site(XLen)/8, maxTransfer=4096))))
+ errorParams = DevNullParams(List(AddressSet(0x3000, 0xfff)), maxAtomic=8, maxTransfer=4096))))
case PeripheryBusKey => PeripheryBusParams(
- beatBytes = site(XLen)/8,
+ beatBytes = 8,
blockBytes = site(CacheBlockBytes),
dtsFrequency = Some(100000000)) // Default to 100 MHz pbus clock
case MemoryBusKey => MemoryBusParams(
- beatBytes = site(XLen)/8,
+ beatBytes = 8,
blockBytes = site(CacheBlockBytes))
case FrontBusKey => FrontBusParams(
- beatBytes = site(XLen)/8,
+ beatBytes = 8,
blockBytes = site(CacheBlockBytes))
// Additional device Parameters
case BootROMLocated(InSubsystem) => Some(BootROMParams(contentFileName = "./bootrom/bootrom.img"))
- case SubsystemExternalResetVectorKey => false
- case DebugModuleKey => Some(DefaultDebugModuleParams(site(XLen)))
+ case HasTilesExternalResetVectorKey => false
+ case DebugModuleKey => Some(DefaultDebugModuleParams(64))
case CLINTKey => Some(CLINTParams())
case PLICKey => Some(PLICParams())
case TilesLocated(InSubsystem) => Nil
+ case PossibleTileLocations => Seq(InSubsystem)
})
/* Composable partial function Configs to set individual parameters */
@@ -80,193 +98,43 @@ class WithCoherentBusTopology extends Config((site, here, up) => {
fbusToSbusXType = site(FbusToSbusXTypeKey)),
driveClocksFromSBus = site(DriveClocksFromSBus)),
CoherentBusTopologyParams(
- sbus = site(SystemBusKey),
mbus = site(MemoryBusKey),
- l2 = site(BankedL2Key),
+ coherence = site(SubsystemBankedCoherenceKey),
sbusToMbusXType = site(SbusToMbusXTypeKey),
driveMBusClockFromSBus = site(DriveClocksFromSBus)))
})
-class WithNBigCores(
- n: Int,
- overrideIdOffset: Option[Int] = None,
- crossing: RocketCrossingParams = RocketCrossingParams()
-) extends Config((site, here, up) => {
- case TilesLocated(InSubsystem) => {
- val prev = up(TilesLocated(InSubsystem), site)
- val idOffset = overrideIdOffset.getOrElse(prev.size)
- val big = RocketTileParams(
- core = RocketCoreParams(mulDiv = Some(MulDivParams(
- mulUnroll = 8,
- mulEarlyOut = true,
- divEarlyOut = true))),
- dcache = Some(DCacheParams(
- rowBits = site(SystemBusKey).beatBits,
- nMSHRs = 0,
- blockBytes = site(CacheBlockBytes))),
- icache = Some(ICacheParams(
- rowBits = site(SystemBusKey).beatBits,
- blockBytes = site(CacheBlockBytes))))
- List.tabulate(n)(i => RocketTileAttachParams(
- big.copy(hartId = i + idOffset),
- crossing
- )) ++ prev
- }
-})
-
-class WithNMedCores(
- n: Int,
- overrideIdOffset: Option[Int] = None,
- crossing: RocketCrossingParams = RocketCrossingParams()
+class WithCluster(
+ clusterId: Int,
+ location: HierarchicalLocation = InSubsystem,
+ crossing: RocketCrossingParams = RocketCrossingParams() // TODO make this not rocket
) extends Config((site, here, up) => {
- case TilesLocated(InSubsystem) => {
- val prev = up(TilesLocated(InSubsystem), site)
- val idOffset = overrideIdOffset.getOrElse(prev.size)
- val med = RocketTileParams(
- core = RocketCoreParams(fpu = None),
- btb = None,
- dcache = Some(DCacheParams(
- rowBits = site(SystemBusKey).beatBits,
- nSets = 64,
- nWays = 1,
- nTLBSets = 1,
- nTLBWays = 4,
- nMSHRs = 0,
- blockBytes = site(CacheBlockBytes))),
- icache = Some(ICacheParams(
- rowBits = site(SystemBusKey).beatBits,
- nSets = 64,
- nWays = 1,
- nTLBSets = 1,
- nTLBWays = 4,
- blockBytes = site(CacheBlockBytes))))
- List.tabulate(n)(i => RocketTileAttachParams(
- med.copy(hartId = i + idOffset),
- crossing
- )) ++ prev
- }
-})
-
-class WithNSmallCores(
- n: Int,
- overrideIdOffset: Option[Int] = None,
- crossing: RocketCrossingParams = RocketCrossingParams()
-) extends Config((site, here, up) => {
- case TilesLocated(InSubsystem) => {
- val prev = up(TilesLocated(InSubsystem), site)
- val idOffset = overrideIdOffset.getOrElse(prev.size)
- val small = RocketTileParams(
- core = RocketCoreParams(useVM = false, fpu = None),
- btb = None,
- dcache = Some(DCacheParams(
- rowBits = site(SystemBusKey).beatBits,
- nSets = 64,
- nWays = 1,
- nTLBSets = 1,
- nTLBWays = 4,
- nMSHRs = 0,
- blockBytes = site(CacheBlockBytes))),
- icache = Some(ICacheParams(
- rowBits = site(SystemBusKey).beatBits,
- nSets = 64,
- nWays = 1,
- nTLBSets = 1,
- nTLBWays = 4,
- blockBytes = site(CacheBlockBytes))))
- List.tabulate(n)(i => RocketTileAttachParams(
- small.copy(hartId = i + idOffset),
- crossing
- )) ++ prev
- }
+ case ClustersLocated(`location`) => up(ClustersLocated(location)) :+ ClusterAttachParams(
+ ClusterParams(clusterId = clusterId),
+ crossing)
+ case TLNetworkTopologyLocated(InCluster(`clusterId`)) => List(
+ ClusterBusTopologyParams(
+ clusterId = clusterId,
+ csbus = site(SystemBusKey),
+ ccbus = site(ControlBusKey).copy(errorDevice = None),
+ coherence = site(ClusterBankedCoherenceKey(clusterId))
+ )
+ )
+ case PossibleTileLocations => up(PossibleTileLocations) :+ InCluster(clusterId)
})
-class With1TinyCore extends Config((site, here, up) => {
- case XLen => 32
- case TilesLocated(InSubsystem) => {
- val tiny = RocketTileParams(
- core = RocketCoreParams(
- useVM = false,
- fpu = None,
- mulDiv = Some(MulDivParams(mulUnroll = 8))),
- btb = None,
- dcache = Some(DCacheParams(
- rowBits = site(SystemBusKey).beatBits,
- nSets = 256, // 16Kb scratchpad
- nWays = 1,
- nTLBSets = 1,
- nTLBWays = 4,
- nMSHRs = 0,
- blockBytes = site(CacheBlockBytes),
- scratch = Some(0x80000000L))),
- icache = Some(ICacheParams(
- rowBits = site(SystemBusKey).beatBits,
- nSets = 64,
- nWays = 1,
- nTLBSets = 1,
- nTLBWays = 4,
- blockBytes = site(CacheBlockBytes)))
- )
- List(RocketTileAttachParams(
- tiny,
- RocketCrossingParams(
- crossingType = SynchronousCrossing(),
- master = TileMasterPortParams())
- ))
- }
+class WithClusterBanks(clusterId: Int, nBanks: Int = 1) extends Config((site, here, up) => {
+ case ClusterBankedCoherenceKey(`clusterId`) => up(ClusterBankedCoherenceKey(clusterId)).copy(nBanks=nBanks)
})
class WithNBanks(n: Int) extends Config((site, here, up) => {
- case BankedL2Key => up(BankedL2Key, site).copy(nBanks = n)
+ case SubsystemBankedCoherenceKey => up(SubsystemBankedCoherenceKey, site).copy(nBanks = n)
})
class WithNTrackersPerBank(n: Int) extends Config((site, here, up) => {
case BroadcastKey => up(BroadcastKey, site).copy(nTrackers = n)
})
-// This is the number of icache sets for all Rocket tiles
-class WithL1ICacheSets(sets: Int) extends Config((site, here, up) => {
- case TilesLocated(InSubsystem) => up(TilesLocated(InSubsystem), site) map {
- case tp: RocketTileAttachParams => tp.copy(tileParams = tp.tileParams.copy(
- icache = tp.tileParams.icache.map(_.copy(nSets = sets))))
- case t => t
- }
-})
-
-// This is the number of icache sets for all Rocket tiles
-class WithL1DCacheSets(sets: Int) extends Config((site, here, up) => {
- case TilesLocated(InSubsystem) => up(TilesLocated(InSubsystem), site) map {
- case tp: RocketTileAttachParams => tp.copy(tileParams = tp.tileParams.copy(
- dcache = tp.tileParams.dcache.map(_.copy(nSets = sets))))
- case t => t
- }
-})
-
-class WithL1ICacheWays(ways: Int) extends Config((site, here, up) => {
- case TilesLocated(InSubsystem) => up(TilesLocated(InSubsystem), site) map {
- case tp: RocketTileAttachParams => tp.copy(tileParams = tp.tileParams.copy(
- icache = tp.tileParams.icache.map(_.copy(nWays = ways))))
- case t => t
- }
-})
-
-class WithL1DCacheWays(ways: Int) extends Config((site, here, up) => {
- case TilesLocated(InSubsystem) => up(TilesLocated(InSubsystem), site) map {
- case tp: RocketTileAttachParams => tp.copy(tileParams = tp.tileParams.copy(
- dcache = tp.tileParams.dcache.map(_.copy(nWays = ways))))
- case t => t
- }
-})
-
-
-class WithRocketCacheRowBits(n: Int) extends Config((site, here, up) => {
- case TilesLocated(InSubsystem) => up(TilesLocated(InSubsystem), site) map {
- case tp: RocketTileAttachParams => tp.copy(tileParams = tp.tileParams.copy(
- dcache = tp.tileParams.dcache.map(_.copy(rowBits = n)),
- icache = tp.tileParams.icache.map(_.copy(rowBits = n))))
- case t => t
- }
-})
-
class WithCacheBlockBytes(linesize: Int) extends Config((site, here, up) => {
case CacheBlockBytes => linesize
})
@@ -275,77 +143,22 @@ class WithBufferlessBroadcastHub extends Config((site, here, up) => {
case BroadcastKey => up(BroadcastKey, site).copy(bufferless = true)
})
-/**
- * WARNING!!! IGNORE AT YOUR OWN PERIL!!!
- *
- * There is a very restrictive set of conditions under which the stateless
- * bridge will function properly. There can only be a single tile. This tile
- * MUST use the blocking data cache (L1D_MSHRS == 0) and MUST NOT have an
- * uncached channel capable of writes (i.e. a RoCC accelerator).
- *
- * This is because the stateless bridge CANNOT generate probes, so if your
- * system depends on coherence between channels in any way,
- * DO NOT use this configuration.
- */
-class WithIncoherentTiles extends Config((site, here, up) => {
- case TilesLocated(InSubsystem) => up(TilesLocated(InSubsystem), site) map {
- case tp: RocketTileAttachParams => tp.copy(crossingParams = tp.crossingParams.copy(
- master = tp.crossingParams.master match {
- case x: TileMasterPortParams => x.copy(cork = Some(true))
- case _ => throw new Exception("Unrecognized type for RocketCrossingParams.master")
- }))
- case t => t
- }
- case BankedL2Key => up(BankedL2Key, site).copy(
- coherenceManager = CoherenceManagerWrapper.incoherentManager
- )
-})
-
-class WithRV32 extends Config((site, here, up) => {
- case XLen => 32
- case TilesLocated(InSubsystem) => up(TilesLocated(InSubsystem), site) map {
- case tp: RocketTileAttachParams => tp.copy(tileParams = tp.tileParams.copy(
- core = tp.tileParams.core.copy(
- fpu = tp.tileParams.core.fpu.map(_.copy(fLen = 32)),
- mulDiv = Some(MulDivParams(mulUnroll = 8)))))
- case t => t
- }
-})
-
-class WithFP16 extends Config((site, here, up) => {
- case TilesLocated(InSubsystem) => up(TilesLocated(InSubsystem), site) map {
- case tp: RocketTileAttachParams => tp.copy(tileParams = tp.tileParams.copy(
- core = tp.tileParams.core.copy(
- fpu = tp.tileParams.core.fpu.map(_.copy(minFLen = 16))
- )
- ))
- case t => t
- }
-})
-
-class WithNonblockingL1(nMSHRs: Int) extends Config((site, here, up) => {
- case TilesLocated(InSubsystem) => up(TilesLocated(InSubsystem), site) map {
- case tp: RocketTileAttachParams => tp.copy(tileParams = tp.tileParams.copy(
- dcache = tp.tileParams.dcache.map(_.copy(nMSHRs = nMSHRs))))
- case t => t
- }
-})
-
-class WithNBreakpoints(hwbp: Int) extends Config ((site, here, up) => {
- case TilesLocated(InSubsystem) => up(TilesLocated(InSubsystem), site) map {
- case tp: RocketTileAttachParams => tp.copy(tileParams = tp.tileParams.copy(
- core = tp.tileParams.core.copy(nBreakpoints = hwbp)))
- case t => t
- }
-})
-
-class WithHypervisor(hext: Boolean = true) extends Config((site, here, up) => {
- case TilesLocated(InSubsystem) => up(TilesLocated(InSubsystem), site) map {
- case tp: RocketTileAttachParams => tp.copy(tileParams = tp.tileParams.copy(
- core = tp.tileParams.core.copy(useHypervisor = hext)))
- case t => t
- }
-})
+class TileAttachConfig[T <: CanAttachTile](f: T => T, locationOpt: Option[HierarchicalLocation], tileIdOpt: Seq[Int])(implicit tag: ClassTag[T])
+ extends Config((site, here, up) => {
+ val partialFn: PartialFunction[CanAttachTile, CanAttachTile] = { case tp: T => if (tileIdOpt.contains(tp.tileParams.tileId) || tileIdOpt.isEmpty) f(tp) else tp }
+ val alterFn: CanAttachTile => CanAttachTile = x => partialFn.applyOrElse(x, identity[CanAttachTile])
+ locationOpt match {
+ case Some(loc) => { case TilesLocated(`loc`) => up(TilesLocated(loc)) map { alterFn(_) } }
+ case None => { case TilesLocated(loc) => up(TilesLocated(loc)) map { alterFn(_) } }
+ }
+ }) {
+ // The default constructor applies the modification to all locations
+ def this(f: T => T)(implicit tag: ClassTag[T]) = this(f, None, Nil)
+ // The atLocation method applies the modification to only the provided location
+ def atLocation(loc: HierarchicalLocation) = new TileAttachConfig(f, Some(loc), tileIdOpt)
+ // The atTileIds method applies the modification only to specified tileIds
+ def atTileIds(ids: Int*) = new TileAttachConfig(f, locationOpt, tileIdOpt ++ ids)
+}
class WithRoccExample extends Config((site, here, up) => {
case BuildRoCC => List(
@@ -367,69 +180,30 @@ class WithRoccExample extends Config((site, here, up) => {
})
})
-class WithDefaultBtb extends Config((site, here, up) => {
- case TilesLocated(InSubsystem) => up(TilesLocated(InSubsystem), site) map {
- case tp: RocketTileAttachParams => tp.copy(tileParams = tp.tileParams.copy(
- btb = Some(BTBParams())))
- case t => t
- }
-})
-
-class WithFastMulDiv extends Config((site, here, up) => {
- case TilesLocated(InSubsystem) => up(TilesLocated(InSubsystem), site) map {
- case tp: RocketTileAttachParams => tp.copy(tileParams = tp.tileParams.copy(
- core = tp.tileParams.core.copy(mulDiv = Some(
- MulDivParams(mulUnroll = 8, mulEarlyOut = (site(XLen) > 32), divEarlyOut = true)))))
- case t => t
- }
-})
-
-class WithoutMulDiv extends Config((site, here, up) => {
- case TilesLocated(InSubsystem) => up(TilesLocated(InSubsystem), site) map {
- case tp: RocketTileAttachParams => tp.copy(tileParams = tp.tileParams.copy(
- core = tp.tileParams.core.copy(mulDiv = None)))
- case t => t
- }
-})
-
-class WithoutFPU extends Config((site, here, up) => {
- case TilesLocated(InSubsystem) => up(TilesLocated(InSubsystem), site) map {
- case tp: RocketTileAttachParams => tp.copy(tileParams = tp.tileParams.copy(
- core = tp.tileParams.core.copy(fpu = None)))
- case t => t
- }
-})
-
-class WithFPUWithoutDivSqrt extends Config((site, here, up) => {
- case TilesLocated(InSubsystem) => up(TilesLocated(InSubsystem), site) map {
- case tp: RocketTileAttachParams => tp.copy(tileParams = tp.tileParams.copy(
- core = tp.tileParams.core.copy(fpu = tp.tileParams.core.fpu.map(_.copy(divSqrt = false)))))
- case t => t
- }
-})
-
-class WithRocketDebugROB(enable: Boolean = true) extends Config((site, here, up) => {
- case TilesLocated(InSubsystem) => up(TilesLocated(InSubsystem), site) map {
- case tp: RocketTileAttachParams => tp.copy(tileParams = tp.tileParams.copy(
- core = tp.tileParams.core.copy(debugROB = enable)
- ))
- }
-})
-
-class WithRocketCease(enable: Boolean = true) extends Config((site, here, up) => {
- case TilesLocated(InSubsystem) => up(TilesLocated(InSubsystem), site) map {
- case tp: RocketTileAttachParams => tp.copy(tileParams = tp.tileParams.copy(
- core = tp.tileParams.core.copy(haveCease = enable)
- ))
- }
-})
-
-class WithNoSimulationTimeout extends Config((site, here, up) => {
- case TilesLocated(InSubsystem) => up(TilesLocated(InSubsystem), site) map {
- case tp: RocketTileAttachParams => tp.copy(tileParams = tp.tileParams.copy(
- core = tp.tileParams.core.copy(haveSimTimeout = false)))
+/**
+ * WARNING!!! IGNORE AT YOUR OWN PERIL!!!
+ *
+ * There is a very restrictive set of conditions under which the stateless
+ * bridge will function properly. There can only be a single tile. This tile
+ * MUST use the blocking data cache (L1D_MSHRS == 0) and MUST NOT have an
+ * uncached channel capable of writes (i.e. a RoCC accelerator).
+ *
+ * This is because the stateless bridge CANNOT generate probes, so if your
+ * system depends on coherence between channels in any way,
+ * DO NOT use this configuration.
+ */
+class WithIncoherentTiles extends Config((site, here, up) => {
+ case TilesLocated(location) => up(TilesLocated(location), site) map {
+ case tp: RocketTileAttachParams => tp.copy(crossingParams = tp.crossingParams.copy(
+ master = tp.crossingParams.master match {
+ case x: HierarchicalElementMasterPortParams => x.copy(cork = Some(true))
+ case _ => throw new Exception("Unrecognized type for RocketCrossingParams.master")
+ }))
case t => t
}
+ case SubsystemBankedCoherenceKey => up(SubsystemBankedCoherenceKey, site).copy(
+ coherenceManager = CoherenceManagerWrapper.incoherentManager
+ )
})
class WithBootROMFile(bootROMFile: String) extends Config((site, here, up) => {
@@ -440,34 +214,9 @@ class WithClockGateModel(file: String = "/vsrc/EICG_wrapper.v") extends Config((
case ClockGateModelFile => Some(file)
})
-class WithSynchronousRocketTiles extends Config((site, here, up) => {
- case TilesLocated(InSubsystem) => up(TilesLocated(InSubsystem), site) map {
- case tp: RocketTileAttachParams => tp.copy(crossingParams = tp.crossingParams.copy(
- crossingType = SynchronousCrossing()))
- case t => t
- }
-})
-
-class WithAsynchronousRocketTiles(depth: Int, sync: Int) extends Config((site, here, up) => {
- case TilesLocated(InSubsystem) => up(TilesLocated(InSubsystem), site) map {
- case tp: RocketTileAttachParams => tp.copy(crossingParams = tp.crossingParams.copy(
- crossingType = AsynchronousCrossing()))
- case t => t
- }
-})
-
-class WithRationalRocketTiles extends Config((site, here, up) => {
- case TilesLocated(InSubsystem) => up(TilesLocated(InSubsystem), site) map {
- case tp: RocketTileAttachParams => tp.copy(crossingParams = tp.crossingParams.copy(
- crossingType = RationalCrossing()))
- case t => t
- }
-})
-
class WithEdgeDataBits(dataBits: Int) extends Config((site, here, up) => {
case MemoryBusKey => up(MemoryBusKey, site).copy(beatBytes = dataBits/8)
case ExtIn => up(ExtIn, site).map(_.copy(beatBytes = dataBits/8))
-
})
class WithJtagDTM extends Config ((site, here, up) => {
@@ -524,6 +273,15 @@ class WithDefaultMemPort extends Config((site, here, up) => {
idBits = 4), 1))
})
+class WithCustomMemPort (base_addr: BigInt, base_size: BigInt, data_width: Int, id_bits: Int, maxXferBytes: Int) extends Config((site, here, up) => {
+ case ExtMem => Some(MemoryPortParams(MasterPortParams(
+ base = base_addr,
+ size = base_size,
+ beatBytes = data_width/8,
+ idBits = id_bits,
+ maxXferBytes = maxXferBytes), 1))
+})
+
class WithNoMemPort extends Config((site, here, up) => {
case ExtMem => None
})
@@ -536,6 +294,15 @@ class WithDefaultMMIOPort extends Config((site, here, up) => {
idBits = 4))
})
+class WithCustomMMIOPort (base_addr: BigInt, base_size: BigInt, data_width: Int, id_bits: Int, maxXferBytes: Int) extends Config((site, here, up) => {
+ case ExtBus => Some(MasterPortParams(
+ base = base_addr,
+ size = base_size,
+ beatBytes = data_width/8,
+ idBits = id_bits,
+ maxXferBytes = maxXferBytes))
+})
+
class WithNoMMIOPort extends Config((site, here, up) => {
case ExtBus => None
})
@@ -544,31 +311,12 @@ class WithDefaultSlavePort extends Config((site, here, up) => {
case ExtIn => Some(SlavePortParams(beatBytes = 8, idBits = 8, sourceBits = 4))
})
-class WithNoSlavePort extends Config((site, here, up) => {
- case ExtIn => None
+class WithCustomSlavePort (data_width: Int, id_bits: Int) extends Config((site, here, up) => {
+ case ExtIn => Some(SlavePortParams(beatBytes = data_width/8, idBits = id_bits, sourceBits = 4))
})
-class WithScratchpadsBaseAddress(address: BigInt) extends Config((site, here, up) => {
- case TilesLocated(InSubsystem) => up(TilesLocated(InSubsystem), site) map {
- case tp: RocketTileAttachParams => tp.copy(tileParams = tp.tileParams.copy(
- dcache = tp.tileParams.dcache.map(
- _.copy(scratch = Some(address))
- )
- ))
- case t => t
- }
-})
-
-class WithScratchpadsOnly extends Config((site, here, up) => {
- case TilesLocated(InSubsystem) => up(TilesLocated(InSubsystem), site) map {
- case tp: RocketTileAttachParams => tp.copy(tileParams = tp.tileParams.copy(
- core = tp.tileParams.core.copy(useVM = false),
- dcache = tp.tileParams.dcache.map(_.copy(
- nSets = 256, // 16Kb scratchpad
- nWays = 1,
- scratch = Some(0x80000000L)))))
- case t => t
- }
+class WithNoSlavePort extends Config((site, here, up) => {
+ case ExtIn => None
})
/**
@@ -619,16 +367,21 @@ class WithDontDriveBusClocksFromSBus extends Config((site, here, up) => {
case DriveClocksFromSBus => false
})
-class WithCloneRocketTiles(n: Int = 1, cloneHart: Int = 0, overrideIdOffset: Option[Int] = None) extends Config((site, here, up) => {
- case TilesLocated(InSubsystem) => {
- val prev = up(TilesLocated(InSubsystem), site)
- val idOffset = overrideIdOffset.getOrElse(prev.size)
- val tileAttachParams = prev(cloneHart).asInstanceOf[RocketTileAttachParams]
- (0 until n).map { i =>
- CloneTileAttachParams(cloneHart, tileAttachParams.copy(
- tileParams = tileAttachParams.tileParams.copy(hartId = i + idOffset)
- ))
- } ++ prev
+class WithCloneCluster(
+ clusterId: Int,
+ cloneClusterId: Int = 0,
+ location: HierarchicalLocation = InSubsystem,
+ cloneLocation: HierarchicalLocation = InSubsystem
+) extends Config((site, here, up) => {
+ case ClustersLocated(`location`) => {
+ val prev = up(ClustersLocated(location))
+ val clusterAttachParams = up(ClustersLocated(cloneLocation)).find(_.clusterParams.clusterId == cloneClusterId)
+ .get.asInstanceOf[ClusterAttachParams]
+ prev :+ CloneClusterAttachParams(
+ cloneClusterId,
+ clusterAttachParams.copy(clusterParams = clusterAttachParams.clusterParams.copy(clusterId = clusterId))
+ )
}
+ case TLNetworkTopologyLocated(InCluster(`clusterId`)) => site(TLNetworkTopologyLocated(InCluster(cloneClusterId)))
+ case PossibleTileLocations => up(PossibleTileLocations) :+ InCluster(clusterId)
})
-
diff --git a/src/main/scala/subsystem/CrossingWrapper.scala b/src/main/scala/subsystem/CrossingWrapper.scala
index 435a90a7b74..c252405fbc4 100644
--- a/src/main/scala/subsystem/CrossingWrapper.scala
+++ b/src/main/scala/subsystem/CrossingWrapper.scala
@@ -2,13 +2,20 @@
package freechips.rocketchip.subsystem
-import org.chipsalliance.cde.config.Parameters
-import freechips.rocketchip.diplomacy._
-import freechips.rocketchip.tilelink._
-import freechips.rocketchip.amba.axi4._
-import freechips.rocketchip.interrupts._
+import org.chipsalliance.cde.config._
+import org.chipsalliance.diplomacy.lazymodule._
+
+import freechips.rocketchip.amba.axi4.{AXI4InwardNode, AXI4OutwardNode}
+import freechips.rocketchip.prci.{ClockCrossingType, HasClockDomainCrossing}
+import freechips.rocketchip.tilelink.{TLInwardNode, TLOutwardNode}
+import freechips.rocketchip.interrupts.{IntInwardNode, IntOutwardNode}
import freechips.rocketchip.prci.{HasResetDomainCrossing, ResetCrossingType}
+import freechips.rocketchip.tilelink.TLClockDomainCrossing
+import freechips.rocketchip.tilelink.TLResetDomainCrossing
+import freechips.rocketchip.interrupts.IntClockDomainCrossing
+import freechips.rocketchip.interrupts.IntResetDomainCrossing
+
@deprecated("Only use this trait if you are confident you island will only ever be crossed to a single clock", "rocket-chip 1.3")
trait HasCrossing extends CrossesToOnlyOneClockDomain { this: LazyModule => }
diff --git a/src/main/scala/subsystem/FrontBus.scala b/src/main/scala/subsystem/FrontBus.scala
index 001af15452e..e968246a130 100644
--- a/src/main/scala/subsystem/FrontBus.scala
+++ b/src/main/scala/subsystem/FrontBus.scala
@@ -2,10 +2,11 @@
package freechips.rocketchip.subsystem
-import org.chipsalliance.cde.config.{Parameters}
-import freechips.rocketchip.devices.tilelink._
-import freechips.rocketchip.diplomacy._
-import freechips.rocketchip.tilelink._
+import org.chipsalliance.cde.config._
+import org.chipsalliance.diplomacy.lazymodule._
+
+import freechips.rocketchip.devices.tilelink.{BuiltInErrorDeviceParams, BuiltInZeroDeviceParams, BuiltInDevices, HasBuiltInDeviceParams}
+import freechips.rocketchip.tilelink.{HasTLBusParams, TLBusWrapper, TLBusWrapperInstantiationLike, HasTLXbarPhy}
import freechips.rocketchip.util.{Location}
case class FrontBusParams(
diff --git a/src/main/scala/subsystem/HasHierarchicalElements.scala b/src/main/scala/subsystem/HasHierarchicalElements.scala
new file mode 100644
index 00000000000..d026395a417
--- /dev/null
+++ b/src/main/scala/subsystem/HasHierarchicalElements.scala
@@ -0,0 +1,249 @@
+// See LICENSE.SiFive for license details.
+
+package freechips.rocketchip.subsystem
+
+import chisel3._
+
+import org.chipsalliance.cde.config._
+import org.chipsalliance.diplomacy.bundlebridge._
+import org.chipsalliance.diplomacy.lazymodule._
+
+import freechips.rocketchip.devices.debug.{TLDebugModule, HasPeripheryDebug}
+import freechips.rocketchip.devices.tilelink.{BasicBusBlocker, BasicBusBlockerParams, CLINT, TLPLIC, CLINTConsts}
+import freechips.rocketchip.interrupts.{
+ IntNode, IntSyncNode, IntEphemeralNode, NullIntSource, IntNexusNode, IntSourcePortParameters,
+ IntSourceParameters, IntSinkPortParameters, IntSinkParameters, IntSyncIdentityNode, NullIntSyncSource
+}
+import freechips.rocketchip.tile.{TileParams, TilePRCIDomain, BaseTile, NMI, TraceBundle}
+import freechips.rocketchip.tilelink.{TLNode, TLBuffer, TLCacheCork, TLTempNode, TLFragmenter}
+import freechips.rocketchip.prci.{ClockCrossingType, ClockGroup, ResetCrossingType, ClockGroupNode, ClockDomain}
+import freechips.rocketchip.rocket.TracedInstruction
+import freechips.rocketchip.util.TraceCoreInterface
+
+import scala.collection.immutable.SortedMap
+
+/** A default implementation of parameterizing the connectivity of the port where the tile is the master.
+ * Optional timing buffers and/or an optional CacheCork can be inserted in the interconnect's clock domain.
+ */
+case class HierarchicalElementMasterPortParams(
+ buffers: Int = 0,
+ cork: Option[Boolean] = None,
+ where: TLBusWrapperLocation = SBUS
+) extends HierarchicalElementPortParamsLike {
+ def injectNode(context: Attachable)(implicit p: Parameters): TLNode = {
+ (TLBuffer.chainNode(buffers) :=* cork.map { u => TLCacheCork(unsafe = u) } .getOrElse { TLTempNode() })
+ }
+}
+
+object HierarchicalElementMasterPortParams {
+ def locationDefault(loc: HierarchicalLocation) = loc match {
+ case InSubsystem => HierarchicalElementMasterPortParams()
+ case InCluster(clusterId) => HierarchicalElementMasterPortParams(where=CSBUS(clusterId))
+ }
+}
+
+/** A default implementation of parameterizing the connectivity of the port giving access to slaves inside the tile.
+ * Optional timing buffers and/or an optional BusBlocker adapter can be inserted in the interconnect's clock domain.
+ */
+case class HierarchicalElementSlavePortParams(
+ buffers: Int = 0,
+ blockerCtrlAddr: Option[BigInt] = None,
+ blockerCtrlWhere: TLBusWrapperLocation = CBUS,
+ where: TLBusWrapperLocation = CBUS
+) extends HierarchicalElementPortParamsLike {
+ def injectNode(context: Attachable)(implicit p: Parameters): TLNode = {
+ val controlBus = context.locateTLBusWrapper(where)
+ val blockerBus = context.locateTLBusWrapper(blockerCtrlWhere)
+ blockerCtrlAddr
+ .map { BasicBusBlockerParams(_, blockerBus.beatBytes, controlBus.beatBytes) }
+ .map { bbbp =>
+ val blocker = LazyModule(new BasicBusBlocker(bbbp))
+ blockerBus.coupleTo("tile_slave_port_bus_blocker") { blocker.controlNode := TLFragmenter(blockerBus) := _ }
+ blocker.node :*= TLBuffer.chainNode(buffers)
+ } .getOrElse { TLBuffer.chainNode(buffers) }
+ }
+}
+
+object HierarchicalElementSlavePortParams {
+ def locationDefault(loc: HierarchicalLocation) = loc match {
+ case InSubsystem => HierarchicalElementSlavePortParams()
+ case InCluster(clusterId) => HierarchicalElementSlavePortParams(where=CCBUS(clusterId), blockerCtrlWhere=CCBUS(clusterId))
+ }
+}
+
+/** InstantiatesTiles adds a Config-urable sequence of HierarchicalElements of any type
+ * to the subsystem class into which it is mixed.
+ */
+trait InstantiatesHierarchicalElements { this: LazyModule with Attachable =>
+ val location: HierarchicalLocation
+
+ /** Record the order in which to instantiate all tiles, based on statically-assigned ids.
+ *
+ * Note that these ids, which are often used as the tiles' default hartid input,
+ * may or may not be those actually reflected at runtime in e.g. the $mhartid CSR
+ */
+ val tileAttachParams: Seq[CanAttachTile] = p(TilesLocated(location)).sortBy(_.tileParams.tileId)
+ val tileParams: Seq[TileParams] = tileAttachParams.map(_.tileParams)
+ val tileCrossingTypes: Seq[ClockCrossingType] = tileAttachParams.map(_.crossingParams.crossingType)
+
+ /** The actual list of instantiated tiles in this block. */
+ val tile_prci_domains: SortedMap[Int, TilePRCIDomain[_]] = tileAttachParams.foldLeft(SortedMap[Int, TilePRCIDomain[_]]()) {
+ case (instantiated, params) => instantiated + (params.tileParams.tileId -> params.instantiate(tileParams, instantiated)(p))
+ }
+
+ val clusterAttachParams: Seq[CanAttachCluster] = p(ClustersLocated(location)).sortBy(_.clusterParams.clusterId)
+ val clusterParams: Seq[ClusterParams] = clusterAttachParams.map(_.clusterParams)
+ val clusterCrossingTypes: Seq[ClockCrossingType] = clusterAttachParams.map(_.crossingParams.crossingType)
+ val cluster_prci_domains: SortedMap[Int, ClusterPRCIDomain] = clusterAttachParams.foldLeft(SortedMap[Int, ClusterPRCIDomain]()) {
+ case (instantiated, params) => instantiated + (params.clusterParams.clusterId -> params.instantiate(clusterParams, instantiated)(p))
+ }
+
+ val element_prci_domains: Seq[HierarchicalElementPRCIDomain[_]] = tile_prci_domains.values.toSeq ++ cluster_prci_domains.values.toSeq
+
+ val leafTiles: SortedMap[Int, BaseTile] = SortedMap(tile_prci_domains.mapValues(_.element.asInstanceOf[BaseTile]).toSeq.sortBy(_._1):_*)
+ val totalTiles: SortedMap[Int, BaseTile] = (leafTiles ++ cluster_prci_domains.values.map(_.element.totalTiles).flatten)
+
+ // Helper functions for accessing certain parameters that are popular to refer to in subsystem code
+ def nLeafTiles: Int = leafTiles.size
+ def nTotalTiles: Int = totalTiles.size
+ def leafTileIdList: Seq[Int] = leafTiles.keys.toSeq.sorted
+ def totalTileIdList: Seq[Int] = totalTiles.keys.toSeq.sorted
+ def localIntCounts: SortedMap[Int, Int] = totalTiles.mapValues(_.tileParams.core.nLocalInterrupts).to(SortedMap)
+
+ require(totalTileIdList.distinct.size == totalTiles.size, s"Every tile must be statically assigned a unique id, but got:\n${totalTileIdList}")
+}
+
+/** HasTiles instantiates and also connects a Config-urable sequence of tiles of any type to subsystem interconnect resources. */
+trait HasHierarchicalElements extends DefaultHierarchicalElementContextType
+{ this: LazyModule with Attachable with InstantiatesHierarchicalElements =>
+ implicit val p: Parameters
+
+ // connect all the tiles to interconnect attachment points made available in this subsystem context
+ tileAttachParams.foreach { params =>
+ params.connect(tile_prci_domains(params.tileParams.tileId).asInstanceOf[TilePRCIDomain[params.TileType]], this.asInstanceOf[params.TileContextType])
+ }
+ clusterAttachParams.foreach { params =>
+ params.connect(cluster_prci_domains(params.clusterParams.clusterId).asInstanceOf[ClusterPRCIDomain], this.asInstanceOf[params.ClusterContextType])
+ }
+}
+
+/** Provides some Chisel connectivity to certain tile IOs
+ * This trait is intended for the root subsystem
+ */
+trait HasHierarchicalElementsRootContextModuleImp extends LazyRawModuleImp {
+ val outer: InstantiatesHierarchicalElements with HasHierarchicalElements with HasHierarchicalElementsRootContext with HasTileInputConstants
+
+ val reset_vector = outer.tileResetVectorIONodes.zipWithIndex.map { case (n, i) => n.makeIO(s"reset_vector_$i") }
+ val tile_hartids = outer.tileHartIdIONodes.zipWithIndex.map { case (n, i) => n.makeIO(s"tile_hartids_$i") }
+
+ val meip = if (outer.meipIONode.isDefined) Some(IO(Input(Vec(outer.meipIONode.get.out.size, Bool())))) else None
+ meip.foreach { m =>
+ m.zipWithIndex.foreach{ case (pin, i) =>
+ (outer.meipIONode.get.out(i)._1)(0) := pin
+ }
+ }
+ val seip = if (outer.seipIONode.isDefined) Some(IO(Input(Vec(outer.seipIONode.get.out.size, Bool())))) else None
+ seip.foreach { s =>
+ s.zipWithIndex.foreach{ case (pin, i) =>
+ (outer.seipIONode.get.out(i)._1)(0) := pin
+ }
+ }
+ val nmi = outer.nmiIONodes.map { case (i, node) =>
+ node.makeIO(s"nmi_$i")
+ }
+}
+
+/** Most tile types require only these traits in order for their standardized connect functions to apply.
+ *
+ * BaseTiles subtypes with different needs can extend this trait to provide themselves with
+ * additional external connection points.
+ */
+trait DefaultHierarchicalElementContextType
+ extends Attachable
+ with HasTileNotificationSinks
+{ this: LazyModule with Attachable =>
+ def msipDomain: LazyScope
+ val msipNodes: SortedMap[Int, IntNode]
+ def meipDomain: LazyScope
+ val meipNodes: SortedMap[Int, IntNode]
+ def seipDomain: LazyScope
+ val seipNodes: SortedMap[Int, IntNode]
+ def toPlicDomain: LazyScope
+ val tileToPlicNodes: SortedMap[Int, IntNode]
+ val debugNodes: SortedMap[Int, IntSyncNode]
+ val nmiNodes: SortedMap[Int, BundleBridgeNode[NMI]]
+ val tileHartIdNodes: SortedMap[Int, BundleBridgeNode[UInt]]
+ val tileResetVectorNodes: SortedMap[Int, BundleBridgeNode[UInt]]
+ val traceCoreNodes: SortedMap[Int, BundleBridgeNode[TraceCoreInterface]]
+ val traceNodes: SortedMap[Int, BundleBridgeNode[TraceBundle]]
+}
+
+/** This trait provides the tile attachment context for the root (outermost) subsystem */
+trait HasHierarchicalElementsRootContext
+{ this: HasHierarchicalElements
+ with HasTileNotificationSinks
+ with InstantiatesHierarchicalElements =>
+
+ val clintOpt: Option[CLINT]
+ val clintDomainOpt: Option[ClockDomain]
+ val plicOpt: Option[TLPLIC]
+ val plicDomainOpt: Option[ClockDomain]
+ val debugOpt: Option[TLDebugModule]
+
+ def msipDomain = clintDomainOpt.getOrElse(this)
+ def meipDomain = plicDomainOpt.getOrElse(this)
+ def seipDomain = plicDomainOpt.getOrElse(this)
+ def toPlicDomain = plicDomainOpt.getOrElse(this)
+
+ val msipNodes: SortedMap[Int, IntNode] = (0 until nTotalTiles).map { i =>
+ (i, IntEphemeralNode())
+ }.to(SortedMap)
+ msipNodes.foreach {
+ _._2 := clintOpt.map(_.intnode).getOrElse(NullIntSource(sources = CLINTConsts.ints))
+ }
+
+ val meipIONode = Option.when(plicOpt.isEmpty)(IntNexusNode(
+ sourceFn = { _ => IntSourcePortParameters(Seq(IntSourceParameters(1))) },
+ sinkFn = { _ => IntSinkPortParameters(Seq(IntSinkParameters())) },
+ outputRequiresInput = false,
+ inputRequiresOutput = false))
+ val meipNodes: SortedMap[Int, IntNode] = (0 until nTotalTiles).map { i =>
+ (i, IntEphemeralNode())
+ }.to(SortedMap)
+
+ val seipIONode = Option.when(plicOpt.isEmpty)(IntNexusNode(
+ sourceFn = { _ => IntSourcePortParameters(Seq(IntSourceParameters(1))) },
+ sinkFn = { _ => IntSinkPortParameters(Seq(IntSinkParameters())) },
+ outputRequiresInput = false,
+ inputRequiresOutput = false))
+ val seipNodes: SortedMap[Int, IntNode] = totalTiles.filter { case (_, t) => t.tileParams.core.hasSupervisorMode }
+ .mapValues( _ => IntEphemeralNode()).to(SortedMap)
+
+ // meip/seip nodes must be connected in MSMSMS order
+ // TODO: This is ultra fragile... the plic should just expose two intnodes
+ for (i <- 0 until nTotalTiles) {
+ meipNodes.get(i).foreach { _ := plicOpt.map(_.intnode).getOrElse(meipIONode.get) }
+ seipNodes.get(i).foreach { _ := plicOpt.map(_.intnode).getOrElse(seipIONode.get) }
+ }
+
+ val tileToPlicNodes: SortedMap[Int, IntNode] = (0 until nTotalTiles).map { i =>
+ plicOpt.map(o => (i, o.intnode :=* IntEphemeralNode()))
+ }.flatten.to(SortedMap)
+
+ val debugNodes: SortedMap[Int, IntSyncNode] = (0 until nTotalTiles).map { i =>
+ (i, IntSyncIdentityNode())
+ }.to(SortedMap)
+
+ debugNodes.foreach { case (hartid, node) =>
+ node := debugOpt.map(_.intnode).getOrElse(NullIntSyncSource())
+ }
+
+ val nmiHarts = totalTiles.filter { case (_, t) => t.tileParams.core.useNMI }.keys
+ val nmiIONodes = nmiHarts.map { i => (i, BundleBridgeSource[NMI]()) }.to(SortedMap)
+ val nmiNodes: SortedMap[Int, BundleBridgeNode[NMI]] = nmiIONodes.map { case (i, n) =>
+ (i, BundleBridgeEphemeralNode[NMI]() := n)
+ }.to(SortedMap)
+
+ val traceCoreNodes: SortedMap[Int, BundleBridgeSink[TraceCoreInterface]] = (0 until nTotalTiles).map { i => (i, BundleBridgeSink[TraceCoreInterface]()) }.to(SortedMap)
+ val traceNodes: SortedMap[Int, BundleBridgeSink[TraceBundle]] = (0 until nTotalTiles).map { i => (i, BundleBridgeSink[TraceBundle]()) }.to(SortedMap)
+}
diff --git a/src/main/scala/subsystem/HasTiles.scala b/src/main/scala/subsystem/HasTiles.scala
index 5c65ed4cd81..ea1f34f7e7b 100644
--- a/src/main/scala/subsystem/HasTiles.scala
+++ b/src/main/scala/subsystem/HasTiles.scala
@@ -3,19 +3,31 @@
package freechips.rocketchip.subsystem
import chisel3._
-import chisel3.dontTouch
-import org.chipsalliance.cde.config.{Field, Parameters}
-import freechips.rocketchip.devices.tilelink.{BasicBusBlocker, BasicBusBlockerParams, CLINTConsts, PLICKey, CanHavePeripheryPLIC, CanHavePeripheryCLINT}
-import freechips.rocketchip.diplomacy._
-import freechips.rocketchip.interrupts._
-import freechips.rocketchip.tile._
-import freechips.rocketchip.tilelink._
-import freechips.rocketchip.prci.{ClockGroup, ResetCrossingType, ClockGroupNode}
-import freechips.rocketchip.util._
+
+import org.chipsalliance.cde.config._
+import org.chipsalliance.diplomacy.bundlebridge._
+import org.chipsalliance.diplomacy.lazymodule._
+
+import freechips.rocketchip.devices.debug.TLDebugModule
+import freechips.rocketchip.diplomacy.{DisableMonitors, FlipRendering}
+import freechips.rocketchip.interrupts.{IntXbar, IntSinkNode, IntSinkPortSimple, IntSyncAsyncCrossingSink}
+import freechips.rocketchip.tile.{MaxHartIdBits, BaseTile, InstantiableTileParams, TileParams, TilePRCIDomain, TraceBundle, PriorityMuxHartIdFromSeq}
+import freechips.rocketchip.tilelink.TLWidthWidget
+import freechips.rocketchip.prci.{ClockGroup, BundleBridgeBlockDuringReset, NoCrossing, SynchronousCrossing, CreditedCrossing, RationalCrossing, AsynchronousCrossing}
+import freechips.rocketchip.rocket.TracedInstruction
+import freechips.rocketchip.util.TraceCoreInterface
+
+import scala.collection.immutable.SortedMap
/** Entry point for Config-uring the presence of Tiles */
case class TilesLocated(loc: HierarchicalLocation) extends Field[Seq[CanAttachTile]](Nil)
+/** List of HierarchicalLocations which might contain a Tile */
+case object PossibleTileLocations extends Field[Seq[HierarchicalLocation]](Nil)
+
+/** For determining static tile id */
+case object NumTiles extends Field[Int](0)
+
/** Whether to add timing-closure registers along the path of the hart id
* as it propagates through the subsystem and into the tile.
*
@@ -24,112 +36,17 @@ case class TilesLocated(loc: HierarchicalLocation) extends Field[Seq[CanAttachTi
*/
case object InsertTimingClosureRegistersOnHartIds extends Field[Boolean](false)
-/** Whether per-tile hart ids are going to be driven as inputs into the subsystem,
+/** Whether per-tile hart ids are going to be driven as inputs into a HasTiles block,
* and if so, what their width should be.
*/
-case object SubsystemExternalHartIdWidthKey extends Field[Option[Int]](None)
+case object HasTilesExternalHartIdWidthKey extends Field[Option[Int]](None)
-/** Whether per-tile reset vectors are going to be driven as inputs into the subsystem.
+/** Whether per-tile reset vectors are going to be driven as inputs into a HasTiles block.
*
* Unlike the hart ids, the reset vector width is determined by the sinks within the tiles,
* based on the size of the address map visible to the tiles.
*/
-case object SubsystemExternalResetVectorKey extends Field[Boolean](true)
-
-/** An interface for describing the parameteization of how Tiles are connected to interconnects */
-trait TileCrossingParamsLike {
- /** The type of clock crossing that should be inserted at the tile boundary. */
- def crossingType: ClockCrossingType
- /** Parameters describing the contents and behavior of the point where the tile is attached as an interconnect master. */
- def master: TilePortParamsLike
- /** Parameters describing the contents and behavior of the point where the tile is attached as an interconnect slave. */
- def slave: TilePortParamsLike
- /** The subnetwork location of the device selecting the apparent base address of MMIO devices inside the tile */
- def mmioBaseAddressPrefixWhere: TLBusWrapperLocation
- /** Inject a reset management subgraph that effects the tile child reset only */
- def resetCrossingType: ResetCrossingType
- /** Keep the tile clock separate from the interconnect clock (e.g. even if they are synchronous to one another) */
- def forceSeparateClockReset: Boolean
-}
-
-/** An interface for describing the parameterization of how a particular tile port is connected to an interconnect */
-trait TilePortParamsLike {
- /** The subnetwork location of the interconnect to which this tile port should be connected. */
- def where: TLBusWrapperLocation
- /** Allows port-specific adapters to be injected into the interconnect side of the attachment point. */
- def injectNode(context: Attachable)(implicit p: Parameters): TLNode
-}
-
-/** A default implementation of parameterizing the connectivity of the port where the tile is the master.
- * Optional timing buffers and/or an optional CacheCork can be inserted in the interconnect's clock domain.
- */
-case class TileMasterPortParams(
- buffers: Int = 0,
- cork: Option[Boolean] = None,
- where: TLBusWrapperLocation = SBUS
-) extends TilePortParamsLike {
- def injectNode(context: Attachable)(implicit p: Parameters): TLNode = {
- (TLBuffer.chainNode(buffers) :=* cork.map { u => TLCacheCork(unsafe = u) } .getOrElse { TLTempNode() })
- }
-}
-
-/** A default implementation of parameterizing the connectivity of the port giving access to slaves inside the tile.
- * Optional timing buffers and/or an optional BusBlocker adapter can be inserted in the interconnect's clock domain.
- */
-case class TileSlavePortParams(
- buffers: Int = 0,
- blockerCtrlAddr: Option[BigInt] = None,
- blockerCtrlWhere: TLBusWrapperLocation = CBUS,
- where: TLBusWrapperLocation = CBUS
-) extends TilePortParamsLike {
- def injectNode(context: Attachable)(implicit p: Parameters): TLNode = {
- val controlBus = context.locateTLBusWrapper(where)
- val blockerBus = context.locateTLBusWrapper(blockerCtrlWhere)
- blockerCtrlAddr
- .map { BasicBusBlockerParams(_, blockerBus.beatBytes, controlBus.beatBytes) }
- .map { bbbp =>
- val blocker = LazyModule(new BasicBusBlocker(bbbp))
- blockerBus.coupleTo("tile_slave_port_bus_blocker") { blocker.controlNode := TLFragmenter(blockerBus) := _ }
- blocker.node :*= TLBuffer.chainNode(buffers)
- } .getOrElse { TLBuffer.chainNode(buffers) }
- }
-}
-
-/** These are sources of interrupts that are driven into the tile.
- * They need to be instantiated before tiles are attached to the subsystem containing them.
- */
-trait HasTileInterruptSources
- extends CanHavePeripheryPLIC
- with CanHavePeripheryCLINT
- with InstantiatesTiles
-{ this: BaseSubsystem => // TODO ideally this bound would be softened to LazyModule
- /** meipNode is used to create a single bit subsystem input in Configs without a PLIC */
- val meipNode = p(PLICKey) match {
- case Some(_) => None
- case None => Some(IntNexusNode(
- sourceFn = { _ => IntSourcePortParameters(Seq(IntSourceParameters(1))) },
- sinkFn = { _ => IntSinkPortParameters(Seq(IntSinkParameters())) },
- outputRequiresInput = false,
- inputRequiresOutput = false))
- }
- val seipNode = p(PLICKey) match {
- case Some(_) => None
- case None => Some(IntNexusNode(
- sourceFn = { _ => IntSourcePortParameters(Seq(IntSourceParameters(1))) },
- sinkFn = { _ => IntSinkPortParameters(Seq(IntSinkParameters())) },
- outputRequiresInput = false,
- inputRequiresOutput = false))
- }
- /** Source of Non-maskable Interrupt (NMI) input bundle to each tile. */
- val tileNMINode = BundleBridgeEphemeralNode[NMI]()
- val tileNMIIONodes: Seq[BundleBridgeSource[NMI]] = {
- Seq.fill(tiles.size) {
- val nmiSource = BundleBridgeSource[NMI]()
- tileNMINode := nmiSource
- nmiSource
- }
- }
-}
+case object HasTilesExternalResetVectorKey extends Field[Boolean](true)
/** These are sources of "constants" that are driven into the tile.
*
@@ -137,9 +54,11 @@ trait HasTileInterruptSources
* they may be either tied to a contant value or programmed during boot or reset.
* They need to be instantiated before tiles are attached within the subsystem containing them.
*/
-trait HasTileInputConstants extends InstantiatesTiles { this: BaseSubsystem =>
+trait HasTileInputConstants { this: LazyModule with Attachable with InstantiatesHierarchicalElements =>
/** tileHartIdNode is used to collect publishers and subscribers of hartids. */
- val tileHartIdNode = BundleBridgeEphemeralNode[UInt]()
+ val tileHartIdNodes: SortedMap[Int, BundleBridgeEphemeralNode[UInt]] = (0 until nTotalTiles).map { i =>
+ (i, BundleBridgeEphemeralNode[UInt]())
+ }.to(SortedMap)
/** tileHartIdNexusNode is a BundleBridgeNexus that collects dynamic hart prefixes.
*
@@ -156,7 +75,7 @@ trait HasTileInputConstants extends InstantiatesTiles { this: BaseSubsystem =>
val tileHartIdNexusNode = LazyModule(new BundleBridgeNexus[UInt](
inputFn = BundleBridgeNexus.orReduction[UInt](registered = p(InsertTimingClosureRegistersOnHartIds)) _,
outputFn = (prefix: UInt, n: Int) => Seq.tabulate(n) { i =>
- val y = dontTouch(prefix | hartIdList(i).U(p(MaxHartIdBits).W)) // dontTouch to keep constant prop from breaking tile dedup
+ val y = dontTouch(prefix | totalTileIdList(i).U(p(MaxHartIdBits).W)) // dontTouch to keep constant prop from breaking tile dedup
if (p(InsertTimingClosureRegistersOnHartIds)) BundleBridgeNexus.safeRegNext(y) else y
},
default = Some(() => 0.U(p(MaxHartIdBits).W)),
@@ -166,7 +85,9 @@ trait HasTileInputConstants extends InstantiatesTiles { this: BaseSubsystem =>
// TODO: Replace the DebugModuleHartSelFuncs config key with logic to consume the dynamic hart IDs
/** tileResetVectorNode is used to collect publishers and subscribers of tile reset vector addresses. */
- val tileResetVectorNode = BundleBridgeEphemeralNode[UInt]()
+ val tileResetVectorNodes: SortedMap[Int, BundleBridgeEphemeralNode[UInt]] = (0 until nTotalTiles).map { i =>
+ (i, BundleBridgeEphemeralNode[UInt]())
+ }.to(SortedMap)
/** tileResetVectorNexusNode is a BundleBridgeNexus that accepts a single reset vector source, and broadcasts it to all tiles. */
val tileResetVectorNexusNode = BundleBroadcast[UInt](
@@ -177,26 +98,32 @@ trait HasTileInputConstants extends InstantiatesTiles { this: BaseSubsystem =>
*
* Or, if such IOs are not configured to exist, tileHartIdNexusNode is used to supply an id to each tile.
*/
- val tileHartIdIONodes: Seq[BundleBridgeSource[UInt]] = p(SubsystemExternalHartIdWidthKey) match {
- case Some(w) => Seq.fill(tiles.size) {
+ val tileHartIdIONodes: Seq[BundleBridgeSource[UInt]] = p(HasTilesExternalHartIdWidthKey) match {
+ case Some(w) => (0 until nTotalTiles).map { i =>
val hartIdSource = BundleBridgeSource(() => UInt(w.W))
- tileHartIdNode := hartIdSource
+ tileHartIdNodes(i) := hartIdSource
hartIdSource
}
- case None => { tileHartIdNode :*= tileHartIdNexusNode; Nil }
+ case None => {
+ (0 until nTotalTiles).map { i => tileHartIdNodes(i) :*= tileHartIdNexusNode }
+ Nil
+ }
}
/** tileResetVectorIONodes may generate subsystem IOs, one per tile, allowing the parent to assign unique reset vectors.
*
* Or, if such IOs are not configured to exist, tileResetVectorNexusNode is used to supply a single reset vector to every tile.
*/
- val tileResetVectorIONodes: Seq[BundleBridgeSource[UInt]] = p(SubsystemExternalResetVectorKey) match {
- case true => Seq.fill(tiles.size) {
+ val tileResetVectorIONodes: Seq[BundleBridgeSource[UInt]] = p(HasTilesExternalResetVectorKey) match {
+ case true => (0 until nTotalTiles).map { i =>
val resetVectorSource = BundleBridgeSource[UInt]()
- tileResetVectorNode := resetVectorSource
+ tileResetVectorNodes(i) := resetVectorSource
resetVectorSource
}
- case false => { tileResetVectorNode :*= tileResetVectorNexusNode; Nil }
+ case false => {
+ (0 until nTotalTiles).map { i => tileResetVectorNodes(i) :*= tileResetVectorNexusNode }
+ Nil
+ }
}
}
@@ -218,20 +145,6 @@ trait HasTileNotificationSinks { this: LazyModule =>
tileCeaseSinkNode := tileCeaseXbarNode
}
-/** Most tile types require only these traits in order for their standardized connect functions to apply.
- *
- * BaseTiles subtypes with different needs can extend this trait to provide themselves with
- * additional external connection points.
- */
-trait DefaultTileContextType
- extends Attachable
- with HasTileInterruptSources
- with HasTileNotificationSinks
- with HasTileInputConstants
-{ this: BaseSubsystem =>
- val debugNode: IntSyncOutwardNode
-} // TODO: ideally this bound would be softened to LazyModule
-
/** Standardized interface by which parameterized tiles can be attached to contexts containing interconnect resources.
*
* Sub-classes of this trait can optionally override the individual connect functions in order to specialize
@@ -240,15 +153,15 @@ trait DefaultTileContextType
*/
trait CanAttachTile {
type TileType <: BaseTile
- type TileContextType <: DefaultTileContextType
+ type TileContextType <: DefaultHierarchicalElementContextType
def tileParams: InstantiableTileParams[TileType]
- def crossingParams: TileCrossingParamsLike
+ def crossingParams: HierarchicalElementCrossingParamsLike
/** Narrow waist through which all tiles are intended to pass while being instantiated. */
- def instantiate(allTileParams: Seq[TileParams], instantiatedTiles: Seq[TilePRCIDomain[_]])(implicit p: Parameters): TilePRCIDomain[TileType] = {
- val clockSinkParams = tileParams.clockSinkParams.copy(name = Some(s"${tileParams.name.getOrElse("core")}_${tileParams.hartId}"))
+ def instantiate(allTileParams: Seq[TileParams], instantiatedTiles: SortedMap[Int, TilePRCIDomain[_]])(implicit p: Parameters): TilePRCIDomain[TileType] = {
+ val clockSinkParams = tileParams.clockSinkParams.copy(name = Some(tileParams.uniqueName))
val tile_prci_domain = LazyModule(new TilePRCIDomain[TileType](clockSinkParams, crossingParams) { self =>
- val tile = self.tile_reset_domain { LazyModule(tileParams.instantiate(crossingParams, PriorityMuxHartIdFromSeq(allTileParams))) }
+ val element = self.element_reset_domain { LazyModule(tileParams.instantiate(crossingParams, PriorityMuxHartIdFromSeq(allTileParams))) }
})
tile_prci_domain
}
@@ -261,13 +174,14 @@ trait CanAttachTile {
connectPRC(domain, context)
connectOutputNotifications(domain, context)
connectInputConstants(domain, context)
+ connectTrace(domain, context)
}
/** Connect the port where the tile is the master to a TileLink interconnect. */
def connectMasterPorts(domain: TilePRCIDomain[TileType], context: Attachable): Unit = {
implicit val p = context.p
val dataBus = context.locateTLBusWrapper(crossingParams.master.where)
- dataBus.coupleFrom(tileParams.name.getOrElse("tile")) { bus =>
+ dataBus.coupleFrom(tileParams.baseName) { bus =>
bus :=* crossingParams.master.injectNode(context) :=* domain.crossMasterPort(crossingParams.crossingType)
}
}
@@ -277,7 +191,7 @@ trait CanAttachTile {
implicit val p = context.p
DisableMonitors { implicit p =>
val controlBus = context.locateTLBusWrapper(crossingParams.slave.where)
- controlBus.coupleTo(tileParams.name.getOrElse("tile")) { bus =>
+ controlBus.coupleTo(tileParams.baseName) { bus =>
domain.crossSlavePort(crossingParams.crossingType) :*= crossingParams.slave.injectNode(context) :*= TLWidthWidget(controlBus.beatBytes) :*= bus
}
}
@@ -291,61 +205,66 @@ trait CanAttachTile {
// we stub out missing interrupts with constant sources here.
// 1. Debug interrupt is definitely asynchronous in all cases.
- domain.tile.intInwardNode := domain { IntSyncAsyncCrossingSink(3) } := context.debugNode
+ domain.element.intInwardNode := domain { IntSyncAsyncCrossingSink(3) } :=
+ context.debugNodes(domain.element.tileId)
- // 2. The CLINT and PLIC output interrupts are synchronous to the TileLink bus clock,
+ // 2. The CLINT and PLIC output interrupts are synchronous to the CLINT/PLIC respectively,
// so might need to be synchronized depending on the Tile's crossing type.
// From CLINT: "msip" and "mtip"
- domain.crossIntIn(crossingParams.crossingType) :=
- context.clintOpt.map { _.intnode }
- .getOrElse { NullIntSource(sources = CLINTConsts.ints) }
+ context.msipDomain {
+ domain.crossIntIn(crossingParams.crossingType, domain.element.intInwardNode) :=
+ context.msipNodes(domain.element.tileId)
+ }
// From PLIC: "meip"
- domain.crossIntIn(crossingParams.crossingType) :=
- context.plicOpt .map { _.intnode }
- .getOrElse { context.meipNode.get }
+ context.meipDomain {
+ domain.crossIntIn(crossingParams.crossingType, domain.element.intInwardNode) :=
+ context.meipNodes(domain.element.tileId)
+ }
// From PLIC: "seip" (only if supervisor mode is enabled)
- if (domain.tile.tileParams.core.hasSupervisorMode) {
- domain.crossIntIn(crossingParams.crossingType) :=
- context.plicOpt .map { _.intnode }
- .getOrElse { context.seipNode.get }
+ if (domain.element.tileParams.core.hasSupervisorMode) {
+ context.seipDomain {
+ domain.crossIntIn(crossingParams.crossingType, domain.element.intInwardNode) :=
+ context.seipNodes(domain.element.tileId)
+ }
}
// 3. Local Interrupts ("lip") are required to already be synchronous to the Tile's clock.
- // (they are connected to domain.tile.intInwardNode in a seperate trait)
+ // (they are connected to domain.element.intInwardNode in a seperate trait)
// 4. Interrupts coming out of the tile are sent to the PLIC,
// so might need to be synchronized depending on the Tile's crossing type.
- context.plicOpt.foreach { plic =>
- FlipRendering { implicit p =>
- plic.intnode :=* domain.crossIntOut(crossingParams.crossingType, domain.tile.intOutwardNode)
- }
+ context.tileToPlicNodes.get(domain.element.tileId).foreach { node =>
+ FlipRendering { implicit p => domain.element.intOutwardNode.foreach { out =>
+ context.toPlicDomain { node := domain.crossIntOut(crossingParams.crossingType, out) }
+ }}
}
// 5. Connect NMI inputs to the tile. These inputs are synchronous to the respective core_clock.
- domain.tile.nmiNode := context.tileNMINode
+ domain.element.nmiNode.foreach(_ := context.nmiNodes(domain.element.tileId))
}
/** Notifications of tile status are connected to be broadcast without needing to be clock-crossed. */
def connectOutputNotifications(domain: TilePRCIDomain[TileType], context: TileContextType): Unit = {
implicit val p = context.p
- context.tileHaltXbarNode :=* domain.crossIntOut(NoCrossing, domain.tile.haltNode)
- context.tileWFIXbarNode :=* domain.crossIntOut(NoCrossing, domain.tile.wfiNode)
- context.tileCeaseXbarNode :=* domain.crossIntOut(NoCrossing, domain.tile.ceaseNode)
+ domain {
+ context.tileHaltXbarNode :=* domain.crossIntOut(NoCrossing, domain.element.haltNode)
+ context.tileWFIXbarNode :=* domain.crossIntOut(NoCrossing, domain.element.wfiNode)
+ context.tileCeaseXbarNode :=* domain.crossIntOut(NoCrossing, domain.element.ceaseNode)
+ }
// TODO should context be forced to have a trace sink connected here?
// for now this just ensures domain.trace[Core]Node has been crossed without connecting it externally
- domain.crossTracesOut()
}
/** Connect inputs to the tile that are assumed to be constant during normal operation, and so are not clock-crossed. */
def connectInputConstants(domain: TilePRCIDomain[TileType], context: TileContextType): Unit = {
implicit val p = context.p
val tlBusToGetPrefixFrom = context.locateTLBusWrapper(crossingParams.mmioBaseAddressPrefixWhere)
- domain.tile.hartIdNode := context.tileHartIdNode
- domain.tile.resetVectorNode := context.tileResetVectorNode
- tlBusToGetPrefixFrom.prefixNode.foreach { domain.tile.mmioAddressPrefixNode := _ }
+ domain.element.hartIdNode := context.tileHartIdNodes(domain.element.tileId)
+ domain.element.resetVectorNode := context.tileResetVectorNodes(domain.element.tileId)
+ tlBusToGetPrefixFrom.prefixNode.foreach { domain.element.mmioAddressPrefixNode := _ }
}
/** Connect power/reset/clock resources. */
@@ -362,19 +281,30 @@ trait CanAttachTile {
case _: RationalCrossing => domain.clockNode := tlBusToGetClockDriverFrom.clockNode
case _: AsynchronousCrossing => {
val tileClockGroup = ClockGroup()
- tileClockGroup := context.asyncClockGroupsNode
+ tileClockGroup := context.allClockGroupsNode
domain.clockNode := tileClockGroup
}
})
domain {
- domain.tile_reset_domain.clockNode := crossingParams.resetCrossingType.injectClockNode := domain.clockNode
+ domain.element_reset_domain.clockNode := crossingParams.resetCrossingType.injectClockNode := domain.clockNode
}
}
+
+ /** Function to handle all trace crossings when tile is instantiated inside domains */
+ def connectTrace(domain: TilePRCIDomain[TileType], context: TileContextType): Unit = {
+ implicit val p = context.p
+ val traceCrossingNode = BundleBridgeBlockDuringReset[TraceBundle](
+ resetCrossingType = crossingParams.resetCrossingType)
+ context.traceNodes(domain.element.tileId) := traceCrossingNode := domain.element.traceNode
+ val traceCoreCrossingNode = BundleBridgeBlockDuringReset[TraceCoreInterface](
+ resetCrossingType = crossingParams.resetCrossingType)
+ context.traceCoreNodes(domain.element.tileId) :*= traceCoreCrossingNode := domain.element.traceCoreNode
+ }
}
case class CloneTileAttachParams(
- sourceHart: Int,
+ sourceTileId: Int,
cloneParams: CanAttachTile
) extends CanAttachTile {
type TileType = cloneParams.TileType
@@ -382,78 +312,18 @@ case class CloneTileAttachParams(
def tileParams = cloneParams.tileParams
def crossingParams = cloneParams.crossingParams
- require(sourceHart < tileParams.hartId)
- override def instantiate(allTileParams: Seq[TileParams], instantiatedTiles: Seq[TilePRCIDomain[_]])(implicit p: Parameters): TilePRCIDomain[TileType] = {
- val clockSinkParams = tileParams.clockSinkParams.copy(name = Some(s"${tileParams.name.getOrElse("core")}_${tileParams.hartId}"))
+ override def instantiate(allTileParams: Seq[TileParams], instantiatedTiles: SortedMap[Int, TilePRCIDomain[_]])(implicit p: Parameters): TilePRCIDomain[TileType] = {
+ require(instantiatedTiles.contains(sourceTileId))
+ val clockSinkParams = tileParams.clockSinkParams.copy(name = Some(tileParams.uniqueName))
val tile_prci_domain = CloneLazyModule(
new TilePRCIDomain[TileType](clockSinkParams, crossingParams) { self =>
- val tile = self.tile_reset_domain { LazyModule(tileParams.instantiate(crossingParams, PriorityMuxHartIdFromSeq(allTileParams))) }
+ val element = self.element_reset_domain { LazyModule(tileParams.instantiate(crossingParams, PriorityMuxHartIdFromSeq(allTileParams))) }
},
- instantiatedTiles(sourceHart).asInstanceOf[TilePRCIDomain[TileType]]
+ instantiatedTiles(sourceTileId).asInstanceOf[TilePRCIDomain[TileType]]
)
- tile_prci_domain
- }
-}
-
-
-/** InstantiatesTiles adds a Config-urable sequence of tiles of any type
- * to the subsystem class into which it is mixed.
- */
-trait InstantiatesTiles { this: BaseSubsystem =>
- /** Record the order in which to instantiate all tiles, based on statically-assigned ids.
- *
- * Note that these ids, which are often used as the tiles' default hartid input,
- * may or may not be those actually reflected at runtime in e.g. the $mhartid CSR
- */
- val tileAttachParams: Seq[CanAttachTile] = p(TilesLocated(location)).sortBy(_.tileParams.hartId)
- val tileParams: Seq[TileParams] = tileAttachParams.map(_.tileParams)
- val tileCrossingTypes: Seq[ClockCrossingType] = tileAttachParams.map(_.crossingParams.crossingType)
-
- /** The actual list of instantiated tiles in this subsystem. */
- val tile_prci_domains: Seq[TilePRCIDomain[_]] = tileAttachParams.foldLeft(Seq[TilePRCIDomain[_]]()) {
- case (instantiated, params) => instantiated :+ params.instantiate(tileParams, instantiated)(p)
- }
-
- val tiles: Seq[BaseTile] = tile_prci_domains.map(_.tile.asInstanceOf[BaseTile])
-
- // Helper functions for accessing certain parameters that are popular to refer to in subsystem code
- def nTiles: Int = tileAttachParams.size
- def hartIdList: Seq[Int] = tileParams.map(_.hartId)
- def localIntCounts: Seq[Int] = tileParams.map(_.core.nLocalInterrupts)
-
- require(hartIdList.distinct.size == tiles.size, s"Every tile must be statically assigned a unique id, but got:\n${hartIdList}")
-}
-
-/** HasTiles instantiates and also connects a Config-urable sequence of tiles of any type to subsystem interconnect resources. */
-trait HasTiles extends InstantiatesTiles with HasCoreMonitorBundles with DefaultTileContextType
-{ this: BaseSubsystem => // TODO: ideally this bound would be softened to Attachable
- implicit val p: Parameters
-
- // connect all the tiles to interconnect attachment points made available in this subsystem context
- tileAttachParams.zip(tile_prci_domains).foreach { case (params, td) =>
- params.connect(td.asInstanceOf[TilePRCIDomain[params.TileType]], this.asInstanceOf[params.TileContextType])
+ tile_prci_domain
}
}
-/** Provides some Chisel connectivity to certain tile IOs */
-trait HasTilesModuleImp extends LazyModuleImp {
- val outer: HasTiles with HasTileInterruptSources with HasTileInputConstants
-
- val reset_vector = outer.tileResetVectorIONodes.zipWithIndex.map { case (n, i) => n.makeIO(s"reset_vector_$i") }
- val tile_hartids = outer.tileHartIdIONodes.zipWithIndex.map { case (n, i) => n.makeIO(s"tile_hartids_$i") }
- val meip = if(outer.meipNode.isDefined) Some(IO(Input(Vec(outer.meipNode.get.out.size, Bool())))) else None
- meip.foreach { m =>
- m.zipWithIndex.foreach{ case (pin, i) =>
- (outer.meipNode.get.out(i)._1)(0) := pin
- }
- }
- val seip = if(outer.seipNode.isDefined) Some(IO(Input(Vec(outer.seipNode.get.out.size, Bool())))) else None
- seip.foreach { s =>
- s.zipWithIndex.foreach{ case (pin, i) =>
- (outer.seipNode.get.out(i)._1)(0) := pin
- }
- }
- val nmi = outer.tiles.zip(outer.tileNMIIONodes).zipWithIndex.map { case ((tile, n), i) => tile.tileParams.core.useNMI.option(n.makeIO(s"nmi_$i")) }
-}
diff --git a/src/main/scala/subsystem/HierarchicalElement.scala b/src/main/scala/subsystem/HierarchicalElement.scala
new file mode 100644
index 00000000000..861a77970e1
--- /dev/null
+++ b/src/main/scala/subsystem/HierarchicalElement.scala
@@ -0,0 +1,82 @@
+package freechips.rocketchip.subsystem
+
+import chisel3._
+import chisel3.util._
+
+import org.chipsalliance.cde.config._
+import org.chipsalliance.diplomacy.lazymodule._
+
+import freechips.rocketchip.devices.debug.TLDebugModule
+import freechips.rocketchip.diplomacy.{BufferParams}
+import freechips.rocketchip.interrupts.IntXbar
+import freechips.rocketchip.prci.{ClockSinkParameters, ResetCrossingType, ClockCrossingType}
+import freechips.rocketchip.tile.{LookupByHartIdImpl, TraceBundle}
+import freechips.rocketchip.tilelink.{TLNode, TLIdentityNode, TLXbar, TLBuffer, TLInwardNode, TLOutwardNode}
+
+trait HierarchicalElementParams {
+ val baseName: String // duplicated instances shouuld share a base name
+ val uniqueName: String
+ val clockSinkParams: ClockSinkParameters
+}
+
+abstract class InstantiableHierarchicalElementParams[ElementType <: BaseHierarchicalElement] extends HierarchicalElementParams
+
+/** An interface for describing the parameteization of how HierarchicalElements are connected to interconnects */
+trait HierarchicalElementCrossingParamsLike {
+ /** The type of clock crossing that should be inserted at the element boundary. */
+ def crossingType: ClockCrossingType
+ /** Parameters describing the contents and behavior of the point where the element is attached as an interconnect master. */
+ def master: HierarchicalElementPortParamsLike
+ /** Parameters describing the contents and behavior of the point where the element is attached as an interconnect slave. */
+ def slave: HierarchicalElementPortParamsLike
+ /** The subnetwork location of the device selecting the apparent base address of MMIO devices inside the element */
+ def mmioBaseAddressPrefixWhere: TLBusWrapperLocation
+ /** Inject a reset management subgraph that effects the element child reset only */
+ def resetCrossingType: ResetCrossingType
+ /** Keep the element clock separate from the interconnect clock (e.g. even if they are synchronous to one another) */
+ def forceSeparateClockReset: Boolean
+}
+
+/** An interface for describing the parameterization of how a particular element port is connected to an interconnect */
+trait HierarchicalElementPortParamsLike {
+ /** The subnetwork location of the interconnect to which this element port should be connected. */
+ def where: TLBusWrapperLocation
+ /** Allows port-specific adapters to be injected into the interconnect side of the attachment point. */
+ def injectNode(context: Attachable)(implicit p: Parameters): TLNode
+}
+
+abstract class BaseHierarchicalElement (val crossing: ClockCrossingType)(implicit p: Parameters)
+ extends LazyModule()(p)
+ with CrossesToOnlyOneClockDomain
+{
+ def module: BaseHierarchicalElementModuleImp[BaseHierarchicalElement]
+
+ protected val tlOtherMastersNode = TLIdentityNode()
+ protected val tlMasterXbar = LazyModule(new TLXbar(nameSuffix = Some(s"MasterXbar_$desiredName")))
+ protected val tlSlaveXbar = LazyModule(new TLXbar(nameSuffix = Some(s"SlaveXbar_$desiredName")))
+ protected val intXbar = LazyModule(new IntXbar)
+
+ def masterNode: TLOutwardNode
+ def slaveNode: TLInwardNode
+
+ /** Helper function to insert additional buffers on master ports at the boundary of the tile.
+ *
+ * The boundary buffering needed to cut feed-through paths is
+ * microarchitecture specific, so this may need to be overridden
+ * in subclasses of this class.
+ */
+ def makeMasterBoundaryBuffers(crossing: ClockCrossingType)(implicit p: Parameters) = TLBuffer(BufferParams.none)
+
+ /** Helper function to insert additional buffers on slave ports at the boundary of the tile.
+ *
+ * The boundary buffering needed to cut feed-through paths is
+ * microarchitecture specific, so this may need to be overridden
+ * in subclasses of this class.
+ */
+ def makeSlaveBoundaryBuffers(crossing: ClockCrossingType)(implicit p: Parameters) = TLBuffer(BufferParams.none)
+
+
+}
+
+abstract class BaseHierarchicalElementModuleImp[+L <: BaseHierarchicalElement](val outer: L) extends LazyModuleImp(outer)
+
diff --git a/src/main/scala/subsystem/HierarchicalElementPRCIDomain.scala b/src/main/scala/subsystem/HierarchicalElementPRCIDomain.scala
new file mode 100644
index 00000000000..b38f208701e
--- /dev/null
+++ b/src/main/scala/subsystem/HierarchicalElementPRCIDomain.scala
@@ -0,0 +1,100 @@
+package freechips.rocketchip.subsystem
+
+import chisel3._
+import chisel3.util._
+
+import org.chipsalliance.cde.config._
+import org.chipsalliance.diplomacy.lazymodule._
+
+import freechips.rocketchip.devices.debug.TLDebugModule
+import freechips.rocketchip.diplomacy.{DisableMonitors, FlipRendering}
+import freechips.rocketchip.interrupts.{IntInwardNode, IntOutwardNode}
+import freechips.rocketchip.prci.{ClockCrossingType, ResetCrossingType, ResetDomain, ClockSinkNode, ClockSinkParameters, ClockIdentityNode, FixedClockBroadcast, ClockDomain}
+import freechips.rocketchip.tile.{RocketTile, TraceBundle}
+import freechips.rocketchip.tilelink.{TLInwardNode, TLOutwardNode}
+import freechips.rocketchip.util.TraceCoreInterface
+
+import freechips.rocketchip.tilelink.TLClockDomainCrossing
+import freechips.rocketchip.tilelink.TLResetDomainCrossing
+import freechips.rocketchip.interrupts.IntClockDomainCrossing
+import freechips.rocketchip.interrupts.IntResetDomainCrossing
+
+/** A wrapper containing all logic within a managed reset domain for a element.
+ *
+ * This does not add a layer of the module hierarchy.
+ */
+class HierarchicalElementResetDomain(clockSinkParams: ClockSinkParameters, resetCrossingType: ResetCrossingType)
+ (implicit p: Parameters)
+ extends ResetDomain
+ with CrossesToOnlyOneResetDomain
+{
+ def crossing = resetCrossingType
+ val clockNode = ClockSinkNode(Seq(clockSinkParams))
+ def clockBundle = clockNode.in.head._1
+ override def shouldBeInlined = true
+}
+
+/** A wrapper containing all logic necessary to safely place a tile
+ * inside of a particular Power/Reset/Clock/Interrupt domain.
+ *
+ * This adds a layer to the module hierarchy which is a parent of the tile
+ * and should contain all logic related to clock crossings, isolation cells,
+ * hierarchical P&R boundary buffers, core-local interrupt handling,
+ * and any other IOs related to PRCI control.
+ */
+abstract class HierarchicalElementPRCIDomain[T <: BaseHierarchicalElement](
+ clockSinkParams: ClockSinkParameters,
+ crossingParams: HierarchicalElementCrossingParamsLike)
+ (implicit p: Parameters)
+ extends ClockDomain
+{
+ val element: T
+ val element_reset_domain = LazyModule(new HierarchicalElementResetDomain(clockSinkParams, crossingParams.resetCrossingType))
+ val tapClockNode = ClockIdentityNode()
+ val clockNode = FixedClockBroadcast() :=* tapClockNode
+ lazy val clockBundle = tapClockNode.in.head._1
+
+ /** External code looking to connect and clock-cross the interrupts driven into this tile can call this. */
+ def crossIntIn(crossingType: ClockCrossingType, tileNode: IntInwardNode): IntInwardNode = {
+ // Unlike the other crossing helpers, here nothing is is blocked during reset because we know these are inputs and assume that tile reset is longer than uncore reset
+ val intInClockXing = this.crossIn(tileNode)
+ intInClockXing(crossingType)
+ }
+
+ /** External code looking to connect and clock/reset-cross
+ * - interrupts raised by devices inside this tile
+ * - notifications raise by the cores and caches
+ * can call this function to instantiate the required crossing hardware.
+ * Takes crossingType as an argument because some interrupts are supposed to be synchronous
+ * Takes tileNode as an argument because tiles might have multiple outbound interrupt nodes
+ */
+ def crossIntOut(crossingType: ClockCrossingType, tileNode: IntOutwardNode): IntOutwardNode = {
+ val intOutResetXing = this { element_reset_domain.crossIntOut(tileNode) }
+ val intOutClockXing = this.crossOut(intOutResetXing)
+ intOutClockXing(crossingType)
+ }
+
+ /** External code looking to connect the ports where this tile is slaved to an interconnect
+ * (while also crossing clock domains) can call this.
+ */
+ def crossSlavePort(crossingType: ClockCrossingType): TLInwardNode = { DisableMonitors { implicit p => FlipRendering { implicit p =>
+ val tlSlaveResetXing = this {
+ element_reset_domain.crossTLIn(element.slaveNode) :*=
+ element { element.makeSlaveBoundaryBuffers(crossingType) }
+ }
+ val tlSlaveClockXing = this.crossIn(tlSlaveResetXing)
+ tlSlaveClockXing(crossingType)
+ } } }
+
+ /** External code looking to connect the ports where this tile masters an interconnect
+ * (while also crossing clock domains) can call this.
+ */
+ def crossMasterPort(crossingType: ClockCrossingType): TLOutwardNode = {
+ val tlMasterResetXing = this { DisableMonitors { implicit p =>
+ element { element.makeMasterBoundaryBuffers(crossingType) } :=*
+ element_reset_domain.crossTLOut(element.masterNode)
+ } }
+ val tlMasterClockXing = this.crossOut(tlMasterResetXing)
+ tlMasterClockXing(crossingType)
+ }
+}
diff --git a/src/main/scala/subsystem/InterruptBus.scala b/src/main/scala/subsystem/InterruptBus.scala
index e50f82a9ad5..24717df3e76 100644
--- a/src/main/scala/subsystem/InterruptBus.scala
+++ b/src/main/scala/subsystem/InterruptBus.scala
@@ -3,10 +3,15 @@
package freechips.rocketchip.subsystem
import chisel3._
-import org.chipsalliance.cde.config.{Field, Parameters}
-import freechips.rocketchip.diplomacy._
-import freechips.rocketchip.interrupts._
-import freechips.rocketchip.prci.{ClockSinkDomain}
+
+import org.chipsalliance.cde.config._
+import org.chipsalliance.diplomacy.lazymodule._
+
+import freechips.rocketchip.resources.{Device, DeviceInterrupts, Description, ResourceBindings}
+import freechips.rocketchip.interrupts.{IntInwardNode, IntOutwardNode, IntXbar, IntNameNode, IntSourceNode, IntSourcePortSimple}
+import freechips.rocketchip.prci.{ClockCrossingType, AsynchronousCrossing, RationalCrossing, ClockSinkDomain}
+
+import freechips.rocketchip.interrupts.IntClockDomainCrossing
/** Collects interrupts from internal and external devices and feeds them into the PLIC */
class InterruptBusWrapper(implicit p: Parameters) extends ClockSinkDomain {
@@ -45,7 +50,7 @@ abstract trait HasExtInterrupts { this: BaseSubsystem =>
*/
trait HasAsyncExtInterrupts extends HasExtInterrupts { this: BaseSubsystem =>
if (nExtInterrupts > 0) {
- ibus.fromAsync := extInterrupts
+ ibus { ibus.fromAsync := extInterrupts }
}
}
@@ -54,7 +59,7 @@ trait HasAsyncExtInterrupts extends HasExtInterrupts { this: BaseSubsystem =>
*/
trait HasSyncExtInterrupts extends HasExtInterrupts { this: BaseSubsystem =>
if (nExtInterrupts > 0) {
- ibus.fromSync := extInterrupts
+ ibus { ibus.fromSync := extInterrupts }
}
}
@@ -70,7 +75,7 @@ trait HasExtInterruptsBundle {
/** This trait performs the translation from a UInt IO into Diplomatic Interrupts.
* The wiring must be done in the concrete LazyModuleImp.
*/
-trait HasExtInterruptsModuleImp extends LazyModuleImp with HasExtInterruptsBundle {
+trait HasExtInterruptsModuleImp extends LazyRawModuleImp with HasExtInterruptsBundle {
val outer: HasExtInterrupts
val interrupts = IO(Input(UInt(outer.nExtInterrupts.W)))
diff --git a/src/main/scala/subsystem/LookupByClusterId.scala b/src/main/scala/subsystem/LookupByClusterId.scala
new file mode 100644
index 00000000000..d0c5c21a5ab
--- /dev/null
+++ b/src/main/scala/subsystem/LookupByClusterId.scala
@@ -0,0 +1,19 @@
+// See LICENSE.SiFive for license details.
+
+package freechips.rocketchip.subsystem
+
+import chisel3._
+import chisel3.util._
+
+abstract class LookupByClusterIdImpl {
+ def apply[T <: Data](f: ClusterParams => Option[T], clusterId: UInt): T
+}
+
+case class ClustersWontDeduplicate(t: ClusterParams) extends LookupByClusterIdImpl {
+ def apply[T <: Data](f: ClusterParams => Option[T], clusterId: UInt): T = f(t).get
+}
+
+case class PriorityMuxClusterIdFromSeq(seq: Seq[ClusterParams]) extends LookupByClusterIdImpl {
+ def apply[T <: Data](f: ClusterParams => Option[T], clusterId: UInt): T =
+ PriorityMux(seq.collect { case t if f(t).isDefined => (t.clusterId.U === clusterId) -> f(t).get })
+}
diff --git a/src/main/scala/subsystem/MemoryBus.scala b/src/main/scala/subsystem/MemoryBus.scala
index 03b8bb22d4b..a58d6b28215 100644
--- a/src/main/scala/subsystem/MemoryBus.scala
+++ b/src/main/scala/subsystem/MemoryBus.scala
@@ -3,10 +3,15 @@
package freechips.rocketchip.subsystem
import org.chipsalliance.cde.config._
-import freechips.rocketchip.devices.tilelink._
-import freechips.rocketchip.diplomacy._
-import freechips.rocketchip.tilelink._
-import freechips.rocketchip.util._
+import org.chipsalliance.diplomacy.lazymodule._
+
+import freechips.rocketchip.devices.tilelink.{BuiltInDevices, HasBuiltInDeviceParams, BuiltInErrorDeviceParams, BuiltInZeroDeviceParams}
+import freechips.rocketchip.tilelink.{
+ ReplicatedRegion, HasTLBusParams, HasRegionReplicatorParams, TLBusWrapper,
+ TLBusWrapperInstantiationLike, RegionReplicator, TLXbar, TLInwardNode,
+ TLOutwardNode, ProbePicker, TLEdge, TLFIFOFixer
+}
+import freechips.rocketchip.util.Location
/** Parameterization of the memory-side bus created for each memory channel */
case class MemoryBusParams(
@@ -39,7 +44,7 @@ class MemoryBus(params: MemoryBusParams, name: String = "memory_bus")(implicit p
addressPrefixNexusNode
}
- private val xbar = LazyModule(new TLXbar).suggestName(busName + "_xbar")
+ private val xbar = LazyModule(new TLXbar(nameSuffix = Some(name))).suggestName(busName + "_xbar")
val inwardNode: TLInwardNode =
replicator.map(xbar.node :*=* TLFIFOFixer(TLFIFOFixer.all) :*=* _.node)
.getOrElse(xbar.node :*=* TLFIFOFixer(TLFIFOFixer.all))
diff --git a/src/main/scala/subsystem/PeripheryBus.scala b/src/main/scala/subsystem/PeripheryBus.scala
index 830e4480925..ee8ccec015e 100644
--- a/src/main/scala/subsystem/PeripheryBus.scala
+++ b/src/main/scala/subsystem/PeripheryBus.scala
@@ -2,11 +2,17 @@
package freechips.rocketchip.subsystem
-import org.chipsalliance.cde.config.{Parameters}
-import freechips.rocketchip.devices.tilelink._
-import freechips.rocketchip.diplomacy._
-import freechips.rocketchip.tilelink._
-import freechips.rocketchip.util._
+import org.chipsalliance.cde.config._
+import org.chipsalliance.diplomacy.lazymodule._
+
+import freechips.rocketchip.devices.tilelink.{BuiltInZeroDeviceParams, BuiltInErrorDeviceParams, HasBuiltInDeviceParams, BuiltInDevices}
+import freechips.rocketchip.diplomacy.BufferParams
+import freechips.rocketchip.tilelink.{
+ RegionReplicator, ReplicatedRegion, HasTLBusParams, HasRegionReplicatorParams, TLBusWrapper,
+ TLBusWrapperInstantiationLike, TLFIFOFixer, TLNode, TLXbar, TLInwardNode, TLOutwardNode,
+ TLBuffer, TLWidthWidget, TLAtomicAutomata, TLEdge
+}
+import freechips.rocketchip.util.Location
case class BusAtomics(
arithmetic: Boolean = true,
@@ -38,6 +44,7 @@ case class PeripheryBusParams(
class PeripheryBus(params: PeripheryBusParams, name: String)(implicit p: Parameters)
extends TLBusWrapper(params, name)
{
+ override lazy val desiredName = s"PeripheryBus_$name"
private val replicator = params.replication.map(r => LazyModule(new RegionReplicator(r)))
val prefixNode = replicator.map { r =>
r.prefix := addressPrefixNexusNode
@@ -46,15 +53,15 @@ class PeripheryBus(params: PeripheryBusParams, name: String)(implicit p: Paramet
private val fixer = LazyModule(new TLFIFOFixer(TLFIFOFixer.all))
private val node: TLNode = params.atomics.map { pa =>
- val in_xbar = LazyModule(new TLXbar)
- val out_xbar = LazyModule(new TLXbar)
+ val in_xbar = LazyModule(new TLXbar(nameSuffix = Some(s"${name}_in")))
+ val out_xbar = LazyModule(new TLXbar(nameSuffix = Some(s"${name}_out")))
val fixer_node = replicator.map(fixer.node :*= _.node).getOrElse(fixer.node)
(out_xbar.node
:*= fixer_node
:*= TLBuffer(pa.buffer)
:*= (pa.widenBytes.filter(_ > beatBytes).map { w =>
- TLWidthWidget(w) :*= TLAtomicAutomata(arithmetic = pa.arithmetic)
- } .getOrElse { TLAtomicAutomata(arithmetic = pa.arithmetic) })
+ TLWidthWidget(w) :*= TLAtomicAutomata(arithmetic = pa.arithmetic, nameSuffix = Some(name))
+ } .getOrElse { TLAtomicAutomata(arithmetic = pa.arithmetic, nameSuffix = Some(name)) })
:*= in_xbar.node)
} .getOrElse { TLXbar() :*= fixer.node }
diff --git a/src/main/scala/subsystem/Ports.scala b/src/main/scala/subsystem/Ports.scala
index 89fc25376fd..d3ed70c5e98 100644
--- a/src/main/scala/subsystem/Ports.scala
+++ b/src/main/scala/subsystem/Ports.scala
@@ -4,11 +4,31 @@ package freechips.rocketchip.subsystem
import chisel3._
-import org.chipsalliance.cde.config.Field
-import freechips.rocketchip.diplomacy._
-import freechips.rocketchip.tilelink._
-import freechips.rocketchip.amba.axi4._
-import freechips.rocketchip.util._
+import org.chipsalliance.cde.config._
+import org.chipsalliance.diplomacy._
+import org.chipsalliance.diplomacy.bundlebridge._
+import org.chipsalliance.diplomacy.lazymodule._
+
+import freechips.rocketchip.amba.axi4.{
+ AXI4SlaveNode, AXI4SlavePortParameters, AXI4SlaveParameters, AXI4UserYanker, AXI4Buffer,
+ AXI4Deinterleaver, AXI4IdIndexer, AXI4MasterNode, AXI4MasterPortParameters, AXI4ToTL,
+ AXI4Fragmenter, AXI4MasterParameters
+}
+import freechips.rocketchip.diplomacy.{
+ AddressSet, RegionType, TransferSizes, IdRange, BufferParams
+}
+import freechips.rocketchip.resources.{
+ MemoryDevice, SimpleBus
+}
+import freechips.rocketchip.tilelink.{
+ TLXbar, RegionReplicator, ReplicatedRegion, TLWidthWidget, TLFilter, TLToAXI4, TLBuffer,
+ TLFIFOFixer, TLSlavePortParameters, TLManagerNode, TLSlaveParameters, TLClientNode,
+ TLSourceShrinker, TLMasterParameters, TLMasterPortParameters
+}
+import freechips.rocketchip.util.StringToAugmentedString
+
+import freechips.rocketchip.tilelink.TLClockDomainCrossing
+import freechips.rocketchip.tilelink.TLResetDomainCrossing
/** Specifies the size and width of external memory ports */
case class MasterPortParams(
@@ -36,6 +56,7 @@ trait CanHaveMasterAXI4MemPort { this: BaseSubsystem =>
private val portName = "axi4"
private val device = new MemoryDevice
private val idBits = memPortParamsOpt.map(_.master.idBits).getOrElse(1)
+ private val mbus = tlBusWrapperLocationMap.get(MBUS).getOrElse(viewpointBus)
val memAXI4Node = AXI4SlaveNode(memPortParamsOpt.map({ case MemoryPortParams(memPortParams, nMemoryChannels, _) =>
Seq.tabulate(nMemoryChannels) { channel =>
@@ -63,7 +84,7 @@ trait CanHaveMasterAXI4MemPort { this: BaseSubsystem =>
memPortParams.incohBase.foreach(incohBase => {
val cohRegion = AddressSet(0, incohBase-1)
val incohRegion = AddressSet(incohBase, incohBase-1)
- val replicator = sbus {
+ val replicator = tlBusWrapperLocationMap(p(TLManagerViewpointLocated(location))) {
val replicator = LazyModule(new RegionReplicator(ReplicatedRegion(cohRegion, cohRegion.widen(incohBase))))
val prefixSource = BundleBridgeSource[UInt](() => UInt(1.W))
replicator.prefix := prefixSource
@@ -71,9 +92,9 @@ trait CanHaveMasterAXI4MemPort { this: BaseSubsystem =>
InModuleBody { prefixSource.bundle := 0.U(1.W) }
replicator
}
- sbus.coupleTo(s"memory_controller_bypass_port_named_$portName") {
+ viewpointBus.coupleTo(s"memory_controller_bypass_port_named_$portName") {
(mbus.crossIn(mem_bypass_xbar)(ValName("bus_xing"))(p(SbusToMbusXTypeKey))
- := TLWidthWidget(sbus.beatBytes)
+ := TLWidthWidget(viewpointBus.beatBytes)
:= replicator.node
:= TLFilter(TLFilter.mSubtract(cohRegion))
:= TLFilter(TLFilter.mResourceRemover)
@@ -116,14 +137,14 @@ trait CanHaveMasterAXI4MMIOPort { this: BaseSubsystem =>
beatBytes = params.beatBytes)).toSeq)
mmioPortParamsOpt.map { params =>
- sbus.coupleTo(s"port_named_$portName") {
+ viewpointBus.coupleTo(s"port_named_$portName") {
(mmioAXI4Node
:= AXI4Buffer()
:= AXI4UserYanker()
- := AXI4Deinterleaver(sbus.blockBytes)
+ := AXI4Deinterleaver(viewpointBus.blockBytes)
:= AXI4IdIndexer(params.idBits)
:= TLToAXI4()
- := TLWidthWidget(sbus.beatBytes)
+ := TLWidthWidget(viewpointBus.beatBytes)
:= _)
}
}
@@ -136,6 +157,7 @@ trait CanHaveSlaveAXI4Port { this: BaseSubsystem =>
private val slavePortParamsOpt = p(ExtIn)
private val portName = "slave_port_axi4"
private val fifoBits = 1
+ private val fbus = tlBusWrapperLocationMap.get(FBUS).getOrElse(viewpointBus)
val l2FrontendAXI4Node = AXI4MasterNode(
slavePortParamsOpt.map(params =>
@@ -174,17 +196,17 @@ trait CanHaveMasterTLMMIOPort { this: BaseSubsystem =>
address = AddressSet.misaligned(params.base, params.size),
resources = device.ranges,
executable = params.executable,
- supportsGet = TransferSizes(1, sbus.blockBytes),
- supportsPutFull = TransferSizes(1, sbus.blockBytes),
- supportsPutPartial = TransferSizes(1, sbus.blockBytes))),
+ supportsGet = TransferSizes(1, viewpointBus.blockBytes),
+ supportsPutFull = TransferSizes(1, viewpointBus.blockBytes),
+ supportsPutPartial = TransferSizes(1, viewpointBus.blockBytes))),
beatBytes = params.beatBytes)).toSeq)
mmioPortParamsOpt.map { params =>
- sbus.coupleTo(s"port_named_$portName") {
+ viewpointBus.coupleTo(s"port_named_$portName") {
(mmioTLNode
:= TLBuffer()
:= TLSourceShrinker(1 << params.idBits)
- := TLWidthWidget(sbus.beatBytes)
+ := TLWidthWidget(viewpointBus.beatBytes)
:= _ )
}
}
@@ -210,7 +232,7 @@ trait CanHaveSlaveTLPort { this: BaseSubsystem =>
sourceId = IdRange(0, 1 << params.idBits))))).toSeq)
slavePortParamsOpt.map { params =>
- sbus.coupleFrom(s"port_named_$portName") {
+ viewpointBus.coupleFrom(s"port_named_$portName") {
( _
:= TLSourceShrinker(1 << params.sourceBits)
:= TLWidthWidget(params.beatBytes)
diff --git a/src/main/scala/subsystem/RTC.scala b/src/main/scala/subsystem/RTC.scala
index 499633f679a..c2fd7a5a3f2 100644
--- a/src/main/scala/subsystem/RTC.scala
+++ b/src/main/scala/subsystem/RTC.scala
@@ -3,27 +3,32 @@
package freechips.rocketchip.subsystem
import chisel3._
-import chisel3.util.Counter
-import freechips.rocketchip.diplomacy.{LazyModuleImp, DTSTimebase}
-import freechips.rocketchip.devices.tilelink.CanHavePeripheryCLINT
+import chisel3.util._
-trait HasRTCModuleImp extends LazyModuleImp {
- val outer: BaseSubsystem with CanHavePeripheryCLINT
- private val pbusFreq = outer.p(PeripheryBusKey).dtsFrequency.get
- private val rtcFreq = outer.p(DTSTimebase)
- private val internalPeriod: BigInt = pbusFreq / rtcFreq
+import org.chipsalliance.diplomacy.lazymodule._
+
+import freechips.rocketchip.resources.DTSTimebase
+import freechips.rocketchip.devices.tilelink.{CLINTAttachKey, CanHavePeripheryCLINT}
- val pbus = outer.locateTLBusWrapper(PBUS)
- // check whether pbusFreq >= rtcFreq
- require(internalPeriod > 0)
- // check wehther the integer division is within 5% of the real division
- require((pbusFreq - rtcFreq * internalPeriod) * 100 / pbusFreq <= 5)
+trait HasRTCModuleImp extends LazyRawModuleImp {
+ val outer: BaseSubsystem with CanHavePeripheryCLINT
// Use the static period to toggle the RTC
- chisel3.withClockAndReset(pbus.module.clock, pbus.module.reset) {
- val (_, int_rtc_tick) = Counter(true.B, internalPeriod.toInt)
- outer.clintOpt.foreach { clint =>
- clint.module.io.rtcTick := int_rtc_tick
+ outer.clintDomainOpt.map { domain => {
+ val bus = outer.locateTLBusWrapper(p(CLINTAttachKey).slaveWhere)
+ val busFreq = bus.dtsFrequency.get
+ val rtcFreq = outer.p(DTSTimebase)
+ val internalPeriod: BigInt = busFreq / rtcFreq
+
+
+ // check whether pbusFreq >= rtcFreq
+ require(internalPeriod > 0)
+ // check wehther the integer division is within 5% of the real division
+ require((busFreq - rtcFreq * internalPeriod) * 100 / busFreq <= 5)
+
+ withClockAndReset (domain.module.clock, domain.module.reset) {
+ val (_, int_rtc_tick) = Counter(true.B, internalPeriod.toInt)
+ outer.clintTickOpt.foreach { _ := int_rtc_tick }
}
- }
+ }}
}
diff --git a/src/main/scala/subsystem/RocketSubsystem.scala b/src/main/scala/subsystem/RocketSubsystem.scala
index e9e1f555515..a10903d050f 100644
--- a/src/main/scala/subsystem/RocketSubsystem.scala
+++ b/src/main/scala/subsystem/RocketSubsystem.scala
@@ -2,37 +2,54 @@
package freechips.rocketchip.subsystem
-import org.chipsalliance.cde.config.Parameters
-import freechips.rocketchip.diplomacy._
-import freechips.rocketchip.prci.{ResetCrossingType, NoResetCrossing}
-import freechips.rocketchip.tile._
-import freechips.rocketchip.devices.debug.{HasPeripheryDebug}
+import org.chipsalliance.cde.config._
+
+import freechips.rocketchip.devices.debug.HasPeripheryDebug
+import freechips.rocketchip.devices.tilelink.{CanHavePeripheryCLINT, CanHavePeripheryPLIC}
+import freechips.rocketchip.prci.{ResetCrossingType, NoResetCrossing, SynchronousCrossing, ClockCrossingType}
+import freechips.rocketchip.tile.{RocketTile, RocketTileParams}
+import freechips.rocketchip.util.HasCoreMonitorBundles
case class RocketCrossingParams(
crossingType: ClockCrossingType = SynchronousCrossing(),
- master: TilePortParamsLike = TileMasterPortParams(),
- slave: TileSlavePortParams = TileSlavePortParams(),
+ master: HierarchicalElementPortParamsLike = HierarchicalElementMasterPortParams(),
+ slave: HierarchicalElementSlavePortParams = HierarchicalElementSlavePortParams(),
mmioBaseAddressPrefixWhere: TLBusWrapperLocation = CBUS,
resetCrossingType: ResetCrossingType = NoResetCrossing(),
forceSeparateClockReset: Boolean = false
-) extends TileCrossingParamsLike
+) extends HierarchicalElementCrossingParamsLike
case class RocketTileAttachParams(
tileParams: RocketTileParams,
crossingParams: RocketCrossingParams
) extends CanAttachTile { type TileType = RocketTile }
-trait HasRocketTiles extends HasTiles { this: BaseSubsystem =>
- val rocketTiles = tiles.collect { case r: RocketTile => r }
+trait HasRocketTiles {
+ this: BaseSubsystem with InstantiatesHierarchicalElements =>
+ val rocketTiles = totalTiles.values.collect { case r: RocketTile => r }
def coreMonitorBundles = (rocketTiles map { t =>
t.module.core.rocketImpl.coreMonitorBundle
}).toList
}
-class RocketSubsystem(implicit p: Parameters) extends BaseSubsystem with HasRocketTiles with HasPeripheryDebug {
+class RocketSubsystem(implicit p: Parameters) extends BaseSubsystem
+ with InstantiatesHierarchicalElements
+ with HasTileNotificationSinks
+ with HasTileInputConstants
+ with CanHavePeripheryCLINT
+ with CanHavePeripheryPLIC
+ with HasPeripheryDebug
+ with HasHierarchicalElementsRootContext
+ with HasHierarchicalElements
+ with HasCoreMonitorBundles
+ with HasRocketTiles
+{
override lazy val module = new RocketSubsystemModuleImp(this)
}
class RocketSubsystemModuleImp[+L <: RocketSubsystem](_outer: L) extends BaseSubsystemModuleImp(_outer)
- with HasTilesModuleImp
+ with HasHierarchicalElementsRootContextModuleImp {
+ override lazy val outer = _outer
+}
+
diff --git a/src/main/scala/subsystem/SystemBus.scala b/src/main/scala/subsystem/SystemBus.scala
index 3d8f98203fb..3596feb01e0 100644
--- a/src/main/scala/subsystem/SystemBus.scala
+++ b/src/main/scala/subsystem/SystemBus.scala
@@ -2,11 +2,18 @@
package freechips.rocketchip.subsystem
-import org.chipsalliance.cde.config.{Parameters}
-import freechips.rocketchip.devices.tilelink._
-import freechips.rocketchip.diplomacy._
-import freechips.rocketchip.tilelink._
-import freechips.rocketchip.util._
+import org.chipsalliance.cde.config._
+import org.chipsalliance.diplomacy.lazymodule._
+
+import freechips.rocketchip.devices.tilelink.{
+ BuiltInDevices, BuiltInZeroDeviceParams, BuiltInErrorDeviceParams, HasBuiltInDeviceParams
+}
+import freechips.rocketchip.tilelink.{
+ TLArbiter, RegionReplicator, ReplicatedRegion, HasTLBusParams, TLBusWrapper,
+ TLBusWrapperInstantiationLike, TLXbar, TLEdge, TLInwardNode, TLOutwardNode,
+ TLFIFOFixer, TLTempNode
+}
+import freechips.rocketchip.util.Location
case class SystemBusParams(
beatBytes: Int,
@@ -37,7 +44,7 @@ class SystemBus(params: SystemBusParams, name: String = "system_bus")(implicit p
addressPrefixNexusNode
}
- private val system_bus_xbar = LazyModule(new TLXbar(policy = params.policy))
+ private val system_bus_xbar = LazyModule(new TLXbar(policy = params.policy, nameSuffix = Some(name)))
val inwardNode: TLInwardNode = system_bus_xbar.node :=* TLFIFOFixer(TLFIFOFixer.allVolatile) :=* replicator.map(_.node).getOrElse(TLTempNode())
val outwardNode: TLOutwardNode = system_bus_xbar.node
def busView: TLEdge = system_bus_xbar.node.edges.in.head
diff --git a/src/main/scala/system/Configs.scala b/src/main/scala/system/Configs.scala
index 9fb7debde82..19e3c174b23 100644
--- a/src/main/scala/system/Configs.scala
+++ b/src/main/scala/system/Configs.scala
@@ -5,6 +5,7 @@ package freechips.rocketchip.system
import org.chipsalliance.cde.config.Config
import freechips.rocketchip.subsystem._
+import freechips.rocketchip.rocket.{WithNBigCores, WithNMedCores, WithNSmallCores, WithRV32, WithFP16, WithHypervisor, With1TinyCore, WithScratchpadsOnly, WithCloneRocketTiles, WithB}
class WithJtagDTMSystem extends freechips.rocketchip.subsystem.WithJtagDTM
class WithDebugSBASystem extends freechips.rocketchip.subsystem.WithDebugSBA
@@ -26,6 +27,8 @@ class DefaultBufferlessConfig extends Config(new WithBufferlessBroadcastHub ++ n
class DefaultSmallConfig extends Config(new WithNSmallCores(1) ++ new WithCoherentBusTopology ++ new BaseConfig)
class DefaultRV32Config extends Config(new WithRV32 ++ new DefaultConfig)
class DefaultFP16Config extends Config(new WithFP16 ++ new DefaultConfig)
+class DefaultBConfig extends Config(new WithB ++ new DefaultConfig)
+class DefaultRV32BConfig extends Config(new WithB ++ new DefaultRV32Config)
class HypervisorConfig extends Config(new WithHypervisor ++ new DefaultConfig)
@@ -34,6 +37,17 @@ class DualCoreConfig extends Config(new WithNBigCores(2) ++ new WithCoherentBusT
class DualChannelConfig extends Config(new WithNMemoryChannels(2) ++ new DefaultConfig)
class EightChannelConfig extends Config(new WithNMemoryChannels(8) ++ new DefaultConfig)
+class ClusterConfig extends Config(
+ new WithNBigCores(2, InCluster(3)) ++
+ new WithNBigCores(2, InCluster(1)) ++
+ new WithNBigCores(2, InCluster(0)) ++
+ new WithCluster(3, location=InCluster(2)) ++
+ new WithCluster(2) ++
+ new WithCluster(1) ++
+ new WithCluster(0) ++
+ new DefaultConfig
+)
+
class DualChannelDualBankConfig extends Config(
new WithNMemoryChannels(2) ++
new WithNBanks(4) ++ new DefaultConfig
diff --git a/src/main/scala/system/RocketTestSuite.scala b/src/main/scala/system/RocketTestSuite.scala
index d26c5fcfc75..f188d3cd7b3 100644
--- a/src/main/scala/system/RocketTestSuite.scala
+++ b/src/main/scala/system/RocketTestSuite.scala
@@ -159,6 +159,23 @@ object DefaultTestSuites {
val rv64uzfhNames = rv64ufNames
val rv64uzfh = new AssemblyTestSuite("rv64uzfh", rv64uzfhNames)(_)
+ val rv32uzbaNames = LinkedHashSet("sh1add", "sh2add", "sh3add")
+ val rv32uzba = new AssemblyTestSuite("rv32uzba", rv32uzbaNames)(_)
+
+ val rv64uzbaNames = rv32uzbaNames ++ rv32uzbaNames.map(_ + "_uw") + "add_uw" + "slli_uw"
+ val rv64uzba = new AssemblyTestSuite("rv64uzba", rv64uzbaNames)(_)
+
+ val rv32uzbbNames = LinkedHashSet("andn", "clz", "cpop", "ctz", "max", "maxu", "min", "minu", "orc_b", "orn", "rev8", "rol", "ror", "rori", "sext_b", "sext_h", "xnor", "zext_h")
+ val rv32uzbb = new AssemblyTestSuite("rv32uzbb", rv32uzbbNames)(_)
+
+ val rv64uzbbNames = rv32uzbbNames + "clzw" + "cpopw" + "ctzw" + "rolw" + "roriw"
+ val rv64uzbb = new AssemblyTestSuite("rv64uzbb", rv64uzbbNames)(_)
+
+ val rv32uzbsNames = LinkedHashSet("bclr", "bclri", "bext", "bexti", "binv", "binvi", "bset", "bseti")
+ val rv32uzbs = new AssemblyTestSuite("rv32uzbs", rv32uzbsNames)(_)
+
+ val rv64uzbsNames = rv32uzbsNames
+ val rv64uzbs = new AssemblyTestSuite("rv64uzbs", rv64uzbsNames)(_)
val rv64siNames = rv32siNames + "icache-alias"
val rv64si = new AssemblyTestSuite("rv64si", rv64siNames)(_)
diff --git a/src/main/scala/system/SimAXIMem.scala b/src/main/scala/system/SimAXIMem.scala
index a0238522641..f0a08e6d5b8 100644
--- a/src/main/scala/system/SimAXIMem.scala
+++ b/src/main/scala/system/SimAXIMem.scala
@@ -3,10 +3,13 @@
package freechips.rocketchip.system // TODO this should really be in a testharness package
import chisel3._
-import freechips.rocketchip.amba._
-import freechips.rocketchip.amba.axi4._
-import org.chipsalliance.cde.config.Parameters
-import freechips.rocketchip.diplomacy._
+
+import org.chipsalliance.cde.config._
+import org.chipsalliance.diplomacy.lazymodule._
+
+import freechips.rocketchip.amba.AMBACorrupt
+import freechips.rocketchip.amba.axi4.{AXI4RAM, AXI4MasterNode, AXI4EdgeParameters, AXI4Xbar, AXI4Buffer, AXI4Fragmenter}
+import freechips.rocketchip.diplomacy.AddressSet
import freechips.rocketchip.subsystem.{CanHaveMasterAXI4MMIOPort, CanHaveMasterAXI4MemPort, ExtBus, ExtMem}
/** Memory with AXI port for use in elaboratable test harnesses.
diff --git a/src/main/scala/system/TestHarness.scala b/src/main/scala/system/TestHarness.scala
index a1e37dea169..80c711880aa 100644
--- a/src/main/scala/system/TestHarness.scala
+++ b/src/main/scala/system/TestHarness.scala
@@ -3,9 +3,11 @@
package freechips.rocketchip.system
import chisel3._
-import org.chipsalliance.cde.config.Parameters
+
+import org.chipsalliance.cde.config._
+import org.chipsalliance.diplomacy.lazymodule._
+
import freechips.rocketchip.devices.debug.Debug
-import freechips.rocketchip.diplomacy.LazyModule
import freechips.rocketchip.util.AsyncResetReg
class TestHarness()(implicit p: Parameters) extends Module {
@@ -16,8 +18,10 @@ class TestHarness()(implicit p: Parameters) extends Module {
val ldut = LazyModule(new ExampleRocketSystem)
val dut = Module(ldut.module)
+ ldut.io_clocks.get.elements.values.foreach(_.clock := clock)
// Allow the debug ndreset to reset the dut, but not until the initial reset has completed
- dut.reset := (reset.asBool | ldut.debug.map { debug => AsyncResetReg(debug.ndreset) }.getOrElse(false.B)).asBool
+ val dut_reset = (reset.asBool | ldut.debug.map { debug => AsyncResetReg(debug.ndreset) }.getOrElse(false.B)).asBool
+ ldut.io_clocks.get.elements.values.foreach(_.reset := dut_reset)
dut.dontTouchPorts()
dut.tieOffInterrupts()
diff --git a/src/main/scala/tile/BaseTile.scala b/src/main/scala/tile/BaseTile.scala
index 448050a0d50..263b73c69a8 100644
--- a/src/main/scala/tile/BaseTile.scala
+++ b/src/main/scala/tile/BaseTile.scala
@@ -4,34 +4,43 @@ package freechips.rocketchip.tile
import chisel3._
import chisel3.util.{log2Ceil, log2Up}
+
import org.chipsalliance.cde.config._
-import freechips.rocketchip.subsystem._
-import freechips.rocketchip.diplomacy._
+import org.chipsalliance.diplomacy._
+import org.chipsalliance.diplomacy.bundlebridge._
+
+
+import freechips.rocketchip.resources.{PropertyMap, PropertyOption, ResourceReference, DTSTimebase}
+import freechips.rocketchip.interrupts.{IntInwardNode, IntOutwardNode}
+import freechips.rocketchip.rocket.{ICacheParams, DCacheParams, BTBParams, ASIdBits, VMIdBits, TraceAux, BPWatch}
+import freechips.rocketchip.subsystem.{
+ HierarchicalElementParams, InstantiableHierarchicalElementParams, HierarchicalElementCrossingParamsLike,
+ CacheBlockBytes, SystemBusKey, BaseHierarchicalElement, InsertTimingClosureRegistersOnHartIds, BaseHierarchicalElementModuleImp
+}
+import freechips.rocketchip.tilelink.{TLEphemeralNode, TLOutwardNode, TLNode, TLFragmenter, EarlyAck, TLWidthWidget, TLManagerParameters, ManagerUnification}
+import freechips.rocketchip.prci.{ClockCrossingType, ClockSinkParameters}
+import freechips.rocketchip.util.{TraceCoreParams, TraceCoreInterface}
-import freechips.rocketchip.interrupts._
-import freechips.rocketchip.rocket._
-import freechips.rocketchip.tilelink._
-import freechips.rocketchip.util._
-import freechips.rocketchip.prci.{ClockSinkParameters}
+import freechips.rocketchip.resources.{BigIntToProperty, IntToProperty, StringToProperty}
+import freechips.rocketchip.util.BooleanToAugmentedBoolean
case object TileVisibilityNodeKey extends Field[TLEphemeralNode]
case object TileKey extends Field[TileParams]
case object LookupByHartId extends Field[LookupByHartIdImpl]
-trait TileParams {
+trait TileParams extends HierarchicalElementParams {
val core: CoreParams
val icache: Option[ICacheParams]
val dcache: Option[DCacheParams]
val btb: Option[BTBParams]
- val hartId: Int
- val beuAddr: Option[BigInt]
+ val tileId: Int // may not be hartid
val blockerCtrlAddr: Option[BigInt]
- val name: Option[String]
- val clockSinkParams: ClockSinkParameters
}
-abstract class InstantiableTileParams[TileType <: BaseTile] extends TileParams {
- def instantiate(crossing: TileCrossingParamsLike, lookup: LookupByHartIdImpl)
+abstract class InstantiableTileParams[TileType <: BaseTile]
+ extends InstantiableHierarchicalElementParams[TileType]
+ with TileParams {
+ def instantiate(crossing: HierarchicalElementCrossingParamsLike, lookup: LookupByHartIdImpl)
(implicit p: Parameters): TileType
}
@@ -52,12 +61,12 @@ trait HasNonDiplomaticTileParameters {
def usingPTW: Boolean = usingVM
def usingDataScratchpad: Boolean = tileParams.dcache.flatMap(_.scratch).isDefined
- def xLen: Int = p(XLen)
+ def xLen: Int = tileParams.core.xLen
def xBytes: Int = xLen / 8
def iLen: Int = 32
def pgIdxBits: Int = 12
def pgLevelBits: Int = 10 - log2Ceil(xLen / 32)
- def pgLevels: Int = p(PgLevels)
+ def pgLevels: Int = tileParams.core.pgLevels
def maxSVAddrBits: Int = pgIdxBits + pgLevels * pgLevelBits
def maxHypervisorExtraAddrBits: Int = 2
def hypervisorExtraAddrBits: Int = {
@@ -77,15 +86,7 @@ trait HasNonDiplomaticTileParameters {
xLen match { case 32 => 34; case 64 => 56 }
}
- /** Use staticIdForMetadataUseOnly to emit information during the build or identify a component to diplomacy.
- *
- * Including it in a constructed Chisel circuit by converting it to a UInt will prevent
- * Chisel/FIRRTL from being able to deduplicate tiles that are otherwise homogeneous,
- * a property which is important for hierarchical place & route flows.
- */
- def staticIdForMetadataUseOnly: Int = tileParams.hartId
- @deprecated("use hartIdSinkNodeOpt.map(_.bundle) or staticIdForMetadataUseOnly", "rocket-chip 1.3")
- def hartId: Int = staticIdForMetadataUseOnly
+ def tileId: Int = tileParams.tileId
def cacheBlockBytes = p(CacheBlockBytes)
def lgCacheBlockBytes = log2Up(cacheBlockBytes)
@@ -103,20 +104,39 @@ trait HasNonDiplomaticTileParameters {
val f = if (tileParams.core.fpu.nonEmpty) "f" else ""
val d = if (tileParams.core.fpu.nonEmpty && tileParams.core.fpu.get.fLen > 32) "d" else ""
val c = if (tileParams.core.useCompressed) "c" else ""
- val v = if (tileParams.core.useVector) "v" else ""
+ val b = if (tileParams.core.useBitmanip) "b" else ""
+ val v = if (tileParams.core.useVector && tileParams.core.vLen >= 128 && tileParams.core.eLen == 64 && tileParams.core.vfLen == 64) "v" else ""
val h = if (usingHypervisor) "h" else ""
+
+ val ext_strs = Seq(
+ (tileParams.core.useVector) -> s"zvl${tileParams.core.vLen}b",
+ (tileParams.core.useVector) -> {
+ val c = tileParams.core.vfLen match {
+ case 64 => "d"
+ case 32 => "f"
+ case 0 => "x"
+ }
+ s"zve${tileParams.core.eLen}$c"
+ },
+ (tileParams.core.useVector && tileParams.core.vfh) -> "zvfh",
+ (tileParams.core.fpu.map(_.fLen >= 16).getOrElse(false) && tileParams.core.minFLen <= 16) -> "zfh",
+ (tileParams.core.useZba) -> "zba",
+ (tileParams.core.useZbb) -> "zbb",
+ (tileParams.core.useZbs) -> "zbs",
+ (tileParams.core.useConditionalZero) -> "zicond"
+ ).filter(_._1).map(_._2)
+
val multiLetterExt = (
// rdcycle[h], rdinstret[h] is implemented
// rdtime[h] is not implemented, and could be provided by software emulation
// see https://github.com/chipsalliance/rocket-chip/issues/3207
//Some(Seq("zicntr")) ++
- Option.when(tileParams.core.useConditionalZero)(Seq("zicond")) ++
Some(Seq("zicsr", "zifencei", "zihpm")) ++
- Option.when(tileParams.core.fpu.nonEmpty && tileParams.core.fpu.get.fLen >= 16 && tileParams.core.fpu.get.minFLen <= 16)(Seq("zfh")) ++
+ Some(ext_strs) ++ Some(tileParams.core.vExts) ++
tileParams.core.customIsaExt.map(Seq(_))
).flatten
val multiLetterString = multiLetterExt.mkString("_")
- s"rv${p(XLen)}$ie$m$a$f$d$c$v$h$multiLetterString"
+ s"rv$xLen$ie$m$a$f$d$c$b$v$h$multiLetterString"
}
def tileProperties: PropertyMap = {
@@ -191,9 +211,8 @@ trait HasTileParameters extends HasNonDiplomaticTileParameters {
}
/** Base class for all Tiles that use TileLink */
-abstract class BaseTile private (val crossing: ClockCrossingType, q: Parameters)
- extends LazyModule()(q)
- with CrossesToOnlyOneClockDomain
+abstract class BaseTile private (crossing: ClockCrossingType, q: Parameters)
+ extends BaseHierarchicalElement(crossing)(q)
with HasNonDiplomaticTileParameters
{
// Public constructor alters Parameters to supply some legacy compatibility keys
@@ -205,19 +224,12 @@ abstract class BaseTile private (val crossing: ClockCrossingType, q: Parameters)
)))
}
+ def intInwardNode: IntInwardNode // Interrupts to the core from external devices
+ def intOutwardNode: Option[IntOutwardNode] // Interrupts from tile-internal devices (e.g. BEU)
+ def haltNode: IntOutwardNode // Unrecoverable error has occurred; suggest reset
+ def ceaseNode: IntOutwardNode // Tile has ceased to retire instructions
+ def wfiNode: IntOutwardNode // Tile is waiting for an interrupt
def module: BaseTileModuleImp[BaseTile]
- def masterNode: TLOutwardNode
- def slaveNode: TLInwardNode
- def intInwardNode: IntInwardNode // Interrupts to the core from external devices
- def intOutwardNode: IntOutwardNode // Interrupts from tile-internal devices (e.g. BEU)
- def haltNode: IntOutwardNode // Unrecoverable error has occurred; suggest reset
- def ceaseNode: IntOutwardNode // Tile has ceased to retire instructions
- def wfiNode: IntOutwardNode // Tile is waiting for an interrupt
-
- protected val tlOtherMastersNode = TLIdentityNode()
- protected val tlMasterXbar = LazyModule(new TLXbar)
- protected val tlSlaveXbar = LazyModule(new TLXbar)
- protected val intXbar = LazyModule(new IntXbar)
/** Node for broadcasting a hart id to diplomatic consumers within the tile. */
val hartIdNexusNode: BundleBridgeNode[UInt] = BundleBroadcast[UInt](registered = p(InsertTimingClosureRegistersOnHartIds))
@@ -250,10 +262,10 @@ abstract class BaseTile private (val crossing: ClockCrossingType, q: Parameters)
resetVectorSinkNode := resetVectorNexusNode := BundleBridgeNameNode("reset_vector")
/** Nodes for connecting NMI interrupt sources and vectors into the tile */
- val nmiNexusNode: BundleBridgeNode[NMI] = BundleBroadcast[NMI]()
- val nmiSinkNode = BundleBridgeSink[NMI](Some(() => new NMI(visiblePhysAddrBits)))
- val nmiNode: BundleBridgeInwardNode[NMI] =
- nmiSinkNode := nmiNexusNode := BundleBridgeNameNode("nmi")
+ val nmiSinkNode = Option.when(tileParams.core.useNMI) {
+ BundleBridgeSink[NMI](Some(() => new NMI(visiblePhysAddrBits)))
+ }
+ val nmiNode: Option[BundleBridgeInwardNode[NMI]] = nmiSinkNode.map(_ := BundleBridgeNameNode("nmi"))
/** Node for broadcasting an address prefix to diplomatic consumers within the tile.
*
@@ -279,15 +291,14 @@ abstract class BaseTile private (val crossing: ClockCrossingType, q: Parameters)
protected def traceRetireWidth = tileParams.core.retireWidth
/** Node for the core to drive legacy "raw" instruction trace. */
val traceSourceNode = BundleBridgeSource(() => new TraceBundle)
- private val traceNexus = BundleBroadcast[TraceBundle]() // backwards compatiblity; not blocked during stretched reset
/** Node for external consumers to source a legacy instruction trace from the core. */
- val traceNode: BundleBridgeOutwardNode[TraceBundle] = traceNexus := traceSourceNode
+ val traceNode = traceSourceNode
- protected def traceCoreParams = new TraceCoreParams()
+ def traceCoreParams = new TraceCoreParams()
/** Node for core to drive instruction trace conforming to RISC-V Processor Trace spec V1.0 */
val traceCoreSourceNode = BundleBridgeSource(() => new TraceCoreInterface(traceCoreParams))
/** Node for external consumers to source a V1.0 instruction trace from the core. */
- val traceCoreNode: BundleBridgeOutwardNode[TraceCoreInterface] = traceCoreSourceNode
+ val traceCoreNode = traceCoreSourceNode
/** Node to broadcast collected trace sideband signals into the tile. */
val traceAuxNexusNode = BundleBridgeNexus[TraceAux](default = Some(() => {
@@ -347,22 +358,6 @@ abstract class BaseTile private (val crossing: ClockCrossingType, q: Parameters)
"hardware-exec-breakpoint-count" -> tileParams.core.nBreakpoints.asProperty
)
- /** Helper function to insert additional buffers on master ports at the boundary of the tile.
- *
- * The boundary buffering needed to cut feed-through paths is
- * microarchitecture specific, so this may need to be overridden
- * in subclasses of this class.
- */
- def makeMasterBoundaryBuffers(crossing: ClockCrossingType)(implicit p: Parameters) = TLBuffer(BufferParams.none)
-
- /** Helper function to insert additional buffers on slave ports at the boundary of the tile.
- *
- * The boundary buffering needed to cut feed-through paths is
- * microarchitecture specific, so this may need to be overridden
- * in subclasses of this class.
- */
- def makeSlaveBoundaryBuffers(crossing: ClockCrossingType)(implicit p: Parameters) = TLBuffer(BufferParams.none)
-
/** Can be used to access derived params calculated by HasCoreParameters
*
* However, callers must ensure they do not access a diplomatically-determined parameter
@@ -373,7 +368,7 @@ abstract class BaseTile private (val crossing: ClockCrossingType, q: Parameters)
new C
}
- this.suggestName(tileParams.name)
+ this.suggestName(tileParams.baseName)
}
-abstract class BaseTileModuleImp[+L <: BaseTile](val outer: L) extends LazyModuleImp(outer) with HasTileParameters
+abstract class BaseTileModuleImp[+L <: BaseTile](outer: L) extends BaseHierarchicalElementModuleImp[L](outer)
diff --git a/src/main/scala/tile/BusErrorUnit.scala b/src/main/scala/tile/BusErrorUnit.scala
index 65c91b38e21..850550afb80 100644
--- a/src/main/scala/tile/BusErrorUnit.scala
+++ b/src/main/scala/tile/BusErrorUnit.scala
@@ -3,17 +3,17 @@
package freechips.rocketchip.tile
import chisel3._
-import chisel3.util.log2Ceil
-// TODO: remove this import
-import chisel3.util.ImplicitConversions._
-import chisel3.util.Valid
-import chisel3.DontCare
+import chisel3.util._
+
import org.chipsalliance.cde.config.Parameters
-import freechips.rocketchip.rocket._
-import freechips.rocketchip.diplomacy._
-import freechips.rocketchip.regmapper._
-import freechips.rocketchip.tilelink._
-import freechips.rocketchip.interrupts._
+import org.chipsalliance.diplomacy.lazymodule._
+
+import freechips.rocketchip.rocket.{DCacheErrors, ICacheErrors}
+import freechips.rocketchip.diplomacy.{AddressSet}
+import freechips.rocketchip.resources.{SimpleDevice}
+import freechips.rocketchip.regmapper.{DescribedReg, RegField, RegFieldDesc, RegFieldGroup}
+import freechips.rocketchip.tilelink.TLRegisterNode
+import freechips.rocketchip.interrupts.{IntSourceNode, IntSourcePortSimple}
import freechips.rocketchip.util.property
trait BusErrors extends Bundle {
@@ -36,14 +36,14 @@ class L1BusErrors(implicit p: Parameters) extends CoreBundle()(p) with BusErrors
case class BusErrorUnitParams(addr: BigInt, size: Int = 4096)
-class BusErrorUnit[T <: BusErrors](t: => T, params: BusErrorUnitParams)(implicit p: Parameters) extends LazyModule {
+class BusErrorUnit[T <: BusErrors](t: => T, params: BusErrorUnitParams, beatBytes: Int)(implicit p: Parameters) extends LazyModule {
val regWidth = 64
val device = new SimpleDevice("bus-error-unit", Seq("sifive,buserror0"))
val intNode = IntSourceNode(IntSourcePortSimple(resources = device.int))
val node = TLRegisterNode(
address = Seq(AddressSet(params.addr, params.size-1)),
device = device,
- beatBytes = p(XLen)/8)
+ beatBytes = beatBytes)
lazy val module = new Impl
class Impl extends LazyModuleImp(this) {
@@ -95,17 +95,17 @@ class BusErrorUnit[T <: BusErrors](t: => T, params: BusErrorUnitParams)(implicit
new_value := DontCare
for ((((s, en), acc), i) <- (sources zip enable zip accrued).zipWithIndex; if s.nonEmpty) {
when (s.get.valid) {
- acc := true
+ acc := true.B
when (en) {
- cause_wen := true
- new_cause := i
+ cause_wen := true.B
+ new_cause := i.asUInt
new_value := s.get.bits
}
property.cover(en, s"BusErrorCause_$i", s"Core;;BusErrorCause $i covered")
}
}
- when (cause === 0 && cause_wen) {
+ when (cause === 0.asUInt && cause_wen) {
cause := new_cause
value := new_value
}
@@ -129,10 +129,10 @@ class BusErrorUnit[T <: BusErrors](t: => T, params: BusErrorUnitParams)(implicit
// hardwire mask bits for unsupported sources to 0
for ((s, i) <- sources.zipWithIndex; if s.isEmpty) {
- enable(i) := false
- global_interrupt(i) := false
- accrued(i) := false
- local_interrupt(i) := false
+ enable(i) := false.B
+ global_interrupt(i) := false.B
+ accrued(i) := false.B
+ local_interrupt(i) := false.B
}
}
}
diff --git a/src/main/scala/tile/Core.scala b/src/main/scala/tile/Core.scala
index 8c9018da50a..1160247e73a 100644
--- a/src/main/scala/tile/Core.scala
+++ b/src/main/scala/tile/Core.scala
@@ -8,7 +8,6 @@ import org.chipsalliance.cde.config._
import freechips.rocketchip.rocket._
import freechips.rocketchip.util._
-case object XLen extends Field[Int]
case object MaxHartIdBits extends Field[Int]
// These parameters can be varied per-core
@@ -26,6 +25,9 @@ trait CoreParams {
val vectorUseDCache: Boolean = false
val useRVE: Boolean
val useConditionalZero: Boolean
+ val useZba: Boolean
+ val useZbb: Boolean
+ val useZbs: Boolean
val mulDiv: Option[MulDivParams]
val fpu: Option[FPUParams]
val fetchWidth: Int
@@ -51,6 +53,8 @@ trait CoreParams {
val mtvecInit: Option[BigInt]
val mtvecWritable: Boolean
val traceHasWdata: Boolean
+ val xLen: Int
+ val pgLevels: Int
def traceCustom: Option[Data] = None
def customIsaExt: Option[String] = None
def customCSRs(implicit p: Parameters): CustomCSRs = new CustomCSRs
@@ -63,10 +67,16 @@ trait CoreParams {
def dcacheReqTagBits: Int = 6
def minFLen: Int = 32
+
def vLen: Int = 0
- def sLen: Int = 0
- def eLen(xLen: Int, fLen: Int): Int = xLen max fLen
+ def eLen: Int = 0
+ def vfLen: Int = 0
+ def vfh: Boolean = false
+ def vExts: Seq[String] = Nil
+ def hasV: Boolean = vLen >= 128 && eLen >= 64 && vfLen >= 64
def vMemDataBits: Int = 0
+
+ def useBitmanip = useZba && useZbb && useZbs
}
trait HasCoreParameters extends HasTileParameters {
@@ -106,14 +116,25 @@ trait HasCoreParameters extends HasTileParameters {
val traceHasWdata = coreParams.traceHasWdata
def vLen = coreParams.vLen
- def sLen = coreParams.sLen
- def eLen = coreParams.eLen(xLen, fLen)
+ def eLen = coreParams.eLen
+ def vfLen = coreParams.vfLen
def vMemDataBits = if (usingVector) coreParams.vMemDataBits else 0
def maxVLMax = vLen
if (usingVector) {
require(isPow2(vLen), s"vLen ($vLen) must be a power of 2")
require(eLen >= 32 && vLen % eLen == 0, s"eLen must divide vLen ($vLen) and be no less than 32")
+ require(eLen == 32 || eLen == 64)
+ require(vfLen <= eLen)
+ require(!coreParams.vfh || (vfLen >= 32 && coreParams.minFLen <= 16))
+ }
+
+ if (coreParams.useVM) {
+ if (coreParams.xLen == 32) {
+ require(coreParams.pgLevels == 2)
+ } else {
+ require(coreParams.pgLevels >= 3)
+ }
}
lazy val hartIdLen: Int = p(MaxHartIdBits)
@@ -136,33 +157,9 @@ abstract class CoreModule(implicit val p: Parameters) extends Module
abstract class CoreBundle(implicit val p: Parameters) extends ParameterizedBundle()(p)
with HasCoreParameters
-class CoreInterrupts(implicit p: Parameters) extends TileInterrupts()(p) {
- val buserror = tileParams.beuAddr.map(a => Bool())
-}
-
// This is a raw commit trace from the core, not the TraceCoreInterface
class TraceBundle(implicit val p: Parameters) extends Bundle with HasCoreParameters {
val insns = Vec(coreParams.retireWidth, new TracedInstruction)
val time = UInt(64.W)
val custom = coreParams.traceCustom
}
-
-trait HasCoreIO extends HasTileParameters {
- implicit val p: Parameters
- def nTotalRoCCCSRs: Int
- val io = IO(new CoreBundle()(p) {
- val hartid = Input(UInt(hartIdLen.W))
- val reset_vector = Input(UInt(resetVectorLen.W))
- val interrupts = Input(new CoreInterrupts())
- val imem = new FrontendIO
- val dmem = new HellaCacheIO
- val ptw = Flipped(new DatapathPTWIO())
- val fpu = Flipped(new FPUCoreIO())
- val rocc = Flipped(new RoCCCoreIO(nTotalRoCCCSRs))
- val trace = Output(new TraceBundle)
- val bpwatch = Output(Vec(coreParams.nBreakpoints, new BPWatch(coreParams.retireWidth)))
- val cease = Output(Bool())
- val wfi = Output(Bool())
- val traceStall = Input(Bool())
- })
-}
diff --git a/src/main/scala/tile/FPU.scala b/src/main/scala/tile/FPU.scala
index 174cd38c7de..1affeb48769 100644
--- a/src/main/scala/tile/FPU.scala
+++ b/src/main/scala/tile/FPU.scala
@@ -19,7 +19,9 @@ case class FPUParams(
fLen: Int = 64,
divSqrt: Boolean = true,
sfmaLatency: Int = 3,
- dfmaLatency: Int = 4
+ dfmaLatency: Int = 4,
+ fpmuLatency: Int = 2,
+ ifpuLatency: Int = 2
)
object FPConstants
@@ -45,6 +47,7 @@ trait HasFPUCtrlSigs {
val div = Bool()
val sqrt = Bool()
val wflags = Bool()
+ val vec = Bool()
}
class FPUCtrlSigs extends Bundle with HasFPUCtrlSigs
@@ -57,121 +60,122 @@ class FPUDecoder(implicit p: Parameters) extends FPUModule()(p) {
private val X2 = BitPat.dontCare(2)
- val default = List(X,X,X,X,X,X,X,X2,X2,X,X,X,X,X,X,X)
+ val default = List(X,X,X,X,X,X,X,X2,X2,X,X,X,X,X,X,X,N)
val h: Array[(BitPat, List[BitPat])] =
- Array(FLH -> List(Y,Y,N,N,N,X,X,X2,X2,N,N,N,N,N,N,N),
- FSH -> List(Y,N,N,Y,N,Y,X, I, H,N,Y,N,N,N,N,N),
- FMV_H_X -> List(N,Y,N,N,N,X,X, H, I,Y,N,N,N,N,N,N),
- FCVT_H_W -> List(N,Y,N,N,N,X,X, H, H,Y,N,N,N,N,N,Y),
- FCVT_H_WU-> List(N,Y,N,N,N,X,X, H, H,Y,N,N,N,N,N,Y),
- FCVT_H_L -> List(N,Y,N,N,N,X,X, H, H,Y,N,N,N,N,N,Y),
- FCVT_H_LU-> List(N,Y,N,N,N,X,X, H, H,Y,N,N,N,N,N,Y),
- FMV_X_H -> List(N,N,Y,N,N,N,X, I, H,N,Y,N,N,N,N,N),
- FCLASS_H -> List(N,N,Y,N,N,N,X, H, H,N,Y,N,N,N,N,N),
- FCVT_W_H -> List(N,N,Y,N,N,N,X, H,X2,N,Y,N,N,N,N,Y),
- FCVT_WU_H-> List(N,N,Y,N,N,N,X, H,X2,N,Y,N,N,N,N,Y),
- FCVT_L_H -> List(N,N,Y,N,N,N,X, H,X2,N,Y,N,N,N,N,Y),
- FCVT_LU_H-> List(N,N,Y,N,N,N,X, H,X2,N,Y,N,N,N,N,Y),
- FCVT_S_H -> List(N,Y,Y,N,N,N,X, H, S,N,N,Y,N,N,N,Y),
- FCVT_H_S -> List(N,Y,Y,N,N,N,X, S, H,N,N,Y,N,N,N,Y),
- FEQ_H -> List(N,N,Y,Y,N,N,N, H, H,N,Y,N,N,N,N,Y),
- FLT_H -> List(N,N,Y,Y,N,N,N, H, H,N,Y,N,N,N,N,Y),
- FLE_H -> List(N,N,Y,Y,N,N,N, H, H,N,Y,N,N,N,N,Y),
- FSGNJ_H -> List(N,Y,Y,Y,N,N,N, H, H,N,N,Y,N,N,N,N),
- FSGNJN_H -> List(N,Y,Y,Y,N,N,N, H, H,N,N,Y,N,N,N,N),
- FSGNJX_H -> List(N,Y,Y,Y,N,N,N, H, H,N,N,Y,N,N,N,N),
- FMIN_H -> List(N,Y,Y,Y,N,N,N, H, H,N,N,Y,N,N,N,Y),
- FMAX_H -> List(N,Y,Y,Y,N,N,N, H, H,N,N,Y,N,N,N,Y),
- FADD_H -> List(N,Y,Y,Y,N,N,Y, H, H,N,N,N,Y,N,N,Y),
- FSUB_H -> List(N,Y,Y,Y,N,N,Y, H, H,N,N,N,Y,N,N,Y),
- FMUL_H -> List(N,Y,Y,Y,N,N,N, H, H,N,N,N,Y,N,N,Y),
- FMADD_H -> List(N,Y,Y,Y,Y,N,N, H, H,N,N,N,Y,N,N,Y),
- FMSUB_H -> List(N,Y,Y,Y,Y,N,N, H, H,N,N,N,Y,N,N,Y),
- FNMADD_H -> List(N,Y,Y,Y,Y,N,N, H, H,N,N,N,Y,N,N,Y),
- FNMSUB_H -> List(N,Y,Y,Y,Y,N,N, H, H,N,N,N,Y,N,N,Y),
- FDIV_H -> List(N,Y,Y,Y,N,N,N, H, H,N,N,N,N,Y,N,Y),
- FSQRT_H -> List(N,Y,Y,N,N,N,X, H, H,N,N,N,N,N,Y,Y))
+ Array(FLH -> List(Y,Y,N,N,N,X,X,X2,X2,N,N,N,N,N,N,N,N),
+ FSH -> List(Y,N,N,Y,N,Y,X, I, H,N,Y,N,N,N,N,N,N),
+ FMV_H_X -> List(N,Y,N,N,N,X,X, H, I,Y,N,N,N,N,N,N,N),
+ FCVT_H_W -> List(N,Y,N,N,N,X,X, H, H,Y,N,N,N,N,N,Y,N),
+ FCVT_H_WU-> List(N,Y,N,N,N,X,X, H, H,Y,N,N,N,N,N,Y,N),
+ FCVT_H_L -> List(N,Y,N,N,N,X,X, H, H,Y,N,N,N,N,N,Y,N),
+ FCVT_H_LU-> List(N,Y,N,N,N,X,X, H, H,Y,N,N,N,N,N,Y,N),
+ FMV_X_H -> List(N,N,Y,N,N,N,X, I, H,N,Y,N,N,N,N,N,N),
+ FCLASS_H -> List(N,N,Y,N,N,N,X, H, H,N,Y,N,N,N,N,N,N),
+ FCVT_W_H -> List(N,N,Y,N,N,N,X, H,X2,N,Y,N,N,N,N,Y,N),
+ FCVT_WU_H-> List(N,N,Y,N,N,N,X, H,X2,N,Y,N,N,N,N,Y,N),
+ FCVT_L_H -> List(N,N,Y,N,N,N,X, H,X2,N,Y,N,N,N,N,Y,N),
+ FCVT_LU_H-> List(N,N,Y,N,N,N,X, H,X2,N,Y,N,N,N,N,Y,N),
+ FCVT_S_H -> List(N,Y,Y,N,N,N,X, H, S,N,N,Y,N,N,N,Y,N),
+ FCVT_H_S -> List(N,Y,Y,N,N,N,X, S, H,N,N,Y,N,N,N,Y,N),
+ FEQ_H -> List(N,N,Y,Y,N,N,N, H, H,N,Y,N,N,N,N,Y,N),
+ FLT_H -> List(N,N,Y,Y,N,N,N, H, H,N,Y,N,N,N,N,Y,N),
+ FLE_H -> List(N,N,Y,Y,N,N,N, H, H,N,Y,N,N,N,N,Y,N),
+ FSGNJ_H -> List(N,Y,Y,Y,N,N,N, H, H,N,N,Y,N,N,N,N,N),
+ FSGNJN_H -> List(N,Y,Y,Y,N,N,N, H, H,N,N,Y,N,N,N,N,N),
+ FSGNJX_H -> List(N,Y,Y,Y,N,N,N, H, H,N,N,Y,N,N,N,N,N),
+ FMIN_H -> List(N,Y,Y,Y,N,N,N, H, H,N,N,Y,N,N,N,Y,N),
+ FMAX_H -> List(N,Y,Y,Y,N,N,N, H, H,N,N,Y,N,N,N,Y,N),
+ FADD_H -> List(N,Y,Y,Y,N,N,Y, H, H,N,N,N,Y,N,N,Y,N),
+ FSUB_H -> List(N,Y,Y,Y,N,N,Y, H, H,N,N,N,Y,N,N,Y,N),
+ FMUL_H -> List(N,Y,Y,Y,N,N,N, H, H,N,N,N,Y,N,N,Y,N),
+ FMADD_H -> List(N,Y,Y,Y,Y,N,N, H, H,N,N,N,Y,N,N,Y,N),
+ FMSUB_H -> List(N,Y,Y,Y,Y,N,N, H, H,N,N,N,Y,N,N,Y,N),
+ FNMADD_H -> List(N,Y,Y,Y,Y,N,N, H, H,N,N,N,Y,N,N,Y,N),
+ FNMSUB_H -> List(N,Y,Y,Y,Y,N,N, H, H,N,N,N,Y,N,N,Y,N),
+ FDIV_H -> List(N,Y,Y,Y,N,N,N, H, H,N,N,N,N,Y,N,Y,N),
+ FSQRT_H -> List(N,Y,Y,N,N,N,X, H, H,N,N,N,N,N,Y,Y,N))
val f: Array[(BitPat, List[BitPat])] =
- Array(FLW -> List(Y,Y,N,N,N,X,X,X2,X2,N,N,N,N,N,N,N),
- FSW -> List(Y,N,N,Y,N,Y,X, I, S,N,Y,N,N,N,N,N),
- FMV_W_X -> List(N,Y,N,N,N,X,X, S, I,Y,N,N,N,N,N,N),
- FCVT_S_W -> List(N,Y,N,N,N,X,X, S, S,Y,N,N,N,N,N,Y),
- FCVT_S_WU-> List(N,Y,N,N,N,X,X, S, S,Y,N,N,N,N,N,Y),
- FCVT_S_L -> List(N,Y,N,N,N,X,X, S, S,Y,N,N,N,N,N,Y),
- FCVT_S_LU-> List(N,Y,N,N,N,X,X, S, S,Y,N,N,N,N,N,Y),
- FMV_X_W -> List(N,N,Y,N,N,N,X, I, S,N,Y,N,N,N,N,N),
- FCLASS_S -> List(N,N,Y,N,N,N,X, S, S,N,Y,N,N,N,N,N),
- FCVT_W_S -> List(N,N,Y,N,N,N,X, S,X2,N,Y,N,N,N,N,Y),
- FCVT_WU_S-> List(N,N,Y,N,N,N,X, S,X2,N,Y,N,N,N,N,Y),
- FCVT_L_S -> List(N,N,Y,N,N,N,X, S,X2,N,Y,N,N,N,N,Y),
- FCVT_LU_S-> List(N,N,Y,N,N,N,X, S,X2,N,Y,N,N,N,N,Y),
- FEQ_S -> List(N,N,Y,Y,N,N,N, S, S,N,Y,N,N,N,N,Y),
- FLT_S -> List(N,N,Y,Y,N,N,N, S, S,N,Y,N,N,N,N,Y),
- FLE_S -> List(N,N,Y,Y,N,N,N, S, S,N,Y,N,N,N,N,Y),
- FSGNJ_S -> List(N,Y,Y,Y,N,N,N, S, S,N,N,Y,N,N,N,N),
- FSGNJN_S -> List(N,Y,Y,Y,N,N,N, S, S,N,N,Y,N,N,N,N),
- FSGNJX_S -> List(N,Y,Y,Y,N,N,N, S, S,N,N,Y,N,N,N,N),
- FMIN_S -> List(N,Y,Y,Y,N,N,N, S, S,N,N,Y,N,N,N,Y),
- FMAX_S -> List(N,Y,Y,Y,N,N,N, S, S,N,N,Y,N,N,N,Y),
- FADD_S -> List(N,Y,Y,Y,N,N,Y, S, S,N,N,N,Y,N,N,Y),
- FSUB_S -> List(N,Y,Y,Y,N,N,Y, S, S,N,N,N,Y,N,N,Y),
- FMUL_S -> List(N,Y,Y,Y,N,N,N, S, S,N,N,N,Y,N,N,Y),
- FMADD_S -> List(N,Y,Y,Y,Y,N,N, S, S,N,N,N,Y,N,N,Y),
- FMSUB_S -> List(N,Y,Y,Y,Y,N,N, S, S,N,N,N,Y,N,N,Y),
- FNMADD_S -> List(N,Y,Y,Y,Y,N,N, S, S,N,N,N,Y,N,N,Y),
- FNMSUB_S -> List(N,Y,Y,Y,Y,N,N, S, S,N,N,N,Y,N,N,Y),
- FDIV_S -> List(N,Y,Y,Y,N,N,N, S, S,N,N,N,N,Y,N,Y),
- FSQRT_S -> List(N,Y,Y,N,N,N,X, S, S,N,N,N,N,N,Y,Y))
+ Array(FLW -> List(Y,Y,N,N,N,X,X,X2,X2,N,N,N,N,N,N,N,N),
+ FSW -> List(Y,N,N,Y,N,Y,X, I, S,N,Y,N,N,N,N,N,N),
+ FMV_W_X -> List(N,Y,N,N,N,X,X, S, I,Y,N,N,N,N,N,N,N),
+ FCVT_S_W -> List(N,Y,N,N,N,X,X, S, S,Y,N,N,N,N,N,Y,N),
+ FCVT_S_WU-> List(N,Y,N,N,N,X,X, S, S,Y,N,N,N,N,N,Y,N),
+ FCVT_S_L -> List(N,Y,N,N,N,X,X, S, S,Y,N,N,N,N,N,Y,N),
+ FCVT_S_LU-> List(N,Y,N,N,N,X,X, S, S,Y,N,N,N,N,N,Y,N),
+ FMV_X_W -> List(N,N,Y,N,N,N,X, I, S,N,Y,N,N,N,N,N,N),
+ FCLASS_S -> List(N,N,Y,N,N,N,X, S, S,N,Y,N,N,N,N,N,N),
+ FCVT_W_S -> List(N,N,Y,N,N,N,X, S,X2,N,Y,N,N,N,N,Y,N),
+ FCVT_WU_S-> List(N,N,Y,N,N,N,X, S,X2,N,Y,N,N,N,N,Y,N),
+ FCVT_L_S -> List(N,N,Y,N,N,N,X, S,X2,N,Y,N,N,N,N,Y,N),
+ FCVT_LU_S-> List(N,N,Y,N,N,N,X, S,X2,N,Y,N,N,N,N,Y,N),
+ FEQ_S -> List(N,N,Y,Y,N,N,N, S, S,N,Y,N,N,N,N,Y,N),
+ FLT_S -> List(N,N,Y,Y,N,N,N, S, S,N,Y,N,N,N,N,Y,N),
+ FLE_S -> List(N,N,Y,Y,N,N,N, S, S,N,Y,N,N,N,N,Y,N),
+ FSGNJ_S -> List(N,Y,Y,Y,N,N,N, S, S,N,N,Y,N,N,N,N,N),
+ FSGNJN_S -> List(N,Y,Y,Y,N,N,N, S, S,N,N,Y,N,N,N,N,N),
+ FSGNJX_S -> List(N,Y,Y,Y,N,N,N, S, S,N,N,Y,N,N,N,N,N),
+ FMIN_S -> List(N,Y,Y,Y,N,N,N, S, S,N,N,Y,N,N,N,Y,N),
+ FMAX_S -> List(N,Y,Y,Y,N,N,N, S, S,N,N,Y,N,N,N,Y,N),
+ FADD_S -> List(N,Y,Y,Y,N,N,Y, S, S,N,N,N,Y,N,N,Y,N),
+ FSUB_S -> List(N,Y,Y,Y,N,N,Y, S, S,N,N,N,Y,N,N,Y,N),
+ FMUL_S -> List(N,Y,Y,Y,N,N,N, S, S,N,N,N,Y,N,N,Y,N),
+ FMADD_S -> List(N,Y,Y,Y,Y,N,N, S, S,N,N,N,Y,N,N,Y,N),
+ FMSUB_S -> List(N,Y,Y,Y,Y,N,N, S, S,N,N,N,Y,N,N,Y,N),
+ FNMADD_S -> List(N,Y,Y,Y,Y,N,N, S, S,N,N,N,Y,N,N,Y,N),
+ FNMSUB_S -> List(N,Y,Y,Y,Y,N,N, S, S,N,N,N,Y,N,N,Y,N),
+ FDIV_S -> List(N,Y,Y,Y,N,N,N, S, S,N,N,N,N,Y,N,Y,N),
+ FSQRT_S -> List(N,Y,Y,N,N,N,X, S, S,N,N,N,N,N,Y,Y,N))
val d: Array[(BitPat, List[BitPat])] =
- Array(FLD -> List(Y,Y,N,N,N,X,X,X2,X2,N,N,N,N,N,N,N),
- FSD -> List(Y,N,N,Y,N,Y,X, I, D,N,Y,N,N,N,N,N),
- FMV_D_X -> List(N,Y,N,N,N,X,X, D, I,Y,N,N,N,N,N,N),
- FCVT_D_W -> List(N,Y,N,N,N,X,X, D, D,Y,N,N,N,N,N,Y),
- FCVT_D_WU-> List(N,Y,N,N,N,X,X, D, D,Y,N,N,N,N,N,Y),
- FCVT_D_L -> List(N,Y,N,N,N,X,X, D, D,Y,N,N,N,N,N,Y),
- FCVT_D_LU-> List(N,Y,N,N,N,X,X, D, D,Y,N,N,N,N,N,Y),
- FMV_X_D -> List(N,N,Y,N,N,N,X, I, D,N,Y,N,N,N,N,N),
- FCLASS_D -> List(N,N,Y,N,N,N,X, D, D,N,Y,N,N,N,N,N),
- FCVT_W_D -> List(N,N,Y,N,N,N,X, D,X2,N,Y,N,N,N,N,Y),
- FCVT_WU_D-> List(N,N,Y,N,N,N,X, D,X2,N,Y,N,N,N,N,Y),
- FCVT_L_D -> List(N,N,Y,N,N,N,X, D,X2,N,Y,N,N,N,N,Y),
- FCVT_LU_D-> List(N,N,Y,N,N,N,X, D,X2,N,Y,N,N,N,N,Y),
- FCVT_S_D -> List(N,Y,Y,N,N,N,X, D, S,N,N,Y,N,N,N,Y),
- FCVT_D_S -> List(N,Y,Y,N,N,N,X, S, D,N,N,Y,N,N,N,Y),
- FEQ_D -> List(N,N,Y,Y,N,N,N, D, D,N,Y,N,N,N,N,Y),
- FLT_D -> List(N,N,Y,Y,N,N,N, D, D,N,Y,N,N,N,N,Y),
- FLE_D -> List(N,N,Y,Y,N,N,N, D, D,N,Y,N,N,N,N,Y),
- FSGNJ_D -> List(N,Y,Y,Y,N,N,N, D, D,N,N,Y,N,N,N,N),
- FSGNJN_D -> List(N,Y,Y,Y,N,N,N, D, D,N,N,Y,N,N,N,N),
- FSGNJX_D -> List(N,Y,Y,Y,N,N,N, D, D,N,N,Y,N,N,N,N),
- FMIN_D -> List(N,Y,Y,Y,N,N,N, D, D,N,N,Y,N,N,N,Y),
- FMAX_D -> List(N,Y,Y,Y,N,N,N, D, D,N,N,Y,N,N,N,Y),
- FADD_D -> List(N,Y,Y,Y,N,N,Y, D, D,N,N,N,Y,N,N,Y),
- FSUB_D -> List(N,Y,Y,Y,N,N,Y, D, D,N,N,N,Y,N,N,Y),
- FMUL_D -> List(N,Y,Y,Y,N,N,N, D, D,N,N,N,Y,N,N,Y),
- FMADD_D -> List(N,Y,Y,Y,Y,N,N, D, D,N,N,N,Y,N,N,Y),
- FMSUB_D -> List(N,Y,Y,Y,Y,N,N, D, D,N,N,N,Y,N,N,Y),
- FNMADD_D -> List(N,Y,Y,Y,Y,N,N, D, D,N,N,N,Y,N,N,Y),
- FNMSUB_D -> List(N,Y,Y,Y,Y,N,N, D, D,N,N,N,Y,N,N,Y),
- FDIV_D -> List(N,Y,Y,Y,N,N,N, D, D,N,N,N,N,Y,N,Y),
- FSQRT_D -> List(N,Y,Y,N,N,N,X, D, D,N,N,N,N,N,Y,Y))
+ Array(FLD -> List(Y,Y,N,N,N,X,X,X2,X2,N,N,N,N,N,N,N,N),
+ FSD -> List(Y,N,N,Y,N,Y,X, I, D,N,Y,N,N,N,N,N,N),
+ FMV_D_X -> List(N,Y,N,N,N,X,X, D, I,Y,N,N,N,N,N,N,N),
+ FCVT_D_W -> List(N,Y,N,N,N,X,X, D, D,Y,N,N,N,N,N,Y,N),
+ FCVT_D_WU-> List(N,Y,N,N,N,X,X, D, D,Y,N,N,N,N,N,Y,N),
+ FCVT_D_L -> List(N,Y,N,N,N,X,X, D, D,Y,N,N,N,N,N,Y,N),
+ FCVT_D_LU-> List(N,Y,N,N,N,X,X, D, D,Y,N,N,N,N,N,Y,N),
+ FMV_X_D -> List(N,N,Y,N,N,N,X, I, D,N,Y,N,N,N,N,N,N),
+ FCLASS_D -> List(N,N,Y,N,N,N,X, D, D,N,Y,N,N,N,N,N,N),
+ FCVT_W_D -> List(N,N,Y,N,N,N,X, D,X2,N,Y,N,N,N,N,Y,N),
+ FCVT_WU_D-> List(N,N,Y,N,N,N,X, D,X2,N,Y,N,N,N,N,Y,N),
+ FCVT_L_D -> List(N,N,Y,N,N,N,X, D,X2,N,Y,N,N,N,N,Y,N),
+ FCVT_LU_D-> List(N,N,Y,N,N,N,X, D,X2,N,Y,N,N,N,N,Y,N),
+ FCVT_S_D -> List(N,Y,Y,N,N,N,X, D, S,N,N,Y,N,N,N,Y,N),
+ FCVT_D_S -> List(N,Y,Y,N,N,N,X, S, D,N,N,Y,N,N,N,Y,N),
+ FEQ_D -> List(N,N,Y,Y,N,N,N, D, D,N,Y,N,N,N,N,Y,N),
+ FLT_D -> List(N,N,Y,Y,N,N,N, D, D,N,Y,N,N,N,N,Y,N),
+ FLE_D -> List(N,N,Y,Y,N,N,N, D, D,N,Y,N,N,N,N,Y,N),
+ FSGNJ_D -> List(N,Y,Y,Y,N,N,N, D, D,N,N,Y,N,N,N,N,N),
+ FSGNJN_D -> List(N,Y,Y,Y,N,N,N, D, D,N,N,Y,N,N,N,N,N),
+ FSGNJX_D -> List(N,Y,Y,Y,N,N,N, D, D,N,N,Y,N,N,N,N,N),
+ FMIN_D -> List(N,Y,Y,Y,N,N,N, D, D,N,N,Y,N,N,N,Y,N),
+ FMAX_D -> List(N,Y,Y,Y,N,N,N, D, D,N,N,Y,N,N,N,Y,N),
+ FADD_D -> List(N,Y,Y,Y,N,N,Y, D, D,N,N,N,Y,N,N,Y,N),
+ FSUB_D -> List(N,Y,Y,Y,N,N,Y, D, D,N,N,N,Y,N,N,Y,N),
+ FMUL_D -> List(N,Y,Y,Y,N,N,N, D, D,N,N,N,Y,N,N,Y,N),
+ FMADD_D -> List(N,Y,Y,Y,Y,N,N, D, D,N,N,N,Y,N,N,Y,N),
+ FMSUB_D -> List(N,Y,Y,Y,Y,N,N, D, D,N,N,N,Y,N,N,Y,N),
+ FNMADD_D -> List(N,Y,Y,Y,Y,N,N, D, D,N,N,N,Y,N,N,Y,N),
+ FNMSUB_D -> List(N,Y,Y,Y,Y,N,N, D, D,N,N,N,Y,N,N,Y,N),
+ FDIV_D -> List(N,Y,Y,Y,N,N,N, D, D,N,N,N,N,Y,N,Y,N),
+ FSQRT_D -> List(N,Y,Y,N,N,N,X, D, D,N,N,N,N,N,Y,Y,N))
val fcvt_hd: Array[(BitPat, List[BitPat])] =
- Array(FCVT_H_D -> List(N,Y,Y,N,N,N,X, D, H,N,N,Y,N,N,N,Y),
- FCVT_D_H -> List(N,Y,Y,N,N,N,X, H, D,N,N,Y,N,N,N,Y))
+ Array(FCVT_H_D -> List(N,Y,Y,N,N,N,X, D, H,N,N,Y,N,N,N,Y,N),
+ FCVT_D_H -> List(N,Y,Y,N,N,N,X, H, D,N,N,Y,N,N,N,Y,N))
+ val vfmv_f_s: Array[(BitPat, List[BitPat])] =
+ Array(VFMV_F_S -> List(N,Y,N,N,N,N,X,X2,X2,N,N,N,N,N,N,N,Y))
- val insns = (minFLen, fLen) match {
+ val insns = ((minFLen, fLen) match {
case (32, 32) => f
case (16, 32) => h ++ f
case (32, 64) => f ++ d
case (16, 64) => h ++ f ++ d ++ fcvt_hd
-
case other => throw new Exception(s"minFLen = ${minFLen} & fLen = ${fLen} is an unsupported configuration")
- }
+ }) ++ (if (usingVector) vfmv_f_s else Array[(BitPat, List[BitPat])]())
val decoder = DecodeLogic(io.inst, default, insns)
val s = io.sigs
val sigs = Seq(s.ldst, s.wen, s.ren1, s.ren2, s.ren3, s.swap12,
s.swap23, s.typeTagIn, s.typeTagOut, s.fromint, s.toint,
- s.fastpipe, s.fma, s.div, s.sqrt, s.wflags)
+ s.fastpipe, s.fma, s.div, s.sqrt, s.wflags, s.vec)
sigs zip decoder map {case(s,d) => s := d}
}
@@ -185,13 +189,15 @@ class FPUCoreIO(implicit p: Parameters) extends CoreBundle()(p) {
val fcsr_rm = Input(Bits(FPConstants.RM_SZ.W))
val fcsr_flags = Valid(Bits(FPConstants.FLAGS_SZ.W))
+ val v_sew = Input(UInt(3.W))
+
val store_data = Output(Bits(fLen.W))
val toint_data = Output(Bits(xLen.W))
- val dmem_resp_val = Input(Bool())
- val dmem_resp_type = Input(Bits(3.W))
- val dmem_resp_tag = Input(UInt(5.W))
- val dmem_resp_data = Input(Bits(fLen.W))
+ val ll_resp_val = Input(Bool())
+ val ll_resp_type = Input(Bits(3.W))
+ val ll_resp_tag = Input(UInt(5.W))
+ val ll_resp_data = Input(Bits(fLen.W))
val valid = Input(Bool())
val fcsr_rdy = Output(Bool())
@@ -466,22 +472,23 @@ class FPToInt(implicit p: Parameters) extends FPUModule()(p) with ShouldBeRetime
dcmp.io.signaling := !in.rm(1)
val tag = in.typeTagOut
- val store = (floatTypes.map(t => if (t == FType.H) Fill(maxType.ieeeWidth / minXLen, ieee(in.in1)(15, 0).sextTo(minXLen))
- else Fill(maxType.ieeeWidth / t.ieeeWidth, ieee(in.in1)(t.ieeeWidth - 1, 0))): Seq[UInt])(tag)
- val toint = WireDefault(store)
+ val toint_ieee = (floatTypes.map(t => if (t == FType.H) Fill(maxType.ieeeWidth / minXLen, ieee(in.in1)(15, 0).sextTo(minXLen))
+ else Fill(maxType.ieeeWidth / t.ieeeWidth, ieee(in.in1)(t.ieeeWidth - 1, 0))): Seq[UInt])(tag)
+
+ val toint = WireDefault(toint_ieee)
val intType = WireDefault(in.fmt(0))
- io.out.bits.store := store
+ io.out.bits.store := (floatTypes.map(t => Fill(fLen / t.ieeeWidth, ieee(in.in1)(t.ieeeWidth - 1, 0))): Seq[UInt])(tag)
io.out.bits.toint := ((0 until nIntTypes).map(i => toint((minXLen << i) - 1, 0).sextTo(xLen)): Seq[UInt])(intType)
io.out.bits.exc := 0.U
when (in.rm(0)) {
val classify_out = (floatTypes.map(t => t.classify(maxType.unsafeConvert(in.in1, t))): Seq[UInt])(tag)
- toint := classify_out | (store >> minXLen << minXLen)
+ toint := classify_out | (toint_ieee >> minXLen << minXLen)
intType := false.B
}
when (in.wflags) { // feq/flt/fle, fcvt
- toint := (~in.rm & Cat(dcmp.io.lt, dcmp.io.eq)).orR | (store >> minXLen << minXLen)
+ toint := (~in.rm & Cat(dcmp.io.lt, dcmp.io.eq)).orR | (toint_ieee >> minXLen << minXLen)
io.out.bits.exc := dcmp.io.exceptionFlags
intType := false.B
@@ -625,6 +632,7 @@ class FPToFP(val latency: Int)(implicit p: Parameters) extends FPUModule()(p) wi
class MulAddRecFNPipe(latency: Int, expWidth: Int, sigWidth: Int) extends Module
{
+ override def desiredName = s"MulAddRecFNPipe_l${latency}_e${expWidth}_s${sigWidth}"
require(latency<=2)
val io = IO(new Bundle {
@@ -688,6 +696,7 @@ class MulAddRecFNPipe(latency: Int, expWidth: Int, sigWidth: Int) extends Module
class FPUFMAPipe(val latency: Int, val t: FType)
(implicit p: Parameters) extends FPUModule()(p) with ShouldBeRetimed {
+ override def desiredName = s"FPUFMAPipe_l${latency}_f${t.ieeeWidth}"
require(latency>0)
val io = IO(new Bundle {
@@ -727,7 +736,9 @@ class FPU(cfg: FPUParams)(implicit p: Parameters) extends FPUModule()(p) {
val io = IO(new FPUIO)
val (useClockGating, useDebugROB) = coreParams match {
- case r: RocketCoreParams => (r.clockGate, r.debugROB)
+ case r: RocketCoreParams =>
+ val sz = if (r.debugROB.isDefined) r.debugROB.get.size else 1
+ (r.clockGate, sz < 1)
case _ => (false, false)
}
val clock_en_reg = Reg(Bool())
@@ -738,18 +749,31 @@ class FPU(cfg: FPUParams)(implicit p: Parameters) extends FPUModule()(p) {
val fp_decoder = Module(new FPUDecoder)
fp_decoder.io.inst := io.inst
- val id_ctrl = fp_decoder.io.sigs
+ val id_ctrl = WireInit(fp_decoder.io.sigs)
+ coreParams match { case r: RocketCoreParams => r.vector.map(v => {
+ val v_decode = v.decoder(p) // Only need to get ren1
+ v_decode.io.inst := io.inst
+ v_decode.io.vconfig := DontCare // core deals with this
+ when (v_decode.io.legal && v_decode.io.read_frs1) {
+ id_ctrl.ren1 := true.B
+ id_ctrl.swap12 := false.B
+ id_ctrl.toint := true.B
+ id_ctrl.typeTagIn := I
+ id_ctrl.typeTagOut := Mux(io.v_sew === 3.U, D, S)
+ }
+ when (v_decode.io.write_frd) { id_ctrl.wen := true.B }
+ })}
val ex_reg_valid = RegNext(io.valid, false.B)
val ex_reg_inst = RegEnable(io.inst, io.valid)
val ex_reg_ctrl = RegEnable(id_ctrl, io.valid)
val ex_ra = List.fill(3)(Reg(UInt()))
- // load response
- val load_wb = RegNext(io.dmem_resp_val)
- val load_wb_typeTag = RegEnable(io.dmem_resp_type(1,0) - typeTagWbOffset, io.dmem_resp_val)
- val load_wb_data = RegEnable(io.dmem_resp_data, io.dmem_resp_val)
- val load_wb_tag = RegEnable(io.dmem_resp_tag, io.dmem_resp_val)
+ // load/vector response
+ val load_wb = RegNext(io.ll_resp_val)
+ val load_wb_typeTag = RegEnable(io.ll_resp_type(1,0) - typeTagWbOffset, io.ll_resp_val)
+ val load_wb_data = RegEnable(io.ll_resp_data, io.ll_resp_val)
+ val load_wb_tag = RegEnable(io.ll_resp_tag, io.ll_resp_val)
class FPUImpl { // entering gated-clock domain
@@ -833,6 +857,10 @@ class FPU(cfg: FPUParams)(implicit p: Parameters) extends FPUModule()(p) {
req.fmaCmd := ex_reg_inst(3,2) | (!ex_ctrl.ren3 && ex_reg_inst(27))
when (ex_cp_valid) {
req := io.cp_req.bits
+ when (io.cp_req.bits.swap12) {
+ req.in1 := io.cp_req.bits.in2
+ req.in2 := io.cp_req.bits.in1
+ }
when (io.cp_req.bits.swap23) {
req.in2 := io.cp_req.bits.in3
req.in3 := io.cp_req.bits.in2
@@ -855,12 +883,12 @@ class FPU(cfg: FPUParams)(implicit p: Parameters) extends FPUModule()(p) {
io.cp_resp.valid := true.B
}
- val ifpu = Module(new IntToFP(2))
+ val ifpu = Module(new IntToFP(cfg.ifpuLatency))
ifpu.io.in.valid := req_valid && ex_ctrl.fromint
ifpu.io.in.bits := fpiu.io.in.bits
ifpu.io.in.bits.in1 := Mux(ex_cp_valid, io.cp_req.bits.in1, io.fromint_data)
- val fpmu = Module(new FPToFP(2))
+ val fpmu = Module(new FPToFP(cfg.fpmuLatency))
fpmu.io.in.valid := req_valid && ex_ctrl.fastpipe
fpmu.io.in.bits := fpiu.io.in.bits
fpmu.io.lt := fpiu.io.out.bits.lt
@@ -868,6 +896,7 @@ class FPU(cfg: FPUParams)(implicit p: Parameters) extends FPUModule()(p) {
val divSqrt_wen = WireDefault(false.B)
val divSqrt_inFlight = WireDefault(false.B)
val divSqrt_waddr = Reg(UInt(5.W))
+ val divSqrt_cp = Reg(Bool())
val divSqrt_typeTag = Wire(UInt(log2Up(floatTypes.size).W))
val divSqrt_wdata = Wire(UInt((fLen+1).W))
val divSqrt_flags = Wire(UInt(FPConstants.FLAGS_SZ.W))
@@ -932,6 +961,7 @@ class FPU(cfg: FPUParams)(implicit p: Parameters) extends FPUModule()(p) {
}
val waddr = Mux(divSqrt_wen, divSqrt_waddr, wbInfo(0).rd)
+ val wb_cp = Mux(divSqrt_wen, divSqrt_cp, wbInfo(0).cp)
val wtypeTag = Mux(divSqrt_wen, divSqrt_typeTag, wbInfo(0).typeTag)
val wdata = box(Mux(divSqrt_wen, divSqrt_wdata, (pipes.map(_.res.data): Seq[UInt])(wbInfo(0).pipeid)), wtypeTag)
val wexc = (pipes.map(_.res.exc): Seq[UInt])(wbInfo(0).pipeid)
@@ -949,11 +979,16 @@ class FPU(cfg: FPUParams)(implicit p: Parameters) extends FPUModule()(p) {
DebugROB.pushWb(clock, reset, io.hartid, (!wbInfo(0).cp && wen(0)) || divSqrt_wen, waddr + 32.U, ieee(wdata))
}
- when (wbInfo(0).cp && wen(0)) {
+ when (wb_cp && (wen(0) || divSqrt_wen)) {
io.cp_resp.bits.data := wdata
io.cp_resp.valid := true.B
}
- io.cp_req.ready := !ex_reg_valid
+
+ assert(!io.cp_req.valid || pipes.forall(_.lat == pipes.head.lat).B,
+ s"FPU only supports coprocessor if FMA pipes have uniform latency ${pipes.map(_.lat)}")
+ // Avoid structural hazards and nacking of external requests
+ // toint responds in the MEM stage, so an incoming toint can induce a structural hazard against inflight FMAs
+ io.cp_req.ready := !ex_reg_valid && !(cp_ctrl.toint && wen =/= 0.U) && !divSqrt_inFlight
val wb_toint_valid = wb_reg_valid && wb_ctrl.toint
val wb_toint_exc = RegEnable(fpiu.io.out.bits.exc, mem_ctrl.toint)
@@ -965,10 +1000,10 @@ class FPU(cfg: FPUParams)(implicit p: Parameters) extends FPUModule()(p) {
val divSqrt_write_port_busy = (mem_ctrl.div || mem_ctrl.sqrt) && wen.orR
io.fcsr_rdy := !(ex_reg_valid && ex_ctrl.wflags || mem_reg_valid && mem_ctrl.wflags || wb_reg_valid && wb_ctrl.toint || wen.orR || divSqrt_inFlight)
- io.nack_mem := write_port_busy || divSqrt_write_port_busy || divSqrt_inFlight
- io.dec <> fp_decoder.io.sigs
+ io.nack_mem := (write_port_busy || divSqrt_write_port_busy || divSqrt_inFlight) && !mem_cp_valid
+ io.dec <> id_ctrl
def useScoreboard(f: ((Pipe, Int)) => Bool) = pipes.zipWithIndex.filter(_._1.lat > 3).map(x => f(x)).fold(false.B)(_||_)
- io.sboard_set := wb_reg_valid && !wb_cp_valid && RegNext(useScoreboard(_._1.cond(mem_ctrl)) || mem_ctrl.div || mem_ctrl.sqrt)
+ io.sboard_set := wb_reg_valid && !wb_cp_valid && RegNext(useScoreboard(_._1.cond(mem_ctrl)) || mem_ctrl.div || mem_ctrl.sqrt || mem_ctrl.vec)
io.sboard_clr := !wb_cp_valid && (divSqrt_wen || (wen(0) && useScoreboard(x => wbInfo(0).pipeid === x._2.U)))
io.sboard_clra := waddr
ccover(io.sboard_clr && load_wb, "DUAL_WRITEBACK", "load and FMA writeback on same cycle")
@@ -980,6 +1015,7 @@ class FPU(cfg: FPUParams)(implicit p: Parameters) extends FPUModule()(p) {
val divSqrt_killed = RegNext(divSqrt_inValid && killm, true.B)
when (divSqrt_inValid) {
divSqrt_waddr := mem_reg_inst(11,7)
+ divSqrt_cp := mem_cp_valid
}
ccover(divSqrt_inFlight && divSqrt_killed, "DIV_KILLED", "divide killed after issued to divider")
@@ -1019,7 +1055,7 @@ class FPU(cfg: FPUParams)(implicit p: Parameters) extends FPUModule()(p) {
mem_reg_valid || mem_cp_valid || // MEM stage
wb_reg_valid || wb_cp_valid || // WB stage
wen.orR || divSqrt_inFlight || // post-WB stage
- io.dmem_resp_val // load writeback
+ io.ll_resp_val // load writeback
} // leaving gated-clock domain
val fpuImpl = withClock (gated_clock) { new FPUImpl }
diff --git a/src/main/scala/tile/Interrupts.scala b/src/main/scala/tile/Interrupts.scala
index 1efdde5983c..6ae4da3d5d2 100644
--- a/src/main/scala/tile/Interrupts.scala
+++ b/src/main/scala/tile/Interrupts.scala
@@ -3,11 +3,16 @@
package freechips.rocketchip.tile
import chisel3._
-import chisel3.util.{RegEnable, log2Ceil}
-import org.chipsalliance.cde.config.Parameters
-import freechips.rocketchip.diplomacy._
-import freechips.rocketchip.interrupts._
-import freechips.rocketchip.util._
+import chisel3.util._
+import org.chipsalliance.cde.config._
+import org.chipsalliance.diplomacy._
+
+import freechips.rocketchip.resources.{Device, DeviceSnippet, Description, ResourceBinding, ResourceInt}
+import freechips.rocketchip.interrupts.{IntIdentityNode, IntSinkNode, IntSinkPortSimple, IntSourceNode, IntSourcePortSimple}
+import freechips.rocketchip.util.CanHaveErrors
+
+import freechips.rocketchip.resources.{IntToProperty, StringToProperty}
+import freechips.rocketchip.util.BooleanToAugmentedBoolean
class NMI(val w: Int) extends Bundle {
val rnmi = Bool()
diff --git a/src/main/scala/tile/LazyRoCC.scala b/src/main/scala/tile/LazyRoCC.scala
index c0218d00312..3b869b9aca4 100644
--- a/src/main/scala/tile/LazyRoCC.scala
+++ b/src/main/scala/tile/LazyRoCC.scala
@@ -5,12 +5,18 @@ package freechips.rocketchip.tile
import chisel3._
import chisel3.util._
-import chisel3.util.HasBlackBoxResource
import chisel3.experimental.IntParam
+
import org.chipsalliance.cde.config._
-import freechips.rocketchip.diplomacy._
-import freechips.rocketchip.rocket._
-import freechips.rocketchip.tilelink._
+import org.chipsalliance.diplomacy.lazymodule._
+
+import freechips.rocketchip.rocket.{
+ MStatus, HellaCacheIO, TLBPTWIO, CanHavePTW, CanHavePTWModule,
+ SimpleHellaCacheIF, M_XRD, PTE, PRV, M_SZ
+}
+import freechips.rocketchip.tilelink.{
+ TLNode, TLIdentityNode, TLClientNode, TLMasterParameters, TLMasterPortParameters
+}
import freechips.rocketchip.util.InOrderArbiter
case object BuildRoCC extends Field[Seq[Parameters => LazyRoCC]](Nil)
@@ -65,6 +71,7 @@ abstract class LazyRoCC(
require(roccCSRs.map(_.id).toSet.size == roccCSRs.size)
val atlNode: TLNode = TLIdentityNode()
val tlNode: TLNode = TLIdentityNode()
+ val stlNode: TLNode = TLIdentityNode()
}
class LazyRoCCModuleImp(outer: LazyRoCC) extends LazyModuleImp(outer) {
@@ -81,13 +88,14 @@ trait HasLazyRoCC extends CanHavePTW { this: BaseTile =>
"LazyRoCC instantiations require overlapping CSRs")
roccs.map(_.atlNode).foreach { atl => tlMasterXbar.node :=* atl }
roccs.map(_.tlNode).foreach { tl => tlOtherMastersNode :=* tl }
+ roccs.map(_.stlNode).foreach { stl => stl :*= tlSlaveXbar.node }
nPTWPorts += roccs.map(_.nPTWPorts).sum
nDCachePorts += roccs.size
}
trait HasLazyRoCCModule extends CanHavePTWModule
- with HasCoreParameters { this: RocketTileModuleImp with HasFpuOpt =>
+ with HasCoreParameters { this: RocketTileModuleImp =>
val (respArb, cmdRouter) = if(outer.roccs.nonEmpty) {
val respArb = Module(new RRArbiter(new RoCCResponse()(outer.p), outer.roccs.size))
@@ -100,23 +108,6 @@ trait HasLazyRoCCModule extends CanHavePTWModule
dcachePorts += dcIF.io.cache
respArb.io.in(i) <> Queue(rocc.module.io.resp)
}
-
- fpuOpt foreach { fpu =>
- val nFPUPorts = outer.roccs.count(_.usesFPU)
- if (usingFPU && nFPUPorts > 0) {
- val fpArb = Module(new InOrderArbiter(new FPInput()(outer.p), new FPResult()(outer.p), nFPUPorts))
- val fp_rocc_ios = outer.roccs.filter(_.usesFPU).map(_.module.io)
- fpArb.io.in_req <> fp_rocc_ios.map(_.fpu_req)
- fp_rocc_ios.zip(fpArb.io.in_resp).foreach {
- case (rocc, arb) => rocc.fpu_resp <> arb
- }
- fpu.io.cp_req <> fpArb.io.out_req
- fpArb.io.out_resp <> fpu.io.cp_resp
- } else {
- fpu.io.cp_req.valid := false.B
- fpu.io.cp_resp.ready := false.B
- }
- }
(Some(respArb), Some(cmdRouter))
} else {
(None, None)
@@ -193,6 +184,7 @@ class AccumulatorExampleModuleImp(outer: AccumulatorExample)(implicit p: Paramet
io.mem.req.bits.phys := false.B
io.mem.req.bits.dprv := cmd.bits.status.dprv
io.mem.req.bits.dv := cmd.bits.status.dv
+ io.mem.req.bits.no_resp := false.B
}
class TranslatorExample(opcodes: OpcodeSet)(implicit p: Parameters) extends LazyRoCC(opcodes, nPTWPorts = 1) {
diff --git a/src/main/scala/tile/LookupByHartId.scala b/src/main/scala/tile/LookupByHartId.scala
index 263dd43c66f..631bb8f651e 100644
--- a/src/main/scala/tile/LookupByHartId.scala
+++ b/src/main/scala/tile/LookupByHartId.scala
@@ -10,10 +10,10 @@ abstract class LookupByHartIdImpl {
}
case class HartsWontDeduplicate(t: TileParams) extends LookupByHartIdImpl {
- def apply[T <: Data](f: TileParams => Option[T], hartId: UInt): T = f(t).get
+ def apply[T <: Data](f: TileParams => Option[T], tileId: UInt): T = f(t).get
}
case class PriorityMuxHartIdFromSeq(seq: Seq[TileParams]) extends LookupByHartIdImpl {
- def apply[T <: Data](f: TileParams => Option[T], hartId: UInt): T =
- PriorityMux(seq.collect { case t if f(t).isDefined => (t.hartId.U === hartId) -> f(t).get })
+ def apply[T <: Data](f: TileParams => Option[T], tileId: UInt): T =
+ PriorityMux(seq.collect { case t if f(t).isDefined => (t.tileId.U === tileId) -> f(t).get })
}
diff --git a/src/main/scala/tile/RocketTile.scala b/src/main/scala/tile/RocketTile.scala
index 930d803e392..619e7d836ca 100644
--- a/src/main/scala/tile/RocketTile.scala
+++ b/src/main/scala/tile/RocketTile.scala
@@ -4,15 +4,29 @@
package freechips.rocketchip.tile
import chisel3._
+
import org.chipsalliance.cde.config._
-import freechips.rocketchip.devices.tilelink._
-import freechips.rocketchip.diplomacy._
-import freechips.rocketchip.interrupts._
-import freechips.rocketchip.tilelink._
-import freechips.rocketchip.rocket._
-import freechips.rocketchip.subsystem.TileCrossingParamsLike
-import freechips.rocketchip.util._
-import freechips.rocketchip.prci.{ClockSinkParameters}
+import org.chipsalliance.diplomacy.lazymodule._
+
+import freechips.rocketchip.devices.tilelink.{BasicBusBlockerParams, BasicBusBlocker}
+import freechips.rocketchip.diplomacy.{
+ AddressSet, DisableMonitors, BufferParams
+}
+import freechips.rocketchip.resources.{
+ SimpleDevice, Description,
+ ResourceAnchors, ResourceBindings, ResourceBinding, Resource, ResourceAddress,
+}
+import freechips.rocketchip.interrupts.IntIdentityNode
+import freechips.rocketchip.tilelink.{TLIdentityNode, TLBuffer}
+import freechips.rocketchip.rocket.{
+ RocketCoreParams, ICacheParams, DCacheParams, BTBParams, HasHellaCache,
+ HasICacheFrontend, ScratchpadSlavePort, HasICacheFrontendModule, Rocket
+}
+import freechips.rocketchip.subsystem.HierarchicalElementCrossingParamsLike
+import freechips.rocketchip.prci.{ClockSinkParameters, RationalCrossing, ClockCrossingType}
+import freechips.rocketchip.util.{Annotated, InOrderArbiter}
+
+import freechips.rocketchip.util.BooleanToAugmentedBoolean
case class RocketTileBoundaryBufferParams(force: Boolean = false)
@@ -22,16 +36,17 @@ case class RocketTileParams(
dcache: Option[DCacheParams] = Some(DCacheParams()),
btb: Option[BTBParams] = Some(BTBParams()),
dataScratchpadBytes: Int = 0,
- name: Option[String] = Some("tile"),
- hartId: Int = 0,
+ tileId: Int = 0,
beuAddr: Option[BigInt] = None,
blockerCtrlAddr: Option[BigInt] = None,
clockSinkParams: ClockSinkParameters = ClockSinkParameters(),
boundaryBuffers: Option[RocketTileBoundaryBufferParams] = None
- ) extends InstantiableTileParams[RocketTile] {
+ ) extends InstantiableTileParams[RocketTile] {
require(icache.isDefined)
require(dcache.isDefined)
- def instantiate(crossing: TileCrossingParamsLike, lookup: LookupByHartIdImpl)(implicit p: Parameters): RocketTile = {
+ val baseName = "rockettile"
+ val uniqueName = s"${baseName}_$tileId"
+ def instantiate(crossing: HierarchicalElementCrossingParamsLike, lookup: LookupByHartIdImpl)(implicit p: Parameters): RocketTile = {
new RocketTile(this, crossing, lookup)
}
}
@@ -49,10 +64,10 @@ class RocketTile private(
with HasICacheFrontend
{
// Private constructor ensures altered LazyModule.p is used implicitly
- def this(params: RocketTileParams, crossing: TileCrossingParamsLike, lookup: LookupByHartIdImpl)(implicit p: Parameters) =
+ def this(params: RocketTileParams, crossing: HierarchicalElementCrossingParamsLike, lookup: LookupByHartIdImpl)(implicit p: Parameters) =
this(params, crossing.crossingType, lookup, p)
- val intOutwardNode = IntIdentityNode()
+ val intOutwardNode = rocketParams.beuAddr map { _ => IntIdentityNode() }
val slaveNode = TLIdentityNode()
val masterNode = visibilityNode
@@ -62,8 +77,8 @@ class RocketTile private(
dtim_adapter.foreach(lm => connectTLSlave(lm.node, lm.node.portParams.head.beatBytes))
val bus_error_unit = rocketParams.beuAddr map { a =>
- val beu = LazyModule(new BusErrorUnit(new L1BusErrors, BusErrorUnitParams(a)))
- intOutwardNode := beu.intNode
+ val beu = LazyModule(new BusErrorUnit(new L1BusErrors, BusErrorUnitParams(a), xLen/8))
+ intOutwardNode.get := beu.intNode
connectTLSlave(beu.node, xBytes)
beu
}
@@ -80,7 +95,7 @@ class RocketTile private(
masterNode :=* tlOtherMastersNode
DisableMonitors { implicit p => tlSlaveXbar.node :*= slaveNode }
- nDCachePorts += 1 /*core */ + (dtim_adapter.isDefined).toInt
+ nDCachePorts += 1 /*core */ + (dtim_adapter.isDefined).toInt + rocketParams.core.vector.map(_.useDCache.toInt).getOrElse(0)
val dtimProperty = dtim_adapter.map(d => Map(
"sifive,dtim" -> d.device.asProperty)).getOrElse(Nil)
@@ -99,8 +114,13 @@ class RocketTile private(
}
}
+ val vector_unit = rocketParams.core.vector.map(v => LazyModule(v.build(p)))
+ vector_unit.foreach(vu => tlMasterXbar.node :=* vu.atlNode)
+ vector_unit.foreach(vu => tlOtherMastersNode :=* vu.tlNode)
+
+
ResourceBinding {
- Resource(cpuDevice, "reg").bind(ResourceAddress(staticIdForMetadataUseOnly))
+ Resource(cpuDevice, "reg").bind(ResourceAddress(tileId))
}
override lazy val module = new RocketTileModuleImp(this)
@@ -125,6 +145,10 @@ class RocketTileModuleImp(outer: RocketTile) extends BaseTileModuleImp(outer)
Annotated.params(this, outer.rocketParams)
val core = Module(new Rocket(outer)(outer.p))
+ outer.vector_unit.foreach { v =>
+ core.io.vector.get <> v.module.io.core
+ v.module.io.tlb <> outer.dcache.module.io.tlb_port
+ }
// reset vector is connected in the Frontend to s2_pc
core.io.reset_vector := DontCare
@@ -149,7 +173,7 @@ class RocketTileModuleImp(outer: RocketTile) extends BaseTileModuleImp(outer)
beu.module.io.errors.icache := outer.frontend.module.io.errors
}
- core.io.interrupts.nmi.foreach { nmi => nmi := outer.nmiSinkNode.bundle }
+ core.io.interrupts.nmi.foreach { nmi => nmi := outer.nmiSinkNode.get.bundle }
// Pass through various external constants and reports that were bundle-bridged into the tile
outer.traceSourceNode.bundle <> core.io.trace
@@ -164,12 +188,15 @@ class RocketTileModuleImp(outer: RocketTile) extends BaseTileModuleImp(outer)
dcachePorts += core.io.dmem // TODO outer.dcachePorts += () => module.core.io.dmem ??
fpuOpt foreach { fpu =>
core.io.fpu :<>= fpu.io.waiveAs[FPUCoreIO](_.cp_req, _.cp_resp)
- fpu.io.cp_req := DontCare
- fpu.io.cp_resp := DontCare
}
if (fpuOpt.isEmpty) {
core.io.fpu := DontCare
}
+ outer.vector_unit foreach { v => if (outer.rocketParams.core.vector.get.useDCache) {
+ dcachePorts += v.module.io.dmem
+ } else {
+ v.module.io.dmem := DontCare
+ } }
core.io.ptw <> ptw.io.dpath
// Connect the coprocessor interfaces
@@ -213,4 +240,27 @@ class RocketTileModuleImp(outer: RocketTile) extends BaseTileModuleImp(outer)
trait HasFpuOpt { this: RocketTileModuleImp =>
val fpuOpt = outer.tileParams.core.fpu.map(params => Module(new FPU(params)(outer.p)))
+ fpuOpt.foreach { fpu =>
+ val nRoCCFPUPorts = outer.roccs.count(_.usesFPU)
+ val nFPUPorts = nRoCCFPUPorts + outer.rocketParams.core.useVector.toInt
+ if (nFPUPorts > 0) {
+ val fpArb = Module(new InOrderArbiter(new FPInput()(outer.p), new FPResult()(outer.p), nFPUPorts))
+ fpu.io.cp_req <> fpArb.io.out_req
+ fpArb.io.out_resp <> fpu.io.cp_resp
+
+ val fp_rocc_ios = outer.roccs.filter(_.usesFPU).map(_.module.io)
+ for (i <- 0 until nRoCCFPUPorts) {
+ fpArb.io.in_req(i) <> fp_rocc_ios(i).fpu_req
+ fp_rocc_ios(i).fpu_resp <> fpArb.io.in_resp(i)
+ }
+ outer.vector_unit.foreach(vu => {
+ fpArb.io.in_req(nRoCCFPUPorts) <> vu.module.io.fp_req
+ vu.module.io.fp_resp <> fpArb.io.in_resp(nRoCCFPUPorts)
+ })
+ } else {
+ fpu.io.cp_req.valid := false.B
+ fpu.io.cp_req.bits := DontCare
+ fpu.io.cp_resp.ready := false.B
+ }
+ }
}
diff --git a/src/main/scala/tile/TilePRCIDomain.scala b/src/main/scala/tile/TilePRCIDomain.scala
index 73972bec4de..80c31f5a4d7 100644
--- a/src/main/scala/tile/TilePRCIDomain.scala
+++ b/src/main/scala/tile/TilePRCIDomain.scala
@@ -2,30 +2,15 @@
package freechips.rocketchip.tile
-import chisel3.Vec
-import org.chipsalliance.cde.config.Parameters
-import freechips.rocketchip.diplomacy._
-import freechips.rocketchip.interrupts._
-import freechips.rocketchip.prci._
-import freechips.rocketchip.rocket.{TracedInstruction}
-import freechips.rocketchip.subsystem.{TileCrossingParamsLike, CrossesToOnlyOneResetDomain}
-import freechips.rocketchip.tilelink._
-import freechips.rocketchip.util.{TraceCoreInterface}
+import chisel3._
+
+import org.chipsalliance.cde.config._
+
+import freechips.rocketchip.prci.ClockSinkParameters
+import freechips.rocketchip.rocket.TracedInstruction
+import freechips.rocketchip.subsystem.{HierarchicalElementCrossingParamsLike, HierarchicalElementPRCIDomain}
+import freechips.rocketchip.util.TraceCoreInterface
-/** A wrapper containing all logic within a managed reset domain for a tile.
- *
- * This does not add a layer of the module hierarchy.
- */
-class TileResetDomain(clockSinkParams: ClockSinkParameters, resetCrossingType: ResetCrossingType)
- (implicit p: Parameters)
- extends ResetDomain
- with CrossesToOnlyOneResetDomain
-{
- def crossing = resetCrossingType
- val clockNode = ClockSinkNode(Seq(clockSinkParams))
- def clockBundle = clockNode.in.head._1
- override def shouldBeInlined = true
-}
/** A wrapper containing all logic necessary to safely place a tile
* inside of a particular Power/Reset/Clock/Interrupt domain.
@@ -37,77 +22,9 @@ class TileResetDomain(clockSinkParams: ClockSinkParameters, resetCrossingType: R
*/
abstract class TilePRCIDomain[T <: BaseTile](
clockSinkParams: ClockSinkParameters,
- crossingParams: TileCrossingParamsLike)
+ crossingParams: HierarchicalElementCrossingParamsLike)
(implicit p: Parameters)
- extends ClockDomain
+ extends HierarchicalElementPRCIDomain[T](clockSinkParams, crossingParams)
{
- val tile: T
- val tile_reset_domain = LazyModule(new TileResetDomain(clockSinkParams, crossingParams.resetCrossingType))
- val tapClockNode = ClockIdentityNode()
- val clockNode = FixedClockBroadcast(None) :=* tapClockNode
- lazy val clockBundle = tapClockNode.in.head._1
-
- private val traceSignalName = "trace"
- private val traceCoreSignalName = "tracecore"
- /** Node to broadcast legacy "raw" instruction trace while surpressing it during (async) reset. */
- val traceNode: BundleBridgeIdentityNode[TraceBundle] = BundleBridgeNameNode(traceSignalName)
- /** Node to broadcast standardized instruction trace while surpressing it during (async) reset. */
- val traceCoreNode: BundleBridgeIdentityNode[TraceCoreInterface] = BundleBridgeNameNode(traceCoreSignalName)
-
- /** Function to handle all trace crossings when tile is instantiated inside domains */
- def crossTracesOut(): Unit = this {
- val traceNexusNode = BundleBridgeBlockDuringReset[TraceBundle](
- resetCrossingType = crossingParams.resetCrossingType,
- name = Some(traceSignalName))
- traceNode :*= traceNexusNode := tile.traceNode
-
- val traceCoreNexusNode = BundleBridgeBlockDuringReset[TraceCoreInterface](
- resetCrossingType = crossingParams.resetCrossingType,
- name = Some(traceCoreSignalName))
- traceCoreNode :*= traceCoreNexusNode := tile.traceCoreNode
- }
-
- /** External code looking to connect and clock-cross the interrupts driven into this tile can call this. */
- def crossIntIn(crossingType: ClockCrossingType): IntInwardNode = {
- // Unlike the other crossing helpers, here nothing is is blocked during reset because we know these are inputs and assume that tile reset is longer than uncore reset
- val intInClockXing = this.crossIn(tile.intInwardNode)
- intInClockXing(crossingType)
- }
-
- /** External code looking to connect and clock/reset-cross
- * - interrupts raised by devices inside this tile
- * - notifications raise by the cores and caches
- * can call this function to instantiate the required crossing hardware.
- * Takes crossingType as an argument because some interrupts are supposed to be synchronous
- * Takes tileNode as an argument because tiles might have multiple outbound interrupt nodes
- */
- def crossIntOut(crossingType: ClockCrossingType, tileNode: IntOutwardNode): IntOutwardNode = {
- val intOutResetXing = this { tile_reset_domain.crossIntOut(tileNode) }
- val intOutClockXing = this.crossOut(intOutResetXing)
- intOutClockXing(crossingType)
- }
-
- /** External code looking to connect the ports where this tile is slaved to an interconnect
- * (while also crossing clock domains) can call this.
- */
- def crossSlavePort(crossingType: ClockCrossingType): TLInwardNode = { DisableMonitors { implicit p => FlipRendering { implicit p =>
- val tlSlaveResetXing = this {
- tile_reset_domain.crossTLIn(tile.slaveNode) :*=
- tile { tile.makeSlaveBoundaryBuffers(crossingType) }
- }
- val tlSlaveClockXing = this.crossIn(tlSlaveResetXing)
- tlSlaveClockXing(crossingType)
- } } }
-
- /** External code looking to connect the ports where this tile masters an interconnect
- * (while also crossing clock domains) can call this.
- */
- def crossMasterPort(crossingType: ClockCrossingType): TLOutwardNode = {
- val tlMasterResetXing = this { DisableMonitors { implicit p =>
- tile { tile.makeMasterBoundaryBuffers(crossingType) } :=*
- tile_reset_domain.crossTLOut(tile.masterNode)
- } }
- val tlMasterClockXing = this.crossOut(tlMasterResetXing)
- tlMasterClockXing(crossingType)
- }
+ def tile_reset_domain = element_reset_domain
}
diff --git a/src/main/scala/tilelink/AddressAdjuster.scala b/src/main/scala/tilelink/AddressAdjuster.scala
index d4a1fc7bbf1..c9de5710ed2 100644
--- a/src/main/scala/tilelink/AddressAdjuster.scala
+++ b/src/main/scala/tilelink/AddressAdjuster.scala
@@ -4,8 +4,12 @@ package freechips.rocketchip.tilelink
import chisel3._
import chisel3.util._
+
import org.chipsalliance.cde.config._
-import freechips.rocketchip.diplomacy._
+import org.chipsalliance.diplomacy.bundlebridge._
+import org.chipsalliance.diplomacy.lazymodule._
+
+import freechips.rocketchip.diplomacy.AddressSet
class AddressAdjuster(
val params: ReplicatedRegion, // only devices in this region get adjusted
diff --git a/src/main/scala/tilelink/AsyncCrossing.scala b/src/main/scala/tilelink/AsyncCrossing.scala
index f974cf3e270..3eb96dd3c74 100644
--- a/src/main/scala/tilelink/AsyncCrossing.scala
+++ b/src/main/scala/tilelink/AsyncCrossing.scala
@@ -3,11 +3,14 @@
package freechips.rocketchip.tilelink
import chisel3._
-import org.chipsalliance.cde.config.Parameters
-import freechips.rocketchip.diplomacy._
+
+import org.chipsalliance.cde.config._
+import org.chipsalliance.diplomacy.lazymodule._
+
+import freechips.rocketchip.diplomacy.{AddressSet, NodeHandle}
+import freechips.rocketchip.prci.{AsynchronousCrossing}
import freechips.rocketchip.subsystem.CrossingWrapper
-import freechips.rocketchip.util._
-import freechips.rocketchip.util.property
+import freechips.rocketchip.util.{AsyncQueueParams, ToAsyncBundle, FromAsyncBundle, Pow2ClockDivider, property}
class TLAsyncCrossingSource(sync: Option[Int])(implicit p: Parameters) extends LazyModule
{
@@ -18,6 +21,7 @@ class TLAsyncCrossingSource(sync: Option[Int])(implicit p: Parameters) extends L
lazy val module = new Impl
class Impl extends LazyModuleImp(this) {
+ override def desiredName = (Seq("TLAsyncCrossingSource") ++ node.in.headOption.map(_._2.bundle.shortName)).mkString("_")
(node.in zip node.out) foreach { case ((in, edgeIn), (out, edgeOut)) =>
val bce = edgeIn.manager.anySupportAcquireB && edgeIn.client.anySupportProbe
val psync = sync.getOrElse(edgeOut.manager.async.sync)
@@ -53,6 +57,7 @@ class TLAsyncCrossingSink(params: AsyncQueueParams = AsyncQueueParams())(implici
lazy val module = new Impl
class Impl extends LazyModuleImp(this) {
+ override def desiredName = (Seq("TLAsyncCrossingSink") ++ node.out.headOption.map(_._2.bundle.shortName)).mkString("_")
(node.in zip node.out) foreach { case ((in, edgeIn), (out, edgeOut)) =>
val bce = edgeOut.manager.anySupportAcquireB && edgeOut.client.anySupportProbe
diff --git a/src/main/scala/tilelink/AtomicAutomata.scala b/src/main/scala/tilelink/AtomicAutomata.scala
index 3bf633db0fb..5f0fc655fdc 100644
--- a/src/main/scala/tilelink/AtomicAutomata.scala
+++ b/src/main/scala/tilelink/AtomicAutomata.scala
@@ -3,11 +3,15 @@
package freechips.rocketchip.tilelink
import chisel3._
-import org.chipsalliance.cde.config.Parameters
-import freechips.rocketchip.diplomacy._
-import freechips.rocketchip.util._
+import chisel3.util._
+
+import org.chipsalliance.cde.config._
+import org.chipsalliance.diplomacy.lazymodule._
+
+import freechips.rocketchip.diplomacy.{AddressSet, TransferSizes}
+import freechips.rocketchip.util.leftOR
+
import scala.math.{min,max}
-import chisel3.util.{PriorityMux, Cat, FillInterleaved, Mux1H, MuxLookup, log2Up}
// Ensures that all downstream RW managers support Atomic operations.
// If !passthrough, intercept all Atomics. Otherwise, only intercept those unsupported downstream.
@@ -178,7 +182,7 @@ class TLAtomicAutomata(logical: Boolean = true, arithmetic: Boolean = true, conc
when (en) {
r.fifoId := a_fifoId
r.bits := in.a.bits
- r.lut := MuxLookup(in.a.bits.param(1, 0), 0.U(4.W), Array(
+ r.lut := MuxLookup(in.a.bits.param(1, 0), 0.U(4.W))(Array(
TLAtomics.AND -> 0x8.U,
TLAtomics.OR -> 0xe.U,
TLAtomics.XOR -> 0x6.U,
@@ -280,9 +284,11 @@ class TLAtomicAutomata(logical: Boolean = true, arithmetic: Boolean = true, conc
object TLAtomicAutomata
{
- def apply(logical: Boolean = true, arithmetic: Boolean = true, concurrency: Int = 1, passthrough: Boolean = true)(implicit p: Parameters): TLNode =
+ def apply(logical: Boolean = true, arithmetic: Boolean = true, concurrency: Int = 1, passthrough: Boolean = true, nameSuffix: Option[String] = None)(implicit p: Parameters): TLNode =
{
- val atomics = LazyModule(new TLAtomicAutomata(logical, arithmetic, concurrency, passthrough))
+ val atomics = LazyModule(new TLAtomicAutomata(logical, arithmetic, concurrency, passthrough) {
+ override lazy val desiredName = (Seq("TLAtomicAutomata") ++ nameSuffix).mkString("_")
+ })
atomics.node
}
diff --git a/src/main/scala/tilelink/BankBinder.scala b/src/main/scala/tilelink/BankBinder.scala
index 8859123754d..21b32729a3d 100644
--- a/src/main/scala/tilelink/BankBinder.scala
+++ b/src/main/scala/tilelink/BankBinder.scala
@@ -2,8 +2,11 @@
package freechips.rocketchip.tilelink
-import org.chipsalliance.cde.config.Parameters
-import freechips.rocketchip.diplomacy._
+import org.chipsalliance.cde.config._
+import org.chipsalliance.diplomacy._
+import org.chipsalliance.diplomacy.lazymodule._
+
+import freechips.rocketchip.diplomacy.{AddressSet, TransferSizes}
case class BankBinderNode(mask: BigInt)(implicit valName: ValName) extends TLCustomNode
{
diff --git a/src/main/scala/tilelink/BlockDuringReset.scala b/src/main/scala/tilelink/BlockDuringReset.scala
index ec676b6fff4..4dc6b2c29ce 100644
--- a/src/main/scala/tilelink/BlockDuringReset.scala
+++ b/src/main/scala/tilelink/BlockDuringReset.scala
@@ -3,8 +3,10 @@
package freechips.rocketchip.tilelink
import chisel3._
-import org.chipsalliance.cde.config.Parameters
-import freechips.rocketchip.diplomacy._
+
+import org.chipsalliance.cde.config._
+import org.chipsalliance.diplomacy.lazymodule._
+
import freechips.rocketchip.util.BlockDuringReset
/** BlockDuringReset ensures that no channel admits to be ready or valid while reset is raised. */
diff --git a/src/main/scala/tilelink/Broadcast.scala b/src/main/scala/tilelink/Broadcast.scala
index 0e69bd5d60f..f73cdb97cd0 100644
--- a/src/main/scala/tilelink/Broadcast.scala
+++ b/src/main/scala/tilelink/Broadcast.scala
@@ -4,12 +4,19 @@ package freechips.rocketchip.tilelink
import chisel3._
import chisel3.util._
-import org.chipsalliance.cde.config.Parameters
-import freechips.rocketchip.diplomacy._
-import freechips.rocketchip.regmapper._
-import freechips.rocketchip.interrupts._
-import freechips.rocketchip.util._
+
+import org.chipsalliance.cde.config._
+import org.chipsalliance.diplomacy.lazymodule._
+
import freechips.rocketchip.amba.AMBAProt
+import freechips.rocketchip.diplomacy.{AddressDecoder, AddressSet, IdRange, RegionType, TransferSizes}
+import freechips.rocketchip.resources.{SimpleDevice}
+import freechips.rocketchip.regmapper.RegField
+import freechips.rocketchip.interrupts.{IntSourceNode, IntSourcePortSimple}
+import freechips.rocketchip.util.leftOR
+
+import freechips.rocketchip.util.DataToAugmentedData
+
import scala.math.{min,max}
case class TLBroadcastControlParams(
diff --git a/src/main/scala/tilelink/Buffer.scala b/src/main/scala/tilelink/Buffer.scala
index 8f43017028c..63fd8ed917f 100644
--- a/src/main/scala/tilelink/Buffer.scala
+++ b/src/main/scala/tilelink/Buffer.scala
@@ -3,8 +3,12 @@
package freechips.rocketchip.tilelink
import chisel3._
-import org.chipsalliance.cde.config.Parameters
-import freechips.rocketchip.diplomacy._
+
+import org.chipsalliance.cde.config._
+import org.chipsalliance.diplomacy._
+import org.chipsalliance.diplomacy.lazymodule._
+
+import freechips.rocketchip.diplomacy.BufferParams
class TLBufferNode (
a: BufferParams,
@@ -34,6 +38,8 @@ class TLBuffer(
lazy val module = new Impl
class Impl extends LazyModuleImp(this) {
+ def headBundle = node.out.head._2.bundle
+ override def desiredName = (Seq("TLBuffer") ++ node.out.headOption.map(_._2.bundle.shortName)).mkString("_")
(node.in zip node.out) foreach { case ((in, edgeIn), (out, edgeOut)) =>
out.a <> a(in .a)
in .d <> d(out.d)
diff --git a/src/main/scala/tilelink/Bundles.scala b/src/main/scala/tilelink/Bundles.scala
index 5bb53dfe429..735e0839af8 100644
--- a/src/main/scala/tilelink/Bundles.scala
+++ b/src/main/scala/tilelink/Bundles.scala
@@ -173,6 +173,7 @@ sealed trait TLAddrChannel extends TLDataChannel
final class TLBundleA(params: TLBundleParameters)
extends TLBundleBase(params) with TLAddrChannel
{
+ override def typeName = s"TLBundleA_${params.shortName}"
val channelName = "'A' channel"
// fixed fields during multibeat:
val opcode = UInt(3.W)
@@ -190,6 +191,7 @@ final class TLBundleA(params: TLBundleParameters)
final class TLBundleB(params: TLBundleParameters)
extends TLBundleBase(params) with TLAddrChannel
{
+ override def typeName = s"TLBundleB_${params.shortName}"
val channelName = "'B' channel"
// fixed fields during multibeat:
val opcode = UInt(3.W)
@@ -206,6 +208,7 @@ final class TLBundleB(params: TLBundleParameters)
final class TLBundleC(params: TLBundleParameters)
extends TLBundleBase(params) with TLAddrChannel
{
+ override def typeName = s"TLBundleC_${params.shortName}"
val channelName = "'C' channel"
// fixed fields during multibeat:
val opcode = UInt(3.W)
@@ -223,6 +226,7 @@ final class TLBundleC(params: TLBundleParameters)
final class TLBundleD(params: TLBundleParameters)
extends TLBundleBase(params) with TLDataChannel
{
+ override def typeName = s"TLBundleD_${params.shortName}"
val channelName = "'D' channel"
// fixed fields during multibeat:
val opcode = UInt(3.W)
@@ -241,6 +245,7 @@ final class TLBundleD(params: TLBundleParameters)
final class TLBundleE(params: TLBundleParameters)
extends TLBundleBase(params) with TLChannel
{
+ override def typeName = s"TLBundleE_${params.shortName}"
val channelName = "'E' channel"
val sink = UInt(params.sinkBits.W) // to
}
diff --git a/src/main/scala/tilelink/BusWrapper.scala b/src/main/scala/tilelink/BusWrapper.scala
index 657bba873f6..c95a572de1e 100644
--- a/src/main/scala/tilelink/BusWrapper.scala
+++ b/src/main/scala/tilelink/BusWrapper.scala
@@ -4,15 +4,28 @@ package freechips.rocketchip.tilelink
import chisel3._
import chisel3.util._
-import org.chipsalliance.cde.config.Parameters
-import freechips.rocketchip.diplomacy._
+
+import org.chipsalliance.cde.config._
+import org.chipsalliance.diplomacy._
+import org.chipsalliance.diplomacy.bundlebridge._
+import org.chipsalliance.diplomacy.lazymodule._
+import org.chipsalliance.diplomacy.nodes._
+
+import freechips.rocketchip.diplomacy.{AddressSet, NoHandle, NodeHandle, NodeBinding}
// TODO This class should be moved to package subsystem to resolve
// the dependency awkwardness of the following imports
-import freechips.rocketchip.devices.tilelink._
-import freechips.rocketchip.prci._
-import freechips.rocketchip.subsystem._
-import freechips.rocketchip.util._
+import freechips.rocketchip.devices.tilelink.{BuiltInDevices, CanHaveBuiltInDevices}
+import freechips.rocketchip.prci.{
+ ClockParameters, ClockDomain, ClockGroup, ClockGroupAggregator, ClockSinkNode,
+ FixedClockBroadcast, ClockGroupEdgeParameters, ClockSinkParameters, ClockSinkDomain,
+ ClockGroupEphemeralNode, asyncMux, ClockCrossingType, NoCrossing
+}
+import freechips.rocketchip.subsystem.{
+ HasTileLinkLocations, CanConnectWithinContextThatHasTileLinkLocations,
+ CanInstantiateWithinContextThatHasTileLinkLocations
+}
+import freechips.rocketchip.util.Location
/** Specifies widths of various attachement points in the SoC */
trait HasTLBusParams {
@@ -72,15 +85,21 @@ abstract class TLBusWrapper(params: HasTLBusParams, val busName: String)(implici
def unifyManagers: List[TLManagerParameters] = ManagerUnification(busView.manager.managers)
def crossOutHelper = this.crossOut(outwardNode)(ValName("bus_xing"))
def crossInHelper = this.crossIn(inwardNode)(ValName("bus_xing"))
+ def generateSynchronousDomain(domainName: String): ClockSinkDomain = {
+ val domain = LazyModule(new ClockSinkDomain(take = fixedClockOpt, name = Some(domainName)))
+ domain.clockNode := fixedClockNode
+ domain
+ }
+ def generateSynchronousDomain: ClockSinkDomain = generateSynchronousDomain("")
protected val addressPrefixNexusNode = BundleBroadcast[UInt](registered = false, default = Some(() => 0.U(1.W)))
def to[T](name: String)(body: => T): T = {
- this { LazyScope(s"coupler_to_${name}", "TLInterconnectCoupler") { body } }
+ this { LazyScope(s"coupler_to_${name}", s"TLInterconnectCoupler_${busName}_to_${name}") { body } }
}
def from[T](name: String)(body: => T): T = {
- this { LazyScope(s"coupler_from_${name}", "TLInterconnectCoupler") { body } }
+ this { LazyScope(s"coupler_from_${name}", s"TLInterconnectCoupler_${busName}_from_${name}") { body } }
}
def coupleTo[T](name: String)(gen: TLOutwardNode => T): T =
@@ -89,15 +108,15 @@ abstract class TLBusWrapper(params: HasTLBusParams, val busName: String)(implici
def coupleFrom[T](name: String)(gen: TLInwardNode => T): T =
from(name) { gen(inwardNode :*=* TLNameNode("tl")) }
- def crossToBus(bus: TLBusWrapper, xType: ClockCrossingType)(implicit asyncClockGroupNode: ClockGroupEphemeralNode): NoHandle = {
- bus.clockGroupNode := asyncMux(xType, asyncClockGroupNode, this.clockGroupNode)
+ def crossToBus(bus: TLBusWrapper, xType: ClockCrossingType, allClockGroupNode: ClockGroupEphemeralNode): NoHandle = {
+ bus.clockGroupNode := asyncMux(xType, allClockGroupNode, this.clockGroupNode)
coupleTo(s"bus_named_${bus.busName}") {
bus.crossInHelper(xType) :*= TLWidthWidget(beatBytes) :*= _
}
}
- def crossFromBus(bus: TLBusWrapper, xType: ClockCrossingType)(implicit asyncClockGroupNode: ClockGroupEphemeralNode): NoHandle = {
- bus.clockGroupNode := asyncMux(xType, asyncClockGroupNode, this.clockGroupNode)
+ def crossFromBus(bus: TLBusWrapper, xType: ClockCrossingType, allClockGroupNode: ClockGroupEphemeralNode): NoHandle = {
+ bus.clockGroupNode := asyncMux(xType, allClockGroupNode, this.clockGroupNode)
coupleFrom(s"bus_named_${bus.busName}") {
_ :=* TLWidthWidget(bus.beatBytes) :=* bus.crossOutHelper(xType)
}
@@ -178,8 +197,8 @@ class TLBusWrapperConnection
val masterTLBus = context.locateTLBusWrapper(master)
val slaveTLBus = context.locateTLBusWrapper(slave)
def bindClocks(implicit p: Parameters) = driveClockFromMaster match {
- case Some(true) => slaveTLBus.clockGroupNode := asyncMux(xType, context.asyncClockGroupsNode, masterTLBus.clockGroupNode)
- case Some(false) => masterTLBus.clockGroupNode := asyncMux(xType, context.asyncClockGroupsNode, slaveTLBus.clockGroupNode)
+ case Some(true) => slaveTLBus.clockGroupNode := asyncMux(xType, context.allClockGroupsNode, masterTLBus.clockGroupNode)
+ case Some(false) => masterTLBus.clockGroupNode := asyncMux(xType, context.allClockGroupsNode, slaveTLBus.clockGroupNode)
case None =>
}
def bindTLNodes(implicit p: Parameters) = nodeBinding match {
@@ -218,7 +237,7 @@ class TLBusWrapperTopology(
}
trait HasTLXbarPhy { this: TLBusWrapper =>
- private val xbar = LazyModule(new TLXbar).suggestName(busName + "_xbar")
+ private val xbar = LazyModule(new TLXbar(nameSuffix = Some(busName))).suggestName(busName + "_xbar")
override def shouldBeInlined = xbar.node.circuitIdentity
def inwardNode: TLInwardNode = xbar.node
@@ -240,8 +259,8 @@ case class AddressAdjusterWrapperParams(
{
val dtsFrequency = None
def instantiate(context: HasTileLinkLocations, loc: Location[TLBusWrapper])(implicit p: Parameters): AddressAdjusterWrapper = {
- val aaWrapper = LazyModule(new AddressAdjusterWrapper(this, loc.name))
- aaWrapper.suggestName(loc.name + "_wrapper")
+ val aaWrapper = LazyModule(new AddressAdjusterWrapper(this, context.busContextName + "_" + loc.name))
+ aaWrapper.suggestName(context.busContextName + "_" + loc.name + "_wrapper")
context.tlBusWrapperLocationMap += (loc -> aaWrapper)
aaWrapper
}
@@ -270,8 +289,8 @@ case class TLJBarWrapperParams(
{
val dtsFrequency = None
def instantiate(context: HasTileLinkLocations, loc: Location[TLBusWrapper])(implicit p: Parameters): TLJBarWrapper = {
- val jbarWrapper = LazyModule(new TLJBarWrapper(this, loc.name))
- jbarWrapper.suggestName(loc.name + "_wrapper")
+ val jbarWrapper = LazyModule(new TLJBarWrapper(this, context.busContextName + "_" + loc.name))
+ jbarWrapper.suggestName(context.busContextName + "_" + loc.name + "_wrapper")
context.tlBusWrapperLocationMap += (loc -> jbarWrapper)
jbarWrapper
}
diff --git a/src/main/scala/tilelink/CacheCork.scala b/src/main/scala/tilelink/CacheCork.scala
index 8ba1e4b9d7f..a8518d97dee 100644
--- a/src/main/scala/tilelink/CacheCork.scala
+++ b/src/main/scala/tilelink/CacheCork.scala
@@ -4,10 +4,18 @@ package freechips.rocketchip.tilelink
import chisel3._
import chisel3.util._
-import org.chipsalliance.cde.config.Parameters
-import freechips.rocketchip.diplomacy._
-import freechips.rocketchip.util._
-import TLMessages._
+
+import org.chipsalliance.cde.config._
+import org.chipsalliance.diplomacy.lazymodule._
+
+import freechips.rocketchip.diplomacy.{IdRange, RegionType, TransferSizes}
+import freechips.rocketchip.tilelink.TLMessages.{
+ AcquireBlock, AcquirePerm, Get, PutFullData, PutPartialData, Release,
+ ReleaseData, Grant, GrantData, AccessAck, AccessAckData, ReleaseAck
+}
+import freechips.rocketchip.util.IDPool
+
+import freechips.rocketchip.util.DataToAugmentedData
case class TLCacheCorkParams(
unsafe: Boolean = false,
diff --git a/src/main/scala/tilelink/Credited.scala b/src/main/scala/tilelink/Credited.scala
index 30c73486012..e8a1085f273 100644
--- a/src/main/scala/tilelink/Credited.scala
+++ b/src/main/scala/tilelink/Credited.scala
@@ -3,11 +3,15 @@
package freechips.rocketchip.tilelink
import chisel3._
-import chisel3.util.Decoupled
-import org.chipsalliance.cde.config.Parameters
-import freechips.rocketchip.diplomacy._
+import chisel3.util._
+
+import org.chipsalliance.cde.config._
+import org.chipsalliance.diplomacy.lazymodule._
+
+import freechips.rocketchip.diplomacy.{AddressSet}
+import freechips.rocketchip.prci.{CreditedCrossing}
import freechips.rocketchip.subsystem.CrossingWrapper
-import freechips.rocketchip.util._
+import freechips.rocketchip.util.{CreditedDelay, CreditedIO}
class TLCreditedBuffer(delay: TLCreditedDelay)(implicit p: Parameters) extends LazyModule
{
diff --git a/src/main/scala/tilelink/CrossingHelper.scala b/src/main/scala/tilelink/CrossingHelper.scala
index 52d96d6f432..fd4bd2e74ce 100644
--- a/src/main/scala/tilelink/CrossingHelper.scala
+++ b/src/main/scala/tilelink/CrossingHelper.scala
@@ -2,9 +2,13 @@
package freechips.rocketchip.tilelink
-import org.chipsalliance.cde.config.Parameters
-import freechips.rocketchip.diplomacy._
-import freechips.rocketchip.prci._
+import org.chipsalliance.cde.config._
+import org.chipsalliance.diplomacy.lazymodule._
+
+import freechips.rocketchip.prci.{
+ AsynchronousCrossing, CrossingType, ClockCrossingType, NoCrossing,
+ RationalCrossing, CreditedCrossing, SynchronousCrossing,
+ ResetCrossingType, NoResetCrossing, StretchedResetCrossing}
trait TLOutwardCrossingHelper {
type HelperCrossingType <: CrossingType
diff --git a/src/main/scala/tilelink/Delayer.scala b/src/main/scala/tilelink/Delayer.scala
index eb70bc5e4d5..bb984787938 100644
--- a/src/main/scala/tilelink/Delayer.scala
+++ b/src/main/scala/tilelink/Delayer.scala
@@ -4,8 +4,9 @@ package freechips.rocketchip.tilelink
import chisel3._
import chisel3.util._
-import org.chipsalliance.cde.config.Parameters
-import freechips.rocketchip.diplomacy._
+
+import org.chipsalliance.cde.config._
+import org.chipsalliance.diplomacy.lazymodule._
// q is the probability to delay a request
class TLDelayer(q: Double)(implicit p: Parameters) extends LazyModule
@@ -30,6 +31,8 @@ class TLDelayer(q: Double)(implicit p: Parameters) extends LazyModule
anoise.size := LFSRNoiseMaker(anoise.params.sizeBits)
anoise.source := LFSRNoiseMaker(anoise.params.sourceBits)
anoise.address := LFSRNoiseMaker(anoise.params.addressBits)
+ anoise.user := DontCare
+ anoise.echo := DontCare
anoise.mask := LFSRNoiseMaker(anoise.params.dataBits/8)
anoise.data := LFSRNoiseMaker(anoise.params.dataBits)
anoise.corrupt := LFSRNoiseMaker(1)
@@ -50,6 +53,8 @@ class TLDelayer(q: Double)(implicit p: Parameters) extends LazyModule
cnoise.size := LFSRNoiseMaker(cnoise.params.sizeBits)
cnoise.source := LFSRNoiseMaker(cnoise.params.sourceBits)
cnoise.address := LFSRNoiseMaker(cnoise.params.addressBits)
+ cnoise.user := DontCare
+ cnoise.echo := DontCare
cnoise.data := LFSRNoiseMaker(cnoise.params.dataBits)
cnoise.corrupt := LFSRNoiseMaker(1)(0)
@@ -60,6 +65,8 @@ class TLDelayer(q: Double)(implicit p: Parameters) extends LazyModule
dnoise.source := LFSRNoiseMaker(dnoise.params.sourceBits)
dnoise.sink := LFSRNoiseMaker(dnoise.params.sinkBits)
dnoise.denied := LFSRNoiseMaker(1)(0)
+ dnoise.user := DontCare
+ dnoise.echo := DontCare
dnoise.data := LFSRNoiseMaker(dnoise.params.dataBits)
dnoise.corrupt := LFSRNoiseMaker(1)(0)
diff --git a/src/main/scala/tilelink/Edges.scala b/src/main/scala/tilelink/Edges.scala
index 2c555c03ac2..ef56eb733c6 100644
--- a/src/main/scala/tilelink/Edges.scala
+++ b/src/main/scala/tilelink/Edges.scala
@@ -4,7 +4,6 @@ package freechips.rocketchip.tilelink
import chisel3._
import chisel3.util._
-import chisel3.internal.sourceinfo.SourceInfo
import chisel3.experimental.SourceInfo
import org.chipsalliance.cde.config.Parameters
import freechips.rocketchip.util._
@@ -274,17 +273,17 @@ class TLEdge(
// Does the request need T permissions to be executed?
def needT(a: TLBundleA): Bool = {
- val acq_needT = MuxLookup(a.param, WireDefault(Bool(), DontCare), Array(
+ val acq_needT = MuxLookup(a.param, WireDefault(Bool(), DontCare))(Array(
TLPermissions.NtoB -> false.B,
TLPermissions.NtoT -> true.B,
TLPermissions.BtoT -> true.B))
- MuxLookup(a.opcode, WireDefault(Bool(), DontCare), Array(
+ MuxLookup(a.opcode, WireDefault(Bool(), DontCare))(Array(
TLMessages.PutFullData -> true.B,
TLMessages.PutPartialData -> true.B,
TLMessages.ArithmeticData -> true.B,
TLMessages.LogicalData -> true.B,
TLMessages.Get -> false.B,
- TLMessages.Hint -> MuxLookup(a.param, WireDefault(Bool(), DontCare), Array(
+ TLMessages.Hint -> MuxLookup(a.param, WireDefault(Bool(), DontCare))(Array(
TLHints.PREFETCH_READ -> false.B,
TLHints.PREFETCH_WRITE -> true.B)),
TLMessages.AcquireBlock -> acq_needT,
@@ -345,14 +344,15 @@ class TLEdgeOut(
require (manager.anySupportAcquireB, s"TileLink: No managers visible from this edge support Acquires, but one of these clients would try to request one: ${client.clients}")
val legal = manager.supportsAcquireBFast(toAddress, lgSize)
val a = Wire(new TLBundleA(bundle))
- a :#= DontCare
a.opcode := TLMessages.AcquireBlock
a.param := growPermissions
a.size := lgSize
a.source := fromSource
a.address := toAddress
+ a.user := DontCare
+ a.echo := DontCare
a.mask := mask(toAddress, lgSize)
- a.data := 0.U
+ a.data := DontCare
a.corrupt := false.B
(legal, a)
}
@@ -366,8 +366,10 @@ class TLEdgeOut(
a.size := lgSize
a.source := fromSource
a.address := toAddress
+ a.user := DontCare
+ a.echo := DontCare
a.mask := mask(toAddress, lgSize)
- a.data := 0.U
+ a.data := DontCare
a.corrupt := false.B
(legal, a)
}
@@ -376,13 +378,14 @@ class TLEdgeOut(
require (manager.anySupportAcquireB, s"TileLink: No managers visible from this edge support Acquires, but one of these clients would try to request one: ${client.clients}")
val legal = manager.supportsAcquireBFast(toAddress, lgSize)
val c = Wire(new TLBundleC(bundle))
- c :#= DontCare
c.opcode := TLMessages.Release
c.param := shrinkPermissions
c.size := lgSize
c.source := fromSource
c.address := toAddress
- c.data := 0.U
+ c.user := DontCare
+ c.echo := DontCare
+ c.data := DontCare
c.corrupt := false.B
(legal, c)
}
@@ -391,12 +394,13 @@ class TLEdgeOut(
require (manager.anySupportAcquireB, s"TileLink: No managers visible from this edge support Acquires, but one of these clients would try to request one: ${client.clients}")
val legal = manager.supportsAcquireBFast(toAddress, lgSize)
val c = Wire(new TLBundleC(bundle))
- c :#= DontCare
c.opcode := TLMessages.ReleaseData
c.param := shrinkPermissions
c.size := lgSize
c.source := fromSource
c.address := toAddress
+ c.user := DontCare
+ c.echo := DontCare
c.data := data
c.corrupt := corrupt
(legal, c)
@@ -410,13 +414,14 @@ class TLEdgeOut(
def ProbeAck(fromSource: UInt, toAddress: UInt, lgSize: UInt, reportPermissions: UInt): TLBundleC = {
val c = Wire(new TLBundleC(bundle))
- c :#= DontCare
c.opcode := TLMessages.ProbeAck
c.param := reportPermissions
c.size := lgSize
c.source := fromSource
c.address := toAddress
- c.data := 0.U
+ c.user := DontCare
+ c.echo := DontCare
+ c.data := DontCare
c.corrupt := false.B
c
}
@@ -426,12 +431,13 @@ class TLEdgeOut(
def ProbeAck(fromSource: UInt, toAddress: UInt, lgSize: UInt, reportPermissions: UInt, data: UInt, corrupt: Bool): TLBundleC = {
val c = Wire(new TLBundleC(bundle))
- c :#= DontCare
c.opcode := TLMessages.ProbeAckData
c.param := reportPermissions
c.size := lgSize
c.source := fromSource
c.address := toAddress
+ c.user := DontCare
+ c.echo := DontCare
c.data := data
c.corrupt := corrupt
c
@@ -452,14 +458,15 @@ class TLEdgeOut(
require (manager.anySupportGet, s"TileLink: No managers visible from this edge support Gets, but one of these clients would try to request one: ${client.clients}")
val legal = manager.supportsGetFast(toAddress, lgSize)
val a = Wire(new TLBundleA(bundle))
- a :#= DontCare
a.opcode := TLMessages.Get
a.param := 0.U
a.size := lgSize
a.source := fromSource
a.address := toAddress
+ a.user := DontCare
+ a.echo := DontCare
a.mask := mask(toAddress, lgSize)
- a.data := 0.U
+ a.data := DontCare
a.corrupt := false.B
(legal, a)
}
@@ -471,12 +478,13 @@ class TLEdgeOut(
require (manager.anySupportPutFull, s"TileLink: No managers visible from this edge support Puts, but one of these clients would try to request one: ${client.clients}")
val legal = manager.supportsPutFullFast(toAddress, lgSize)
val a = Wire(new TLBundleA(bundle))
- a :#= DontCare
a.opcode := TLMessages.PutFullData
a.param := 0.U
a.size := lgSize
a.source := fromSource
a.address := toAddress
+ a.user := DontCare
+ a.echo := DontCare
a.mask := mask(toAddress, lgSize)
a.data := data
a.corrupt := corrupt
@@ -490,12 +498,13 @@ class TLEdgeOut(
require (manager.anySupportPutPartial, s"TileLink: No managers visible from this edge support masked Puts, but one of these clients would try to request one: ${client.clients}")
val legal = manager.supportsPutPartialFast(toAddress, lgSize)
val a = Wire(new TLBundleA(bundle))
- a :#= DontCare
a.opcode := TLMessages.PutPartialData
a.param := 0.U
a.size := lgSize
a.source := fromSource
a.address := toAddress
+ a.user := DontCare
+ a.echo := DontCare
a.mask := mask
a.data := data
a.corrupt := corrupt
@@ -506,12 +515,13 @@ class TLEdgeOut(
require (manager.anySupportArithmetic, s"TileLink: No managers visible from this edge support arithmetic AMOs, but one of these clients would try to request one: ${client.clients}")
val legal = manager.supportsArithmeticFast(toAddress, lgSize)
val a = Wire(new TLBundleA(bundle))
- a :#= DontCare
a.opcode := TLMessages.ArithmeticData
a.param := atomic
a.size := lgSize
a.source := fromSource
a.address := toAddress
+ a.user := DontCare
+ a.echo := DontCare
a.mask := mask(toAddress, lgSize)
a.data := data
a.corrupt := corrupt
@@ -522,12 +532,13 @@ class TLEdgeOut(
require (manager.anySupportLogical, s"TileLink: No managers visible from this edge support logical AMOs, but one of these clients would try to request one: ${client.clients}")
val legal = manager.supportsLogicalFast(toAddress, lgSize)
val a = Wire(new TLBundleA(bundle))
- a :#= DontCare
a.opcode := TLMessages.LogicalData
a.param := atomic
a.size := lgSize
a.source := fromSource
a.address := toAddress
+ a.user := DontCare
+ a.echo := DontCare
a.mask := mask(toAddress, lgSize)
a.data := data
a.corrupt := corrupt
@@ -538,14 +549,15 @@ class TLEdgeOut(
require (manager.anySupportHint, s"TileLink: No managers visible from this edge support Hints, but one of these clients would try to request one: ${client.clients}")
val legal = manager.supportsHintFast(toAddress, lgSize)
val a = Wire(new TLBundleA(bundle))
- a :#= DontCare
a.opcode := TLMessages.Hint
a.param := param
a.size := lgSize
a.source := fromSource
a.address := toAddress
+ a.user := DontCare
+ a.echo := DontCare
a.mask := mask(toAddress, lgSize)
- a.data := 0.U
+ a.data := DontCare
a.corrupt := false.B
(legal, a)
}
@@ -553,13 +565,14 @@ class TLEdgeOut(
def AccessAck(b: TLBundleB): TLBundleC = AccessAck(b.source, address(b), b.size)
def AccessAck(fromSource: UInt, toAddress: UInt, lgSize: UInt) = {
val c = Wire(new TLBundleC(bundle))
- c :#= DontCare
c.opcode := TLMessages.AccessAck
c.param := 0.U
c.size := lgSize
c.source := fromSource
c.address := toAddress
- c.data := 0.U
+ c.user := DontCare
+ c.echo := DontCare
+ c.data := DontCare
c.corrupt := false.B
c
}
@@ -569,12 +582,13 @@ class TLEdgeOut(
def AccessAck(fromSource: UInt, toAddress: UInt, lgSize: UInt, data: UInt): TLBundleC = AccessAck(fromSource, toAddress, lgSize, data, false.B)
def AccessAck(fromSource: UInt, toAddress: UInt, lgSize: UInt, data: UInt, corrupt: Bool) = {
val c = Wire(new TLBundleC(bundle))
- c :#= DontCare
c.opcode := TLMessages.AccessAckData
c.param := 0.U
c.size := lgSize
c.source := fromSource
c.address := toAddress
+ c.user := DontCare
+ c.echo := DontCare
c.data := data
c.corrupt := corrupt
c
@@ -583,13 +597,14 @@ class TLEdgeOut(
def HintAck(b: TLBundleB): TLBundleC = HintAck(b.source, address(b), b.size)
def HintAck(fromSource: UInt, toAddress: UInt, lgSize: UInt) = {
val c = Wire(new TLBundleC(bundle))
- c :#= DontCare
c.opcode := TLMessages.HintAck
c.param := 0.U
c.size := lgSize
c.source := fromSource
c.address := toAddress
- c.data := 0.U
+ c.user := DontCare
+ c.echo := DontCare
+ c.data := DontCare
c.corrupt := false.B
c
}
@@ -620,7 +635,7 @@ class TLEdgeIn(
b.source := toSource
b.address := fromAddress
b.mask := mask(fromAddress, lgSize)
- b.data := 0.U
+ b.data := DontCare
b.corrupt := false.B
(legal, b)
}
@@ -634,7 +649,9 @@ class TLEdgeIn(
d.source := toSource
d.sink := fromSink
d.denied := denied
- d.data := 0.U
+ d.user := DontCare
+ d.echo := DontCare
+ d.data := DontCare
d.corrupt := false.B
d
}
@@ -648,6 +665,8 @@ class TLEdgeIn(
d.source := toSource
d.sink := fromSink
d.denied := denied
+ d.user := DontCare
+ d.echo := DontCare
d.data := data
d.corrupt := corrupt
d
@@ -662,7 +681,9 @@ class TLEdgeIn(
d.source := toSource
d.sink := 0.U
d.denied := denied
- d.data := 0.U
+ d.user := DontCare
+ d.echo := DontCare
+ d.data := DontCare
d.corrupt := false.B
d
}
@@ -678,7 +699,7 @@ class TLEdgeIn(
b.source := toSource
b.address := fromAddress
b.mask := mask(fromAddress, lgSize)
- b.data := 0.U
+ b.data := DontCare
b.corrupt := false.B
(legal, b)
}
@@ -759,7 +780,7 @@ class TLEdgeIn(
b.source := toSource
b.address := fromAddress
b.mask := mask(fromAddress, lgSize)
- b.data := 0.U
+ b.data := DontCare
b.corrupt := false.B
(legal, b)
}
@@ -775,7 +796,9 @@ class TLEdgeIn(
d.source := toSource
d.sink := 0.U
d.denied := denied
- d.data := 0.U
+ d.user := DontCare
+ d.echo := DontCare
+ d.data := DontCare
d.corrupt := false.B
d
}
@@ -791,6 +814,8 @@ class TLEdgeIn(
d.source := toSource
d.sink := 0.U
d.denied := denied
+ d.user := DontCare
+ d.echo := DontCare
d.data := data
d.corrupt := corrupt
d
@@ -807,7 +832,9 @@ class TLEdgeIn(
d.source := toSource
d.sink := 0.U
d.denied := denied
- d.data := 0.U
+ d.user := DontCare
+ d.echo := DontCare
+ d.data := DontCare
d.corrupt := false.B
d
}
diff --git a/src/main/scala/tilelink/ErrorEvaluator.scala b/src/main/scala/tilelink/ErrorEvaluator.scala
index 533cae0475f..e8931e9c650 100644
--- a/src/main/scala/tilelink/ErrorEvaluator.scala
+++ b/src/main/scala/tilelink/ErrorEvaluator.scala
@@ -3,9 +3,14 @@
package freechips.rocketchip.tilelink
import chisel3._
-import org.chipsalliance.cde.config.Parameters
-import freechips.rocketchip.diplomacy._
-import freechips.rocketchip.util._
+
+import org.chipsalliance.cde.config._
+import org.chipsalliance.diplomacy.lazymodule._
+
+import freechips.rocketchip.diplomacy.AddressSet
+import freechips.rocketchip.util.UIntToOH1
+
+import freechips.rocketchip.util.DataToAugmentedData
// Check if a request satisfies some interesting property
class RequestPattern(test: TLBundleA => Bool)
diff --git a/src/main/scala/tilelink/FIFOFixer.scala b/src/main/scala/tilelink/FIFOFixer.scala
index 6aaff7ad641..efa0e966b46 100644
--- a/src/main/scala/tilelink/FIFOFixer.scala
+++ b/src/main/scala/tilelink/FIFOFixer.scala
@@ -4,8 +4,12 @@ package freechips.rocketchip.tilelink
import chisel3._
import chisel3.util._
+
import org.chipsalliance.cde.config.Parameters
-import freechips.rocketchip.diplomacy._
+import org.chipsalliance.diplomacy.lazymodule._
+import org.chipsalliance.diplomacy.nodes._
+
+import freechips.rocketchip.diplomacy.RegionType
import freechips.rocketchip.util.property
class TLFIFOFixer(policy: TLFIFOFixer.Policy = TLFIFOFixer.all)(implicit p: Parameters) extends LazyModule
@@ -33,12 +37,14 @@ class TLFIFOFixer(policy: TLFIFOFixer.Policy = TLFIFOFixer.all)(implicit p: Para
(fixMap, splatMap)
}
- val node = TLAdapterNode(
- clientFn = { cp => cp },
- managerFn = { mp =>
+ val node = new AdapterNode(TLImp)(
+ { cp => cp },
+ { mp =>
val (fixMap, _) = fifoMap(mp.managers)
mp.v1copy(managers = (fixMap zip mp.managers) map { case (id, m) => m.v1copy(fifoId = id) })
- })
+ }) with TLFormatNode {
+ override def circuitIdentity = edges.in.map(_.client.clients.filter(c => c.requestFifo && c.sourceId.size > 1).size).sum == 0
+ }
lazy val module = new Impl
class Impl extends LazyModuleImp(this) {
diff --git a/src/main/scala/tilelink/Filter.scala b/src/main/scala/tilelink/Filter.scala
index fcc59dc5eb5..cd6ab212d2a 100644
--- a/src/main/scala/tilelink/Filter.scala
+++ b/src/main/scala/tilelink/Filter.scala
@@ -3,8 +3,11 @@
package freechips.rocketchip.tilelink
import chisel3._
-import org.chipsalliance.cde.config.Parameters
-import freechips.rocketchip.diplomacy._
+
+import org.chipsalliance.cde.config._
+import org.chipsalliance.diplomacy.lazymodule._
+
+import freechips.rocketchip.diplomacy.{AddressSet, RegionType, TransferSizes}
class TLFilter(
mfilter: TLFilter.ManagerFilter = TLFilter.mIdentity,
diff --git a/src/main/scala/tilelink/Fragmenter.scala b/src/main/scala/tilelink/Fragmenter.scala
index 0aace162b46..68eae711aa2 100644
--- a/src/main/scala/tilelink/Fragmenter.scala
+++ b/src/main/scala/tilelink/Fragmenter.scala
@@ -4,11 +4,18 @@ package freechips.rocketchip.tilelink
import chisel3._
import chisel3.util._
-import org.chipsalliance.cde.config.Parameters
-import freechips.rocketchip.diplomacy._
-import freechips.rocketchip.util._
+
+import org.chipsalliance.cde.config._
+import org.chipsalliance.diplomacy._
+import org.chipsalliance.diplomacy.lazymodule._
+
+import freechips.rocketchip.diplomacy.{AddressSet, BufferParams, IdRange, TransferSizes}
+import freechips.rocketchip.util.{Repeater, OH1ToUInt, UIntToOH1}
+
import scala.math.min
+import freechips.rocketchip.util.DataToAugmentedData
+
object EarlyAck {
sealed trait T
case object AllPuts extends T
@@ -21,10 +28,11 @@ object EarlyAck {
// alwaysMin: fragment all requests down to minSize (else fragment to maximum supported by manager)
// earlyAck: should a multibeat Put should be acknowledged on the first beat or last beat
// holdFirstDeny: allow the Fragmenter to unsafely combine multibeat Gets by taking the first denied for the whole burst
+// nameSuffix: appends a suffix to the module name
// Fragmenter modifies: PutFull, PutPartial, LogicalData, Get, Hint
// Fragmenter passes: ArithmeticData (truncated to minSize if alwaysMin)
// Fragmenter cannot modify acquire (could livelock); thus it is unsafe to put caches on both sides
-class TLFragmenter(val minSize: Int, val maxSize: Int, val alwaysMin: Boolean = false, val earlyAck: EarlyAck.T = EarlyAck.None, val holdFirstDeny: Boolean = false)(implicit p: Parameters) extends LazyModule
+class TLFragmenter(val minSize: Int, val maxSize: Int, val alwaysMin: Boolean = false, val earlyAck: EarlyAck.T = EarlyAck.None, val holdFirstDeny: Boolean = false, val nameSuffix: Option[String] = None)(implicit p: Parameters) extends LazyModule
{
require(isPow2 (maxSize), s"TLFragmenter expects pow2(maxSize), but got $maxSize")
require(isPow2 (minSize), s"TLFragmenter expects pow2(minSize), but got $minSize")
@@ -82,6 +90,7 @@ class TLFragmenter(val minSize: Int, val maxSize: Int, val alwaysMin: Boolean =
lazy val module = new Impl
class Impl extends LazyModuleImp(this) {
+ override def desiredName = (Seq("TLFragmenter") ++ nameSuffix).mkString("_")
(node.in zip node.out) foreach { case ((in, edgeIn), (out, edgeOut)) =>
if (noChangeRequired) {
out <> in
@@ -92,8 +101,9 @@ class TLFragmenter(val minSize: Int, val maxSize: Int, val alwaysMin: Boolean =
val beatBytes = manager.beatBytes
val fifoId = managers(0).fifoId
require (fifoId.isDefined && managers.map(_.fifoId == fifoId).reduce(_ && _))
- require (!manager.anySupportAcquireB)
-
+ require (!manager.anySupportAcquireB || !edgeOut.client.anySupportProbe,
+ s"TLFragmenter (with parent $parent) can't fragment a caching client's requests into a cacheable region")
+
require (minSize >= beatBytes, s"TLFragmenter (with parent $parent) can't support fragmenting ($minSize) to sub-beat ($beatBytes) accesses")
// We can't support devices which are cached on both sides of us
require (!edgeOut.manager.anySupportAcquireB || !edgeIn.client.anySupportProbe)
@@ -275,7 +285,7 @@ class TLFragmenter(val minSize: Int, val maxSize: Int, val alwaysMin: Boolean =
val maxLgHint = Mux1H(find, maxLgHints)
val limit = if (alwaysMin) lgMinSize else
- MuxLookup(in_a.bits.opcode, lgMinSize, Array(
+ MuxLookup(in_a.bits.opcode, lgMinSize)(Array(
TLMessages.PutFullData -> maxLgPutFull,
TLMessages.PutPartialData -> maxLgPutPartial,
TLMessages.ArithmeticData -> maxLgArithmetic,
@@ -329,15 +339,17 @@ class TLFragmenter(val minSize: Int, val maxSize: Int, val alwaysMin: Boolean =
object TLFragmenter
{
- def apply(minSize: Int, maxSize: Int, alwaysMin: Boolean = false, earlyAck: EarlyAck.T = EarlyAck.None, holdFirstDeny: Boolean = false)(implicit p: Parameters): TLNode =
+ def apply(minSize: Int, maxSize: Int, alwaysMin: Boolean = false, earlyAck: EarlyAck.T = EarlyAck.None, holdFirstDeny: Boolean = false, nameSuffix: Option[String] = None)(implicit p: Parameters): TLNode =
{
if (minSize <= maxSize) {
- val fragmenter = LazyModule(new TLFragmenter(minSize, maxSize, alwaysMin, earlyAck, holdFirstDeny))
+ val fragmenter = LazyModule(new TLFragmenter(minSize, maxSize, alwaysMin, earlyAck, holdFirstDeny, nameSuffix))
fragmenter.node
} else { TLEphemeralNode()(ValName("no_fragmenter")) }
}
- def apply(wrapper: TLBusWrapper)(implicit p: Parameters): TLNode = apply(wrapper.beatBytes, wrapper.blockBytes)
+ def apply(wrapper: TLBusWrapper, nameSuffix: Option[String])(implicit p: Parameters): TLNode = apply(wrapper.beatBytes, wrapper.blockBytes, nameSuffix = nameSuffix)
+
+ def apply(wrapper: TLBusWrapper)(implicit p: Parameters): TLNode = apply(wrapper, None)
}
// Synthesizable unit tests
diff --git a/src/main/scala/tilelink/Fuzzer.scala b/src/main/scala/tilelink/Fuzzer.scala
index 1b3ed7fee7e..0dbf21fc831 100644
--- a/src/main/scala/tilelink/Fuzzer.scala
+++ b/src/main/scala/tilelink/Fuzzer.scala
@@ -4,9 +4,14 @@ package freechips.rocketchip.tilelink
import chisel3._
import chisel3.util._
-import org.chipsalliance.cde.config.Parameters
-import freechips.rocketchip.diplomacy._
-import freechips.rocketchip.util._
+
+import org.chipsalliance.cde.config._
+import org.chipsalliance.diplomacy.lazymodule._
+
+import freechips.rocketchip.diplomacy.{AddressSet, IdRange}
+import freechips.rocketchip.util.{leftOR, UIntToOH1}
+
+import freechips.rocketchip.util.DataToAugmentedData
class IDMapGenerator(numIds: Int) extends Module {
require (numIds > 0)
@@ -180,7 +185,7 @@ class TLFuzzer(
// Pick a specific message to try to send
val a_type_sel = noiseMaker(3, inc, 0)
- val legal = legal_dest && MuxLookup(a_type_sel, glegal, Seq(
+ val legal = legal_dest && MuxLookup(a_type_sel, glegal)(Seq(
"b000".U -> glegal,
"b001".U -> (pflegal && !noModify.B),
"b010".U -> (pplegal && !noModify.B),
@@ -188,7 +193,7 @@ class TLFuzzer(
"b100".U -> (llegal && !noModify.B),
"b101".U -> hlegal))
- val bits = MuxLookup(a_type_sel, gbits, Seq(
+ val bits = MuxLookup(a_type_sel, gbits)(Seq(
"b000".U -> gbits,
"b001".U -> pfbits,
"b010".U -> ppbits,
diff --git a/src/main/scala/tilelink/HintHandler.scala b/src/main/scala/tilelink/HintHandler.scala
index 3b581a84621..982a1461d81 100644
--- a/src/main/scala/tilelink/HintHandler.scala
+++ b/src/main/scala/tilelink/HintHandler.scala
@@ -3,9 +3,12 @@
package freechips.rocketchip.tilelink
import chisel3._
-import org.chipsalliance.cde.config.Parameters
-import freechips.rocketchip.diplomacy._
-import freechips.rocketchip.util._
+
+import org.chipsalliance.cde.config._
+import org.chipsalliance.diplomacy.lazymodule._
+
+import freechips.rocketchip.diplomacy.{AddressSet, RegionType, IdRange, TransferSizes}
+import freechips.rocketchip.util.Repeater
import freechips.rocketchip.devices.tilelink.TLROM
// Acks Hints for managers that don't support them or Acks all Hints if !passthrough
diff --git a/src/main/scala/tilelink/Isolation.scala b/src/main/scala/tilelink/Isolation.scala
index 44154313c4c..90ebe4dd07a 100644
--- a/src/main/scala/tilelink/Isolation.scala
+++ b/src/main/scala/tilelink/Isolation.scala
@@ -3,8 +3,10 @@
package freechips.rocketchip.tilelink
import chisel3._
-import org.chipsalliance.cde.config.Parameters
-import freechips.rocketchip.diplomacy._
+
+import org.chipsalliance.cde.config._
+import org.chipsalliance.diplomacy.lazymodule._
+
import freechips.rocketchip.util.AsyncBundle
// READ the comments in the TLIsolation object before you instantiate this module
diff --git a/src/main/scala/tilelink/Jbar.scala b/src/main/scala/tilelink/Jbar.scala
index c4ce2396fdc..084af313489 100644
--- a/src/main/scala/tilelink/Jbar.scala
+++ b/src/main/scala/tilelink/Jbar.scala
@@ -3,8 +3,11 @@
package freechips.rocketchip.tilelink
import chisel3._
+
import org.chipsalliance.cde.config._
-import freechips.rocketchip.diplomacy._
+import org.chipsalliance.diplomacy.lazymodule._
+
+import freechips.rocketchip.diplomacy.AddressSet
class TLJbar(policy: TLArbiter.Policy = TLArbiter.roundRobin)(implicit p: Parameters) extends LazyModule
{
diff --git a/src/main/scala/tilelink/Map.scala b/src/main/scala/tilelink/Map.scala
index a37bb04f5bc..b3578c05a0f 100644
--- a/src/main/scala/tilelink/Map.scala
+++ b/src/main/scala/tilelink/Map.scala
@@ -3,8 +3,11 @@
package freechips.rocketchip.tilelink
import chisel3._
-import org.chipsalliance.cde.config.Parameters
-import freechips.rocketchip.diplomacy._
+
+import org.chipsalliance.cde.config._
+import org.chipsalliance.diplomacy.lazymodule._
+
+import freechips.rocketchip.diplomacy.AddressSet
// Moves the AddressSets of slave devices around
// Combine with TLFilter to remove slaves or reduce their size
diff --git a/src/main/scala/tilelink/Metadata.scala b/src/main/scala/tilelink/Metadata.scala
index cbd0d8c509d..7f4f2854c7e 100644
--- a/src/main/scala/tilelink/Metadata.scala
+++ b/src/main/scala/tilelink/Metadata.scala
@@ -81,7 +81,7 @@ class ClientMetadata extends Bundle {
import ClientStates._
val c = categorize(cmd)
//assert(c === rd || param === toT, "Client was expecting trunk permissions.")
- MuxLookup(Cat(c, param), Nothing, Seq(
+ MuxLookup(Cat(c, param), Nothing)(Seq(
//(effect param) -> (next)
Cat(rd, toB) -> Branch,
Cat(rd, toT) -> Trunk,
@@ -137,7 +137,7 @@ class ClientMetadata extends Bundle {
private def cmdToPermCap(cmd: UInt): UInt = {
import MemoryOpCategories._
import TLPermissions._
- MuxLookup(cmd, toN, Seq(
+ MuxLookup(cmd, toN)(Seq(
M_FLUSH -> toN,
M_PRODUCE -> toB,
M_CLEAN -> toT))
diff --git a/src/main/scala/tilelink/Monitor.scala b/src/main/scala/tilelink/Monitor.scala
index f34e388e54c..0c5586cd583 100644
--- a/src/main/scala/tilelink/Monitor.scala
+++ b/src/main/scala/tilelink/Monitor.scala
@@ -5,10 +5,13 @@ package freechips.rocketchip.tilelink
import chisel3._
import chisel3.util._
import chisel3.experimental.SourceLine
-import org.chipsalliance.cde.config.Parameters
-import freechips.rocketchip.diplomacy._
+
+import org.chipsalliance.cde.config._
+import org.chipsalliance.diplomacy._
+
+import freechips.rocketchip.diplomacy.EnableMonitors
+import freechips.rocketchip.formal.{MonitorDirection, IfThen, Property, PropertyClass, TestplanTestType, TLMonitorStrictMode}
import freechips.rocketchip.util.PlusArg
-import freechips.rocketchip.formal._
case class TLMonitorArgs(edge: TLEdge)
@@ -587,7 +590,7 @@ class TLMonitor(args: TLMonitorArgs, monitorDir: MonitorDirection = MonitorDirec
}
if (edge.manager.minLatency > 0) {
- assume(a_set =/= d_clr || !a_set.orR, s"'A' and 'D' concurrent, despite minlatency ${edge.manager.minLatency}" + extra)
+ assume(a_set =/= d_clr || !a_set.orR, s"'A' and 'D' concurrent, despite minlatency > 0" + extra)
}
inflight := (inflight | a_set) & ~d_clr
@@ -608,7 +611,7 @@ class TLMonitor(args: TLMonitorArgs, monitorDir: MonitorDirection = MonitorDirec
val log_a_size_bus_size = log2Ceil(a_size_bus_size)
def size_to_numfullbits(x: UInt): UInt = (1.U << x) - 1.U //convert a number to that many full bits
- val inflight = RegInit(0.U(edge.client.endSourceId.W))
+ val inflight = RegInit(0.U((2 max edge.client.endSourceId).W)) // size up to avoid width error
inflight.suggestName("inflight")
val inflight_opcodes = RegInit(0.U((edge.client.endSourceId << log_a_opcode_bus_size).W))
inflight_opcodes.suggestName("inflight_opcodes")
@@ -629,7 +632,7 @@ class TLMonitor(args: TLMonitorArgs, monitorDir: MonitorDirection = MonitorDirec
val a_sizes_set = WireInit(0.U((edge.client.endSourceId << log_a_size_bus_size).W))
a_sizes_set.suggestName("a_sizes_set")
- val a_opcode_lookup = WireInit(0.U((1 << log_a_opcode_bus_size).W))
+ val a_opcode_lookup = WireInit(0.U((a_opcode_bus_size - 1).W))
a_opcode_lookup.suggestName("a_opcode_lookup")
a_opcode_lookup := ((inflight_opcodes) >> (bundle.d.bits.source << log_a_opcode_bus_size.U) & size_to_numfullbits(1.U << log_a_opcode_bus_size.U)) >> 1.U
@@ -696,7 +699,7 @@ class TLMonitor(args: TLMonitorArgs, monitorDir: MonitorDirection = MonitorDirec
}
if (edge.manager.minLatency > 0) {
- assume(a_set_wo_ready =/= d_clr_wo_ready || !a_set_wo_ready.orR, s"'A' and 'D' concurrent, despite minlatency ${edge.manager.minLatency}" + extra)
+ assume(a_set_wo_ready =/= d_clr_wo_ready || !a_set_wo_ready.orR, s"'A' and 'D' concurrent, despite minlatency > 0" + extra)
}
inflight := (inflight | a_set) & ~d_clr
@@ -720,7 +723,7 @@ class TLMonitor(args: TLMonitorArgs, monitorDir: MonitorDirection = MonitorDirec
val log_c_size_bus_size = log2Ceil(c_size_bus_size)
def size_to_numfullbits(x: UInt): UInt = (1.U << x) - 1.U //convert a number to that many full bits
- val inflight = RegInit(0.U(edge.client.endSourceId.W))
+ val inflight = RegInit(0.U((2 max edge.client.endSourceId).W))
val inflight_opcodes = RegInit(0.U((edge.client.endSourceId << log_c_opcode_bus_size).W))
val inflight_sizes = RegInit(0.U((edge.client.endSourceId << log_c_size_bus_size).W))
inflight.suggestName("inflight")
@@ -804,7 +807,7 @@ class TLMonitor(args: TLMonitorArgs, monitorDir: MonitorDirection = MonitorDirec
if (edge.manager.minLatency > 0) {
when (c_set_wo_ready.orR) {
- assume(c_set_wo_ready =/= d_clr_wo_ready, s"'C' and 'D' concurrent, despite minlatency ${edge.manager.minLatency}" + extra)
+ assume(c_set_wo_ready =/= d_clr_wo_ready, s"'C' and 'D' concurrent, despite minlatency > 0" + extra)
}
}
diff --git a/src/main/scala/tilelink/Nodes.scala b/src/main/scala/tilelink/Nodes.scala
index ddf4cfb0440..6b193f8ec0b 100644
--- a/src/main/scala/tilelink/Nodes.scala
+++ b/src/main/scala/tilelink/Nodes.scala
@@ -4,8 +4,11 @@ package freechips.rocketchip.tilelink
import chisel3._
import chisel3.experimental.SourceInfo
-import org.chipsalliance.cde.config.{Field, Parameters}
-import freechips.rocketchip.diplomacy._
+
+import org.chipsalliance.cde.config._
+import org.chipsalliance.diplomacy._
+import org.chipsalliance.diplomacy.nodes._
+
import freechips.rocketchip.util.{AsyncQueueParams,RationalDirection}
case object TLMonitorBuilder extends Field[TLMonitorArgs => TLMonitorBase](args => new TLMonitor(args))
diff --git a/src/main/scala/tilelink/Parameters.scala b/src/main/scala/tilelink/Parameters.scala
index eb32ea8638a..66748a1bd68 100644
--- a/src/main/scala/tilelink/Parameters.scala
+++ b/src/main/scala/tilelink/Parameters.scala
@@ -5,9 +5,20 @@ package freechips.rocketchip.tilelink
import chisel3._
import chisel3.util._
import chisel3.experimental.SourceInfo
-import org.chipsalliance.cde.config.Parameters
-import freechips.rocketchip.diplomacy._
-import freechips.rocketchip.util._
+
+import org.chipsalliance.cde.config._
+import org.chipsalliance.diplomacy.nodes._
+
+import freechips.rocketchip.diplomacy.{
+ AddressDecoder, AddressSet, BufferParams, DirectedBuffers, IdMap, IdMapEntry,
+ IdRange, RegionType, TransferSizes
+}
+import freechips.rocketchip.resources.{Resource, ResourceAddress, ResourcePermissions}
+import freechips.rocketchip.util.{
+ AsyncQueueParams, BundleField, BundleFieldBase, BundleKeyBase,
+ CreditedDelay, groupByIntoSeq, RationalDirection, SimpleProduct
+}
+
import scala.math.max
//These transfer sizes describe requests issued from masters on the A channel that will be responded by slaves on the D channel
@@ -177,6 +188,7 @@ class TLSlaveParameters private(
// ReleaseAck may NEVER be denied
extends SimpleProduct
{
+ def sortedAddress = address.sorted
override def canEqual(that: Any): Boolean = that.isInstanceOf[TLSlaveParameters]
override def productPrefix = "TLSlaveParameters"
// We intentionally omit nodePath for equality testing / formatting
@@ -516,6 +528,7 @@ class TLSlavePortParameters private(
val responseFields: Seq[BundleFieldBase],
val requestKeys: Seq[BundleKeyBase]) extends SimpleProduct
{
+ def sortedSlaves = slaves.sortBy(_.sortedAddress.head)
override def canEqual(that: Any): Boolean = that.isInstanceOf[TLSlavePortParameters]
override def productPrefix = "TLSlavePortParameters"
def productArity: Int = 6
@@ -596,16 +609,16 @@ class TLSlavePortParameters private(
def find(address: BigInt) = slaves.find(_.address.exists(_.contains(address)))
// The safe version will check the entire address
- def findSafe(address: UInt) = VecInit(slaves.map(_.address.map(_.contains(address)).reduce(_ || _)))
+ def findSafe(address: UInt) = VecInit(sortedSlaves.map(_.address.map(_.contains(address)).reduce(_ || _)))
// The fast version assumes the address is valid (you probably want fastProperty instead of this function)
def findFast(address: UInt) = {
val routingMask = AddressDecoder(slaves.map(_.address))
- VecInit(slaves.map(_.address.map(_.widen(~routingMask)).distinct.map(_.contains(address)).reduce(_ || _)))
+ VecInit(sortedSlaves.map(_.address.map(_.widen(~routingMask)).distinct.map(_.contains(address)).reduce(_ || _)))
}
// Compute the simplest AddressSets that decide a key
def fastPropertyGroup[K](p: TLSlaveParameters => K): Seq[(K, Seq[AddressSet])] = {
- val groups = groupByIntoSeq(slaves.map(m => (p(m), m.address)))( _._1).map { case (k, vs) =>
+ val groups = groupByIntoSeq(sortedSlaves.map(m => (p(m), m.address)))( _._1).map { case (k, vs) =>
k -> vs.flatMap(_._2)
}
val reductionMask = AddressDecoder(groups.map(_._2))
@@ -1299,6 +1312,9 @@ case class TLBundleParameters(
val addrLoBits = log2Up(dataBits/8)
+ // Used to uniquify bus IP names
+ def shortName = s"a${addressBits}d${dataBits}s${sourceBits}k${sinkBits}z${sizeBits}" + (if (hasBCE) "c" else "u")
+
def union(x: TLBundleParameters) =
TLBundleParameters(
max(addressBits, x.addressBits),
diff --git a/src/main/scala/tilelink/PatternPusher.scala b/src/main/scala/tilelink/PatternPusher.scala
index 7276d6ea48b..08e9eaba740 100644
--- a/src/main/scala/tilelink/PatternPusher.scala
+++ b/src/main/scala/tilelink/PatternPusher.scala
@@ -4,9 +4,11 @@ package freechips.rocketchip.tilelink
import chisel3._
import chisel3.util._
-import org.chipsalliance.cde.config.Parameters
-import freechips.rocketchip.diplomacy._
-import freechips.rocketchip.util._
+
+import org.chipsalliance.cde.config._
+import org.chipsalliance.diplomacy.lazymodule._
+
+import freechips.rocketchip.util.DataToAugmentedData
trait Pattern {
def address: BigInt
@@ -73,7 +75,7 @@ class TLPatternPusher(name: String, pattern: Seq[Pattern])(implicit p: Parameter
}
val (plegal, pbits) = pattern.map(_.bits(edgeOut)).unzip
- assert (end || VecInit(plegal)(step), s"Pattern pusher ${name} tried to push an illegal request")
+ assert (end || VecInit(plegal)(step), s"Pattern pusher ${this.name} tried to push an illegal request")
a.valid := io.run && ready && !end && !flight
a.bits := VecInit(pbits)(step)
diff --git a/src/main/scala/tilelink/ProbePicker.scala b/src/main/scala/tilelink/ProbePicker.scala
index 7b902b771c2..abb4e70f583 100644
--- a/src/main/scala/tilelink/ProbePicker.scala
+++ b/src/main/scala/tilelink/ProbePicker.scala
@@ -4,8 +4,11 @@ package freechips.rocketchip.tilelink
import chisel3._
import chisel3.util._
-import org.chipsalliance.cde.config.Parameters
-import freechips.rocketchip.diplomacy._
+
+import org.chipsalliance.cde.config._
+import org.chipsalliance.diplomacy.lazymodule._
+
+import freechips.rocketchip.diplomacy.{AddressSet, IdRange}
/* A ProbePicker is used to unify multiple cache banks into one logical cache */
class ProbePicker(implicit p: Parameters) extends LazyModule
diff --git a/src/main/scala/tilelink/RAMModel.scala b/src/main/scala/tilelink/RAMModel.scala
index 46c02cdd804..4a785242906 100644
--- a/src/main/scala/tilelink/RAMModel.scala
+++ b/src/main/scala/tilelink/RAMModel.scala
@@ -4,9 +4,13 @@ package freechips.rocketchip.tilelink
import chisel3._
import chisel3.util._
-import org.chipsalliance.cde.config.Parameters
-import freechips.rocketchip.diplomacy._
-import freechips.rocketchip.util._
+
+import org.chipsalliance.cde.config._
+import org.chipsalliance.diplomacy.lazymodule._
+
+import freechips.rocketchip.util.{CRC, UIntToOH1}
+
+import freechips.rocketchip.util.DataToAugmentedData
// We detect concurrent puts that put memory into an undefined state.
// put0, put0Ack, put1, put1Ack => ok: defined
diff --git a/src/main/scala/tilelink/RationalCrossing.scala b/src/main/scala/tilelink/RationalCrossing.scala
index e39860e3797..3dd7ad289b9 100644
--- a/src/main/scala/tilelink/RationalCrossing.scala
+++ b/src/main/scala/tilelink/RationalCrossing.scala
@@ -10,9 +10,15 @@
package freechips.rocketchip.tilelink
import chisel3._
-import org.chipsalliance.cde.config.Parameters
-import freechips.rocketchip.diplomacy._
-import freechips.rocketchip.util._
+
+import org.chipsalliance.cde.config._
+import org.chipsalliance.diplomacy.lazymodule._
+
+import freechips.rocketchip.diplomacy.{AddressSet, NodeHandle}
+import freechips.rocketchip.util.{
+ FromRational, ToRational, RationalDirection, Symmetric, FastToSlow, SlowToFast, Pow2ClockDivider, ClockDivider3
+}
+
class TLRationalCrossingSource(implicit p: Parameters) extends LazyModule
{
diff --git a/src/main/scala/tilelink/RegionReplication.scala b/src/main/scala/tilelink/RegionReplication.scala
index 567b120ae71..396f5052562 100644
--- a/src/main/scala/tilelink/RegionReplication.scala
+++ b/src/main/scala/tilelink/RegionReplication.scala
@@ -3,8 +3,12 @@
package freechips.rocketchip.tilelink
import chisel3._
+
import org.chipsalliance.cde.config._
-import freechips.rocketchip.diplomacy._
+import org.chipsalliance.diplomacy.bundlebridge._
+import org.chipsalliance.diplomacy.lazymodule._
+
+import freechips.rocketchip.diplomacy.AddressSet
/* Address inside the 'local' space are replicated to fill the 'remote' space.
*/
diff --git a/src/main/scala/tilelink/RegisterRouter.scala b/src/main/scala/tilelink/RegisterRouter.scala
index 5a76cce107e..f66a018bf23 100644
--- a/src/main/scala/tilelink/RegisterRouter.scala
+++ b/src/main/scala/tilelink/RegisterRouter.scala
@@ -4,11 +4,16 @@ package freechips.rocketchip.tilelink
import chisel3._
import chisel3.util._
-import chisel3.RawModule
-import org.chipsalliance.cde.config.Parameters
-import freechips.rocketchip.diplomacy._
-import freechips.rocketchip.regmapper._
-import freechips.rocketchip.util._
+
+import org.chipsalliance.cde.config._
+import org.chipsalliance.diplomacy._
+import org.chipsalliance.diplomacy.nodes._
+
+import freechips.rocketchip.diplomacy.{AddressSet, TransferSizes}
+import freechips.rocketchip.resources.{Device, Resource, ResourceBindings}
+import freechips.rocketchip.prci.{NoCrossing}
+import freechips.rocketchip.regmapper.{RegField, RegMapper, RegMapperParams, RegMapperInput, RegisterRouter}
+import freechips.rocketchip.util.{BundleField, ControlKey, ElaborationArtefacts, GenRegDescsAnno}
import scala.math.min
@@ -128,66 +133,6 @@ case class TLRegisterNode(
}
}
-@deprecated("Use HasTLControlRegMap+HasInterruptSources traits in place of TLRegisterRouter+TLRegBundle+TLRegModule", "rocket-chip 1.3")
-abstract class TLRegisterRouterBase(devname: String, devcompat: Seq[String], val address: AddressSet, interrupts: Int, concurrency: Int, beatBytes: Int, undefZero: Boolean, executable: Boolean)(implicit p: Parameters) extends LazyModule
-{
- // Allow devices to extend the DTS mapping
- def extraResources(resources: ResourceBindings) = Map[String, Seq[ResourceValue]]()
- val device = new SimpleDevice(devname, devcompat) {
- override def describe(resources: ResourceBindings): Description = {
- val Description(name, mapping) = super.describe(resources)
- Description(name, mapping ++ extraResources(resources))
- }
- }
-
- val node = TLRegisterNode(Seq(address), device, "reg/control", concurrency, beatBytes, undefZero, executable)
- import freechips.rocketchip.interrupts._
- val intnode = IntSourceNode(IntSourcePortSimple(num = interrupts, resources = Seq(Resource(device, "int"))))
-}
-
-@deprecated("TLRegBundleArg is no longer necessary, use IO(...) to make any additional IOs", "rocket-chip 1.3")
-case class TLRegBundleArg()(implicit val p: Parameters)
-
-@deprecated("TLRegBundleBase is no longer necessary, use IO(...) to make any additional IOs", "rocket-chip 1.3")
-class TLRegBundleBase(arg: TLRegBundleArg) extends Bundle
-{
- implicit val p = arg.p
-}
-
-@deprecated("Use HasTLControlRegMap+HasInterruptSources traits in place of TLRegisterRouter+TLRegBundle+TLRegModule", "rocket-chip 1.3")
-class TLRegBundle[P](val params: P, val arg: TLRegBundleArg) extends TLRegBundleBase(arg)
-
-@deprecated("Use HasTLControlRegMap+HasInterruptSources traits in place of TLRegisterRouter+TLRegBundle+TLRegModule", "rocket-chip 1.3")
-class TLRegModule[P, B <: TLRegBundleBase](val params: P, bundleBuilder: => B, router: TLRegisterRouterBase)
- extends LazyModuleImp(router) with HasRegMap
-{
- val io = IO(bundleBuilder)
- val interrupts = if (router.intnode.out.isEmpty) Vec(0, Bool()) else router.intnode.out(0)._1
- val address = router.address
- def regmap(mapping: RegField.Map*) = router.node.regmap(mapping:_*)
-}
-
-@deprecated("Use HasTLControlRegMap+HasInterruptSources traits in place of TLRegisterRouter+TLRegBundle+TLRegModule", "rocket-chip 1.3")
-class TLRegisterRouter[B <: TLRegBundleBase, M <: LazyModuleImp](
- val base: BigInt,
- val devname: String,
- val devcompat: Seq[String],
- val interrupts: Int = 0,
- val size: BigInt = 4096,
- val concurrency: Int = 0,
- val beatBytes: Int = 4,
- val undefZero: Boolean = true,
- val executable: Boolean = false)
- (bundleBuilder: TLRegBundleArg => B)
- (moduleBuilder: (=> B, TLRegisterRouterBase) => M)(implicit p: Parameters)
- extends TLRegisterRouterBase(devname, devcompat, AddressSet(base, size-1), interrupts, concurrency, beatBytes, undefZero, executable)
-{
- require (isPow2(size))
- // require (size >= 4096) ... not absolutely required, but highly recommended
-
- lazy val module = moduleBuilder(bundleBuilder(TLRegBundleArg()), this)
-}
-
/** Mix HasTLControlRegMap into any subclass of RegisterRouter to gain helper functions for attaching a device control register map to TileLink.
* - The intended use case is that controlNode will diplomatically publish a SW-visible device's memory-mapped control registers.
* - Use the clock crossing helper controlXing to externally connect controlNode to a TileLink interconnect.
diff --git a/src/main/scala/tilelink/RegisterRouterTest.scala b/src/main/scala/tilelink/RegisterRouterTest.scala
index 238c8d7a730..d3a64055f69 100644
--- a/src/main/scala/tilelink/RegisterRouterTest.scala
+++ b/src/main/scala/tilelink/RegisterRouterTest.scala
@@ -3,10 +3,12 @@
package freechips.rocketchip.tilelink
import chisel3._
-import org.chipsalliance.cde.config.Parameters
-import freechips.rocketchip.diplomacy._
+
+import org.chipsalliance.cde.config._
+import org.chipsalliance.diplomacy.lazymodule._
+
import freechips.rocketchip.regmapper.{RRTest0, RRTest1}
-import freechips.rocketchip.unittest._
+import freechips.rocketchip.unittest.{UnitTest, UnitTestModule}
class TLRRTest0(address: BigInt)(implicit p: Parameters)
extends RRTest0(address)
diff --git a/src/main/scala/tilelink/SRAM.scala b/src/main/scala/tilelink/SRAM.scala
index f92e142ccaf..6703bac3c37 100644
--- a/src/main/scala/tilelink/SRAM.scala
+++ b/src/main/scala/tilelink/SRAM.scala
@@ -4,10 +4,17 @@ package freechips.rocketchip.tilelink
import chisel3._
import chisel3.util._
-import org.chipsalliance.cde.config.Parameters
-import freechips.rocketchip.diplomacy._
-import freechips.rocketchip.util._
-import freechips.rocketchip.util.property
+
+import org.chipsalliance.cde.config._
+import org.chipsalliance.diplomacy.bundlebridge._
+import org.chipsalliance.diplomacy.lazymodule._
+
+import freechips.rocketchip.diplomacy.{AddressSet, RegionType, TransferSizes}
+import freechips.rocketchip.resources.{Device, DeviceRegName, DiplomaticSRAM, HasJustOneSeqMem}
+import freechips.rocketchip.util.{CanHaveErrors, ECCParams, property, SECDEDCode}
+
+import freechips.rocketchip.util.DataToAugmentedData
+import freechips.rocketchip.util.BooleanToAugmentedBoolean
class TLRAMErrors(val params: ECCParams, val addrBits: Int) extends Bundle with CanHaveErrors {
val correctable = (params.code.canCorrect && params.notifyErrors).option(Valid(UInt(addrBits.W)))
@@ -44,7 +51,7 @@ class TLRAM(
supportsPutFull = TransferSizes(1, beatBytes),
supportsArithmetic = if (atomics) TransferSizes(1, beatBytes) else TransferSizes.none,
supportsLogical = if (atomics) TransferSizes(1, beatBytes) else TransferSizes.none,
- fifoId = Some(0))), // requests are handled in order
+ fifoId = Some(0)).v2copy(name=devName)), // requests are handled in order
beatBytes = beatBytes,
minLatency = 1))) // no bypass needed for this device
@@ -229,14 +236,15 @@ class TLRAM(
val r_ready = !d_wb && !r_replay && (!d_full || d_ready) && (!r_respond || (!d_win && in.d.ready))
in.a.ready := !(d_full && d_wb) && (!r_full || r_ready) && (!r_full || !(r_atomic || r_sublane))
- // ignore sublane if mask is all set
+ // ignore sublane if it is a read or mask is all set
+ val a_read = in.a.bits.opcode === TLMessages.Get
val a_sublane = if (eccBytes == 1) false.B else
- ((in.a.bits.opcode === TLMessages.PutPartialData) && (~in.a.bits.mask.andR)) ||
- in.a.bits.size < log2Ceil(eccBytes).U
+ ~a_read &&
+ (((in.a.bits.opcode === TLMessages.PutPartialData) && (~in.a.bits.mask.andR)) ||
+ in.a.bits.size < log2Ceil(eccBytes).U)
val a_atomic = if (!atomics) false.B else
in.a.bits.opcode === TLMessages.ArithmeticData ||
in.a.bits.opcode === TLMessages.LogicalData
- val a_read = in.a.bits.opcode === TLMessages.Get
// Forward pipeline stage from R to D
when (d_ready) { d_full := false.B }
diff --git a/src/main/scala/tilelink/SourceShrinker.scala b/src/main/scala/tilelink/SourceShrinker.scala
index 16fac848d60..c72d42f3e85 100644
--- a/src/main/scala/tilelink/SourceShrinker.scala
+++ b/src/main/scala/tilelink/SourceShrinker.scala
@@ -4,9 +4,14 @@ package freechips.rocketchip.tilelink
import chisel3._
import chisel3.util._
-import org.chipsalliance.cde.config.Parameters
-import freechips.rocketchip.diplomacy._
-import freechips.rocketchip.util._
+
+import org.chipsalliance.cde.config._
+import org.chipsalliance.diplomacy.lazymodule._
+
+import freechips.rocketchip.diplomacy.IdRange
+import freechips.rocketchip.util.leftOR
+
+import freechips.rocketchip.util.DataToAugmentedData
class TLSourceShrinker(maxInFlight: Int)(implicit p: Parameters) extends LazyModule
{
diff --git a/src/main/scala/tilelink/ToAHB.scala b/src/main/scala/tilelink/ToAHB.scala
index 5f960aa944c..a5267704295 100644
--- a/src/main/scala/tilelink/ToAHB.scala
+++ b/src/main/scala/tilelink/ToAHB.scala
@@ -4,13 +4,17 @@ package freechips.rocketchip.tilelink
import chisel3._
import chisel3.util._
-import freechips.rocketchip.amba._
-import freechips.rocketchip.amba.ahb._
-import org.chipsalliance.cde.config.Parameters
-import freechips.rocketchip.diplomacy._
-import freechips.rocketchip.util._
-import AHBParameters._
-import chisel3.util.{RegEnable, Queue, Cat, log2Ceil}
+
+import org.chipsalliance.cde.config._
+import org.chipsalliance.diplomacy._
+import org.chipsalliance.diplomacy.lazymodule._
+import org.chipsalliance.diplomacy.nodes._
+
+import freechips.rocketchip.amba.{AMBAProt, AMBAProtField}
+import freechips.rocketchip.amba.ahb.{AHBImpMaster, AHBParameters, AHBMasterParameters, AHBMasterPortParameters}
+import freechips.rocketchip.amba.ahb.AHBParameters.{BURST_INCR, BURST_SINGLE, TRANS_NONSEQ, TRANS_SEQ, TRANS_IDLE, TRANS_BUSY, PROT_DEFAULT}
+import freechips.rocketchip.diplomacy.TransferSizes
+import freechips.rocketchip.util.{BundleMap, UIntToOH1}
case class TLToAHBNode(supportHints: Boolean)(implicit valName: ValName) extends MixedAdapterNode(TLImp, AHBImpMaster)(
dFn = { cp =>
diff --git a/src/main/scala/tilelink/ToAPB.scala b/src/main/scala/tilelink/ToAPB.scala
index 91c172d658a..8b045144fd3 100644
--- a/src/main/scala/tilelink/ToAPB.scala
+++ b/src/main/scala/tilelink/ToAPB.scala
@@ -3,13 +3,18 @@
package freechips.rocketchip.tilelink
import chisel3._
-import org.chipsalliance.cde.config.Parameters
-import freechips.rocketchip.diplomacy._
-import freechips.rocketchip.amba.apb._
-import freechips.rocketchip.amba._
-import APBParameters._
import chisel3.util._
+import org.chipsalliance.cde.config._
+import org.chipsalliance.diplomacy._
+import org.chipsalliance.diplomacy.lazymodule._
+import org.chipsalliance.diplomacy.nodes._
+
+import freechips.rocketchip.diplomacy.TransferSizes
+import freechips.rocketchip.amba.{AMBAProt, AMBAProtField}
+import freechips.rocketchip.amba.apb.{APBImp, APBMasterParameters, APBMasterPortParameters}
+import freechips.rocketchip.amba.apb.APBParameters.PROT_DEFAULT
+
case class TLToAPBNode()(implicit valName: ValName) extends MixedAdapterNode(TLImp, APBImp)(
dFn = { cp =>
APBMasterPortParameters(
diff --git a/src/main/scala/tilelink/ToAXI4.scala b/src/main/scala/tilelink/ToAXI4.scala
index 2c8ab84bb31..a01ad75cf7a 100644
--- a/src/main/scala/tilelink/ToAXI4.scala
+++ b/src/main/scala/tilelink/ToAXI4.scala
@@ -3,12 +3,19 @@
package freechips.rocketchip.tilelink
import chisel3._
-import org.chipsalliance.cde.config.Parameters
-import freechips.rocketchip.diplomacy._
-import freechips.rocketchip.util._
-import freechips.rocketchip.amba.axi4._
-import freechips.rocketchip.amba._
-import chisel3.util.{log2Ceil, UIntToOH, Queue, Decoupled, Cat}
+import chisel3.util._
+
+import org.chipsalliance.cde.config._
+import org.chipsalliance.diplomacy._
+import org.chipsalliance.diplomacy.lazymodule._
+import org.chipsalliance.diplomacy.nodes._
+
+import freechips.rocketchip.amba.{AMBACorrupt, AMBACorruptField, AMBAProt, AMBAProtField}
+import freechips.rocketchip.amba.axi4.{AXI4BundleARW, AXI4MasterParameters, AXI4MasterPortParameters, AXI4Parameters, AXI4Imp}
+import freechips.rocketchip.diplomacy.{IdMap, IdMapEntry, IdRange}
+import freechips.rocketchip.util.{BundleField, ControlKey, ElaborationArtefacts, UIntToOH1}
+
+import freechips.rocketchip.util.DataToAugmentedData
class AXI4TLStateBundle(val sourceBits: Int) extends Bundle {
val size = UInt(4.W)
@@ -145,8 +152,8 @@ class TLToAXI4(val combinational: Boolean = true, val adapterName: Option[String
val depth = if (combinational) 1 else 2
val out_arw = Wire(Decoupled(new AXI4BundleARW(out.params)))
val out_w = Wire(chiselTypeOf(out.w))
- out.w :<>= Queue.irrevocable(out_w, entries=depth, combinational)
- val queue_arw = Queue.irrevocable(out_arw, entries=depth, combinational)
+ out.w :<>= Queue.irrevocable(out_w, entries=depth, flow=combinational)
+ val queue_arw = Queue.irrevocable(out_arw, entries=depth, flow=combinational)
// Fan out the ARW channel to AR and AW
out.ar.bits := queue_arw.bits
diff --git a/src/main/scala/tilelink/WidthWidget.scala b/src/main/scala/tilelink/WidthWidget.scala
index 514f0c5a9ef..e8b21026f0c 100644
--- a/src/main/scala/tilelink/WidthWidget.scala
+++ b/src/main/scala/tilelink/WidthWidget.scala
@@ -3,10 +3,13 @@
package freechips.rocketchip.tilelink
import chisel3._
-import chisel3.util.{DecoupledIO, log2Ceil, Cat, RegEnable}
-import org.chipsalliance.cde.config.Parameters
-import freechips.rocketchip.diplomacy._
-import freechips.rocketchip.util._
+import chisel3.util._
+
+import org.chipsalliance.cde.config._
+import org.chipsalliance.diplomacy.lazymodule._
+
+import freechips.rocketchip.diplomacy.AddressSet
+import freechips.rocketchip.util.{Repeater, UIntToOH1}
// innBeatBytes => the new client-facing bus width
class TLWidthWidget(innerBeatBytes: Int)(implicit p: Parameters) extends LazyModule
@@ -18,6 +21,8 @@ class TLWidthWidget(innerBeatBytes: Int)(implicit p: Parameters) extends LazyMod
override def circuitIdentity = edges.out.map(_.manager).forall(noChangeRequired)
}
+ override lazy val desiredName = s"TLWidthWidget$innerBeatBytes"
+
lazy val module = new Impl
class Impl extends LazyModuleImp(this) {
def merge[T <: TLDataChannel](edgeIn: TLEdge, in: DecoupledIO[T], edgeOut: TLEdge, out: DecoupledIO[T]) = {
@@ -174,14 +179,19 @@ class TLWidthWidget(innerBeatBytes: Int)(implicit p: Parameters) extends LazyMod
// The assumption is that this sort of situation happens only where
// you connect a narrow master to the system bus, so there are few sources.
- def sourceMap(source: UInt) = {
+ def sourceMap(source_bits: UInt) = {
+ val source = if (edgeIn.client.endSourceId == 1) 0.U(0.W) else source_bits
require (edgeOut.manager.beatBytes > edgeIn.manager.beatBytes)
val keepBits = log2Ceil(edgeOut.manager.beatBytes)
val dropBits = log2Ceil(edgeIn.manager.beatBytes)
val sources = Reg(Vec(edgeIn.client.endSourceId, UInt((keepBits-dropBits).W)))
val a_sel = in.a.bits.address(keepBits-1, dropBits)
when (in.a.fire) {
- sources(in.a.bits.source) := a_sel
+ if (edgeIn.client.endSourceId == 1) { // avoid extraction-index-width warning
+ sources(0) := a_sel
+ } else {
+ sources(in.a.bits.source) := a_sel
+ }
}
// depopulate unused source registers:
diff --git a/src/main/scala/tilelink/Xbar.scala b/src/main/scala/tilelink/Xbar.scala
index 1d6a82bbdc6..4d6c9ef7b63 100644
--- a/src/main/scala/tilelink/Xbar.scala
+++ b/src/main/scala/tilelink/Xbar.scala
@@ -4,9 +4,12 @@ package freechips.rocketchip.tilelink
import chisel3._
import chisel3.util._
-import org.chipsalliance.cde.config.{Field, Parameters}
-import freechips.rocketchip.diplomacy._
-import freechips.rocketchip.util._
+
+import org.chipsalliance.cde.config._
+import org.chipsalliance.diplomacy.lazymodule._
+
+import freechips.rocketchip.diplomacy.{AddressDecoder, AddressSet, RegionType, IdRange, TriStateValue}
+import freechips.rocketchip.util.BundleField
// Trades off slave port proximity against routing resource cost
object ForceFanout
@@ -30,7 +33,7 @@ object ForceFanout
private case class ForceFanoutParams(a: Boolean, b: Boolean, c: Boolean, d: Boolean, e: Boolean)
private case object ForceFanoutKey extends Field(ForceFanoutParams(false, false, false, false, false))
-class TLXbar(policy: TLArbiter.Policy = TLArbiter.roundRobin)(implicit p: Parameters) extends LazyModule
+class TLXbar(policy: TLArbiter.Policy = TLArbiter.roundRobin, nameSuffix: Option[String] = None)(implicit p: Parameters) extends LazyModule
{
val node = new TLNexusNode(
clientFn = { seq =>
@@ -74,7 +77,8 @@ class TLXbar(policy: TLArbiter.Policy = TLArbiter.roundRobin)(implicit p: Parame
println (s" Your TLXbar ($name with parent $parent) is very large, with ${node.in.size} Masters and ${node.out.size} Slaves.")
println (s"!!! WARNING !!!")
}
-
+ val wide_bundle = TLBundleParameters.union((node.in ++ node.out).map(_._2.bundle))
+ override def desiredName = (Seq("TLXbar") ++ nameSuffix ++ Seq(s"i${node.in.size}_o${node.out.size}_${wide_bundle.shortName}")).mkString("_")
TLXbar.circuit(policy, node.in, node.out)
}
}
@@ -157,8 +161,8 @@ object TLXbar
val r = inputIdRanges(i)
if (connectAIO(i).exists(x=>x)) {
- in(i).a.squeezeAll.waiveAll :<>= io_in(i).a.squeezeAll.waiveAll
in(i).a.bits.user := DontCare
+ in(i).a.squeezeAll.waiveAll :<>= io_in(i).a.squeezeAll.waiveAll
in(i).a.bits.source := io_in(i).a.bits.source | r.start.U
} else {
in(i).a := DontCare
@@ -178,8 +182,8 @@ object TLXbar
}
if (connectCIO(i).exists(x=>x)) {
- in(i).c.squeezeAll.waiveAll :<>= io_in(i).c.squeezeAll.waiveAll
in(i).c.bits.user := DontCare
+ in(i).c.squeezeAll.waiveAll :<>= io_in(i).c.squeezeAll.waiveAll
in(i).c.bits.source := io_in(i).c.bits.source | r.start.U
} else {
in(i).c := DontCare
@@ -214,8 +218,8 @@ object TLXbar
val r = outputIdRanges(o)
if (connectAOI(o).exists(x=>x)) {
- io_out(o).a.squeezeAll.waiveAll :<>= out(o).a.squeezeAll.waiveAll
out(o).a.bits.user := DontCare
+ io_out(o).a.squeezeAll.waiveAll :<>= out(o).a.squeezeAll.waiveAll
} else {
out(o).a := DontCare
io_out(o).a := DontCare
@@ -233,8 +237,8 @@ object TLXbar
}
if (connectCOI(o).exists(x=>x)) {
- io_out(o).c.squeezeAll.waiveAll :<>= out(o).c.squeezeAll.waiveAll
out(o).c.bits.user := DontCare
+ io_out(o).c.squeezeAll.waiveAll :<>= out(o).c.squeezeAll.waiveAll
} else {
out(o).c := DontCare
io_out(o).c := DontCare
@@ -337,9 +341,9 @@ object TLXbar
}
}
- def apply(policy: TLArbiter.Policy = TLArbiter.roundRobin)(implicit p: Parameters): TLNode =
+ def apply(policy: TLArbiter.Policy = TLArbiter.roundRobin, nameSuffix: Option[String] = None)(implicit p: Parameters): TLNode =
{
- val xbar = LazyModule(new TLXbar(policy))
+ val xbar = LazyModule(new TLXbar(policy, nameSuffix))
xbar.node
}
diff --git a/src/main/scala/tilelink/package.scala b/src/main/scala/tilelink/package.scala
index 6afc522d813..317d4052b08 100644
--- a/src/main/scala/tilelink/package.scala
+++ b/src/main/scala/tilelink/package.scala
@@ -2,8 +2,10 @@
package freechips.rocketchip
-import freechips.rocketchip.diplomacy.{HasClockDomainCrossing, _}
-import freechips.rocketchip.prci.{HasResetDomainCrossing}
+import org.chipsalliance.diplomacy._
+import org.chipsalliance.diplomacy.nodes._
+
+import freechips.rocketchip.prci.{HasResetDomainCrossing, HasClockDomainCrossing}
package object tilelink
{
diff --git a/src/main/scala/unittest/TestGenerator.scala b/src/main/scala/unittest/TestGenerator.scala
index 9440ebad0d6..d38fe9fc30c 100644
--- a/src/main/scala/unittest/TestGenerator.scala
+++ b/src/main/scala/unittest/TestGenerator.scala
@@ -3,8 +3,9 @@
package freechips.rocketchip.unittest
import chisel3._
+
import org.chipsalliance.cde.config._
-import freechips.rocketchip.diplomacy._
+import org.chipsalliance.diplomacy.lazymodule._
abstract class LazyUnitTest(implicit p: Parameters) extends LazyModule
{ self =>
diff --git a/src/main/scala/util/Annotations.scala b/src/main/scala/util/Annotations.scala
index 6cb8a4be85d..851571ba46e 100644
--- a/src/main/scala/util/Annotations.scala
+++ b/src/main/scala/util/Annotations.scala
@@ -4,11 +4,14 @@ package freechips.rocketchip.util
import chisel3._
import chisel3.experimental.{annotate, ChiselAnnotation}
-import chisel3.RawModule
+
import firrtl.annotations._
-import freechips.rocketchip.diplomacy._
-import freechips.rocketchip.regmapper._
+import org.chipsalliance.diplomacy
+
+import freechips.rocketchip.diplomacy.{AddressRange, AddressSet}
+import freechips.rocketchip.resources.{AddressMapEntry, ResourcePermissions}
+import freechips.rocketchip.regmapper.{RegField, RegFieldDescSer, RegistersSer}
import org.json4s.JsonDSL._
import org.json4s.jackson.JsonMethods.{pretty, render}
diff --git a/src/main/scala/util/AsyncQueue.scala b/src/main/scala/util/AsyncQueue.scala
index a7332358c56..713393ce9e3 100644
--- a/src/main/scala/util/AsyncQueue.scala
+++ b/src/main/scala/util/AsyncQueue.scala
@@ -68,6 +68,8 @@ class AsyncValidSync(sync: Int, desc: String) extends RawModule {
}
class AsyncQueueSource[T <: Data](gen: T, params: AsyncQueueParams = AsyncQueueParams()) extends Module {
+ override def desiredName = s"AsyncQueueSource_${gen.typeName}"
+
val io = IO(new Bundle {
// These come from the source domain
val enq = Flipped(Decoupled(gen))
@@ -132,6 +134,8 @@ class AsyncQueueSource[T <: Data](gen: T, params: AsyncQueueParams = AsyncQueueP
}
class AsyncQueueSink[T <: Data](gen: T, params: AsyncQueueParams = AsyncQueueParams()) extends Module {
+ override def desiredName = s"AsyncQueueSink_${gen.typeName}"
+
val io = IO(new Bundle {
// These come from the sink domain
val deq = Decoupled(gen)
diff --git a/src/main/scala/util/DelayQueue.scala b/src/main/scala/util/DelayQueue.scala
index cdfa2f50743..47a9ace983a 100644
--- a/src/main/scala/util/DelayQueue.scala
+++ b/src/main/scala/util/DelayQueue.scala
@@ -15,23 +15,23 @@ import chisel3.util._
* @param timer cycle count timer
* @param entries cycle delay
*/
-class DelayQueue[T <: Data](gen: T, entries: Int) extends Module {
+class DelayQueue[T <: Data](gen: T, entries: Int, width: Int) extends Module {
val io = IO(new Bundle {
val enq = Flipped(DecoupledIO(gen))
val deq = DecoupledIO(gen)
- val timer = Input(UInt())
- val delay = Input(UInt())
+ val timer = Input(UInt(width.W))
+ val delay = Input(UInt(width.W))
})
val q = Module(new Queue(new Bundle {
- val data = gen
- val time = UInt(io.timer.getWidth.W)
+ val data = gen.cloneType
+ val time = UInt(width.W)
}, entries, flow=true))
- val delay_r = RegInit(0.U(io.delay.getWidth.W))
+ val delay_r = RegInit(0.U(width.W))
when (delay_r =/= io.delay) {
delay_r := io.delay
- assert(q.io.count == 0, "Undefined behavior when delay is changed while queue has elements.")
+ //assert(q.io.count == 0, "Undefined behavior when delay is changed while queue has elements.")
}
q.io.enq.bits.data := io.enq.bits
@@ -53,7 +53,7 @@ object DelayQueue {
* @param depth queue size
*/
def apply[T <: Data](source: DecoupledIO[T], timer: UInt, delay: UInt, depth: Int): DecoupledIO[T] = {
- val delayQueue = Module(new DelayQueue(chiselTypeOf(source.bits), depth))
+ val delayQueue = Module(new DelayQueue(chiselTypeOf(source.bits), depth, timer.getWidth))
delayQueue.io.enq <> source
delayQueue.io.timer := timer
delayQueue.io.delay := delay
diff --git a/src/main/scala/util/HeterogeneousBag.scala b/src/main/scala/util/HeterogeneousBag.scala
deleted file mode 100644
index f9a591b4b42..00000000000
--- a/src/main/scala/util/HeterogeneousBag.scala
+++ /dev/null
@@ -1,24 +0,0 @@
-// See LICENSE.SiFive for license details.
-
-package freechips.rocketchip.util
-
-import chisel3._
-import chisel3.Record
-import chisel3.reflect.DataMirror.internal.chiselTypeClone
-import scala.collection.immutable.ListMap
-
-final case class HeterogeneousBag[T <: Data](elts: Seq[T]) extends Record with collection.IndexedSeq[T] {
- def apply(x: Int) = elements(x.toString).asInstanceOf[T]
- def length = elts.length
-
- override def className: String = super.className
- val elements = ListMap(elts.zipWithIndex.map { case (n,i) => (i.toString, chiselTypeClone(n)) }:_*)
- // IndexedSeq has its own hashCode/equals that we must not use
- override def hashCode: Int = super[Record].hashCode
- override def equals(that: Any): Boolean = super[Record].equals(that)
-}
-
-object HeterogeneousBag
-{
- def fromNode[D <: Data, E](elts: Seq[(D, E)]) = new HeterogeneousBag(elts.map(_._1.cloneType))
-}
diff --git a/src/main/scala/util/PSDTestMode.scala b/src/main/scala/util/PSDTestMode.scala
index 1ca26d79596..30c97a9078c 100644
--- a/src/main/scala/util/PSDTestMode.scala
+++ b/src/main/scala/util/PSDTestMode.scala
@@ -3,8 +3,10 @@
package freechips.rocketchip.util
import chisel3._
+
import org.chipsalliance.cde.config._
-import freechips.rocketchip.diplomacy.{BundleBridgeEphemeralNode, ValName}
+import org.chipsalliance.diplomacy._
+import org.chipsalliance.diplomacy.bundlebridge._
case object IncludePSDTest extends Field[Boolean](false)
case object PSDTestModeBroadcastKey extends Field(
diff --git a/src/main/scala/util/RecordMap.scala b/src/main/scala/util/RecordMap.scala
index 4dd6bc11ae9..fb2b227164c 100644
--- a/src/main/scala/util/RecordMap.scala
+++ b/src/main/scala/util/RecordMap.scala
@@ -4,8 +4,8 @@ package freechips.rocketchip.util
import chisel3._
import scala.collection.immutable.ListMap
-import chisel3.internal.requireIsChiselType
-import chisel3.experimental.DataMirror.internal.chiselTypeClone
+import chisel3.experimental.requireIsChiselType
+import chisel3.reflect.DataMirror.internal.chiselTypeClone
final class RecordMap[T <: Data] (eltMap: ListMap[String, T])
extends Record {
diff --git a/src/main/scala/util/Repeater.scala b/src/main/scala/util/Repeater.scala
index a0b0c5b297d..f97593d9ffd 100644
--- a/src/main/scala/util/Repeater.scala
+++ b/src/main/scala/util/Repeater.scala
@@ -9,6 +9,7 @@ import chisel3.util.{Decoupled, DecoupledIO}
// When repeat is asserted, the Repeater copies the input and repeats it next cycle.
class Repeater[T <: Data](gen: T) extends Module
{
+ override def desiredName = s"Repeater_${gen.typeName}"
val io = IO( new Bundle {
val repeat = Input(Bool())
val full = Output(Bool())
diff --git a/src/main/scala/util/TraceCoreInterface.scala b/src/main/scala/util/TraceCoreInterface.scala
index 6f948e09d32..fad9263a47d 100644
--- a/src/main/scala/util/TraceCoreInterface.scala
+++ b/src/main/scala/util/TraceCoreInterface.scala
@@ -4,7 +4,6 @@
package freechips.rocketchip.util
import chisel3._
-import chisel3.experimental.ChiselEnum
// Definitions for Trace core Interface defined in RISC-V Processor Trace Specification V1.0
object TraceItype extends ChiselEnum {
diff --git a/src/main/scala/util/package.scala b/src/main/scala/util/package.scala
index 6fb8895fb5c..6ca4961d580 100644
--- a/src/main/scala/util/package.scala
+++ b/src/main/scala/util/package.scala
@@ -270,7 +270,7 @@ package object util {
val y = Output(chiselTypeOf(in))
})
io.y := io.x
- override def desiredName = "OptimizationBarrier"
+ override def desiredName = s"OptimizationBarrier_${in.typeName}"
})
barrier.io.x := in
barrier.io.y
@@ -294,4 +294,10 @@ package object util {
case x if x == n => in
case _ => throw new Exception(s"must provide exactly 1 or $n of some field, but got:\n$in")
}
+
+ // HeterogeneousBag moved to standalond diplomacy
+ @deprecated("HeterogeneousBag has been absorbed into standalone diplomacy library", "rocketchip 2.0.0")
+ def HeterogeneousBag[T <: Data](elts: Seq[T]) = _root_.org.chipsalliance.diplomacy.nodes.HeterogeneousBag[T](elts)
+ @deprecated("HeterogeneousBag has been absorbed into standalone diplomacy library", "rocketchip 2.0.0")
+ val HeterogeneousBag = _root_.org.chipsalliance.diplomacy.nodes.HeterogeneousBag
}
diff --git a/torture b/torture
deleted file mode 160000
index 99d8b2b441e..00000000000
--- a/torture
+++ /dev/null
@@ -1 +0,0 @@
-Subproject commit 99d8b2b441ecaa18b852505bb7718ee04e2753f5