CPU《酷能指令集》及相关专利技术介绍和讨论
来源:EETOP BBS 作者:吾要单片机
浏览论坛处理器设计板块时发现了这个帖子,觉得很有意思,所以转发给大家,欢迎CPU设计的朋友一起讨论和提出建议。
原帖地址:http://bbs.eetop.cn/thread-628380-1-1.html
以下是原文:
在介绍本人的《酷能指令集》之前先介绍与之先关的专利技术:
第一项专利技术:专利号:201310153746.1,专利名:《一种在计算机数据处理指令中附加跳转功能的方法及CPU模块》。
这项专利的主要思想是:在计算机数据处理指令中增加设置执行的条件码、反条件码和跳转矢量,从而使得数据处理指令不再是单一的数据处理,而且具备跳转能力,其好处是提高程序的密度和执行效率。(具体内容参见专利的说明书)
通过上述技术方法实施后数据处理指令具有跳转功能了,在此我称之为具有跳转功能的数据处理指令。这些具有跳转功能的数据处理指令的汇编格式如下所示:
操作码<条件码> [操作数1] , [操作数2], [操作数3],[E][JMP 跳转标号]
其中E是反条件码,跳转矢量是相对PC的跳转矢量。
注意观察该汇编指令格式,我们发现比现在传统的数据处理指令指令多出了“[E][JMP 跳转标号]”字段,这个字段就是用于描述跳转功能。其中E是反条件码助记符,JMP是立即跳转助记符。如果E被隐去,则表示同条件跳转,即附加的跳转条件和操作码后缀的条件码相同;如果E被显现,则表示反条件跳转,即附加的跳转条件和操作码后缀的条件码相反。
汇编指令格式:操作符<cond> 操作数1,操作数2,..,[E][JMP #v]
其中: cond------条件码,其意思是:如果满足条件码的要求,则执行操作符定义的操作;如果没有条件码,其意思是:无条件执行操作符定义的操作。
E—-------反条件码,意思是否则(Else)。
JMP #v---意思是立即跳转#v条指令。
例如:
SUB<cond> Rd, Rn, Rj, [E][JMP #v_5]
需要特别指出的是:有些数据处理指令是无条件执行,没有条件码、反条件码、跳转矢量。
实际应用举例如下:
SUBEQ R3, R1, R2, EJMP lab_1;//如果相等,则执行R3ßR1-R2;否则立即跳到lab_1处。属于反条件跳转。这种情况下它顶得3条MIPS指令。
SUBEQ R3,
R1, R2, JMP lab_1;//如果相等,则执行R3ßR1-R2,并且立即跳到lab_1处。属于同条件跳转。这种情况下它顶得3条MIPS指令。
SUB R3,
R1, R2;//无条件执行R3ßR1-R2。没有跳转功能,属于反条件跳转。这种情况下它只//顶得1条MIPS指令。
SUB R3,
R1, R2, JMP lab_1;// 无条件执行R3ßR1-R2,并且立即跳到lab_1处。属于同条件//跳转。这种情况下它顶得2条MIPS指令。
SUBRE R3,
R1, R2, JMP lab_1;//无条件执行RCßRC-1的操作,如果Z==1&&RC>0,则执行R3ßR1-R2,并且立即跳到lab_1处。属于同条件跳转。这种情况下有最高效率,它顶得5条MIPS指令!
从上面可以看出:在数据处理指令(含数据转送指令)中附加执行条件码、反条件码和跳转矢量后,可以使得数据处理指令不但有条件执行,而且具有跳转功能。这种指令的效率显然高于现在主流的RISC指令,不过由于附加的跳转矢量位数有限(6位或7位),所以跳转的范围都比较小,属于短跳转。
第二项专利:专利号:201512153746.1,专利名:《一种将计算机指令中立即数扩展的方法和装置》
技术背景:RISC指令可以携带的立即数一般都不大,比如ARM的数据运算指令携带的立即数最大是12位,而MIPS指令系统的数据运算指令携带的立即数最大是16位,要这些RISC指令系统携带32位的立即数是不可能的,因为其指令长度只有32位,所以在RISC指令系统中要取得32位立即数就费不少周折了,目前常用的方法有两种:第一种是分段读取法,具体是先读取高16位的立即数,再读取低16位的立即数,从而组成32位立即数,为了支持这种分段读取法,几乎所有的RISC指令系统都是专门制定了相应的指令,比如ARM的MOVW和MOVT指令、MIPS的LUI和ADDIU指令;第二种是访存法,具体是把32位立即数当做常数放在离当前PC值不太远的地方,然后使用一条与PC相关的访存指令读取它。但是不管使用哪种读取方法,要获取一个32位的立即数都是费时,怎么都要花2个周期才能完成。
比如要处理表达式:R2=R3&0x87654321,当前ARM的做法是:
使用分段读取法的是:
MOVT R1,#8765H;(取得高16位常数,要花1个周期时间)
MOVW R1,#4321H;(取得低16位常数,要花1个周期时间)
AND R2,R3,R1;
使用访存法的是:
LDR R1, [PC, #offest];(这条指令要花2个周期时间)
AND R2,R3,R1;
由此可见,ARM处理R2=R3&0x87654321共需要花3个周期时间,其中获取32位常数0x87654321需要花2个周期时间。
发明内容:为了解决现有的RISC指令系统获取大立即数执行效率低下的不足,又要维持RISC指令系统精简、统一长度的优点,本人提出了一种将计算机指令中立即数扩展的专利方法,其方法是:在RISC指令系统中至少新增一条立即数扩展指令,该指令包含有操作码和立即数域,具体应用是将一个大的立即数分成两段,一段是高位立即数,另一段是低位立即数,将高位立即数经过有符号或无符号扩展后装入该立即数扩展指令的立即数域,而将低位立即数装满执行指令的立即数域,并且规定该立即数扩展指令要前缀于携带该低位立即数的执行指令,中间不能插入别的指令。在取指令时,取指令电路将该立即数扩展指令和紧随其后的执行指令同步送入它们各自的译码器进行译码,立即数扩展指令译码器输出高位立即数经过逻辑左移位后再和执行指令译码器输出的低位立即数进行合并,合并结果输出的立即数再经过有符号数或无符号数扩展后还原为原来的大的立即数。该立即数扩展指令是一条非执行指令,它到译码这一阶段就终结了,它不需要经历执行、回写的阶段。具体内容见本人的专利资料详细说明(专利号:201512153746.1,专利名:一种将计算机指令中立即数扩展的方法和装置)。
通过使用本发明的方法,同样要处理上述的表达式:R2=R3&0x87654321,其做法是:
HIMM #8765h; (这是新增的立即数扩展指令,其携带高位立即数#8765h)
AND R2, R3, #4321h;(执行指令携带低16位立即数#4321h)
如果取指令电路工作于单倍速取指令模式(即程序存贮器每次只能在其接口总线上输出1条指令),则处理R2=R3&0x87654321共需要花2个周期时间,其中立即数扩展指令(HIMM #8765h)需要延迟 1条指令的时间,以等待紧随其后的执行指令(AND R2, R3, #4321h)的到来,才能同步译码。
如果取指令电路工作于双倍速取指令模式(即程序存贮器每次都能在其接口总线上输出2条指令),则处理R2=R3&0x87654321仅需要花1个周期时间,此时立即数扩展指令(HIMM #8765h)不需要任何延迟就可以和紧随其后的执行指令(AND R2, R3, #4321h)同步译码,所以它不花任何时间!
对比ARM和本发明的做法可以看出,使用本发明的方法可以极大改善RISC指令集计算机执行程序的效率,既节省时间又节省空间。
第三项专利:一种处理C语言SWITCH/CASE语句的方法
技术领域:
本发明属于计算机领域,具体涉及一种处理C语言SWITCH/CASE语句的方法,利用这一方法设计出专门处理C语言SWITCH/CASE语句的计算机指令,使得C编译器能利用这些指令编译C语言SWITCH/CASE语句时产生简洁高效的代码,显著提高计算机的执行速度。
背景技术
C语言SWITCH/CASE语句是大家经常用到的语句,从字面上看程序逻辑清晰,结构一目了然,很受程序员欢迎,但是基于现有的指令集,C编译器编译C语言SWITCH/CASE语句成汇编指令时相当费劲。目前C编译器处理C语言SWITCH/CASE语句时通常使用两种方法,它们是:列表驱动法和逐项查找法。其中列表驱动法是在程序存贮器中建立一个常数的数组,该数组是所有CASE常数项所对应的跳转矢量的集合,所以该数组被称为CASE跳转矢量表,某个CASE常数项对应的跳转矢量在该表格的位置等于该CASE常数项与最小CASE常数项的差值,然后使用SWITCH的表达式的值减去最小CASE常数项的差值去索引所述的CASE跳转矢量表,从而得到跳转的目标,这种方法处理速度很快,也是C编译器优先使用的方法;而逐项查找法是使用SWITCH的表达式的值和CASE常数项逐个比较,如果有相等,则跳转到该CASE常数项所对应的地址,也就是说C编译器使用if/else的方法从上往下逐个比较,从而找到跳转的目标, 这就造成了越靠后的case项查找的时间就越长,所以这种方法处理速度很慢。
虽然列表驱动法具有快速的优点,但是那是用空间换取时间。该方法的缺点是CASE跳转矢量表的规模往往很大,其大小等于CASE常数项的最大值与最小值的差值+1,在实际应用中, CASE常数项的离散性往往很大,没有规律可循,那么CASE跳转矢量表就有很多空白项,这会浪费很多程序空间。如果浪费程序的空间过多,C编译器只好使用逐项查找法进行编译。另外,如果case项比较少,C编译器也会使用逐项查找法进行编译。
例如下面这段C语言代码,如果使用列表驱动法进行编译,则CASE跳转矢量表长达247项(246=0xf7-0x01+1),而实际有用的case项只有4个(0x01,0x22,0x4c,0xf7),显然浪费的程序空间太多了,所以C编译器就会使用逐项查找法进行编译。
switch (test){
case 0x01: c=a&b;break;
case 0x22: c=a|b;break;
case 0x4c: c=a+b;break;
case 0xf7: c=a-b;break;
default:break;
}
汇编代码如下:(逐项查找法,使用ARM指令集)
;switch (test){
0x080002ec LDR r0, [pc, #92]
0x080002ee LDRB r0, [r0, #0x00]; r0 <= test
0x080002f0 CMP r0, #0x01
0x080002f2 BEQ 0x08000302;if(test == 0x01) than jump to 0x08000302
0x080002f4 CMP r0, #0x22
0x080002f6 BEQ 0x08000312;if(test == 0x22) than jump to 0x08000312
0x080002f8 CMP r0, #0x4c
0x080002fa BEQ 0x08000322;if(test == 0x4c) than jump to 0x08000322
0x080002fc CMP r0, #0xf7
0x080002fe BEQ 0x08000332 ;if(test == 0xf7) than jump to 0x08000332
…
从上面的汇编代码可以看出,在使用逐项查找法时,越靠后的case项查找的时间就越长,因此改善逐项查找法的执行效率具有重要意义。
观察C程序中的SWITCH/CASE语句不难发现,在绝大多数SWITCH/CASE语句中:SWITCH表达式的值的字长为8位或16位,CASE常数项所对应的跳转都是小范围相对跳转,而且都是往前跳转。
发明内容
本发明提供一种处理C语言SWITCH/CASE语句的方法,利用这一方法,本发明设计出专门和用于处理C语言SWITCH/CASE语句的计算机指令,使得C编译器利用这些指令来编译C语言SWITCH/CASE语句时,能够产生简洁高效的代码,以提高计算机的执行速度。
一种处理C语言SWITCH/CASE语句的方法,该方法内容包括如下内容:
在现有的指令系统中增加3条指令,它们是字节型查找指令、半字型查找指令、散转指令;
所述的字节型查找指令包含目的寄存器、第一源寄存器和第二源操作数;其中,所述字节型查找指令的目的寄存器是通用寄存器或PSR(即程序状态寄存器),所述字节型查找指令的第一源寄存器是通用寄存器,所述字节型查找指令的第二源操作数是通用寄存器或立即数;如果所述的字节型查找指令的助记符为CASEB,那么该字节型查找指令的汇编格式是:CASEB Rd,Rs,Rt或者CASEB Rd,Rs,#imm ,其中Rd是目的寄存器,Rs是第一源寄存器,Rt是第二源寄存器,#imm是立即数;对于指令CASEB Rd,Rs,Rt来说:如果Rt是32位通用寄存器,那么Rt里面装载的是4个字长为字节的常数,如果Rt是64位通用寄存器,那么Rt里面装载的是8个字长为字节的常数;对于指令CASEB Rd,Rs,#imm来说:如果#imm是32位立即数,那么该#imm是由4个字长为字节的常数组成,如果#imm是16位立即数,那么该#imm是由2个字长为字节的常数组成;
所述的字节型查找指令的处理内容是:将字节型查找指令的第一源寄存器(Rs)中的第0字节同时分别与字节型查找指令的第二源操作数(Rt或#imm)中的所有字长为字节的常数进行比较,如果在这些比较运算中有一个运算结果为相等,那么置相等标记z为1,否则置相等标记z为0,并且按照一定的优先级顺序来选择其中一个运算结果为相等的、参与该比较运算的常数处于字节型查找指令的第二源操作数(Rs或#imm)中的位置编号位置序号n,再把该位置编号位置序号n以及相等标记z保存到字节型查找指令的目的寄存器Rd;
所述的半字型查找指令包含目的寄存器、第一源寄存器和第二源操作数;其中,所述半字型查找指令的目的寄存器是通用寄存器或PSR(即程序状态寄存器),所述半字型查找指令的第一源寄存器是通用寄存器,所述半字型查找指令的第二源操作数是通用寄存器或立即数;如果所述的半字型查找指令的助记符为CASEH,那么字节型查找指令的汇编格式是那么半字型查找指令的汇编格式是:CASEH Rd,Rs,Rt,或者CASEH Rd,Rs,#imm ,其中Rd是目的寄存器,Rs是第一源寄存器,Rt是第二源寄存器,#imm是立即数;对于指令CASEH Rd,Rs,Rt来说:如果Rt是32位通用寄存器,那么Rt里面装载的是2个字长为半字的常数,如果Rt是64位通用寄存器,那么Rt里面装载的是4个字长为半字的常数;对于指令CASEH Rd,Rs,#imm来说:如果#imm是32位立即数,那么该#imm是由2个字长为半字的常数组成;
所述的半字型查找指令的处理内容是:将半字型查找指令的第一源寄存器(Rs)中的第0半字同时分别与半字型查找指令的第二源操作数(Rt或#imm)中的所有字长为半字的常数进行比较,如果在这些比较运算中有一个运算结果为相等,那么置相等标记z为1,否则置相等标记z为0,并且按照一定的优先级顺序来选择其中一个运算结果为相等的、参与该比较运算的常数处于半字型查找指令的第二源操作数(Rs或#imm)中的位置编号位置序号n,再把该位置编号位置序号n以及相等标记z保存到半字型查找指令的目的寄存器Rd;
所述的散转指令包含第一源寄存器和第二源操作数;其中,所述散转指令的第一源寄存器是通用寄存器或PSR(即程序状态寄存器),该散转指令的第一源寄存器包含使能位z和索引值n;所述散转指令的第二源操作数是通用寄存器或立即数;如果所述的散转指令的助记符为SWITCH,那么该散转指令的汇编格式是:SWITCH Rs,Rt 或SWITCH Rs, #imm,其中Rs是第一源寄存器,Rt是第二源寄存器,#imm是立即数;如果Rt是32位通用寄存器,那么Rt里面装载的是4个字长为字节的常数;如果Rt是64位通用寄存器,那么Rt里面装载的是8个字长为字节的常数;如果#imm是32位立即数,那么该#imm是由4个字长为字节的常数组成,如果#imm是16位立即数,那么该#imm是由2个字长为字节的常数组成;
所述的散转指令的处理内容是:如果散转指令的Rs中的能使位z为真,那么使用散转指令的Rs中的索引值n选择第二源操作数(Rt或#imm)中的一个字长为字节的常数作为跳转矢量(该跳转矢量是无符号数),然后用该跳转矢量与当前的PC值相加,相加的结果就是跳转的目标地址,从而完成跳转;如果散转指令的Rs中的能使位z为假,则顺序执行;
另外还规定设定:散转指令的第一源寄存器中的能使位z是对应于字节型查找指令和半字型查找指令的目的寄存器中的相等标记z,而散转指令的第一源寄存器中的索引值n是对应于字节型查找指令和半字型查找指令的目的寄存器中的位置编号位置序号n,这样做就使得字节型查找指令和半字型查找指令的执行结果值直接被散转指令使用。
在编译C语言SWITCH/CASE语句时,采用如下编译步骤:
第一步是根据C语言SWITCH表达式的值的字长来选择字节型查找指令或半字型查找指令,查找相等的CASE常数项,具体是:
如果C语言SWITCH表达式的值的字长为8位,那么CASE常数项的字长也是8位,所以要使用字节型查找指令(CASEB Rd,Rs,Rt或者CASEB Rd,Rs,#imm)来查找相等的CASE常数项;如果C语言SWITCH表达式的值的字长为16位,那么CASE常数项的字长也是16位,所以要使用半字型查找指令(CASEH Rd,Rs,Rt或者CASEH Rd,Rs,#imm)来查找相等的CASE常数项。查找的方法是:将若干个待查找的CASE常数项按照一定的顺序填满第二源操作数(Rt或#imm)和把SWITCH表达式的值装入源寄存器(Rs)中,执行字节型查找指令或半字型查找指令后,在其目的寄存器(Rd)就得到相等标记z和位置编号位置序号n。另外,如果待查找的CASE常数项不够填满第二源操作数(Rt或#imm),那么重复使用其中某一个待查找的CASE常数项来填充,直到填满为止。
第二步是使用所述的散转指令根据上述第一步的字节型查找指令或半字型查找指令的结果值来索引跳转矢量,完成分支转移。具体方法是:
将构成第一步的字节型查找指令或半字型查找指令的第二源操作数(Rt或#imm)的CASE常数项所对应的跳转矢量装入散转指令的第二源操作数(Rt或#imm)中,并且要求各CASE常数项所对应的跳转矢量处于该散转指令的第二源操作数(Rt或#imm)中的位置顺序是与该CASE常数项处于字节型查找指令或半字型查找指令的第二源操作数(Rt或#imm)的位置顺序相同。由于散转指令的第一源寄存器中的能使位z是对应于字节型查找指令和半字型查找指令的目的寄存器中的相等标记z,还有散转指令的第一源寄存器中的索引值n是对应于字节型查找指令和半字型查找指令的目的寄存器中的位置编号位置序号n,所以如果散转指令的第一源寄存器等于字节型查找指令或半字型查找指令的目的寄存器,那么执行散转指令就可以索引到正确的跳转矢量,并根据其能使位z的状态决定跳转还是顺序执行。
使用本发明的方法,同样要处理背景技术所述的C程序:
switch (test){
case 0x01: c=a&b;break; //假设此处的分支地址偏移为0x12
case 0x22: c=a|b;break; //假设此处的分支地址偏移为0x34
case 0x4c: c=a+b;break; //假设此处的分支地址偏移为0x56
case 0xf7: c=a-b;break; //假设此处的分支地址偏移为0x78
default:break;
}
假设test的字长为字节,指令系统可以携带32位立即数,那么使用本发明的方法,其汇编代码如下:
;switch (test){
LDR r0, [pc, #92]
LDRB r0, [r0, #0x00];r0 <= test
CASEB r1, r0, #0xf74C2201;字节型查找指令(CASEB Rd,Rs,#imm),查找
;相等的CASE常数项,32位立即数#imm是由CASE
;常数项0xf7, 0x4C,0x22,0x01组成,结果存入
;r1
SWITCH r1, #0x78563412 ;散转指令(SWITCH Rs, #imm) ,32位立即数
;#imm是由跳转矢量0x78,0x56,0x34, 0x12组
;成,由r1索引跳转矢量,完成跳转
…
如果test的字长为半字, 指令系统可以携带32位立即数,那么使用本发明的方法,其汇编代码如下:
;switch (test){
LDR r0, [pc, #92]
LDRH r0, [r0, #0x00]; r0 <= test
CASEH r1, r0, #0x00220001;半字型查找指令(CASEH Rd,Rs,#imm),查找
;相等的CASE常数项,32位立即数#imm是由CASE
;常数项0x0022,0x0001组成,结果存入r1
SWITCH r1, #0x00003412 ;散转指令(SWITCH Rs, #imm) ,32位立即数
;#imm是由跳转矢量0x00,0x00,0x34,0x12组成,
;由r1索引跳转矢量,完成跳转
CASEH r1, r0, #0x00f7004c;半字型查找指令(CASEH Rd,Rs,#imm),查找
;相等的CASE常数项,32位立即数#imm是由CASE
;常数项0x00f7,0x004c组成,结果存入r1
SWITCH r1, #0x00007856 ;散转指令(SWITCH Rs, #imm) ,32位立即数
;#imm是由跳转矢量0x00,0x00,0x78,0x56组成,
;由r1索引跳转矢量,完成跳转
…
从以上的汇编代码可以看到,由CASE常数项构成的字节型查找指令或半字型查找指令的第二源操作数(通用寄存器或立即数)的位置顺序是与由该CASE常数项所对应的跳转矢量所构成的散转指令的第二源操作数(通用寄存器或立即数)的位置顺序完全相同。
对比处理背景技术所述的汇编代码不难发现,使用本发明方法的指令,其汇编代码非常简短,能够显著提高计算机的执行效能。
以下摘录一些论坛相关讨论:
现在可以介绍指令集和CPU了,先介绍CPU的寄存器组:寄存器介绍:寄存器的宽度是32位,所以本CPU是32位CPU。
R0--------零寄存器,它是只读寄存器,并且只读出零值,所以称之为零寄存器,这个零寄存器将为数据运算、变量清零以及变量寻址等指令提高灵活性。
当CPU处于16位指令模式时,其通用寄存器为R1—R15,R16(HR0)--R31(HR15)用特别的指令访问。
当CPU处于32位指令模式时,其通用寄存器为R1—R31。
其中:R1-----UMAC指令的目的寄存器。
R26---LO寄存器,用于存贮乘法或乘加的64位结果的低32位,或者用于存贮32位除法运算的商。
R27---HI寄存器,用于存贮乘法或乘加的64位结果的高32位,或者用于存贮32位除法运算的余数。
R28---EPC,即错误指令地址。
R29---INT,即中断的信息。
R30---SP寄存器,即推栈指针。当CPU处于用户态时是PSP;而当CPU处于管理态时是PSP或MSP,由PSR.P选择。
R31---LR寄存器,即子程序返回链接寄存器。
另外,CPU设置2个系统控制寄存器,它们定义如下:
PC寄存器,即程序计数器。
PSR寄存器,即程序状态寄存器,里面有程序状态标志位以及系统状态和控制信息。
寄存器组.png (14.04 KB)
条件码表
本指令集定义的反条件码:E=0表示相反条件跳转,E=1表示相同条件跳转。
从条件码表可以看出本指令集使用的条件码和ARM有所不同,主要是加入了与RC(重复计数器)相关的条件码(RE、RN、RP),本系统就是靠这3种条件码控制RC(重复计数器)进行减1操作的。
定义的操作数扩展指令,其中:RIMM指令用于扩展寄存器号,CIMM指令用于扩展条件码(cond)、反条件码(E)、跳转矢量(V),HIMM指令用于扩展高12位立即数,WIMM指令用于扩展高28位立即数。在16位指令集中,可以使用的前缀扩展指令是RIMM、CIMM、HIMM以及WIMM。在32位指令集中,只能使用的前缀扩展指令是WIMM,用于扩展32位立即数。
本16位指令集的技术特点:
1.支持的通用寄存器16个,即R0---R15(其中R0是零寄存器),这比其他的16位指令集大一倍,为用户提供更多的寄存器变量空间,有利于提高效能。
2.可以携带16位或32位的立即数,这一优势是其他16位指令集不能比拟的。
3.LOAD/STORE寻址方式灵活多样,支持EA=Rn、EA=Rn+#imm12、EA=Rn+#imm28、EA=Rn+Ra.比其他16位指令集强。
4.有布尔处理指令,有位与指令bit_and、位或指令bit_or、位异或指令bit_xor、位取反指令bit_not、位运算结果保存指令zmb.。这一特点比MCS-51或ARM的位操作指令更通用,位变量定义不再受限制。
5.本16位指令集自成一体,不用借助32位指令集就能实现所有功能,代码密度更高,与32位指令集相比,其性能损失非常小。
需要说明的是:
1、16位指令集和32位指令集都是完整独立的,这和ARM不同。
2、16位指令集前缀的立即数扩展指令为16位或32位,因此该16位指令的长度等效于16位、32和48位。
3、32位指令集前缀的立即数扩展指令位32位,因此该32位指令的长度等效于32位或64位。
本人已经完成基于这3项专利的CPU设计,根据仿真结果表明,设计达到预期效果,振奋人心! 该CPU使用verilog HDL编写,五级流水线,同时支持16位指令集(81条指令)和32位指令集(95条指令),与Thumb/microMIPS有所不同,本指令系统规定:一个子程序(即函数)只能使用一套指令集,也就是说,在一个子程序(即函数)中,要么全部使用16位的指令集,或要么全部使用32位指令集!这是因为译码器是根据该指令的地址的第0位(PC.0)的状态来区分该指令是16位指令集还是32位指令集,而只有CALL指令、int指令、硬件中断响应、中断返回指令iret和子程序返回指令ret才可以改变PC.0的状态值。本CPU设定:当PC.0为0时,指令为16位指令集;当PC.0为1时,指令为32位指令集。
特别说明:在发生分支跳转时,如果跳转的目标无法获得完整的指令(有前缀的立即数扩展指令)时,那么立即数扩展指令要延时一个周期,以等待紧随其后的执行指令的到来,除此以外立即数扩展指令不用延迟。仿真结果也证明了这一点。
关于中断系统:
本CPU的硬件中断系统有:
复位,不可屏蔽,优先级0(最高), 抢占型中断,入口地址:0x80000000
MEM错误,不可屏蔽,优先级1, 抢占型中断,入口地址:0x80000100
ROM错误,不可屏蔽,优先级2, 完整型中断,入口地址:0x80000200
EXT中断, 可屏蔽,优先级3(最低), 完整型中断,入口地址:0x80000300
注明:抢占型中断指的是不管指令处于哪个阶段都立即终止指令执行,即夭折; 完整型中断指的是指令执行完成后才可以中断。
看看立即数扩展指令的使用(16位指令集):(例如计算
R3=#76543210+#fedcba98)
f765
4321
0100 ;mov R1, #76543210
ffed
cba9
7318 ;add R3, R1,#fedcba98
计算这个表达式只需要2个周期,比ARM和MIPS快了不少啊。
需要说明的是:
1、本CPU是哈佛结构,即指令总线和数据总线分开,指令总线64位,这样可以实现前缀的操作数扩展指令和紧随其后的执行指令同步送入译码器,才能达到最高效能。2、本CPU包含有基于历史记录表的转移预测功能(记录最近的4个分支点),对于循环体的提速很有效。
CPU结构图
CPU.pdf (请登录论坛在帖子15#楼下载)
32位指令集比16位指令集具有的优点是:
1、32位指令集拥有32个通用寄存器,而16位指令集只有16个通用寄存器,所以面向大型数据运算时,32位指令集具有优势。
2、32位指令集前缀有立即数扩展指令WIMM时,其32位数据处理指令仍然可以包含有跳转功能。
..................