Skip to content

Commit 291733d

Browse files
authored
Merge pull request #2316 from ucb-bar/ctc-bridge
Add CTC link
2 parents 44fec76 + 9f9900a commit 291733d

File tree

20 files changed

+820
-3
lines changed

20 files changed

+820
-3
lines changed

build.sbt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,7 @@ lazy val rocketLibDeps = (rocketchip / Keys.libraryDependencies)
160160

161161
// -- Chipyard-managed External Projects --
162162

163-
lazy val testchipip = withInitCheck((project in file("generators/testchipip")), "testchipip")
163+
lazy val testchipip = withInitCheck(freshProject("testchipip", file("generators/testchipip")), "testchipip")
164164
.dependsOn(rocketchip, rocketchip_blocks)
165165
.settings(libraryDependencies ++= rocketLibDeps.value)
166166
.settings(commonSettings)

docs/Generators/TestChipIP.rst

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,3 +104,18 @@ The pin can be added to a system with the ``testchipip.soc.WithChipIdPin`` confi
104104
width and MMIO address are parameterizable and can be set by passing ``ChipIdPinParams`` as an
105105
argument to the config. The width can additionally be set using the ``testchipip.soc.WithChipIdPinWidth``
106106
config.
107+
108+
CTC
109+
---------------
110+
111+
The CTC (Chip-To-Chip) link converts TileLink requests to a simple 32-bit protocol,
112+
similar to TSI. This link is intended to connect chiplets in a Chipyard design, and can be
113+
added to a multichip config using ``chipyard.harness.WithMultiChipCTC``. To add CTC ports to
114+
a single SoC, use ``testchipip.ctc.WithCTC``. Refer to
115+
`ChipletConfigs.scala <https://github.com/ucb-bar/chipyard/blob/main/generators/chipyard/src/main/scala/config/ChipletConfigs.scala>`_
116+
for examples of configs with CTC.
117+
118+
By default, CTC uses the credited PHY provided with the Serial TileLink interface (see
119+
:ref:`Generators/TestChipIP:TileLink SERDES`). CTC can also be instantiated without a PHY. The
120+
intended use for this mode is for multi-chiplet FireSim simulations using the CTC bridge. For
121+
more information on FireSim, see :ref:`Simulation/FPGA-Accelerated-Simulation:FireSim`.

generators/chipyard/src/main/scala/DigitalTop.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ class DigitalTop(implicit p: Parameters) extends ChipyardSystem
3636
with chipyard.clocking.CanHaveClockTap // Enables optionally adding a clock tap output port
3737
with constellation.soc.CanHaveGlobalNoC // Support instantiating a global NoC interconnect
3838
with rerocc.CanHaveReRoCCTiles // Support tiles that instantiate rerocc-attached accelerators
39+
with testchipip.ctc.CanHavePeripheryCTC // Support optional CTC link
3940
{
4041
override lazy val module = new DigitalTopModule(this)
4142
}

