CCIX协议层
事务结构
请求事务
基于结构的不同请求类型如下:
全一致性读事务,包括:ReadUnique,ReadClean, ReadNotSharedDirty,ReadShared。其事务流程如下图。
请求芯片发出一个读请求事务,占用一个请求信用(request credit)。
主芯片返回读数据和相应的事务响应(使用CompData操作码)。
请求者发送确认响应,确认事务完成(使用CompAck操作码)。
非一致性或IO一致性读事务,包括:ReadNoSnp,ReadOnce,ReadOnceCleanInvalid,ReadOnceMakeInvalid。其事务流程如下图。
请求芯片发出一个读请求事务,占用一个请求信用(request credit)。
主芯片返回读数据和相应的事务响应(使用CompData操作码)。
此类事务不需要CompAck
无CompAck的无数据事务,包括:CleanShared,CleanSharedPersist,CleanInvalid,MakeInvalid,Evict. 其事务流程如下图。
请求芯片发出一个读请求事务,占用一个请求信用(request credit)。
主芯片返回Comp响应
有CompAck的无数据事务,包括:CleanUnique,MakeUnique。事务流程如下图。
请求芯片发出一个读请求事务,占用一个请求信用。
主芯片返回Comp响应
请求者发送确认响应,确认事务完成(使用CompAck操作码)。
所有写事务都使用相同的事务结构。事务流程如下图。
请求芯片发送一个写请求(带数据),占用一个请求信用和一个数据信用。
主芯片返回Comp响应。
原子事务基于Comp响应,分成两类,一类是AtomicStore(无数据),另一类是AtomicLoad,AtomicSwap,AtomicCompare(有数据)。事务流程如下图。
求芯片发送一个原子请求(带数据),占用一个请求信用和一个数据信用。
主芯片返回Comp(对应AtomicStore)或CompData(对应non-AtomicStore)。
监听事务
无数据响应的监听事务流程如下
主芯片发送监听请求,占用一个监听信用(snoop credit)。
被监听的芯片返回SnpResp,监听响应,包
有数据响应的监听事务流程如下
主芯片发出监听请求(除去SnpMakeI),占用一个监听信用。
被监听的芯片返回数据和响应的响应(SnpRespData或SnpRespDataPtl )
地址,控制和数据
地址和数据分配
对于读、无数据、写和原子事务,使用Addr字段和NonSec比特位访问内存位置。对于访问小于一个缓存行大小的ReadNoSnp、WriteNoSNPTL、WriteUniquePtl和原子事务,如果Addr[5:0]不全为零,则需要包含低阶地址位的扩展字段。如果Addr[5:0]全部为零,则允许(但不要求)使用扩展字段。原子事务中的地址必须与操作数大小对齐。
对于监听请求,Addr字段和NonSec指向可以被监听的地址。这两个字段足以唯一标识监听要访问的缓存行。
请求属性
请求属性表示请求数据的大小、内存类型及其属性。内存类型可以是设备(device)或普通(normal)。关于这两种类型可以参考以前的文章。
请求允许的内存类型
请求允许的内存类型包括:
ReadNoSnp/WriteNoSnp可以是Normal Non-cacheable或Device
除ReadNoSnp外的所有读事务只能写回。
所有无数据事务都可以写回
CleanShared、CleanSharedPersist、CleanInvalid和MakeInvalid的无数据事务也可以是Normal Non-cacheable或Device。
除WriteNonP外的所有写事务只能进行写回。
原子事务可以写回,Normal Non-cacheable或Device
数据和字节使能
在读请求或写请求中,ReqAttr字段的Size子字段决定了事务相关联的数据字节数。Size子字段的允许值为1B、2B、4B、5 8B、16B、32B、64B、128B。读响应或写请求中包含的数据字节可以是8B、16B、32B、64B或128B。仅当缓存行的大小配置为128B时,才允许使用128B。
当ReqAttr字段中的Size子字段为1B、2B或4B时,读响应消息或写请求消息中包含的数据字节数为8B。在所有其它情况下,请求的ReqAttr字段中的Size子字段与读响应消息或写请求消息中包含的数据字节数相同。当ReqAttr字段中的Size子字段为1B、2B或4B时,请求数据在消息中的位置由请求中的Address字段(Addr)确定。
对于以下的写请求,可以使用字节使能:
WriteNoSnpPtl
WriteUniquePtl
WriteBackPtl
排序
多拷贝原子性(multi-copy atomicity)
CCIX要求多拷贝原子性。所有组件都必须确保写请求是多拷贝原子的。如果满足以下两个条件,则写请求为多拷贝原子:
对同一位置的所有写入都是序列化的,也就是说,所有请求者都会以相同的顺序观察到所有写操作,尽管有些请求者可能不会观察到所有写入。
在所有请求者观察到写操作之前,对此位置的读操作不会得到写操作的值。
其实以上的要求,就是要确保存储一致性。
在CCIX规范中,如果两个缓存行地址和非安全属性相同,则认为这两个地址是相同的。
请求响应和排序
为了确保事务的先后顺序,无论是来自相同代理还是不同代理的Comp和CompData响应要遵循如下的规则:
对于Normal non-cacheable或Device的读事务和原子事务,CompData响应可确保该事务可被任何代理在相同端点地址范围内的后续事务观察到。端点地址范围的大小由实现定义。
对于WriteBack位置的读取和原子事务,CompData响应保证该事务可被任何代理到同一位置的后续事务观察到。
对于Device-nRnE或Device-nRE位置的写事务、无数据事务和原子事务,Comp响应保证该事务可被任何代理在同一端点地址范围内的后续事务观察到。端点地址范围的大小取决于具体实现。
对于WriteBack位置的写事务、无数据事务和原子事务。Comp响应可确保事务可被任何代理到同一位置的后续事务观察到。
流量控制和协议信用
此处穿插一些关于“信用”的数据传输机理。如果发送方和接收方之间没有什么握手协议的话,发送方就不知道接收方的具体情况。此时,如果接收方没有足够的能力接收新的数据,而发送方依然源源不断的发送数据,那么就很可能造成数据的丢失。因此,接收方需要一定的机制来控制数据流量。最直观的办法,就是当接收方不能接收新的数据时,要及时告知发送方,发送方应根据接收方的状态调整发送数据,这就是常说“反压(Back Pressure)”机制。
在简单的SoC设计中,可以通过总线实现接收方的“反压”,比如在APB总线中,从机(Slave)可以通过驱动ready信号来与主机(Master)共同控制数据传输。对于复杂的SoC设计,通过总线方式“反压”可能就不适合了,需要其它新的机制。基于信用的传输流量控制就是其中之一。其基本原理是,在发送方和接收方事先协调好一组“信用”值,发送方每发一次数据需要占用一个或几个“信用”,如果发送方的“信用”耗尽,就不能再发送新的数据,必须等待足够的“信用”;接收方每处理完一笔发送方的数据,返回一个或者几个“信用”给发送方,发送方得到新的“信用”以后就可以继续发送数据了。
关于基于信用的流量控制,有很多文章,具体实现也不尽相同,这里就不再展开了。
协议信用
定义了四种信用类型来管理消息流:
Request
Data
Snoop
Misc
消息的接收者必须授予信用,也就是说,向它有链接的每个发送者芯片发送信用。对于请求、数据和Snoop消息信用,信用的授予是通过其它消息或明确的信用交换机制进行的。对于杂项消息信用,信用的授予仅通过明确的信用交换机制,或通过使用credited杂项消息中的MiscCredit字段。
只有当发送方收到目标芯片的请求信用时,才能发送non-write或non-atomic请求。
只有当发送方从接收方收到请求信用和数据信用时,才能发送写请求或原子请求。
只有当发送方从接收方收到snoop信用时,才能发送snoop请求。
响应不需要任何明确的信用交换,所有响应都必须被接受。
只有当适当数量的杂项信息信用可用时,才能发送credited杂项信息。
信用交换
两种信用交换方式:
用于信用交换的独立消息,信用授予和信用返还消息。这种方式使用专用消息交换信用。消息格式允许信用授予和信用返还。在单个消息中的信用交换,必须是所有信用授予或所有信用返还,不允许混合使用这两种类型。
包头内信用授权。数据包头信用授权使用数据包头中6-bit的MsgCredit字段。
信用交换的规则:
对于每种信用类型,每个独立信用交换报文中可发送的最大信用数为255。
发送超过255个信用需要使用额外的信息。
独立的信用交换信息不需要发送任何形式的信用。
信用交换信息的发送速率没有上限。
允许单个数据包同时包含“数据包头信用授权”,和一条或多条“独立信用交换消息”。
每个信用类型最多可授予1023个信用。
原作者:老秦谈芯
更多回帖