Post

Constellation

refrence — Constellation文档

NoC 的物理规格本身分为五个部分:topology、Channels、ingresses、egresses、routerParams

物理spec

topology

PhysicalTopology是一个描述有向图的案例类,其中节点表示路由器,边表示单向通道。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
trait PhysicalTopology {
  // Number of nodes in this physical topology
  val nNodes: Int

  /** Method that describes the particular topology represented by the concrete
    * class. Returns true if the two nodes SRC and DST can be connected via a
    * directed channel in this topology and false if they cannot.
    *
    *  @param src source point
    *  @param dst destination point
    */
  def topo(src: Int, dst: Int): Boolean //为1代表有向连接

  /** Plotter from TopologyPlotters.scala.
    * Helps construct diagram of a concrete topology. */
  val plotter: PhysicalTopologyPlotter
}
  • Terminal Router Topologies在原有路由基础上包装进一步拓扑,TerminalRouter拓扑必须与TerminalRouting路由关系包装器一起使用

terminal_topology

  • Hierarchical分层拓扑,HierarchicalTopology拓扑必须与HierarchicalRouting路由关系包装器一起使用

Hierarchical

topo_archi

Channels

PhysicalTopology指向的每条edge都会调用函数来确定通道参数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
case class UserChannelParams(
  virtualChannelParams: Seq[UserVirtualChannelParams] =
    Seq(UserVirtualChannelParams()),
  channelGen: Parameters => ChannelOutwardNode => ChannelOutwardNode =
    p => u => u,
  crossingType: ClockCrossingType = NoCrossing,//Currently unsupported
  useOutputQueues: Boolean = true,
  srcSpeedup: Int = 1,
  destSpeedup: Int = 1
) {
  val nVirtualChannels = virtualChannelParams.size
}

case class UserVirtualChannelParams(
  bufferSize: Int = 1
)
virtualChannelParams

包含一个对象的列表,其中的每一个元素代表一个虚拟通道,并且该对象保存该虚拟通道的缓冲区条目数

channelGen

仅用于指定在通道中添加额外的pipeline buffers

srcSpeedup

表示一个周期内可能进入通道的flits数量。当srcSpeedup > 1 时,发生器将有效增加通道的输入带宽。

destSpeedup

表示一个循环中可能退出通道的 flits 数量。增加这个压力会给目的路由器的路由资源和交换机带来压力。

Terminals

 UserIngressParamsUserEgressParams案例类指定入口和出口终端的位置

还可以显示指定负载,Constellation 将自动生成宽度转换器以进一步分段或合并 flits。

1
2
3
4
5
6
7
8
ingresses = Seq(UserIngressParams(0), payloadBits=128)),
egresses  = Seq( UserEgressParams(1), payloadBits=128)),
routers   = (i) => UserRouterParams(payloadBits=64),

//可以指定其内部的payloadWidth,宽度需要是彼此的倍数
 routerParams = (i) => UserRouterParams(payloadWidth =
    if (i == 1 or i == 2) 128 else 64),
)

payload

前提是终端有效负载宽度是路由器有效负载宽度的倍数或因子。谨慎使用有效负载宽度转换器。例如,每片 64 位的 3 片数据包,如果放大为每片 128 位的 2 片数据包,则将被缩小为每片 64 位的 4 片数据包

Routers

RouteComputer对应RC阶段

VirtualChannelAllocator对应VA阶段

Flits 在SA阶段向SwitchAllocator请求访问路由器中的crossbar switch。该阶段还检查下一个虚拟通道是否有一个空的缓冲区槽来容纳该 flit。

A flit traverses(遍历) the crossbar switch in the ST stage.

流量控制是基于信用的,离开InputUnit flit 将信用向后发送到其源路由器上的OutputUnit 。


终端 Ingress 和 Egress 点视为InputUnitsOutputUnits的特殊instances

当启用coupleSAVA时,释放的虚拟通道将在同一周期立即可用。然而, `coupleSAVA`可以在高基数路由器上引入长组合路径

coupleSAVA

Virtual Channel Allocator请查阅

  • PIMMultiVCAllocator为可分离分配器实现并行迭代匹配

  • ISLIPMultiVCAllocator实现可分离分配器的 ISLIP 策略

  • RotatingSingleVCAllocator在传入请求之间轮换

  • PrioritizingSingleVCAllocator根据路由关系给出的优先级,将某些 VC 优先于其他 VC

Flows Specification

1
2
3
4
  // (blocker, blockee) => bool
  // If true, then blocker must be able to proceed when blockee is blocked
  vNetBlocking: (Int, Int) => Boolean = (_, _) => true,
  flows: Seq[FlowParams] = Nil,

NoCParamsflowsclasses FlowParams的一个列表,每个flowuniquely identifies its source ingress terminal, destination egress terminal, and the virtual subnetwork identifier.

Virtual subnetworks are used to delineate between different channels of a actual messaging protocol, and is necessary for avoiding protocol-deadlock.vNetId字段可用于指定flow的虚拟子网标识符

vNetBlocking功能指示哪些虚拟子网必须在某些其他虚拟子网被阻止时进行转发。如果vNetBlocking(x, y) == true ,则来自子网x的数据包必须继续转发,而子网y的数据包则停滞。

Routing Configuration

