diff --git a/build.sbt b/build.sbt index 7138a20..b81a83b 100644 --- a/build.sbt +++ b/build.sbt @@ -1,3 +1,40 @@ +// ThisBuild / organization := "edu.berkeley.cs" +// ThisBuild / version := "0.0.1-SNAPSHOT" + +// ThisBuild / scalaVersion := "2.13.10" +// ThisBuild / scalacOptions := Seq( +// "-deprecation", +// "-feature", +// "-language:reflectiveCalls", +// "-Xcheckinit", +// "-Xlint", +// ) + +// Compile / doc / scalacOptions += "-groups" + +// val chiselVersion = "3.6.0" + +// lazy val root = (project in file(".")) +// .settings( +// name := "uciedigital", +// libraryDependencies ++= Seq( +// "edu.berkeley.cs" %% "chisel3" % chiselVersion, +// "edu.berkeley.cs" %% "chiseltest" % "0.6.2" % Test, +// "org.scalatest" %% "scalatest" % "3.2.17" % Test, +// "edu.berkeley.cs" %% "rocketchip" % "1.6.0", +// "edu.berkeley.cs" %% "rocket-macros" % "1.6.0", +// "edu.berkeley.cs" %% "cde" % "1.6.0", +// ), +// addCompilerPlugin( +// "edu.berkeley.cs" % "chisel3-plugin" % chiselVersion cross CrossVersion.full, +// ), +// ) + +// // Plugins +// Global / excludeLintKeys += idePackagePrefix +// root / idePackagePrefix := Some("edu.berkeley.cs.ucie.digital") + +name := "ucie_digital" ThisBuild / organization := "edu.berkeley.cs" ThisBuild / version := "0.0.1-SNAPSHOT" @@ -14,19 +51,29 @@ Compile / doc / scalacOptions += "-groups" val chiselVersion = "3.6.0" -lazy val root = (project in file(".")) - .settings( - name := "uciedigital", - libraryDependencies ++= Seq( - "edu.berkeley.cs" %% "chisel3" % chiselVersion, - "edu.berkeley.cs" %% "chiseltest" % "0.6.2" % Test, - "org.scalatest" %% "scalatest" % "3.2.17" % Test, - ), - addCompilerPlugin( - "edu.berkeley.cs" % "chisel3-plugin" % chiselVersion cross CrossVersion.full, - ), +// SNAPSHOT repositories +libraryDependencies ++= + Seq( + "edu.berkeley.cs" %% "rocketchip-3.6.0" % "1.6-3.6.0-e3773366a-SNAPSHOT", + "edu.berkeley.cs" %% "chisel3" % chiselVersion, + "edu.berkeley.cs" %% "chiseltest" % "0.6.2" % "test", + "org.scalatest" %% "scalatest" % "3.2.17" % "test", ) -// Plugins -Global / excludeLintKeys += idePackagePrefix -root / idePackagePrefix := Some("edu.berkeley.cs.ucie.digital") +resolvers ++= Resolver.sonatypeOssRepos("snapshots") +resolvers ++= Resolver.sonatypeOssRepos("releases") +resolvers += Resolver.mavenLocal + +addCompilerPlugin("edu.berkeley.cs" % "chisel3-plugin" % chiselVersion cross CrossVersion.full) + +import Tests._ + +Test / fork := true +Test / testGrouping := (Test / testGrouping).value.flatMap { group => + group.tests.map { test => + Group(test.name, Seq(test), SubProcess(ForkOptions())) + } +} + +concurrentRestrictions := Seq(Tags.limit(Tags.ForkedTestGroup, 72)) + diff --git a/project/build.properties b/project/build.properties index abbbce5..e8a1e24 100644 --- a/project/build.properties +++ b/project/build.properties @@ -1 +1 @@ -sbt.version=1.9.8 +sbt.version=1.9.7 diff --git a/src/main/scala/sideband/sb-msg-encoding.scala b/src/main/scala/sideband/sb-msg-encoding.scala new file mode 100644 index 0000000..a6850a2 --- /dev/null +++ b/src/main/scala/sideband/sb-msg-encoding.scala @@ -0,0 +1,403 @@ +package edu.berkeley.cs.ucie.digital +package sideband + +import chisel3._ +import chisel3.util._ +import chisel3.experimental._ +import freechips.rocketchip._ + +/* Automatically generated by parse_opcodes */ +object SBM { + def MEMR_32 = BitPat( + "b???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????00000", + ) + def MEMW_32 = BitPat( + "b???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????00001", + ) + def CONFR_32 = BitPat( + "b???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????00100", + ) + def CONFW_32 = BitPat( + "b???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????00101", + ) + def MEMR_64 = BitPat( + "b???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????01000", + ) + def MEMW_64 = BitPat( + "b???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????01001", + ) + def CONFR_64 = BitPat( + "b???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????01100", + ) + def CONFW_64 = BitPat( + "b???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????01101", + ) + def COMP_0 = BitPat( + "b???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????10000", + ) + def COMP_32 = BitPat( + "b???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????10001", + ) + def COMP_64 = BitPat( + "b???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????11001", + ) + def MSG_0 = BitPat( + "b???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????10010", + ) + def MSG_64 = BitPat( + "b???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????11011", + ) + def NOP_CRD = BitPat( + "b????????????????????????????????????????????????????????????????????????????????????????00000000??????????00000000?????????10010", + ) + def LINK_MGMT_RDI_REQ_ACTIVE = BitPat( + "b????????????????????????????????????????????????????????????????????????????????????????00000001??????????00000001?????????10010", + ) + def LINK_MGMT_RDI_REQ_L1 = BitPat( + "b????????????????????????????????????????????????????????????????????????????????????????00000100??????????00000001?????????10010", + ) + def LINK_MGMT_RDI_REQ_L2 = BitPat( + "b????????????????????????????????????????????????????????????????????????????????????????00001000??????????00000001?????????10010", + ) + def LINK_MGMT_RDI_REQ_LINK_RESET = BitPat( + "b????????????????????????????????????????????????????????????????????????????????????????00001001??????????00000001?????????10010", + ) + def LINK_MGMT_RDI_REQ_LINK_ERROR = BitPat( + "b????????????????????????????????????????????????????????????????????????????????????????00001010??????????00000001?????????10010", + ) + def LINK_MGMT_RDI_REQ_RETRAIN = BitPat( + "b????????????????????????????????????????????????????????????????????????????????????????00001011??????????00000001?????????10010", + ) + def LINK_MGMT_RDI_REQ_DISABLE = BitPat( + "b????????????????????????????????????????????????????????????????????????????????????????00001100??????????00000001?????????10010", + ) + def LINK_MGMT_RDI_RSP_ACTIVE = BitPat( + "b????????????????????????????????????????????????????????????????????????000000000000000000000001??????????00000010?????????10010", + ) + def LINK_MGMT_RDI_RSP_PM_NAK = BitPat( + "b????????????????????????????????????????????????????????????????????????000000000000000000000010??????????00000010?????????10010", + ) + def LINK_MGMT_RDI_RSP_L1 = BitPat( + "b????????????????????????????????????????????????????????????????????????000000000000000000000100??????????00000010?????????10010", + ) + def LINK_MGMT_RDI_RSP_L2 = BitPat( + "b????????????????????????????????????????????????????????????????????????000000000000000000001000??????????00000010?????????10010", + ) + def LINK_MGMT_RDI_RSP_LINK_RESET = BitPat( + "b????????????????????????????????????????????????????????????????????????000000000000000000001001??????????00000010?????????10010", + ) + def LINK_MGMT_RDI_RSP_LINK_ERROR = BitPat( + "b????????????????????????????????????????????????????????????????????????000000000000000000001010??????????00000010?????????10010", + ) + def LINK_MGMT_RDI_RSP_RETRAIN = BitPat( + "b????????????????????????????????????????????????????????????????????????000000000000000000001011??????????00000010?????????10010", + ) + def LINK_MGMT_RDI_RSP_DISABLE = BitPat( + "b????????????????????????????????????????????????????????????????????????000000000000000000001100??????????00000010?????????10010", + ) + def LINK_MGMT_ADAPTER0_REQ_ACTIVE = BitPat( + "b????????????????????????????????????????????????????????????????????????000000000000000000000001??????????00000011?????????10010", + ) + def LINK_MGMT_ADAPTER0_REQ_L1 = BitPat( + "b????????????????????????????????????????????????????????????????????????????????????????00000100??????????00000011?????????10010", + ) + def LINK_MGMT_ADAPTER0_REQ_L2 = BitPat( + "b????????????????????????????????????????????????????????????????????????????????????????00001000??????????00000011?????????10010", + ) + def LINK_MGMT_ADAPTER0_REQ_LINK_RESET = BitPat( + "b????????????????????????????????????????????????????????????????????????????????????????00001001??????????00000011?????????10010", + ) + def LINK_MGMT_ADAPTER0_REQ_DISABLE = BitPat( + "b????????????????????????????????????????????????????????????????????????????????????????00001100??????????00000011?????????10010", + ) + def LINK_MGMT_ADAPTER0_RSP_ACTIVE = BitPat( + "b????????????????????????????????????????????????????????????????????????000000000000000000000001??????????00000100?????????10010", + ) + def LINK_MGMT_ADAPTER0_RSP_PM_NAK = BitPat( + "b????????????????????????????????????????????????????????????????????????000000000000000000000010??????????00000100?????????10010", + ) + def LINK_MGMT_ADAPTER0_RSP_L1 = BitPat( + "b????????????????????????????????????????????????????????????????????????000000000000000000000100??????????00000100?????????10010", + ) + def LINK_MGMT_ADAPTER0_RSP_L2 = BitPat( + "b????????????????????????????????????????????????????????????????????????000000000000000000001000??????????00000100?????????10010", + ) + def LINK_MGMT_ADAPTER0_RSP_LINK_RESET = BitPat( + "b????????????????????????????????????????????????????????????????????????000000000000000000001001??????????00000100?????????10010", + ) + def LINK_MGMT_ADAPTER0_RSP_DISABLE = BitPat( + "b????????????????????????????????????????????????????????????????????????000000000000000000001100??????????00000100?????????10010", + ) + def LINK_MGMT_ADAPTER1_REQ_ACTIVE = BitPat( + "b????????????????????????????????????????????????????????????????????????000000000000000000000001??????????00000101?????????10010", + ) + def LINK_MGMT_ADAPTER1_REQ_L1 = BitPat( + "b????????????????????????????????????????????????????????????????????????000000000000000000000100??????????00000101?????????10010", + ) + def LINK_MGMT_ADAPTER1_REQ_L2 = BitPat( + "b????????????????????????????????????????????????????????????????????????000000000000000000001000??????????00000101?????????10010", + ) + def LINK_MGMT_ADAPTER1_REQ_LINK_RESET = BitPat( + "b????????????????????????????????????????????????????????????????????????000000000000000000001001??????????00000101?????????10010", + ) + def LINK_MGMT_ADAPTER1_REQ_DISABLE = BitPat( + "b????????????????????????????????????????????????????????????????????????000000000000000000001100??????????00000101?????????10010", + ) + def LINK_MGMT_ADAPTER1_RSP_ACTIVE = BitPat( + "b????????????????????????????????????????????????????????????????????????000000000000000000000001??????????00000110?????????10010", + ) + def LINK_MGMT_ADAPTER1_RSP_PM_NAK = BitPat( + "b????????????????????????????????????????????????????????????????????????000000000000000000000010??????????00000110?????????10010", + ) + def LINK_MGMT_ADAPTER1_RSP_L1 = BitPat( + "b????????????????????????????????????????????????????????????????????????000000000000000000000100??????????00000110?????????10010", + ) + def LINK_MGMT_ADAPTER1_RSP_L2 = BitPat( + "b????????????????????????????????????????????????????????????????????????000000000000000000001000??????????00000110?????????10010", + ) + def LINK_MGMT_ADAPTER1_RSP_LINK_RESET = BitPat( + "b????????????????????????????????????????????????????????????????????????000000000000000000001001??????????00000110?????????10010", + ) + def LINK_MGMT_ADAPTER1_RSP_DISABLE = BitPat( + "b????????????????????????????????????????????????????????????????????????000000000000000000001100??????????00000110?????????10010", + ) + def PARITY_FEATURE_REQ = BitPat( + "b????????????????????????????????????????????????????????????????????????000000000000000000000000??????????00000111?????????10010", + ) + def PARITY_FEATURE_ACK = BitPat( + "b????????????????????????????????????????????????????????????????????????000000000000000000000000??????????00001000?????????10010", + ) + def PARITY_FEATURE_NAK = BitPat( + "b????????????????????????????????????????????????????????????????????????000000000000000000000001??????????00001000?????????10010", + ) + def ERRMSG_CORRECTABLE = BitPat( + "b????????????????????????????????????????????????????????????????????????????????????????00000000??????????00001001?????????10010", + ) + def ERRMSG_NON_FATAL = BitPat( + "b????????????????????????????????????????????????????????????????????????????????????????00000001??????????00001001?????????10010", + ) + def ERRMSG_FATAL = BitPat( + "b????????????????????????????????????????????????????????????????????????????????????????00000010??????????00001001?????????10010", + ) + def START_TX_INITIATED_D2C_POINT_TEST_RESP = BitPat( + "b????????????????????????????????????????????????????????????????????????000000000000000000000001??????????10001010?????????10010", + ) + def LFSR_CLEAR_ERROR_REQ = BitPat( + "b????????????????????????????????????????????????????????????????????????000000000000000000000010??????????10000101?????????10010", + ) + def LFSR_CLEAR_ERROR_RESP = BitPat( + "b????????????????????????????????????????????????????????????????????????000000000000000000000010??????????10001010?????????10010", + ) + def TXINIT_D2C_RESULTS_REQ = BitPat( + "b????????????????????????????????????????????????????????????????????????000000000000000000000011??????????10000101?????????10010", + ) + def END_TX_INITIATED_D2C_POINT_TEST_REQ = BitPat( + "b????????????????????????????????????????????????????????????????????????000000000000000000000100??????????10000101?????????10010", + ) + def END_TX_INITIATED_D2C_POINT_TEST_RESP = BitPat( + "b????????????????????????????????????????????????????????????????????????000000000000000000000100??????????10001010?????????10010", + ) + def START_TX_INIT_D2C_EYE_SWEEP_RESP = BitPat( + "b????????????????????????????????????????????????????????????????????????000000000000000000000101??????????10001010?????????10010", + ) + def LFSR_CLEAR_ERROR_REQ_2 = BitPat( + "b????????????????????????????????????????????????????????????????????????000000000000000000000010??????????10000101?????????10010", + ) + def LFSR_CLEAR_ERROR_RESP_2 = BitPat( + "b????????????????????????????????????????????????????????????????????????000000000000000000000010??????????10001010?????????10010", + ) + def TXINIT_D2C_RESULTS_REQ_2 = BitPat( + "b????????????????????????????????????????????????????????????????????????000000000000000000000011??????????10000101?????????10010", + ) + def END_TX_INIT_D2C_EYE_SWEEP_REQ = BitPat( + "b????????????????????????????????????????????????????????????????????????000000000000000000000110??????????10000101?????????10010", + ) + def END_TX_INIT_D2C_EYE_SWEEP_RESP = BitPat( + "b????????????????????????????????????????????????????????????????????????000000000000000000000110??????????10001010?????????10010", + ) + def START_RX_INIT_D2C_POINT_TEST_RESP = BitPat( + "b????????????????????????????????????????????????????????????????????????000000000000000000000111??????????10001010?????????10010", + ) + def LFSR_CLEAR_ERROR_REQ_3 = BitPat( + "b????????????????????????????????????????????????????????????????????????000000000000000000000010??????????10000101?????????10010", + ) + def LFSR_CLEAR_ERROR_RESP_3 = BitPat( + "b????????????????????????????????????????????????????????????????????????000000000000000000000010??????????10001010?????????10010", + ) + def TX_COUNT_DONE_REQ = BitPat( + "b????????????????????????????????????????????????????????????????????????000000000000000000001000??????????10000101?????????10010", + ) + def TX_COUNT_DONE_RESP = BitPat( + "b????????????????????????????????????????????????????????????????????????000000000000000000001000??????????10001010?????????10010", + ) + def END_RX_INIT_D2C_POINT_TEST_RESP = BitPat( + "b????????????????????????????????????????????????????????????????????????000000000000000000001001??????????10001010?????????10010", + ) + def START_RX_INIT_D2C_EYE_SWEEP_RESP = BitPat( + "b????????????????????????????????????????????????????????????????????????000000000000000000001010??????????10001010?????????10010", + ) + def LFSR_CLEAR_ERROR_REQ_4 = BitPat( + "b????????????????????????????????????????????????????????????????????????000000000000000000000010??????????10000101?????????10010", + ) + def LFSR_CLEAR_ERROR_RESP_4 = BitPat( + "b????????????????????????????????????????????????????????????????????????000000000000000000000010??????????10001010?????????10010", + ) + def RXINIT_D2C_RESULTS_REQ = BitPat( + "b????????????????????????????????????????????????????????????????????????000000000000000000001011??????????10000101?????????10010", + ) + def END_RX_INIT_D2C_EYE_SWEEP_REQ = BitPat( + "b????????????????????????????????????????????????????????????????????????000000000000000000001101??????????10000101?????????10010", + ) + def END_RX_INIT_D2C_EYE_SWEEP_RESP = BitPat( + "b????????????????????????????????????????????????????????????????????????000000000000000000001101??????????10001010?????????10010", + ) + def SBINIT_OUT_OF_RESET = BitPat( + "b????????????????????????????????????????????????????????????????????????000000000000000000000000??????????10010001?????????00000", + ) + def SBINIT_DONE_REQ = BitPat( + "b????????????????????????????????????????????????????????????????????????000000000000000000000001??????????10010101?????????10010", + ) + def SBINIT_DONE_RESP = BitPat( + "b????????????????????????????????????????????????????????????????????????000000000000000000000001??????????10011010?????????10010", + ) + def MBINIT_CAL_DONE_REQ = BitPat( + "b????????????????????????????????????????????????????????????????????????000000000000000000000010??????????10100101?????????10010", + ) + def MBINIT_CAL_DONE_RESP = BitPat( + "b????????????????????????????????????????????????????????????????????????000000000000000000000010??????????10101010?????????10010", + ) + def MBINIT_REPAIRCLK_INIT_REQ = BitPat( + "b????????????????????????????????????????????????????????????????????????000000000000000000000011??????????10100101?????????10010", + ) + def MBINIT_REPAIRCLK_INIT_RESP = BitPat( + "b????????????????????????????????????????????????????????????????????????000000000000000000000011??????????10101010?????????10010", + ) + def MBINIT_REPAIRCLK_RESULT_REQ = BitPat( + "b????????????????????????????????????????????????????????????????????????000000000000000000000100??????????10100101?????????10010", + ) + def MBINIT_REPAIRCLK_APPLY_REPAIR_RESP = BitPat( + "b????????????????????????????????????????????????????????????????????????000000000000000000000101??????????10101010?????????10010", + ) + def MBINIT_REPAIRCLK_CHECK_REPAIR_INIT_REQ = BitPat( + "b????????????????????????????????????????????????????????????????????????000000000000000000000110??????????10100101?????????10010", + ) + def MBINIT_REPAIRCLK_CHECK_REPAIR_INIT_RESP = BitPat( + "b????????????????????????????????????????????????????????????????????????000000000000000000000110??????????10101010?????????10010", + ) + def MBINIT_REPAIRCLK_CHECK_RESULTS_REQ = BitPat( + "b????????????????????????????????????????????????????????????????????????000000000000000000000111??????????10100101?????????10010", + ) + def MBINIT_REPAIRCLK_DONE_REQ = BitPat( + "b????????????????????????????????????????????????????????????????????????000000000000000000001000??????????10100101?????????10010", + ) + def MBINIT_REPAIRCLK_DONE_RESP = BitPat( + "b????????????????????????????????????????????????????????????????????????000000000000000000001000??????????10101010?????????10010", + ) + def MBINIT_REPAIRVAL_INIT_REQ = BitPat( + "b????????????????????????????????????????????????????????????????????????000000000000000000001001??????????10100101?????????10010", + ) + def MBINIT_REPAIRVAL_INIT_RESP = BitPat( + "b????????????????????????????????????????????????????????????????????????000000000000000000001001??????????10101010?????????10010", + ) + def MBINIT_REPAIRVAL_RESULT_REQ = BitPat( + "b????????????????????????????????????????????????????????????????????????000000000000000000001010??????????10100101?????????10010", + ) + def MBINIT_REPAIRVAL_APPLY_REPAIR_RESP = BitPat( + "b????????????????????????????????????????????????????????????????????????000000000000000000001011??????????10101010?????????10010", + ) + def MBINIT_REPAIRVAL_DONE_REQ = BitPat( + "b????????????????????????????????????????????????????????????????????????000000000000000000001100??????????10100101?????????10010", + ) + def MBINIT_REPAIRVAL_DONE_RESP = BitPat( + "b????????????????????????????????????????????????????????????????????????000000000000000000001100??????????10101010?????????10010", + ) + def MBINIT_REVERSALMB_INIT_REQ = BitPat( + "b????????????????????????????????????????????????????????????????????????000000000000000000001101??????????10100101?????????10010", + ) + def MBINIT_REVERSALMB_INIT_RESP = BitPat( + "b????????????????????????????????????????????????????????????????????????000000000000000000001101??????????10101010?????????10010", + ) + def MBINIT_REVERSALMB_CLEAR_ERROR_REQ = BitPat( + "b????????????????????????????????????????????????????????????????????????000000000000000000001110??????????10100101?????????10010", + ) + def MBINIT_REVERSALMB_CLEAR_ERROR_RESP = BitPat( + "b????????????????????????????????????????????????????????????????????????000000000000000000001110??????????10101010?????????10010", + ) + def MBINIT_REVERSALMB_RESULT_REQ = BitPat( + "b????????????????????????????????????????????????????????????????????????000000000000000000001111??????????10100101?????????10010", + ) + def MBINIT_REVERSALMB_DONE_REQ = BitPat( + "b????????????????????????????????????????????????????????????????????????000000000000000000010000??????????10100101?????????10010", + ) + def MBINIT_RVERSALMB_DONE_RESP = BitPat( + "b????????????????????????????????????????????????????????????????????????000000000000000000010000??????????10101010?????????10010", + ) + def MBINIT_REPAIRMB_START_REQ = BitPat( + "b????????????????????????????????????????????????????????????????????????000000000000000000010001??????????10100101?????????10010", + ) + def MBINIT_REPAIRMB_START_RESP = BitPat( + "b????????????????????????????????????????????????????????????????????????000000000000000000010001??????????10101010?????????10010", + ) + def MBINIT_REPAIRMB_APPLY_REPAIR_RESP = BitPat( + "b????????????????????????????????????????????????????????????????????????000000000000000000010010??????????10101010?????????10010", + ) + def MBINIT_REPAIRMB_END_REQ = BitPat( + "b????????????????????????????????????????????????????????????????????????000000000000000000010011??????????10100101?????????10010", + ) + def MBINIT_REPAIRMB_END_RESP = BitPat( + "b????????????????????????????????????????????????????????????????????????000000000000000000010011??????????10101010?????????10010", + ) + def MBTRAIN_VALVREF_START_REQ = BitPat( + "b????????????????????????????????????????????????????????????????????????????????????????00000000??????????10110101?????????00000", + ) + def MBTRAIN_VALVREF_START_RESP = BitPat( + "b????????????????????????????????????????????????????????????????????????????????????????00000000??????????10111010?????????00000", + ) + def MBTRAIN_VALVREF_END_REQ = BitPat( + "b????????????????????????????????????????????????????????????????????????????????????????00000001??????????10110101?????????00000", + ) + def ADV_CAP = BitPat( + "b????????????????????????????????????????????????????????????????????????000000000000000000000000??????????00000001?????????11011", + ) + + def isComplete(x: UInt) = x === COMP_0 | x === COMP_32 | x === COMP_64 + def isMessage(x: UInt) = x === MSG_0 | x === MSG_64 + def isRequest(x: UInt) = ~x(4) +} + +// A factory function to create a message from a bitpat, source, destination, and data +object SBMessage_factory { + def apply( + base: BitPat, + src: String, + remote: Boolean = false, + dst: String, + data: UInt = 0.U(64.W), + ) = { + // take the bottom 64 bits of the base by modulo + var msg: BigInt = base.value % (BigInt(1) << 64) + val src_num: BigInt = src match { + case "Protocol_0" => 0 + case "Protocol_1" => 4 + case "D2D" => 1 + case "PHY" => 2 + case _ => 0 + } + var dst_num: BigInt = dst match { + case "Protocol_0" => 0 + case "Protocol_1" => 4 + case "D2D" => 1 + case "PHY" => 2 + case _ => 0 + } + dst_num += (if (remote) 4 else 0) + msg += src_num << 29 + dst_num = dst_num << 30 + dst_num = dst_num << 26 + msg += dst_num + println("SBMessage_factory: " + msg) + val new_msg = Cat(data, msg.U(64.W)) + println("SBMessage_factory: " + new_msg) + new_msg + } +} diff --git a/src/main/scala/sideband/sidebandChannel.scala b/src/main/scala/sideband/sidebandChannel.scala new file mode 100644 index 0000000..41b32cc --- /dev/null +++ b/src/main/scala/sideband/sidebandChannel.scala @@ -0,0 +1,63 @@ +package edu.berkeley.cs.ucie.digital +package sideband + +import chisel3._ +import chisel3.util._ +import chisel3.experimental._ + +import interfaces._ + +// import freechips.rocketchip.config.Parameters +import freechips.rocketchip.util._ + +class D2DSidebandChannel( + val myID: BigInt = BigInt(1), + val sbParams: SidebandParams, + val fdiParams: FdiParams, +) extends Module { + val io = IO(new D2DSidebandChannelIO(sbParams, fdiParams)) + + // Instantiate submodule + val upper_node = Module(new SidebandNode(sbParams, fdiParams)) + val switcher = Module(new sidebandSwitcher(myID, sbParams)) + val lower_node = Module(new SidebandNode(sbParams, fdiParams)) + + // Connect outer signals + io.to_upper_layer <> upper_node.io.outer + io.to_lower_layer <> lower_node.io.outer + + // Connect two sidebandNodes and switcher + upper_node.io.inner.layer_to_node <> switcher.io.outer.layer_to_node_above + upper_node.io.inner.node_to_layer <> switcher.io.outer.node_to_layer_above + lower_node.io.inner.layer_to_node <> switcher.io.outer.layer_to_node_below + lower_node.io.inner.node_to_layer <> switcher.io.outer.node_to_layer_below + + // Connect inner signals + io.inner <> switcher.io.inner +} + +class PHYSidebandChannel( + val myID: BigInt = BigInt(2), + val sbParams: SidebandParams, + val fdiParams: FdiParams, +) extends Module { + val io = IO(new PHYSidebandChannelIO(sbParams, fdiParams)) + + // Instantiate submodule + val upper_node = Module(new SidebandNode(sbParams, fdiParams)) + val switcher = Module(new sidebandSwitcher(myID, sbParams)) + val lower_node = Module(new SidebandLinkNode(sbParams, fdiParams)) + + // Connect outer signals + io.to_upper_layer <> upper_node.io.outer + io.to_lower_layer <> lower_node.io.outer + + // Connect two sidebandNodes and switcher + upper_node.io.inner.layer_to_node <> switcher.io.outer.layer_to_node_above + upper_node.io.inner.node_to_layer <> switcher.io.outer.node_to_layer_above + lower_node.io.inner.layer_to_node <> switcher.io.outer.layer_to_node_below + lower_node.io.inner.node_to_layer <> switcher.io.outer.node_to_layer_below + + // Connect inner signals + io.inner <> switcher.io.inner +} diff --git a/src/main/scala/sideband/sidebandIO.scala b/src/main/scala/sideband/sidebandIO.scala new file mode 100644 index 0000000..dce4378 --- /dev/null +++ b/src/main/scala/sideband/sidebandIO.scala @@ -0,0 +1,171 @@ +package edu.berkeley.cs.ucie.digital +package sideband + +import chisel3._ +import chisel3.util._ +import chisel3.experimental._ + +import interfaces._ + +// import freechips.rocketchip.config.Parameters +import freechips.rocketchip.util._ + +class D2DSidebandChannelIO( + val sbParams: SidebandParams, + val fdiParams: FdiParams, +) extends Bundle { + // connect to another sideband node in the layer above (protocol layer) + val to_upper_layer = new Bundle { + val tx = new Bundle { + val bits = Output(UInt(fdiParams.sbWidth.W)) + val valid = Output(Bool()) + val credit = Input(Bool()) + } + val rx = new Bundle { + val bits = Input(UInt(fdiParams.sbWidth.W)) + val valid = Input(Bool()) + val credit = Output(Bool()) + } + } + // connect to another sideband node in the layer below (physical layer) + val to_lower_layer = new Bundle { + val tx = new Bundle { + val bits = Output(UInt(fdiParams.sbWidth.W)) + val valid = Output(Bool()) + val credit = Input(Bool()) + } + val rx = new Bundle { + val bits = Input(UInt(fdiParams.sbWidth.W)) + val valid = Input(Bool()) + val credit = Output(Bool()) + } + } + // d2d layer drive these + val inner = Flipped(new SidebandSwitcherbundle(sbParams)) +} + +class PHYSidebandChannelIO( + val sbParams: SidebandParams, + val fdiParams: FdiParams, +) extends Bundle { + // connect to another sideband node in the layer above (d2d layer) + val to_upper_layer = new Bundle { + val tx = new Bundle { + val bits = Output(UInt(fdiParams.sbWidth.W)) + val valid = Output(Bool()) + val credit = Input(Bool()) + } + val rx = new Bundle { + val bits = Input(UInt(fdiParams.sbWidth.W)) + val valid = Input(Bool()) + val credit = Output(Bool()) + } + } + // connect to another sideband node in the layer below (link layer) + val to_lower_layer = new Bundle { + val tx = new Bundle { + val bits = Output(UInt(fdiParams.sbWidth.W)) + val clock = Output(Bool()) + } + val rx = new Bundle { + val bits = Input(UInt(fdiParams.sbWidth.W)) + val clock = Input(Bool()) + } + } + // phy layer drive these + val inner = Flipped(new SidebandSwitcherbundle(sbParams)) +} + +// IO for the RDI and FDI sideband +class SidebandNodeIO(val sbParams: SidebandParams, val fdiParams: FdiParams) + extends Bundle { + // layers drive these + val inner = new Bundle { + val layer_to_node = Flipped(Decoupled(UInt(sbParams.sbNodeMsgWidth.W))) + /* This signal overrides the tx.ready and takes up the priority reserved + * queue slot */ + // Should only be asserted high for access completion packets + val node_to_layer = Decoupled(UInt(sbParams.sbNodeMsgWidth.W)) + } + // connect these to another sideband node + val outer = new Bundle { + val tx = new Bundle { + val bits = Output(UInt(fdiParams.sbWidth.W)) + val valid = Output(Bool()) + val credit = Input(Bool()) + } + val rx = new Bundle { + val bits = Input(UInt(fdiParams.sbWidth.W)) + val valid = Input(Bool()) + val credit = Output(Bool()) + } + } +} + +class SidebandNodeOuterIO( + val sbParams: SidebandParams, + val fdiParams: FdiParams, +) extends Bundle { + val tx = new Bundle { + val bits = Output(UInt(fdiParams.sbWidth.W)) + val valid = Output(Bool()) + val credit = Input(Bool()) + } + val rx = new Bundle { + val bits = Input(UInt(fdiParams.sbWidth.W)) + val valid = Input(Bool()) + val credit = Output(Bool()) + } +} + +class SidebandLinkNodeOuterIO( + val sbParams: SidebandParams, + val fdiParams: FdiParams, +) extends Bundle { + val tx = new Bundle { + val bits = Output(UInt(fdiParams.sbWidth.W)) + val clock = Output(Bool()) + } + val rx = new Bundle { + val bits = Input(UInt(fdiParams.sbWidth.W)) + val clock = Input(Bool()) + } +} + +// IO for the remote sideband +class SidebandLinkIO(val sbParams: SidebandParams, val fdiParams: FdiParams) + extends Bundle { + // layers drive these + val inner = new Bundle { + val layer_to_node = Flipped(Decoupled(UInt(sbParams.sbNodeMsgWidth.W))) + /* This signal overrides the tx.ready and takes up the priority reserved + * queue slot */ + // Should only be asserted high for access completion packets + val node_to_layer = Decoupled(UInt(sbParams.sbNodeMsgWidth.W)) + } + // connect these to another sideband node + val outer = new Bundle { + val tx = new Bundle { + val bits = Output(UInt(fdiParams.sbWidth.W)) + val clock = Output(Bool()) + } + val rx = new Bundle { + val bits = Input(UInt(fdiParams.sbWidth.W)) + val clock = Input(Bool()) + } + } +} + +class SidebandSwitcherIO(val sbParams: SidebandParams) extends Bundle { + // layer drive these + val inner = Flipped(new SidebandSwitcherbundle(sbParams)) + // Sideband node drive these + val outer = new SidebandSwitcherbundle(sbParams) +} + +class SidebandSwitcherbundle(val sbParams: SidebandParams) extends Bundle { + val node_to_layer_above = Flipped(Decoupled(UInt(sbParams.sbNodeMsgWidth.W))) + val layer_to_node_above = Decoupled(UInt(sbParams.sbNodeMsgWidth.W)) + val node_to_layer_below = Flipped(Decoupled(UInt(sbParams.sbNodeMsgWidth.W))) + val layer_to_node_below = Decoupled(UInt(sbParams.sbNodeMsgWidth.W)) +} diff --git a/src/main/scala/sideband/sidebandNode.scala b/src/main/scala/sideband/sidebandNode.scala new file mode 100644 index 0000000..b846f2d --- /dev/null +++ b/src/main/scala/sideband/sidebandNode.scala @@ -0,0 +1,331 @@ +package edu.berkeley.cs.ucie.digital +package sideband + +import chisel3._ +import chisel3.util._ +import chisel3.experimental._ + +import interfaces._ + +//TODO: 1) L289-290 should be reconsidered +// 2) SidebandLinkDeserializer needs to have CDC crossings + +// import freechips.rocketchip.config.Parameters +import freechips.rocketchip.util._ + +case class SidebandParams( + // val NC_width: Int = 32, // This is merged into the FDI Params + val sbNodeMsgWidth: Int = 128, // Internal SB msg widths in individual layers + val maxCrd: Int = 32, +) + +// SidebandLinkNode connects the SB messaging to the AFE, so it does not carry credit +class SidebandLinkNode(val sbParams: SidebandParams, val fdiParams: FdiParams) + extends Module { + val io = IO(new SidebandLinkIO(sbParams, fdiParams)) + + val tx_ser = Module(new SidebandLinkSerializer(sbParams, fdiParams)) + val rx_des = Module(new SidebandLinkDeserializer(sbParams, fdiParams)) + val rx_queue = Module(new SidebandPriorityQueue(sbParams)) + + // Connect outer signals + io.outer.tx <> tx_ser.io.out + io.outer.rx.clock <> rx_des.io.in.remote_clock + io.outer.rx.bits <> rx_des.io.in.bits + + // Connect rx queue and deserializer + rx_queue.io.enq <> rx_des.io.out + + // Connect inner signals + io.inner.layer_to_node.ready <> tx_ser.io.in.ready + + tx_ser.io.in.bits <> Cat( + io.inner.layer_to_node.bits(127, 59), + 0.U(1.W), + io.inner.layer_to_node.bits(57, 0), + ) + tx_ser.io.in.valid <> io.inner.layer_to_node.valid + + io.inner.node_to_layer <> rx_queue.io.deq + +} + +// SidebandNode is the inter/intra layer SB messaging and uses credit flow +class SidebandNode(val sbParams: SidebandParams, val fdiParams: FdiParams) + extends Module { + val io = IO(new SidebandNodeIO(sbParams, fdiParams)) + + val tx_ser = Module(new SidebandSerializer(sbParams, fdiParams)) + val rx_queue = Module(new SidebandPriorityQueue(sbParams)) + val rx_des = Module(new SidebandDeserializer(sbParams, fdiParams)) + + // Connect outer signals + io.outer.tx <> tx_ser.io.out + io.outer.rx.valid <> rx_des.io.in.valid + io.outer.rx.bits <> rx_des.io.in.bits + io.outer.rx.credit := rx_queue.io.deq.fire && (!SBM.isComplete( + rx_queue.io.deq.bits.asUInt, + )) + + // Connect rx queue and deserializer + rx_queue.io.enq <> rx_des.io.out + + // Connect inner signals + io.inner.layer_to_node.ready <> tx_ser.io.in.ready + + tx_ser.io.in.bits <> io.inner.layer_to_node.bits + tx_ser.io.in.valid <> io.inner.layer_to_node.valid + + io.inner.node_to_layer <> rx_queue.io.deq +} + +class SidebandPriorityQueue(val sbParams: SidebandParams) extends Module { + val io = IO(new Bundle { + val enq = Flipped(Decoupled(UInt(sbParams.sbNodeMsgWidth.W))) + val deq = Decoupled(UInt(sbParams.sbNodeMsgWidth.W)) + }) + + val p0_queue = Module( + new Queue(UInt(sbParams.sbNodeMsgWidth.W), 4), + ) // highest priority queue, for access completion packets + val p1_queue = Module( + new Queue(UInt(sbParams.sbNodeMsgWidth.W), sbParams.maxCrd), + ) // second highest priority queue, for message packets + val p2_queue = Module( + new Queue(UInt(sbParams.sbNodeMsgWidth.W), sbParams.maxCrd), + ) // lowest priority queue, for access request packets + + val enq_arb = Module(new SidebandEnqArbiter(sbParams)) + val deq_arb = Module(new SidebandDeqArbiter(sbParams)) + + enq_arb.io.in <> io.enq + enq_arb.io.out(0) <> p0_queue.io.enq + enq_arb.io.out(1) <> p1_queue.io.enq + enq_arb.io.out(2) <> p2_queue.io.enq + + deq_arb.io.in(0) <> p0_queue.io.deq + deq_arb.io.in(1) <> p1_queue.io.deq + deq_arb.io.in(2) <> p2_queue.io.deq + deq_arb.io.out <> io.deq +} + +class SidebandEnqArbiter(val sbParams: SidebandParams) extends Module { + val io = IO(new Bundle { + val out = Vec(3, Decoupled(UInt(sbParams.sbNodeMsgWidth.W))) + val in = Flipped(Decoupled(UInt(sbParams.sbNodeMsgWidth.W))) + }) + val lIndex: Array[Int] = Array(0, 1, 2) + lIndex.foreach(i => io.out(i).bits := io.in.bits) + // fake decoupled interface, out(*).ready is always true + // lIndex.foreach(i => io.out(i).ready := true.B) + // fake decoupled interface, in.ready is always true + io.in.ready := true.B + io.out(0).valid := io.in.valid && SBM.isComplete(io.in.bits) + io.out(1).valid := io.in.valid && SBM.isMessage(io.in.bits) + io.out(2).valid := io.in.valid && SBM.isRequest(io.in.bits) +} + +class SidebandDeqArbiter(val sbParams: SidebandParams) extends Module { + val io = IO(new Bundle { + val out = Decoupled(UInt(sbParams.sbNodeMsgWidth.W)) + val in = Vec(3, Flipped(Decoupled(UInt(sbParams.sbNodeMsgWidth.W)))) + }) + val lIndex: Array[Int] = Array(0, 1, 2) + io.out.valid := io.in(0).valid || io.in(1).valid || io.in(2).valid + // traffic arbitration + when(io.in(0).valid) { + lIndex.foreach(i => + io.in(i).ready := (if (i == 0) io.out.ready else false.B), + ) + io.out.bits := io.in(0).bits + }.elsewhen(io.in(1).valid) { + lIndex.foreach(i => + io.in(i).ready := (if (i == 1) io.out.ready else false.B), + ) + io.out.bits := io.in(1).bits + }.elsewhen(io.in(2).valid) { + lIndex.foreach(i => + io.in(i).ready := (if (i == 2) io.out.ready else false.B), + ) + io.out.bits := io.in(2).bits + }.otherwise { + lIndex.foreach(i => io.in(i).ready := (false.B)) + io.out.bits := io.in(0).bits + } +} + +class SidebandSerializer(val sbParams: SidebandParams, val fdiParams: FdiParams) + extends Module { + val sb_w = fdiParams.sbWidth + val msg_w = sbParams.sbNodeMsgWidth + val cdt_max = sbParams.maxCrd + val io = IO(new Bundle { + val in = Flipped(Decoupled(UInt(msg_w.W))) + val out = new Bundle { + val bits = Output(UInt(sb_w.W)) + val valid = Output(Bool()) + val credit = Input(Bool()) + } + }) + + val dataBits = msg_w + val dataBeats = (dataBits - 1) / sb_w + 1 + val data = Reg(UInt(dataBits.W)) + + val sending = RegInit(false.B) + val (sendCount, sendDone) = Counter(io.out.valid, dataBeats) + + val current_credit = RegInit(cdt_max.U((log2Ceil(cdt_max) + 1).W)) + val isComplete = RegInit(false.B) + + io.in.ready := (!sending && (SBM.isComplete( + io.in.bits.asUInt, + ) || (current_credit > 0.U))) // set ready if credit>0 or completion packet + io.out.valid := (((current_credit > 0.U) || isComplete) && sending) // Don't need to check credit for access completion packets + io.out.bits := data(sb_w - 1, 0) + + when(io.in.fire) { + data := io.in.bits.asUInt + sending := true.B + isComplete := SBM.isComplete(io.in.bits.asUInt) + } + + when(io.out.valid) { data := data >> sb_w.U } + + when(sendDone) { + sending := false.B + when(isComplete === false.B) { current_credit := current_credit - 1.U } + } + + when(io.out.credit) { current_credit := current_credit + 1.U } +} + +class SidebandDeserializer( + val sbParams: SidebandParams, + val fdiParams: FdiParams, +) extends Module { + val sb_w = fdiParams.sbWidth + val msg_w = sbParams.sbNodeMsgWidth + val io = IO(new Bundle { + val in = new Bundle { + val bits = Input(UInt(sb_w.W)) + val valid = Input(Bool()) + } + val out = Decoupled(UInt(msg_w.W)) + }) + + val dataBits = msg_w + val dataBeats = (dataBits - 1) / sb_w + 1 + val data = Reg(Vec(dataBeats, UInt(sb_w.W))) + + val receiving = RegInit(true.B) + val (recvCount, recvDone) = Counter(io.in.valid, dataBeats) + + io.out.valid := !receiving + io.out.bits := data.asUInt + + when(io.in.valid) { + data(recvCount) := io.in.bits + } + + when(recvDone) { receiving := false.B } + + when(io.out.fire) { receiving := true.B } +} + +class SidebandLinkSerializer( + val sbParams: SidebandParams, + val fdiParams: FdiParams, +) extends Module { + val sb_w = fdiParams.sbWidth + val msg_w = sbParams.sbNodeMsgWidth + val io = IO(new Bundle { + val in = Flipped(Decoupled(UInt(msg_w.W))) + val out = new Bundle { + val bits = Output(UInt(sb_w.W)) + val clock = Output(Bool()) + } + val counter = Output(UInt(log2Ceil(32).W)) + }) + + val dataBits = msg_w + val dataBeats = (dataBits - 1) / sb_w + 1 + val data = Reg(UInt(dataBits.W)) + + val counter_en = Wire(Bool()) + val counter_next = Wire(UInt(log2Ceil(32).W)) + val counter = RegEnable(counter_next, 0.U(log2Ceil(32).W), counter_en) + counter_next := Mux(counter === 31.U, 31.U, counter + 1.U) + + val sending = RegInit(false.B) + val done = RegInit(false.B) + val waited = RegInit(true.B) + val (sendCount, sendDone) = Counter(sending, dataBeats) + + val isComplete = RegInit(false.B) + + io.in.ready := (waited) // wait for 32 cycles between SB messages + io.out.clock := Mux(sending, clock.asUInt, false.B) + io.out.bits := data(sb_w - 1, 0) + + counter_en := false.B + + io.counter := counter + + when(io.in.fire) { + data := io.in.bits.asUInt + sending := true.B + waited := false.B + counter_next := 0.U + } + + when(sending) { data := data >> sb_w.U } + + when(sendDone) { + sending := false.B + done := true.B + } + + when(done) { + counter_en := true.B + waited := counter === 31.U + } +} + +class SidebandLinkDeserializer( + val sbParams: SidebandParams, + val fdiParams: FdiParams, +) extends Module { + val sb_w = fdiParams.sbWidth + val msg_w = sbParams.sbNodeMsgWidth + val io = IO(new Bundle { + val in = new Bundle { + val bits = Input(UInt(sb_w.W)) + val remote_clock = Input(Bool()) + } + val out = Decoupled(UInt(msg_w.W)) + }) + + val remote_clock = io.in.remote_clock.asClock + + val dataBits = msg_w + val dataBeats = (dataBits - 1) / sb_w + 1 + val data = Reg(Vec(dataBeats, UInt(sb_w.W))) + + val receiving = RegInit(true.B) + + withClock(remote_clock) { + + val (recvCount, recvDone) = Counter(true.B, dataBeats) + + val recvCount_delay = RegInit(0.U(log2Ceil(dataBeats).W)) + recvCount_delay := recvCount + + data(recvCount_delay) := io.in.bits + when(recvDone) { receiving := false.B } + when(io.out.fire) { receiving := true.B } + io.out.valid := !receiving + + io.out.bits := data.asUInt + } +} diff --git a/src/main/scala/sideband/sidebandSwitcher.scala b/src/main/scala/sideband/sidebandSwitcher.scala new file mode 100644 index 0000000..5958600 --- /dev/null +++ b/src/main/scala/sideband/sidebandSwitcher.scala @@ -0,0 +1,131 @@ +package edu.berkeley.cs.ucie.digital +package sideband + +import chisel3._ +import chisel3.util._ +import chisel3.experimental._ +//import circt.stage.ChiselStage + +import interfaces._ + +// import freechips.rocketchip.config.Parameters +import freechips.rocketchip.util._ + +class sidebandSwitcher(val myID: BigInt, val sbParams: SidebandParams) + extends Module { + val io = IO(new SidebandSwitcherIO(sbParams)) + + val node_to_node_below_to_above = Wire( + Decoupled(UInt(sbParams.sbNodeMsgWidth.W)), + ) + val node_to_node_above_to_below = Wire( + Decoupled(UInt(sbParams.sbNodeMsgWidth.W)), + ) + + val outer_node_to_layer_below_subswitch = Module( + new sidebandOneInTwoOutSwitch(myID, sbParams), + ) + val outer_node_to_layer_above_subswitch = Module( + new sidebandOneInTwoOutSwitch(myID, sbParams), + ) + + outer_node_to_layer_below_subswitch.io.outer_node_to_layer <> io.outer.node_to_layer_below + outer_node_to_layer_above_subswitch.io.outer_node_to_layer <> io.outer.node_to_layer_above + + outer_node_to_layer_below_subswitch.io.inner_node_to_layer <> io.inner.node_to_layer_below + outer_node_to_layer_above_subswitch.io.inner_node_to_layer <> io.inner.node_to_layer_above + + node_to_node_below_to_above <> outer_node_to_layer_below_subswitch.io.node_to_node + node_to_node_above_to_below <> outer_node_to_layer_above_subswitch.io.node_to_node + + val outer_layer_to_node_above_subswitch = Module( + new sidebandTwoInOneOutSwitch(sbParams), + ) + val outer_layer_to_node_below_subswitch = Module( + new sidebandTwoInOneOutSwitch(sbParams), + ) + + outer_layer_to_node_above_subswitch.io.node_to_node <> node_to_node_below_to_above + outer_layer_to_node_below_subswitch.io.node_to_node <> node_to_node_above_to_below + + outer_layer_to_node_above_subswitch.io.outer_layer_to_node <> io.outer.layer_to_node_above + outer_layer_to_node_below_subswitch.io.outer_layer_to_node <> io.outer.layer_to_node_below + + outer_layer_to_node_above_subswitch.io.inner_layer_to_node <> io.inner.layer_to_node_above + outer_layer_to_node_below_subswitch.io.inner_layer_to_node <> io.inner.layer_to_node_below +} + +class sidebandOneInTwoOutSwitch(val myID: BigInt, val sbParams: SidebandParams) + extends Module { + val io = IO(new Bundle { + val outer_node_to_layer = + Flipped(Decoupled(UInt(sbParams.sbNodeMsgWidth.W))) + val inner_node_to_layer = Decoupled(UInt(sbParams.sbNodeMsgWidth.W)) + val node_to_node = Decoupled(UInt(sbParams.sbNodeMsgWidth.W)) + }) + io.inner_node_to_layer.valid := io.outer_node_to_layer.valid && io.outer_node_to_layer + .bits(58, 56) === myID.U + io.inner_node_to_layer.bits := io.outer_node_to_layer.bits + io.node_to_node.valid := io.outer_node_to_layer.valid && io.outer_node_to_layer + .bits(58, 56) =/= myID.U + io.node_to_node.bits := io.outer_node_to_layer.bits + + io.outer_node_to_layer.ready := Mux( + io.outer_node_to_layer.bits(58, 56) === myID.U, + io.inner_node_to_layer.ready, + io.node_to_node.ready, + ) +} + +class sidebandTwoInOneOutSwitch(val sbParams: SidebandParams) extends Module { + val io = IO(new Bundle { + val outer_layer_to_node = Decoupled(UInt(sbParams.sbNodeMsgWidth.W)) + val inner_layer_to_node = + Flipped(Decoupled(UInt(sbParams.sbNodeMsgWidth.W))) + val node_to_node = Flipped(Decoupled(UInt(sbParams.sbNodeMsgWidth.W))) + }) + // indicates whether node_to_node or inner_layer_to_node has priority + val flag = Wire(Bool()) + // priority is 0 if SBM.isComplete(x), 1 if SBM.isMessage(x), 2 otherwise + val priority_node_to_node = Wire(UInt(2.W)) + val priority_inner_layer_to_node = Wire(UInt(2.W)) + + priority_node_to_node := Mux( + SBM.isComplete(io.node_to_node.bits), + 0.U, + Mux(SBM.isMessage(io.node_to_node.bits), 1.U, 2.U), + ) + priority_inner_layer_to_node := Mux( + SBM.isComplete(io.inner_layer_to_node.bits), + 0.U, + Mux(SBM.isMessage(io.inner_layer_to_node.bits), 1.U, 2.U), + ) + flag := Mux( + io.node_to_node.valid && io.inner_layer_to_node.valid, + priority_inner_layer_to_node > priority_node_to_node, + Mux(io.node_to_node.valid, true.B, false.B), + ) + // if flag is true, then node_to_node has priority + io.outer_layer_to_node.valid := io.node_to_node.valid || io.inner_layer_to_node.valid + io.outer_layer_to_node.bits := Mux( + flag, + io.node_to_node.bits, + io.inner_layer_to_node.bits, + ) + io.node_to_node.ready := Mux(flag, io.outer_layer_to_node.ready, false.B) + io.inner_layer_to_node.ready := Mux( + flag, + false.B, + io.outer_layer_to_node.ready, + ) +} + +// object FirrtlMain extends App { +// ChiselStage.emitCHIRRTL(new sidebandSwitcher(0, new SidebandParams())) +// } + +// object VerilogMain extends App { +// ChiselStage.emitSystemVerilog( +// new sidebandOneInTwoOutSwitch(0, new SidebandParams()), +// ) +// }