generators/chipyard/src/main/scala/config/AbstractConfig.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ class AbstractConfig extends Config(
4949
new chipyard.iobinders.WithExtInterruptIOCells ++
5050
new chipyard.iobinders.WithChipIdIOCells ++
5151
new chipyard.iobinders.WithCustomBootPin ++
52+
new chipyard.iobinders.WithCTCIOCells ++
5253
// The "punchthrough" IOBInders below don't generate IOCells, as these interfaces shouldn't really be mapped to ASIC IO
5354
// Instead, they directly pass through the DigitalTop ports to ports in the ChipTop
5455
new chipyard.iobinders.WithI2CPunchthrough ++

generators/chipyard/src/main/scala/config/ChipletConfigs.scala

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,3 +142,34 @@ class MultiSimLLCChipletRocketConfig extends Config(
142142
new chipyard.harness.WithMultiChip(0, new RocketCoreChipletConfig) ++
143143
new chipyard.harness.WithMultiChip(1, new LLCChipletConfig)
144144
)
145+
146+
class CTCRocketConfig extends Config(
147+
new chipyard.harness.WithCTCLoopback ++
148+
new testchipip.ctc.WithCTC(Seq(new testchipip.ctc.CTCParams(onchipAddr = 0x1000000000L, offchipAddr = 0x0L, size = ((1L << 32) - 1), noPhy=true))) ++
149+
new RocketConfig
150+
)
151+
152+
class DoubleCTCRocketConfig extends Config(
153+
new chipyard.harness.WithCTCLoopback ++
154+
new testchipip.ctc.WithCTC(Seq(
155+
new testchipip.ctc.CTCParams(onchipAddr = 0x1000000000L, offchipAddr = 0x0L, size = ((1L << 32) - 1), noPhy=false),
156+
new testchipip.ctc.CTCParams(onchipAddr = 0x2000000000L, offchipAddr = 0x0L, size = ((1L << 32) - 1), noPhy=true)
157+
)) ++
158+
new RocketConfig
159+
)
160+
161+
class MultiCTCRocketConfig extends Config(
162+
new chipyard.harness.WithAbsoluteFreqHarnessClockInstantiator ++
163+
new chipyard.harness.WithMultiChipCTC(chip0=0, chip1=1, chip0portId=0, chip1portId=0) ++ // connect CTC port 0 of chip 0 and CTC port 0 of chip 1
164+
new chipyard.harness.WithMultiChip(0, new CTCRocketConfig) ++
165+
new chipyard.harness.WithMultiChip(1, new CTCRocketConfig)
166+
)
167+
168+
class MultiDoubleCTCRocketConfig extends Config(
169+
new chipyard.harness.WithAbsoluteFreqHarnessClockInstantiator ++
170+
new chipyard.harness.WithMultiChipCTC(chip0=0, chip1=1, chip0portId=0, chip1portId=0) ++ // connect CTC port 0 of chip 0 and CTC port 0 of chip 1
171+
new chipyard.harness.WithMultiChipCTC(chip0=0, chip1=1, chip0portId=1, chip1portId=1) ++ // connect CTC port 1 of chip 0 and CTC port 1 of chip 1
172+
new chipyard.harness.WithMultiChip(0, new DoubleCTCRocketConfig) ++
173+
new chipyard.harness.WithMultiChip(1, new DoubleCTCRocketConfig)
174+
)
175+

generators/chipyard/src/main/scala/harness/HarnessBinders.scala

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import testchipip.uart.{UARTAdapter, UARTToSerial}
2121
import testchipip.serdes._
2222
import testchipip.iceblk.{SimBlockDevice, BlockDeviceModel}
2323
import testchipip.cosim.{SpikeCosim}
24+
import testchipip.ctc.{CTCBridgeIO}
2425
import icenet.{NicLoopback, SimNetwork}
2526
import chipyard._
2627
import chipyard.clocking.{HasChipyardPRCI}
@@ -341,3 +342,38 @@ class WithOffchipBusSelPlusArg extends HarnessBinder({
341342
}
342343
})
343344

345+
class WithCTCTiedOff extends HarnessBinder({
346+
case (th: HasHarnessInstantiators, port: CTCPort, chipId: Int) => {
347+
port.io match {
348+
case io: CreditedSourceSyncPhitIO => {
349+
io.clock_in := false.B.asClock
350+
io.reset_in := false.B.asAsyncReset
351+
io.in := DontCare
352+
}
353+
case io: CTCBridgeIO => {
354+
io.manager_flit := DontCare
355+
io.manager_flit.in.valid := false.B
356+
io.manager_flit.out.ready := false.B
357+
io.client_flit := DontCare
358+
io.client_flit.in.valid := false.B
359+
io.client_flit.out.ready := false.B
360+
}
361+
}
362+
}
363+
})
364+
365+
class WithCTCLoopback extends HarnessBinder({
366+
case (th: HasHarnessInstantiators, port: CTCPort, chipId: Int) => {
367+
port.io match {
368+
case io: CreditedSourceSyncPhitIO => {
369+
io.clock_in := io.clock_out
370+
io.reset_in := io.reset_out
371+
io.in := io.out
372+
}
373+
case io: CTCBridgeIO => {
374+
io.client_flit.in <> io.manager_flit.out
375+
io.manager_flit.in <> io.client_flit.out
376+
}
377+
}
378+
}
379+
})

generators/chipyard/src/main/scala/harness/MultiHarnessBinders.scala

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,10 @@ import freechips.rocketchip.subsystem._
1010
import freechips.rocketchip.util._
1111

1212
import testchipip.serdes._
13+
import testchipip.ctc.{CTCBridgeIO}
1314

1415
import chipyard._
15-
import chipyard.iobinders.{GetSystemParameters, JTAGChipIO, HasChipyardPorts, Port, SerialTLPort}
16+
import chipyard.iobinders.{GetSystemParameters, JTAGChipIO, HasChipyardPorts, Port, SerialTLPort, CTCPort}
1617

1718
import scala.reflect.{ClassTag}
1819

@@ -78,3 +79,30 @@ class WithMultiChipSerialTL(chip0: Int, chip1: Int, chip0portId: Int = 0, chip1p
7879
}
7980
}
8081
)
82+
83+
class WithMultiChipCTC(chip0: Int, chip1: Int, chip0portId: Int = 0, chip1portId: Int = 0) extends MultiHarnessBinder(
84+
chip0, chip1,
85+
(p0: CTCPort) => p0.portId == chip0portId,
86+
(p1: CTCPort) => p1.portId == chip1portId,
87+
(th: HasHarnessInstantiators, p0: CTCPort, p1: CTCPort) => {
88+
(p0.io, p1.io) match {
89+
case(io0: CreditedSourceSyncPhitIO, io1: CreditedSourceSyncPhitIO) => {
90+
io0.clock_in := io1.clock_out
91+
io1.clock_in := io0.clock_out
92+
io0.reset_in := io1.reset_out
93+
io1.reset_in := io0.reset_out
94+
io0.in := io1.out
95+
io1.in := io0.out
96+
}
97+
case(io0: CTCBridgeIO, io1: CTCBridgeIO) => {
98+
// io0 client to io1 manager
99+
io0.client_flit.in <> io1.manager_flit.out
100+
io1.manager_flit.in <> io0.client_flit.out
101+
102+
// io1 client to io0 manager
103+
io1.client_flit.in <> io0.manager_flit.out
104+
io0.manager_flit.in <> io1.client_flit.out
105+
}
106+
}
107+
}
108+
)

