https://mp.weixin.qq.com/s/qv9ia9bU2mvvihk5OxL5EQ
简单介绍ex_reg_mem_size相关的实现。
1. ex_reg_mem_size
1) 定义
ex_reg_mem_size是一个无符号整形寄存器,是IE/EX阶段的流水线寄存器,用于ID阶段向EX阶段传递参数:
2) 赋值
如果没有kill id阶段,则对ex_reg_mem_size的值进行更新:
其中:
a. 正常情况下,根据指令编码中相应的域,对其进行赋值:
整理如下:
b. 如果是fence_i指令,则不涉及内存操作,将size置为0:
注:这里的两层判断:if判断在构建阶段执行,用于判断生成的逻辑当中是否包含when() {…}这个逻辑块。when() {…}这个判断则是一个逻辑代码块,是最后生成的电路中的判断,用于在流水线中判断是否fence_i指令,而后将ex_reg_mem_size寄存器的值更新为0。
c. 如果是sfence指令,则将rs1/rs2待操作寄存器是否x0寄存器,编码存入ex_reg_mem_size:
2. ex_reg_mem_size与ex_slow_bypass
如果mem_size < 2,亦即操作的内存大小为字节或者半字,则(根据注释)bypass时要delay 2个cycle:
这里不展开进行分析。
3. ex_reg_mem_size用于sfence
针对sfence指令,其行为根据rs1/rx2寄存器与x0的关系而不同:
比较结果被编码在ex_reg_mem_size寄存器中:
其中:
a. bit0编码rs0是不是x0寄存器;
b. bit1编码rs1是不是x0寄存器;
ex_reg_mem_size的值用于更新mem_reg_mem_size:
其中,ex_reg_mem_size也用于从rs2中取出相应的域(字节、半字等)存入mem_reg_rs2。(其逻辑由StoreGen生成)
mem_reg_mem_size的值用于更新wb_reg_mem_size:
其中,mem_reg_rs2也用于更新wb_reg_rs2。
最后,wb_reg_mem_size/wb_reg_rs2用于封装io.imem.sfence:
忽略rocc的情况,wb_reg_rs2也只有这一个用途。
4. ex_reg_mem_size用于io.dmem.req
寄存器ex_reg_mem_size直接用于对dmem的请求:
其中:
a. io.dmem.req.valid由ex_reg_valid和ex_ctrl_mem决定,说明在ex阶段即对io.dmem发起了请求,而不是等到mem阶段。
b. ex_waddr即rd寄存器编号用于生成dcache_tag;
c. ex_ctrl.mem_cmd用于表明请求类型;
d. ex_reg_mem_size用于表明请求内存块的大小;
e. 可以推测s1/s2为io.dmem的stage1/stage2;