1
2
3
4
5
6
7
8
9
10
11
12
13
14
abstract class RoutingRelation(topo: PhysicalTopology) {
  // Child classes must implement these
  def rel       (srcC: ChannelRoutingInfo,
                 nxtC: ChannelRoutingInfo,
                 flow: FlowRoutingInfo): Boolean

  def isEscape  (c: ChannelRoutingInfo,
                 vNetId: Int): Boolean = true

  def getNPrios (src: ChannelRoutingInfo): Int = 1

  def getPrio   (srcC: ChannelRoutingInfo,
                 nxtC: ChannelRoutingInfo,
                 flow: FlowRoutingInfo): Int = 0
ChannelRoutingInfo

唯一标识

1
2
3
4
5
6
case class ChannelRoutingInfo(
  src: Int,//channel的source physical node,如果这是入口通道,则该值为-1
  dst: Int,
  vc: Int,//virtual channel index within the channel
  n_vc: Int//该物理通道中可用的虚拟通道的数量
) {

In the current implementations, packets arriving at the egress physical node are always directed to the egress. Thus, ChannelRoutingInfo for the egress channels are not used.到达出口物理节点的数据包总是被定向到出口,这种限制阻碍了偏转路由算法的实现

Flow Identifier

唯一标识可能穿过 NoC 的potential flow, or packet

1
2
3
4
5
6
7
8
9
10
case class FlowRoutingInfo(
  ingressId: Int,//ingress index of the flow
  egressId: Int,
  vNetId: Int,//virtual subnetwork identifier of this flow
  ingressNode: Int,//the physical node of the ingress of this flow.
  ingressNodeId: Int,//物理节点上所有入口中入口的索引
  egressNode: Int,
  egressNodeId: Int,
  fifo: Boolean
) {

flowrouting

这里我没有怎么看懂他的例子

组合路由

constellation/src/main/scala/routing/RoutingRelations.scala中有多种routing relations,为所包含的拓扑生成器提供无死锁路由,这里面有组合路由,可以这样用:

1
2
3
4
5
6
//a Mesh2DEscapeRouting algorithm with two escape channels using dimension-orderd routing
EscapeChannelRouting(
  escapeRouter    = Mesh2DDimensionOrderedRouting(),
  normalRouter    = Mesh2DMinimalRouting(),
  nEscapeChannels = 2
)

Terminal Router Routing

1
2
topolog = TerminalRouter(BidirectionalLine(4)) //Terminal Router Topologies
routing = TerminalRouterRouting(BidirectionalLineRouting())//`TerminalRouterRouting`路由关系

TerminalRouterRouting

terminal的topo描述

Hierarchical Topology Routing

Hierarchicalrouting

Hierarchical的topo描述

虚拟子网路由关系–看不懂

Protocol

Abstract Protocol Interface

1
2
3
4
5
6
7
8
9
10
11
12
13
14
trait ProtocolParams {
  val minPayloadWidth: Int// flits 传输此协议所需的最小有效负载宽度
  val ingressNodes: Seq[Int]//所有入口终端的物理节点目的地的有序列表
  val egressNodes: Seq[Int]
  val nVirtualNetworks: Int//该协议中虚拟子网的数量,通常是协议通道的数量
  val vNetBlocking: (Int, Int) => Boolean//该协议中虚拟子网之间的阻塞/非阻塞关系
  val flows: Seq[FlowParams]// possible flows for the protocol
  def genIO()(implicit p: Parameters): Data//返回整个互连的协议级 IO
  def interface(
    terminals: NoCTerminalIO,//为NoC 提供接口
    ingressOffset: Int,
    egressOffset: Int,
    protocol: Data)(implicit p: Parameters)//为协议提供接口
}

Standalone Protocol NoC

1
2
3
4
5
6
7
8
9
case class ProtocolNoCParams(
  nocParams: NoCParams,//参数化network
  protocolParams: Seq[ProtocolParams]//参数化协议接口
)
class ProtocolNoC(params: ProtocolNoCParams)(implicit p: Parameters) extends Module {
  val io = IO(new Bundle {
    val ctrl = if (params.nocParams.hasCtrl) Vec(params.nocParams.topology.nNodes, new RouterCtrlBundle) else Nil
    val protocol = MixedVec(params.protocolParams.map { u => u.genIO() })
  })

通过将多个ProtocolParams传递给protocolParams可以在共享互连上支持多个协议

AXI4

1
2
3
4
5
6
7
8
9
10
case class AXI4ProtocolParams(
  edgesIn: Seq[AXI4EdgeParameters],
  edgesOut: Seq[AXI4EdgeParameters],
  edgeInNodes: Seq[Int],
  edgeOutNodes: Seq[Int],
  awQueueDepth: Int
) extends ProtocolParams {
//AXI4EdgeParameters类的定义可以在 Rocketchip 中找到。
// edgesIn和edgesOut是向内和向外 AXI-4 边缘的有序列表(分别来自主设备和从设备)
// edgeInNodes和edgeOutNodes将主节点和从节点映射到物理节点索引

Diplomatic Protocol

没看懂。待定

NoC 集成的示例可以在 Chipyard 的MultiNoCConfig中的NoCConfigs.scala文件中找到

Constellation 还支持无死锁的共享全局互连。追求这种集成风格的配置应该设置GlobalNoCParams字段 constellation.soc.WithGlobalNoC 。

全局共享 NoC 配置的一个示例是 Chipyard 中NoCConfigs.scala中的SharedNoCConfig 。

This post is licensed under CC BY 4.0 by the author.