SoCs with NoC-based Interconnects
The primary way to integrate a network-on-chip into a Chipyard SoC is to map one of the standard TileLink crossbar-based buses (System Bus, Memory Bus, Control Bus, etc.) to a Constellation-generated NoC.
The interconnect can be mapped as a “private” interconnect for the TileLink bus, in which case a dedicated interconnect to carry the bus traffic will be generated. Alternatively, the interconnect can be mapped to a shared global interconnect, in which case multiple TileLink buses can be transported over a single shared interconnect.
Private Interconnects
Section titled “Private Interconnects”An example of integrating dedicated private interconnects for the System Bus, Memory Bus, and Control Bus can be seen in the MultiNoCConfig of generators/chipyard/src/main/scala/config/NoCConfigs.scala.
class MultiNoCConfig extends Config( new constellation.soc.WithCbusNoC(constellation.protocol.SimpleTLNoCParams( constellation.protocol.DiplomaticNetworkNodeMapping( inNodeMapping = ListMap( "serial_tl" -> 0), outNodeMapping = ListMap( "error" -> 1, "ctrls[0]" -> 2, "pbus" -> 3, "plic" -> 4, "clint" -> 5, "dmInner" -> 6, "bootrom" -> 7, "clock" -> 8)), NoCParams( topology = TerminalRouter(BidirectionalLine(9)), channelParamGen = (a, b) => UserChannelParams(Seq.fill(5) { UserVirtualChannelParams(4) }), routingRelation = NonblockingVirtualSubnetworksRouting(TerminalRouterRouting(BidirectionalLineRouting()), 5, 1)) )) ++ new constellation.soc.WithMbusNoC(constellation.protocol.SimpleTLNoCParams( constellation.protocol.DiplomaticNetworkNodeMapping( inNodeMapping = ListMap( "L2 InclusiveCache[0]" -> 1, "L2 InclusiveCache[1]" -> 2, "L2 InclusiveCache[2]" -> 5, "L2 InclusiveCache[3]" -> 6), outNodeMapping = ListMap( "system[0]" -> 0, "system[1]" -> 3, "system[2]" -> 4 , "system[3]" -> 7, "ram[0]" -> 0)), NoCParams( topology = TerminalRouter(BidirectionalTorus1D(8)), channelParamGen = (a, b) => UserChannelParams(Seq.fill(10) { UserVirtualChannelParams(4) }), routingRelation = BlockingVirtualSubnetworksRouting(TerminalRouterRouting(BidirectionalTorus1DShortestRouting()), 5, 2)) )) ++ new constellation.soc.WithSbusNoC(constellation.protocol.SimpleTLNoCParams( constellation.protocol.DiplomaticNetworkNodeMapping( inNodeMapping = ListMap( "Core 0" -> 1, "Core 1" -> 2, "Core 2" -> 4 , "Core 3" -> 7, "Core 4" -> 8, "Core 5" -> 11, "Core 6" -> 13, "Core 7" -> 14, "serial_tl" -> 0), outNodeMapping = ListMap( "system[0]" -> 5, "system[1]" -> 6, "system[2]" -> 9, "system[3]" -> 10, "pbus" -> 3)), NoCParams( topology = TerminalRouter(Mesh2D(4, 4)), channelParamGen = (a, b) => UserChannelParams(Seq.fill(8) { UserVirtualChannelParams(4) }), routingRelation = BlockingVirtualSubnetworksRouting(TerminalRouterRouting(Mesh2DEscapeRouting()), 5, 1)) )) ++ new freechips.rocketchip.rocket.WithNHugeCores(8) ++ new freechips.rocketchip.subsystem.WithNBanks(4) ++ new freechips.rocketchip.subsystem.WithNMemoryChannels(4) ++ new chipyard.config.AbstractConfig)Note that for each bus (Sbus / Mbus / Cbus), the configuration fragment provides both a parameterization of the private NoC, as well as a mapping between TileLink agents and physical NoC nodes.
For more information on how to construct the NoC parameters, see the Constellation documentation.