Rocket - regmapper - RegMapper

https://mp.weixin.qq.com/s/aXxgzWwh6unuztjgyVX0iQ

 

Brief realization of RegMapper.

 

1. brief

 

RegMapper specified input interface, read and write access logic generates a set of registers.

 

2. RegMapperParams

 

RegMapper define the parameters needed:

. A indexBits: the index number of occupied bits;

. B maskBits: data mask bits;

. C extraBits: median additional parameters;

 

3. RegMapperInput

 

Access logic input interface used:

. A read: if a read request;

. B index: the index number of the access destination register;

. C data: input data write request;

. D mask: the mask data, each byte bit mask;

. E extra: additional parameters;

 

4. RegMapperOutput

 

An output interface access logic, in response to the return request:

. A read: if the read response to the request;

. B data: response data read request;

. C extra: additional data returned;

 

5. RegMapper

 

1) The method can be extracted

 

a. toBits/ofBits

 

Convert to and from Bits:

 

Example:

 

b. Kantor

 

The first parameter for determining whether the participating OR literal value true, if the determination result returned directly truncated, i.e. Bool (true):

 

c. mux

 

a) MuxSeq using the index to select cases, if no default value is used:

b) f of type Seq [(Bool, Bool)];

c) Each set of s / g / f a return out || g!;

d) outputting the results of all tuples phase f in the second element (and) to OUT;

 

2) RegMapper.apply

 

The reconstructed code below after introduction.

 

A. Parameters

 

. A beatBytes: bus width (number of bytes);

. B concurrency: How many concurrent access support;

. C in: an access request input interface;

d mapping:. All registers field to access:

根据注释,Map的第一个元素为字节地址,第二个元素为这个字节地址对应的寄存器包含的寄存器域;

 

B. 过滤掉长度为0的寄存器域

 

其中,offset为字节地址偏移量;

 

C. 寄存器的字节地址不能为负值

 

 

D. 把字节地址分组的寄存器域,展开成使用位偏移量的寄存器域

 

其中,元组的第一个元素为寄存器域的位偏移量。

 

E. 检查寄存器域是否重叠

 

因为bitmap中的寄存器域已经排序了,所以只需要比较相邻的两个寄存器域是否重叠即可:

 

F. 把bitmap转换为wordmap:

 

每个word包含beatBytes个字节。wordmap中的key为字偏移量。对比之下,bytemap中二元组的第一个元素为字节地址偏移量,bitmap中二元组的第一个元素为位偏移量。

 

G. 确保所有寄存器域都可以按照字偏移量进行索引:

 

从中可以看出:寄存器索引(index)以字为单位,每个字包含beatBytes个字节。

 

H. 使用out返回响应结果

 

 

I. 使用front接收请求信息

 

 

J. 处理并发请求

 

a. 若寄存器域的读写有一个是时序逻辑,则需要使用pipeline;

b. depth为可以缓存的请求数量,即可以同时处理的请求数量;

c. back为Queue的输出端,或者就是front本身;

 

K. 找到区分字偏移量所需要的最少的位

 

其中:

a. mask:使用AddressDecoder获取到的包含最少掩码位的掩码;

b. maskMatch:undefZero相关,这里不关注;

c. maskFilter:把mask中各个位的值转换为Boolean列表;

d. maskBits:统计mask中为1的位的个数;

 

L. 计算有效寄存器字的数量

 

 

M. 计算有效寄存器字索引号

 

a. 软件计算:regIndexI;

b. 硬件计算:regIndexU;

 

这里为什么不用重载呢?两个方法都可以叫做regIndex,参数类型不同,编译器可以区分。

 

N. 使用有效字偏移量,摊平寄存器域

 

返回值是三元组序列:

a. 第一个元素是使用regIndexI计算出来的有效字偏移量;

b. 第二个元素是寄存器域的字内位偏移量;

c. 第三个元素是寄存器域;

 

O. 为每个寄存器域和有效寄存器字声明控制信号

 

其中:

a. frontMask和backMask是把位掩码拓宽为字节掩码的结果;

b. xxvalid/xxready每个寄存器域一个;

c. xxfire每个有效寄存器字一个;

d. dataOut每个有效寄存器字一个,用于处理读取请求时返回寄存器字的数据;

 

P. 逐个处理每个寄存器域

 

 

Q. 提取寄存器域信息

 

a. reg为有效字索引号;

b. low为字内位起始偏移量;

c. high为字内位终止偏移量;high不能超过字的范围;

d. field为寄存器域;

 

R. 提取寄存器域对应的掩码

 

a. rimask:前端掩码相应位相或的结果,r指read,i指input,即读请求的输入掩码;orR()的意义为只要涉及寄存器域的一个位,该寄存器域就参与操作;

b. romask:后端掩码相应位相或的结果,r指read,o指output,即读请求的输出掩码;

c. wimask:前端掩码相应位相与的结果,w指write,i指input,即写请求的输入掩码;andR()的意义为需要涉及寄存器域的全部位,该寄存器域才参与操作;

d. womask:后端掩码相应位相与的结果,w指write,o指output,即写请求的输出掩码;

e. front和back分别是Queue的前端和后端,亦即输入端和输出端,所以这里i和o也有输入端和输出端的意涵(implication),接下来在使用中还要具体辨析其含义;

 

S. 生成寄存器域的读写逻辑

 

这里以读请求为例,寄存器域读请求相关信号如下图:

先看f_rivalid:

a. rimask表明请求涉及到当前寄存器域;

b. rivalid(i)标识该寄存器域所在寄存器字中的其他寄存器域是否都准备好接收读请求;