generators/chipyard/src/main/scala/iobinders/IOBinders.scala

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ import testchipip.util.{ClockedIO}
3737
import testchipip.iceblk.{CanHavePeripheryBlockDevice, BlockDeviceKey, BlockDeviceIO}
3838
import testchipip.cosim.{CanHaveTraceIO, TraceOutputTop, SpikeCosimConfig}
3939
import testchipip.tsi.{CanHavePeripheryUARTTSI, UARTTSIIO}
40+
import testchipip.ctc.{CanHavePeripheryCTC}
4041
import icenet.{CanHavePeripheryIceNIC, SimNetwork, NicLoopback, NICKey, NICIOvonly}
4142
import chipyard.{CanHaveMasterTLMemPort, ChipyardSystem, ChipyardSystemModule}
4243
import chipyard.example.{CanHavePeripheryGCD}
@@ -607,3 +608,25 @@ class WithOffchipBusSel extends OverrideIOBinder({
607608
}.getOrElse(Nil, Nil)
608609
}
609610
})
611+
612+
class WithCTCIOCells extends OverrideIOBinder({
613+
(system: CanHavePeripheryCTC) => {
614+
val (ports, cells) = system.ctc_ios.zipWithIndex.map ({ case (c, id) =>
615+
val sys = system.asInstanceOf[BaseSubsystem]
616+
val (port, cells) = IOCell.generateIOFromSignal(c.getWrappedValue, s"ctc${id}_port", sys.p(IOCellKey), abstractResetAsAsync = true)
617+
(CTCPort(() => port, id), cells)
618+
}).unzip
619+
(ports.toSeq, cells.flatten.toSeq)
620+
}
621+
})
622+
623+
class WithCTCPunchthrough extends OverrideIOBinder({
624+
(system: CanHavePeripheryCTC) => {
625+
val (ports, cells) = system.ctc_ios.zipWithIndex.map ({ case (c, id) =>
626+
val port = IO(chiselTypeOf(c.getWrappedValue)).suggestName(s"ctc${id}_port") // Since CTC IO varies depending on params
627+
port <> c.getWrappedValue
628+
(CTCPort(() => port, id), Nil)
629+
}).unzip
630+
(ports.toSeq, cells.flatten.toSeq)
631+
}
632+
})

generators/chipyard/src/main/scala/iobinders/Ports.scala

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import testchipip.spi.{SPIChipIO}
1111
import testchipip.cosim.{TraceOutputTop, SpikeCosimConfig}
1212
import testchipip.iceblk.{BlockDeviceIO, BlockDeviceConfig}
1313
import testchipip.tsi.{UARTTSIIO}
14+
import testchipip.ctc.{CTCBridgeIO}
1415
import icenet.{NICIOvonly, NICConfig}
1516
import org.chipsalliance.cde.config.{Parameters}
1617
import freechips.rocketchip.amba.axi4.{AXI4Bundle, AXI4EdgeParameters}
@@ -115,3 +116,5 @@ case class GCDBusyPort (val getIO: () => Bool)
115116
case class OffchipSelPort (val getIO: () => UInt)
116117
extends Port[UInt]
117118

119+
case class CTCPort (val getIO: () => Data, val portId: Int)
120+
extends Port[Data]
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
// // See LICENSE for license details.
2+
3+
package firechip.bridgeinterfaces
4+
5+
import chisel3._
6+
import chisel3.util._
7+
8+
class DecoupledFlitIO(val flitWidth: Int) extends Bundle {
9+
val in = Flipped(Decoupled(UInt(flitWidth.W)))
10+
val out = Decoupled(UInt(flitWidth.W))
11+
}
12+
13+
class CTCBridgeIO(val w: Int) extends Bundle {
14+
val client_flit = new DecoupledFlitIO(w)
15+
val manager_flit = new DecoupledFlitIO(w)
16+
}
17+
18+
// NOTE: CTCBridgeIO in ctc is CTC.INNER_WIDTH=32b
19+
object CTC {
20+
val WIDTH = 32
21+
}
22+
23+
class CTCBridgeTargetIO extends Bundle {
24+
val clock = Input(Clock())
25+
val reset = Input(Bool())
26+
val ctc_io = Flipped(new CTCBridgeIO(CTC.WIDTH))
27+
}

0 commit comments

Comments
 (0)