tilelink_c

TL-C

TL-C在TL-UH的基础上增加了cache一致性支持,兼容MOESI协议。需要ABCDE五个通道,五个通道优先级递增。

Status

Status Description
Nothing 无效,没有cache数据,没有读写权限
Trunk 中间节点,没有读写权限,它的上级肯定有Tip,它不知道数据是否被改了,所有不能直接从它这里拿数据,也就没有读写权限了。
Tip (with no Branches) 顶层节点,有读写权限,可能有dirty数据
Tip (with Branches) 中间节点,只有读权限,可能有dirty数据。上层还有branch,所有没有写权限,如果要写需要先把上面的branch杀掉
Branch Tip的上层节点,只有读权限,不会有dirty数据。

Topology

拓扑结构有如下四种。其中TT代表Tip,T代表Trunk,B代表Branch。

Message

要变更权限,需要Acquire, Release, Probe一系列消息。

权限都是在param里面给的,acuqire都是请求升权限,release和probe都是降权限。

State Transform

假设现在拓扑结构如下图所示,有3个hart,hart0是没有L1 Cache的,它只能发出TL-UH的消息,hart1和hart2是有L1 Cache的,它支持TL-C。3个hart连到L2上,L2再连到MEMORY上。

每个Cache里的每条line都会保存自己的状态STATE,默认都是N,表示没有数据。还要保存是否有脏数据DIRTY,默认是0,表示没有脏数据。

对于L2来说,由于是中间节点,它还需要保存它的上一层哪个持有这条line,也就是CLIENT,每一bit代表一个上层节点,由于Hart0并没有Cache,所有它并不需要在L2有记录。

如果此时Hart0来读请求,Hart0会发送GET给L2,然后L2会从MEMORY里取出对应的Cache Line,放到L2中,然后L2的状态会成TIP。

如果此时Hart0再来写请求,Hart0会发送PUT给L2,然后L2把数据写到自己的Cache Line里面,并把DIRTY置1,表示和MEMORY已经不一致了。此时一般不会立即写回。

如果Hart1再来读请求,L1_1会发送AcquireBlock请求给L2,param是toB。L2发现现在只有并没有其他的节点拥有Cache Line,就会返回GrantData,param是toT,这是更激进的处理,因为Hart1很可能会再次操作这条Cache Line。L1_1收到响应后就把自己状态变为TIP,然后回L2一个GrantAck。L2收到知道处理完了,并把自己的状态变成TRUNK,CLIENT记录下L1_1拿走了Cache Line。

那之后Hart2又来了写请求,L1_2发送AcquireBlock toT给L2,L2发现自己是TRUNK,意味着它的上层一定有TIP,就向CLIENT发送PROBE请求,L1_1就把自己状态变成N,把权限还给L2,L2拿到权限再把数据回给L1_2,这时L1_2就把自己变成TIP,由于是写操作,就把DIRTY也变为一,然后再回L2GRANTACK,L2知道收到了,更新自己的CLIENT,标识现在L1_2拥有TIP权限了。

再来看下,如果此时Hart1又来了读请求。前面处理基本一致,但是L2发现两个想要权限,而此时L1_1要的是读权限,所以这次L2就直接回Branch权限给L1_1。把TIP权限保留在L2,并把L1_2也变成Branch,这样一来,L1_1和L1_2都能读,下次他两再读的时候就不用操作了。当然,如果有任意一方要写,还是需要把权限抢过来,并杀掉另一边的Branch。

最后再看一种情况,在这种情况下,Hart0来了一笔写操作。L2收到后,虽然它的状态是TIP,但是CLIENT是11,就意味着上面有人是BRANCH,是不能直接写的,需要先发probe把权限收回来,再把CLIENT清掉,才能写入数据,最后再回Hart0 AccessAck。

到目前为止,所有的状态都已经出现了。所有的消息类型也都出现了,除了Release类消息,这个消息处理也是类似的,只不过是主动交出数据和权限而已。

Concurrency

TODO