跳转至

灵犀指令集约束

为了保证程序执行的正确性和安全性,灵犀指令集对于特定的指令,在特定的环境或条件下,进行一系列必要的限制和约束。这些约束可能涉及到指令的执行顺序、操作数的选择、内存访问方式等。

1 块指令约束

分类 约束事项
A1 在灵犀指令集中,所有的执行逻辑按照程序顺序保序执行。微架构内部允许乱序执行,但是在提交时,对程序状态和内存访问保序。每条微指令对内存访问保证同地址保序。
A2 块指令只是表达了架构状态的层次和范围(Scope)。块指令内部的微指令个数不限,执行次数不限。部分种类的块指令内部无法编程,无法拆解(例如矩阵Tile块)。
块类型 灵犀指令集中,按照程序属性和功能,分为整型标量块,系统块,浮点标量块以及一系列Tile块。不同块指令拥有的指令种类不同以及执行模型不同。
A3 整型标量块(BSTART.STD):通用完备的标量整数运算指令,无浮点指令。用于基础控制流和兜底计算操作。特征如下:
A3.1 整型标量块支持全量跳转方式(Fall, Direct, Call, Cond, Ind, Icall, Ret)
A3.2 整型标量块允许访问 全局寄存器GGPR,系统寄存器SSR和内存等全局状态。不允许访问Tile寄存器。
A3.3 整型标量块只支持一体块形式
A3.4 整型标量块不支持块内跳转
A4 系统块(BSTART.SYS):提供系统配置相关的操作和特权级切换功能,系统块有独特的保序执行功能。特征如下:
A4.1 系统块只支持Fall跳转方式
A4.2 系统块允许访问 全局寄存器GGPR,系统寄存器SSR和内存等全局状态。不允许访问Tile寄存器。
A4.3 系统块只支持一体块形式
A4.4 系统块不支持块内跳转
A5 浮点标量块(BSTART.FP):拥有FP32和FP64等传统的浮点计算能力。特征如下:
A5.1 浮点标量块支持全量跳转方式(Fall, Direct, Call, Cond, Ind, Icall, Ret)
A5.2 浮点标量块允许访问 全局寄存器GGPR,系统寄存器SSR和内存等全局状态。不允许访问Tile寄存器。
A5.3 浮点标量块只支持一体块形式
A5.4 浮点标量块不支持块内跳转
A6 向量串行块(BSTART.VSEQ):提供向量计算能力。拆成多个Group执行,Group间访存必须保序执行。特征如下:
A6.1 向量串行块只支持分离块形式的块结构
A6.2 向量串行块仅支持Fall跳转方式
A6.3 向量串行块允许访问 全局寄存器GGPR,系统寄存器SSR,以及Tile寄存器等全局状态。不允许访问内存。
A6.4 向量串行块内不允许有load global或store global指令,否则报非法指令异常。
A6.5 向量串行块最多允许读8个Tile寄存器,写4个tile寄存器。
A6.6 向量串行块最多允许读12个GGPR,写4个GGPR
A6.7 向量串行块块内只有Reduce指令允许写全局寄存器GGPR
A6.8 向量串行块内的Reduce指令输出的全局寄存器不允许作为本块指令的输入,否则报非法指令异常
A6.9 向量串行块内的load local指令的地址不能超过本块输入输出tile寄存器的范围,否则报非法越界异常。
A6.10 向量串行块内的store local指令不能访问TA/TB/TC指向的tile寄存器的地址范围,只能访问TO/TS指向的tile寄存器的地址范围,否则报非法越界异常。
A6.11 向量串行块内只允许多个group按照程序序以group id由小到大顺序提交,最后一个group提交后则向量串行块整体提交。
A6.12 向量串行块内的不同group间的load/store local 允许地址重合,但需要按照group id的顺序按序修改。
A6.13 向量串行块内的同一个group内的load/store local 基于地址保序,不同group的load/store local按照地址顺序进行全局保序。
A7 向量并行块(BSTART.PAR):提供向量计算能力。拆成多个Group执行,Group间访存不需要保序执行。特征如下:
A7.1 向量并行块只支持分离块形式的块结构
A7.2 向量并行块仅支持Fall跳转方式
A7.3 向量并行块允许访问 全局寄存器GGPR,系统寄存器SSR,以及Tile寄存器等全局状态。不允许访问内存。
A7.4 向量并行块内不允许有load global或store global指令,否则报非法指令异常。
A7.5 向量并行块最多允许读8个Tile寄存器,写4个tile寄存器。
A7.6 向量并行块最多允许读12个GGPR,写4个GGPR
A7.7 向量并行块内只有Reduce指令允许写全局寄存器GGPR
A7.8 向量并行块内的Reduce指令输出的全局寄存器不允许作为本并行块指令的输入,否则报非法指令异常
A7.9 向量并行块内的load local指令的地址不能超过本块输入输出tile寄存器的范围,否则报非法越界异常。
A7.10 向量并行块内的store local指令不能访问TA/TB/TC指向的tile寄存器的地址范围,只能访问TO/TS指向的tile寄存器的地址范围,否则报非法越界异常。
A7.11 向量并行块内的不同group间的load/store local 不允许地址重合,如出现重合硬件不保证执行的正确性。
A7.12 向量并行块内的同一个group内的load/store local 基于地址保序,不同group的地址不保序。
A7.13 向量并行块内的提交需要等所有group提交,每个group的提交定义为本group内最后一条指令的提交。
A8 访存并行块(BSTART.MTC):提供共享内存和Tile寄存器间的数据搬移能力。拆成多个Group执行,Group可对外访问DDR。
A8.1 访存并行块只支持分离块形式的块结构
A8.2 访存并行块仅支持Fall跳转方式
A8.3 访存并行块允许访问 全局寄存器GGPR,系统寄存器SSR和内存,以及Tile寄存器等全局状态。
A8.4 访存并行块最多允许读8个Tile寄存器,写4个tile寄存器。
A8.5 访存并行块最多允许读12个GGPR,写4个GGPR
A8.6 访存并行块内只有Reduce指令允许写全局寄存器GGPR
A8.7 访存并行块内的Reduce指令输出的全局寄存器不允许作为本并行块指令的输入,否则报非法指令异常
A8.8 访存并行块内的load local指令的地址不能超过本块输入输出tile寄存器的范围,否则报非法越界异常。
A8.9 访存并行块内的store local指令不能访问TA/TB/TC指向的tile寄存器的地址范围,只能访问TO/TS指向的tile寄存器的地址范围,否则报非法越界异常。
A8.10 访存并行块内的不同group间的load/store local 不允许地址重合,如出现重合硬件不保证执行的正确性。
A8.11 访存并行块内的同一个group内的load/store local 基于地址保序,不同group的地址不保序。
A8.12 访存并行块内的不同group间的load/store global 不允许地址重合,如出现重合硬件不保证执行的正确性。
A8.13 访存并行块内的不同group间的load/store global 不允许和标量块的load/store地址重合,如出现重合硬件不保证执行的正确性。
A8.14 访存并行块内无DMB/DSB等同步操作,如若做同步需要强行切块,通过系统块进行同步。
A8.15 访存并行块内的同一个group内的load/store global 基于地址保序,不同group的地址不保序。
A8.16 访存并行块的load/store global指令可以访问non-cacheable和device IO等地址空间,并且不保证group间的访问顺序。
A8.17 访存并行块的load/store global原子指令允许对内存进行原子访问,不保证group间原子访问的顺序。
A8.18 访存并行块内的提交需要等所有group提交,每个group的提交定义为本group内最后一条指令的提交。
A9 矩阵Tile块(BSTART.CUBE):提供矩阵运算能力,将矩阵拆成N个分形,每个分形执行一次运算。特征如下:
A9.1 矩阵Tile块内部无法编程,不可拆解
A9.2 矩阵Tile块仅支持Fall跳转方式
A9.3 矩阵Tile块允许访问 全局寄存器GGPR以及Tile寄存器,不允许访问内存和系统寄存器SSR。
A9.4 矩阵Tile块一个块最多允许读8个Tile寄存器,写4个tile寄存器
A9.5 矩阵Tile块只允许输出到ACC寄存器
A9.6 矩阵Tile块的ACC寄存器内数据搬运出去后,ACC寄存器立即被释放掉,后序指令不允许读取。
A9.7 矩阵Tile块的ACC寄存器内元素的数据类型只能是FP32、S32和U32,其他数据类型报非法指令异常。
A9.8 矩阵Tile块输入的左矩阵必须采用Nz(大N小z)的布局进行存储,并且一个分形大小固定为512字节。
A9.9 矩阵Tile块输入的右矩阵必须采用Zn(大Z小n)的布局进行存储,并且一个分形大小固定为512字节。
A9.10 矩阵Tile块的累加矩阵的一个分形大小固定为1024字节。
块结构 灵犀指令集中,按照块指令的结构,分为分离块(模版块是一种特殊的分离块)和一体块。
A10 分离块约束(分离块:块头和块体分开存储)
A10.1 分离块内访问的GGPR必须通过B.IOR指令表达,并且输出寄存器不允许重复
A10.2 分离块内访问的Tile寄存器必须通过B.IOT指令表达
A10.3 分离块内必须通过形参方式访问Tile寄存器
A10.4 分离块内只能访问块内私有寄存器(Local GPR和相对索引寄存器等),不能直接访问GGPR
A10.5 分离块内不能重复写同一个Local GPR(RO0-RO3),否则触发重复设置异常。
A10.6 分离块块体内不允许使用16bit和48bit编码的指令,否则报非法指令异常。
A10.7 整型标量块、浮点标量块和系统块不支持分离块形式
A11 模版块约束(模版块:软件只定义块头,块体由硬件产生)
A11.1 模板块产生指令时,产生的指令数在获取输入后是确定的
A11.2 模板块产生指令的Index和TPC对应,对于一个指定的Index会产生确定的指令
A11.3 模板块产生的访存指令范围是确定的,保证不会在模板内产生nuke flush  
A11.4 MCOPY指令源地址和目的地址范围之间不能有重叠部分,以8 Byte为单位
A12 一体块约束(一体块:块头和块体连续存储)
A12.1 向量块,访存块和矩阵运算块等不支持一体块形式
A12.2 一体块块内不允许使用B.TEXT指令
A12.3 一体块块内支持16/48/32/64bit编码的指令
A12.4 一体块内允许重复读写同一个GGPR
跳转方式 灵犀指令集中,块指令之间的跳转方式包括以下几种方式,部分跳转方式的块内需要有一些必须存在的指令,以保证程序的正确执行。
A13 CALL:不能是空块,必须包含一条setret,setret必须放在bstart的后面
A14 COND:不能是空块,必须包含一条setc.cond
A15 IND:不能是空块,必须包含一条setc.tgt
A16 ICALL:不能是空块,必须包含一条setc.tgt和一条setret,setret必须放在bstart的后面
A17 RET:不能是空块,必须包含一条setc.tgt
A18 FALL:只有FALL块支持Fixup跳转

