F3PreDecoder

子模块:F3PreDecoder模块简介

这个模块是从PreDecoder中时序优化出来的,负责判定CFI指令的类型

F3PreDecoder功能介绍

CFI指令类型判定

要想确定CFI指令类型,只需要分别尝试匹配JAL、JALR、BR和他们的RVC版本即可,注意,RVC的EBREAK 不应该被视为CFI指令。在匹配的过程中,自然CFI指令的类型就被甄别出来了。在这一步中,我们将所有指令分到如下四类brType中:

CFI指令类型 brType类型编码
非CFI 00
branch指令 01
jal指令 10
jalr指令 11

ret、call判定

然后,我们需要判断是否为call或者ret,这可以通过rd和rs的取值来考察,具体来说,RISCV的RVI指令中,提供了对rd和rs取值的约定, 当二者取到link寄存器的序号(x1为标准的返回地址寄存器,x5为备用的link寄存器),分别对应着压栈和弹栈。详细的对应情况如下:

links

F3Predecoder接口说明

in_instr: 传递 16 x 4B的拼接指令码

out_pd:每条指令的预译码信息,在F3Predecoder分析得到的是brType、isCall和isRet

F3PreDecoder子模块测试点和功能点

功能点1 CFI指令类型判定

要想确定CFI指令类型,只需要分别尝试匹配JAL、JALR、BR和他们的RVC版本即可,注意,RVC的EBREAK 不应该被视为CFI指令。

序号 名称 描述
1.1 非CFI判定 对传入的非CFI指令(包括RVC.EBREAK),应该判定为类型0
1.2 BR判定 对传入的BR指令,应该判定为类型1
1.3 JAL判定 对传入的JAL指令,应该判定为类型2
1.4 JALR判定 对传入的JALR指令,应该判定为类型3

功能点2 ret、call判定

然后,需要判断是否为call或者ret,这可以通过rd和rs的取值来考察。当然,首先必须得满足无条件跳转指令。

对于类型2,只有不为RVC指令且目的寄存器rd为link寄存器(x1或x5)时,才为Call。

对于类型3,在RVI指令下,当rd为link寄存器时,必为Call。当rs为link寄存器且rd不为时,必为Ret。 在RVC指令下,对C.JALR指令,为call,对C.JR指令,当rs1为link时,为Ret

序号 名称 描述
2.1 非CFI和BR不判定 对传入的非CFI和BR指令,都不应判定为call或者ret
2.2.1.1 RVI.JAL判定call 对传入的RVI.JAL指令,当rd设置为1或5,应当判定该指令为call
2.2.1.2 RVI.JAL例外 对传入的RVI.JAL指令,当rd设置为1和5之外的值,不应当判定该指令为call或ret
2.2.2 RVC.JAL不判定 对传入的RVC.JAL指令,无论什么情况都不能判定为call或ret
2.3.1.1 RVI.JALR和rd为link 传入RVI.JALR指令,并且rd为1或5,无论其他取值,都应判定为call
2.3.1.2 RVI.JALR且仅rs为link 传入RVI.JALR指令,rd不为1和5,rs为1或5,应判定为ret
2.3.1.3 RVI.JALR无link 对传入的JALR指令,若rd和rs均不为link,则不应判定为ret和cal
2.3.2.1 RVC.JALR为Ret 传入RVC.JALR指令,必定为call
2.3.2.2.1 RVC.JR且rs为link 传入RVC.JR指令,rs为1或5,应判定为ret
2.3.2.2.2 RVC.JR且rs不为link 传入RVC.JR指令,rs不为1或5,不应判定为ret

测试点汇总

序号 功能 名称 描述
1.1 CFI指令类型判定 非CFI判定 对传入的非CFI指令(包括RVC.EBREAK),应该判定为类型0
1.2 CFI指令类型判定 BR判定 对传入的BR指令,应该判定为类型1
1.3 CFI指令类型判定 JAL判定 对传入的JAL指令,应该判定为类型2
1.4 CFI指令类型判定 JALR判定 对传入的JALR指令,应该判定为类型3
2.1 ret、call判定 非CFI和BR不判定 对传入的非CFI和BR指令,都不应判定为call或者ret
2.2.1.1 ret、call判定 RVC.JAL判定call 对传入的RVC.JAL指令,当rd设置为1或5,应当判定该指令为call
2.2.1.2 ret、call判定 RVC.JAL例外 对传入的RVC.JAL指令,当rd设置为1和5之外的值,不应当判定该指令为call或ret
2.2.2 ret、call判定 RVI.JAL不判定 对传入的RVI.JAL指令,无论什么情况都不能判定为call或ret
2.3.1.1 ret、call判定 RVI.JALR和rd为link 传入RVI.JALR指令,并且rd为1或5,无论其他取值,都应判定为call
2.3.1.2 ret、call判定 RVI.JALR且仅rs为link 传入RVI.JALR指令,rd不为1和5,rs为1或5,应判定为ret
2.3.1.3 ret、call判定 RVI.JALR无link 对传入的JALR指令,若rd和rs均不为link,则不应判定为ret和cal
2.3.2.1 ret、call判定 RVC.JALR为Ret 传入RVC.JALR指令,必定为call
2.3.2.2.1 ret、call判定 RVC.JR且rs为link 传入RVC.JR指令,rs为1或5,应判定为ret
2.3.2.2.2 ret、call判定 RVC.JR且rs不为link 传入RVC.JR指令,rs不为1或5,不应判定为ret
最后修改 February 22, 2025: ifu top rtl build scripts modify (#76) (5520758)