c. 可以想见,其他寄存器域是否准备好接收读请求,也依赖于当前这个寄存器域是否准备好接收(f_riready);也就是说当rivalid(i)为真时,f_riready为真;

d. f_rivalid的意义为读请求输入有效;

 

再看f_roready:

a. romask表示请求涉及到当前寄存器域;

b. roready(i)表示是否准备好接收,所属寄存器字中的其他寄存器域的响应;

c. 是否准备好接收其他寄存器域的响应,也依赖于是否准备好接收当前寄存器域的响应(f_rovalid),也就是说当roready(i)为真时,f_rovalid为真;

d. f_roready的意义为准备好接收该寄存器域的响应;

 

然后看i/o:

a. f_rivalid是rimask掩码后的结果,rimask是请求队列(Queue)输入端的掩码,也就是说,只有涉及到该寄存器域时,其输入才有效;

b. f_roready是romask掩码后的结果,romask是请求队列(Queue)输出端的掩码,也就是说只有涉及到该寄存器域的请求出队时,才打开接收响应的开关。Queue是请求队列,没有涉及到该寄存器域的请求出队,则没有对该寄存器域的请求,自然也不需要接收响应;

 

最后:

a. f_riready由寄存器域输出;

b. f_rovalid由寄存器域输出;

c. 由寄存器域输出的信号,由寄存器域的读函数(RegReadFn)决定,而RegMapper这里不涉及如何产生这些信号的问题;

 

T. 收集寄存器字的控制信号

 

a. reg为有效寄存器字索引号,随着对所有寄存器域的遍历,该寄存器字包含的所有寄存器域的控制信号二元组都会被归集到该序列中;

b. litOR(f_riready, !rimask)等效于f_riready || !rimask,即寄存器域准备好接收请求或者不涉及该寄存器域;如果不涉及该寄存器域,那么接收请求又何妨呢?

c. rivalid(i)的值使用所在寄存器字的其他寄存器域的litOR(f_riready, !rimask)决定,这在后续代码中实现;

根据mux的实现:

a) f中包含寄存器字包含的全部寄存器域;

b) ReduceOthers的第一个效果是把f中所有元组的第二个元素相与之后赋值给out;第二个作用就是给rivalid(i)赋值,使用的就是f中除i之外的所有元组的第二个元素相与,然后再与valid && s && g相与;

 

U. 使用寄存器域读出的数据,组合寄存器字读请求应该返回的数据

 

a. 如果寄存器域偏移量为0,则直接使用相与的f_data即可;

b. 如果不是0,则需要把已经搜集的寄存器域数据,与f_data组合;需要注意的是flat中的寄存器域都是排过序的,所以f_data应该被置在高位,而dataOut(reg)与UInt(0, width=low)相或,则把现有的dataOut(reg)的位数拓展为low位;

c. 然后再与f_data组合之后的prepend,位数为high位;

d. 更新dataOut(reg)的值为组合之后的新值;需要注意的是,这个更新是在循环中进行。也就是在软件构建过程中进行。当该寄存器字包含的所有寄存器域都遍历完之后,dataOut(reg)中就组合了所有寄存器域读取数据,最后硬件逻辑中使用的是这个构建结果;

 

V. 入队请求索引号/出队请求索引号

 

 

W. 是否可以入队/是否可以出队

 

a. rifireMux表示读请求是否可以入队;wifireMux表示写请求是否可以入队;

b. rofireMux表示读请求是否可以出队;wofireMux表示写请求是否可以出队;

c. 这里忽略iRightReg/oRightReg,假设其中所有值都为true;

d. 以rifireMux为例:

a) in.valid && front.ready && front.bits.read表示读请求合法,且队列允许输入;

b) 接下来就看各个寄存器域是否允许读请求;

c) f为寄存器字中包含的所有寄存器域对应的二元组:

d) ReduceOthers把f中所有二元组的第二个元素相与之后,输出给out;也就是所有寄存器域的litOR(f_riready, !rimask),即所有寄存器域都准备好接收输入了;

e) 忽略!g,mux方法的输出为out;

f) out只取决于所有寄存器域是否准备好接收输入(f_riready);

g) 每个寄存器域是否有合法输入(f_rivalid),除了取决于其他寄存器域是否准备好接收输入外,则同时取决于valid && s && g。也就是说,即便所有寄存器域都准备好接收请求了,也未必有合法请求输入,取决于valid && s && g:

h) 所有寄存器域的rivalid(i)都依赖于valid && s && g,也就是说,当valid && s && g为假时,所有寄存器域都没有合法请求输入;

i) valid = in.valid && front.ready && front.bits.read,参考a);g忽略;s的意义为请求是否针对当前寄存器字;

j) 可见out在意义上,只相当于ready;在ready为真的情况下,valid && s && g在意义上相当于valid;

 

X. 根据是否读请求,确定请求队列输入端和输出端的ready信号

 

 

Y. 把输入接口与队列输入端相连,把输出接口与队列输出端相连

 

 

Z. 输出响应

 

a. 输出是否读请求的响应;

b. 输出读请求响应的数据;

c. extra原封不动的返回;

 

从中可以看出,输出接口中包含的响应,是针对队列输出端输出的请求的响应。

当然,如果队列为空,输入其中的请求,可以即时输出。队列是先入先出的。

 

3) 遗留问题

 

A. undefZero及其相关的iRightReg/oRightReg:

 

B. field.write.combinational选择数据的差异:

 

Guess you like

Origin www.cnblogs.com/wjcdx/p/11616211.html