2 寄存器约束

序号 约束
寄存器 在灵犀指令集中,Tile寄存器是寄存器,并不是内存。寄存器的属性有:
B1 原子性:在计算过程中,块指令对Tile Register的写是原子的。不存在多个块指令同时写一个Tile Register。
B2 独占性:在计算过程中,块指令拥有自己的Destination Tile Register的独占权。后续块指令无法读取,直到当前块指令提交。
B3 幂等性:一个Tile寄存器只能被赋值一次,无法被反复覆写。
B4 直接性:Tile寄存器无法获取指针,也无法通过指针直接访问。
Tile Reg Tile寄存器的约束如下:
B5 一个Tile寄存器一旦被Producer块赋值并提交后,它就变成了只读的。后续的块指令无法修改其值。因此,Tile Register可以被复制到多个物理实体且并没有一致性问题。
B6 一个Tile寄存器只有一个Producer块指令,但可以有0到多个Consumer块指令。
B7 Tile寄存器的Reuse标记记录在consumer指令的输入上。在consumer指令提交后,可对输入寄存器进行资源释放。
B8 一个Tile寄存器容量Size一定是矩阵最小分形大小(即512字节)的整数倍。目前Tile Reg的大小在512B和32KB之间。
B9 Tile寄存器分配的地址不能重合。
B10 Tile寄存器中的ACC寄存器只能被矩阵Tile块写,其他块不允许写
GGPR 全局寄存器GGPR的约束如下:
B11 全局寄存器不需要标记reuse信息,默认都是reuse的
B12 分离块内不能访问GGPR,否则报非法指令异常
T/U 标量寄存器(t/u)的约束包括:
B13 标量寄存器不需要标记reuse信息,默认都是reuse的
VT/VU/VM/VN 向量寄存器(vt/vu/vm/vn)的约束如下:
B14 向量寄存器的reuse记录在consumer指令的输入寄存器上。在consumer指令提交后,可对输入寄存器进行资源释放。
B15 向量寄存器被释放后,如果存在后序指令读取该寄存器,硬件应产生异常。
B16 向量寄存器的producer和consumer必须保证使用相同的位宽
LB/LC lb/lc寄存器的约束如下:
B17 LB/LC寄存器位宽上限16bit。
B18 LB寄存器只能被B.DIM指令写,其他指令只读。
B19 LC寄存器是只读的,不允许指令写。其值由硬件根据lane_id进行分配。
PRED P寄存器的使用约束如下:
B20 P寄存器被比较cmp指令写时为向量操作,每个lane写1bit。
B21 P寄存器被其他指令写时为标量操作。

