https://mp.weixin.qq.com/s/oZCYBdy5glxJQmYKVWvpvA
简单介绍BankBinder的实现。
1. 基本介绍
A BankBinder is used to divide contiguous memory regions into banks, suitable for a cache:
a. BankBinder把连续的内存区域分成多个bank;
b. 每个Bank的大小与cache相匹配;
2. 使用
在ExampleRocketSystem中有使用:
其中:
a. 上游节点out连接到下游节点BankBinder,星号(*)在BankBinder一侧,即绑定中所包含的连接数由BankBinder节点决定;
b. 上游节点BankBinder连接到下游节点mbus.inwardNode,星号(*)在BankBinder一侧,即绑定中所包含的连接数由BankBinder节点决定;
c. nBanks和mbus.blockBytes都是2的幂;
3. BankBinderNode
LazyModule BankBinder中用于协商参数的diplomacy Node即为BankBinderNode:
BankBinderNode决定星型绑定中连接的数量,以及参数如何向上向下传递。
1) mask
生成BankBinder使用的参数,包含:
a. 每个bank的大小;
b. bank的mask;
实际使用中:
a. mbus.blockBytes为2的幂,是一个bank的大小,假设为0b0001_0000;
b. nBanks为2的幂,是bank的数目,假设为4,那么nBanks - 1 = 3 = 0b11;
c. mbus.blockBytes * (nBanks - 1) = 0b0011_0000;
2) bit
从mask中取出的最低位的1(mask & -mask),就是mbus.blockBytes,即bank的大小;
3) ids
mask中所有1的所有组合(AddressSet.enumerateMask(mask)),就是nBanks,即bank的数目;
4) maxXfer
最大的传输大小不超过bank的大小:
5) resolveStar
BankBinderNode是一个TLCustomNode,需要自己实现resolveStar:
a. BankBinder只是把上游的各个bank和下游的各个bank一一绑定到一起,两者数目相同都是ids.size;
b. oStars是输出侧星号的数目,如果星号的数目为0,那么星型绑定resove之后所得连接的数目也是0;如果星号的数目不是0,那么总连接数(ports)减去已知连接数的差值,除以星型绑定的数目,就是星型绑定中包含的连接的数目。(这里假设每个星型绑定包含的连接数目相等,否则就只能有一个星型绑定。)
c. iStars与oStars同理;
d. ports == iKnown + iStar * iStars表明了各个参数之间的关系;
6) mapParamsD
参数向下传递,根据上游节点传递给BankBinder的参数,生成BankBinder传递给下游节点的参数。亦即使用BankBinder看到的上游节点的参数,生成BankBinder给下游节点看的参数。
其中:
a. visibility使用id取其中的部分,即当前bank对应的那部分;
b. 支持的传输大小(supportsXXX)需要与maxXfer取交集;
7) mapParamsU
参数向上传递,根据下游节点传递给BankBinder的参数,生成BankBinder传递给上游节点的参数。亦即使用BankBinder看到的下游节点的参数,生成BankBinder给上游节点看的参数。
4. class BankBinder
LazyModule BankBinder中包含两个部分:
a. diplomacy节点:node;
b. lazy val module;
diplomacy节点node根据与上下游节点的连接以及协商而得的参数,生成模块外部接口(输入和输出接口);
lazy val module实现内部逻辑,即如何使用输入接口输入的数据、如何连接到输出接口;
这里的内部逻辑很简单,就是直接相连:out <> in。
5. object BankBinder
伴生对象,方便创建BankBinder(LazyModule),返回的其diplomacy node。用于与其他节点连接和绑定。