3 微指令约束

序号 约束
常规运算指令
C1 c.movi指令的目的寄存器不能是r10寄存器,否则报非法指令异常
控制流指令
C2 c.setret,setret指令只能写r10寄存器,否则报非法指令异常
C3 c.setret,setret指令仅在CALL/ICALL块内使用,且一个块内有且仅有一条
C4 setc.tgt指令仅在IND/ICALL/RET块内有效,且一个块内有且仅有一条
C5 setc.cond类指令仅在COND块内有效,且一个块内有且仅有一条
访存操作指令
C6 普通load/store访存指令支持地址非对齐访问
SSR访问指令
C7 ssrget/ssrset指令只能访问SSR_ID[15:12]等于0的系统寄存器,否则需要使用hl.ssrget/hl.ssrset指令
比特位操作指令
C8 rev/l.rev指令的M参数合法取值为{2,4,8,16,32,64},N参数的合法取值为{1,2,4,8,16,32},并且M必须大于N,否则应报非法参数异常。
C9 l.bxu指令的M和N参数取值必须小于源寄存器位宽,否则硬件执行结果不可知。
C10 l.bxs指令的M和N参数取值必须小于源寄存器位宽,否则硬件执行结果不可知。
C11 l.bic指令的M和N参数取值必须小于源寄存器位宽,否则硬件执行结果不可知。
C12 l.bis指令的M和N参数取值必须小于源寄存器位宽,否则硬件执行结果不可知。
C13 l.clz指令的M和N参数取值必须小于源寄存器位宽,否则硬件执行结果不可知。
C14 l.ctz指令的M和N参数取值必须小于源寄存器位宽,否则硬件执行结果不可知。
C15 l.bcnt指令的M和N参数取值必须小于源寄存器位宽,否则硬件执行结果不可知。
C16 l.rev指令的M和N参数取值必须小于源寄存器位宽,否则硬件执行结果不可知。
双输出指令
C17 hl.mul指令的两个目的寄存器如果相同,那么执行结果不可知(硬件决定保留哪个结果)。
C18 hl.mulu指令的两个目的寄存器如果相同,那么执行结果不可知(硬件决定保留哪个结果)。
C19 hl.madd指令的两个目的寄存器如果相同,那么执行结果不可知(硬件决定保留哪个结果)。
C20 hl.maddw指令的两个目的寄存器如果相同,那么执行结果不可知(硬件决定保留哪个结果)。
C21 hl.div指令的两个目的寄存器如果相同,那么执行结果不可知(硬件决定保留哪个结果)。
C22 hl.divu指令的两个目的寄存器如果相同,那么执行结果不可知(硬件决定保留哪个结果)。
C23 hl.divw指令的两个目的寄存器如果相同,那么执行结果不可知(硬件决定保留哪个结果)。
C24 hl.divuw指令的两个目的寄存器如果相同,那么执行结果不可知(硬件决定保留哪个结果)。
C25 hl.rem指令的两个目的寄存器如果相同,那么执行结果不可知(硬件决定保留哪个结果)。
C26 hl.remu指令的两个目的寄存器如果相同,那么执行结果不可知(硬件决定保留哪个结果)。
C27 hl.remw指令的两个目的寄存器如果相同,那么执行结果不可知(硬件决定保留哪个结果)。
C28 hl.remuw指令的两个目的寄存器如果相同,那么执行结果不可知(硬件决定保留哪个结果)。
C29 hl.load pair类指令的两个目的寄存器如果相同,那么执行结果不可知(硬件决定保留哪个结果)。
C30 hl.load pre-index类指令的两个目的寄存器如果相同,那么执行结果不可知(硬件决定保留哪个结果)。
C31 hl.load post-index类指令的两个目的寄存器如果相同,那么执行结果不可知(硬件决定保留哪个结果)。
C32 hl.ccat指令的两个目的寄存器如果相同,那么执行结果不可知(硬件决定保留哪个结果)。
C33 hl.ccatw指令的两个目的寄存器如果相同,那么执行结果不可知(硬件决定保留哪个结果)。
C34 hl.qpop指令的两个目的寄存器如果相同,那么执行结果不可知(硬件决定保留哪个结果)。
原子操作指令
C35 原子指令的内存访问地址必须按照访存位宽进行对齐,否则触发地址不对齐异常
C35.1 ld.op/sd.op指令(包括向量版本)的访存地址必须8字节对齐
C35.2 lw.op/sw.op指令(包括向量版本)的访存地址必须4字节对齐
C35.3 swapd指令的访存地址必须8字节对齐
C35.4 swapw指令的访存地址必须4字节对齐
C35.5 swaph指令的访存地址必须2字节对齐
C35.6 hl.casd指令的访存地址必须8字节对齐
C35.7 hl.casw指令的访存地址必须4字节对齐
C35.8 hl.cash指令的访存地址必须2字节对齐
C35.9 l.casdp指令的访存地址必须8字节对齐
C35.10 l.caswp指令的访存地址必须4字节对齐
C35.11 l.cashp指令的访存地址必须2字节对齐
C36 加载保留与条件存储(lr/sc)指令内存访问地址必须按照访存位宽进行对齐,否则触发地址不对齐异常
C36.1 lr.d/sc.d指令的访存地址必须8字节对齐
C36.2 lr.w/sc.w指令的访存地址必须4字节对齐
C36.3 lr.h/sc.h指令的访存地址必须2字节对齐
执行控制指令
C37 屏障指令isb的实现不会对预取到Icache和Bcache中的指令数据做处理,即不需要重新从内存中取指
C38 acrc/acre指令如果在同一个块中被重复调用,或者acrc和acre同时使用,在程序序后方指令会覆盖前方指令的请求
C39 bwe指令是一种bstop指令,因此其必须作为块内的最后一条指令。系统块内最多只能有一条bwe指令。
C40 bse指令是一种bstop指令,因此其必须作为块内的最后一条指令。系统块内最多只能有一条bse指令。
C41 bwt指令是一种bstop指令,因此其必须作为块内的最后一条指令。系统块内最多只能有一条bwt指令。
C42 bwi指令是一种bstop指令,因此其必须作为块内的最后一条指令。系统块内最多只能有一条bwi指令。
GQM指令
C43 访存指令不允许访问GQM队列内存块
C44 GQM队列的最大空间是 2^10 字节
浮点指令
C45 当fdiv/l.fdiv指令的除数是0且被除数是一个有限的非零数据时,产生除零异常
C46 当fdiv/l.fdiv指令的除数和被除数都为0或无穷大时,此指令触发非法操作异常
C47 当fsqrt/l.sqrt指令输入为负数时,该指令触发非法操作NV异常
C48 当frecip/l.frecip指令源操作数为0时,该指令会触发除零异常