首页 > 代码库 > cpu设计-->cpu指令设计与全程逻辑分析

cpu设计-->cpu指令设计与全程逻辑分析

CPU指令设计,除了命名之外,更重要的是分析出指令如何才能够实现。对于图 3 1的CPU结构,如果指令是预先放到irom里的,那么,指令执行时要一条一条地从irom取出来,放到ir指令寄存器中,提供给control进行分析执行。每一条指令如何转变成机器动作,CPU的设计者必须认真地进行分析和规划。这一过程叫指令全程动作分析,简称指令全程分析。

我们针对图 3-1的结构,可以尝试设计一些用符号表示的汇编指令,然后对这些汇编指令如何实现,进行细致地分析。汇编指令的二进制数表示就是机器指令。汇编指令和机器指令是一一对应的。逐条对汇编指令的这些进行全程分析,也就是对CPU的机器指令进行全程分析。

我们设想如下的一些指令,并且给每一条指令一个惟一的5位编码,依据图 3-1,根据节拍的变化和指令的功能分析,就能找出每个指令一连串的CPU基本动作。

1 . Lda 指令

我们想设计的第一条指令功能是:将指定数据存储单元r的内容,送到累加器da。这个指令的助记符号为Lda,编号是00001,汇编指令的格式为Lda r。

假定程序计数器pc就指向Lda r在程序存储器的地址,节拍器初始值是0,那么要执行这条指令的连续动作步骤应该如下:

(1)节拍为0时,irom→指令寄存器ir,节拍器加一;

(2)节拍为1时,ir高5位是00001,让标志Lda=1,并将ir的低11位送mar,节拍器加一;

(3)节拍为2时,且标志Lda=1,则pc+1,节拍器加一;

(4)节拍为3时,且标志Lda=1,将dram送da,节拍器加一;

(5)节拍为4时,让标志Lda=0,节拍器归零复位。

2 . Add 指令

设想汇编指令Add r的功能设定为:将数据存储器中r单元的数据与累加器da相加,结果送到累加器da。Add的编号定为00010。

假定pc指向存放Add r的地址,节拍器初始值是0,那么指令Add r的连续动作步骤如下:

(1)节拍为0时,irom→指令寄存器ir,节拍器加一;

(2)节拍为1时,ir高5位是00010,让标志Add=1,将低11位送mar,节拍器加一;

(3)节拍为2时,且标志Add=1,pc+1,节拍器加一;

(4)节拍为3时,且标志Add=1,将dram送寄存器b,节拍器加一;

(5)节拍为4时,且标志Add=1,将da送寄存器a,节拍器加一;

(6)节拍为5时,且标志Add=1,将a+b送da,节拍器加一;

(7)节拍为6时,让标志Add=0,节拍器归零复位。

由于总线上不能同时传播多个数据,所以a、b寄存器不能够同时接收数据,而是分为2个节拍,一个节拍总线传输数据存储器的数据,另一个节拍总线传输累加器da的数据。

3 . Out 指令

设想汇编指令Out r的功能是将数据存储器r单元的数据,送到输出寄存器out输出。Out的指令编号是00011。

假定pc指向Out r在程序存储器的存放地址,节拍器初始值是0,那么指令Out r连续的动作步骤如下:

(1)节拍为0时,irom→指令寄存器ir,节拍器加一;

(2)节拍为1时,ir高5位是00011,让标志Out=1,将低11位送mar,节拍器加一;

(3)节拍为2时,且标志Out=1,pc+1,节拍器加一;

(4)节拍为3时,且标志Out=1,将dram送out寄存器,节拍器加一;

(5)节拍为4时,让标志Out=0,节拍器归零复位。

4 . Sdal 指令

图 3 1的CPU结构中没有外部数据输入的设备,要想将数据进行输入,只有考虑把数据写入指令当中,这样指令执行时,数据就可以送到寄存器或存储器当中了。设想汇编指令Sdal n的功能是:将指令中的8位数n送到累加器da的低8位。Sdal的指令编号是00100。

假定pc指向Sdal n在程序存储器的存放地址,节拍器初始值是0,那么指令Sdal n连续的动作步骤如下:

(1)节拍为0时,irom→指令寄存器ir,节拍器加一;

(2)节拍为1时,若ir高5位是00100,让标志Sdal=1,pc+1,节拍器加一;

(3)节拍为2时,且标志Sdal=1,将ir低8位送da低8位,节拍器加一;

(4)节拍为3时,让标志Sdal=0,节拍器归零复位。

5 . Sdah 指令

由于我们设计的是一个16位的CPU,因而数据应该是16位的。但一条指令只有16位,除了指令编号的位置之外,只有11位。如果用一条指令表示送入的数据,最多也就是11位。为解决16位数的问题,我们设计了两条联系在一起的指令。我们设想的汇编指令Sdah n的功能是:将这个指令中的8位数送到累加器da的高8位。这样就可以与前面的Sdal指令一起使累加器da获得一个16位二进制数。Sdah的指令编号是00101。下面对Sdah n指令进行全程变动分析。

假定pc指向Sdah n在程序存储器的地址,节拍器初始值是0,那么连续的动作步骤如下:

(1)节拍为0时,irom→指令寄存器ir,节拍器加一;

(2)节拍为1时,若ir高5位是00101,让标志Sdah=1,pc+1,节拍器加一;

(3)节拍为2时,且标志Sdah=1,将ir低8位送da高8位,节拍器加一;

(4)节拍为3时,让标志Sdah=0,节拍器归零复位。

6 . Str 指令

设想汇编指令Str r的功能是:将累加da的数据送到数据存储器dram的r存储单元。Str的指令编号是00110。

假定pc指向Str r的程序存储器地址,节拍器初始值是0,那么连续的动作步骤如下:

(1)节拍为0时,irom→指令寄存器ir,节拍器加一;

(2)节拍为1时,若ir高5位是00110,让标志Str=1,将ir的低11位送到mar,节拍器加一;

(3)节拍为2时,且标志Str=1,pc+1,节拍器加一;

(4)节拍为3时,将da送dram,节拍器加一;

(5)节拍为3时,让标志Str=0,节拍器归零复位。

7 . Sub 指令

设想汇编指令Sub r的功能设定为:将数据存储器中r单元的数据与累加器da相减,结果送到累加器da。Sub的编号定为00111。

假定pc指向存放Sub r的地址,节拍器初始值是0,那么指令Sub r的连续动作步骤如下:

(1)节拍为0时,irom→指令寄存器ir,节拍器加一;

(2)节拍为1时,ir高5位是00111,让标志Sub=1,将低11位送mar,节拍器加一;

(3)节拍为2时,且标志Sub=1,pc+1,节拍器加一;

(4)节拍为3时,且标志Sub=1,将dram送寄存器b,节拍器加一;

(5)节拍为4时,且标志Sub=1,将da送寄存器a,节拍器加一;

(6)节拍为5时,且标志Sub=1,将a-b送da,节拍器加一;

(7)节拍为6时,让标志Sub=0,节拍器归零复位。

8 . Jmp 指令

前面我们设想的都是简单的数据传送或运算的指令,只用这些指令来编写程序,将是十分困难的事情。我们编程会碰到分支结构、循环结构和子程序调用结构等,对于这些结构也必须设计出相应的指令,不然就不能完成程序设计的这些必要结构。无条件跳转汇编指令Jmp r就是不能缺少的指令之一。

设想的汇编指令Jmp r的功能是:执行完这条指令之后,就转到程序存储器的r单元取指令执行。Jmp指令的编号定为01000。

仍然假定pc指向Jmp r在程序存储器地址,节拍器初始值是0,那么连续的动作步骤如下:

(1)节拍为0时,irom→指令寄存器ir,节拍器加一;

(2)节拍为1时,ir高5位是01000,将ir低11位送pc,节拍器加一;

(3)节拍为2时,节拍器归零复位。

9 . Jz 指令

对于分支程序结构来说,必须有条件转移指令来确定。汇编指令Jz r的功能是:如果累加器da=0,那么在这个指令执行完成后,转到程序存储器的r单元取指令执行。Jz指令的编号定为01001。

假定pc指向Jz r在程序存储器的地址,节拍器初始值是0,那么连续的动作步骤如下:

(1)节拍为0时,irom→指令寄存器ir,节拍器加一;

(2)节拍为1时,ir高5位是01001,且da=0,则将ir低11位送pc,节拍器加一;

(3)节拍为2时,节拍器归零复位。

10 . Jn 指令

汇编指令Jn r的功能是:如果累加器da<0,那么在这个指令执行完成后,转到程序存储器的r单元取指令执行。Jn指令的编号定为01010。

假定pc指向Jn r的地址,节拍器初始值是0,那么连续的动作步骤如下:

(1)节拍为0时,irom→指令寄存器ir,节拍器加一;

(2)节拍为1时,ir高5位是01001,且da<0,则将ir低11位送pc,节拍器加一;

(3)节拍为2时,节拍器归零复位。

需要指出,在数位有限的情况下,判断da是否小于零,不能用da<0的表达式,而应当使用最高位数码是不是1来判断。这是因为Verilog HDL的设计判断正负数,是以第32位或64位为1否进行的,当我们设计的数位不是32位或64时,Verilog HDL会将不足位添0,这就不能判断出正负。

11 . Call 指令

编写软件程序调用子程序的指令是必不可少的。因而我们要必须考虑设计子程序调用指令。汇编指令Call r的功能是:执行完这条指令之后,要转到程序存储器的r单元取指令执行。Call 指令的编号是01011.

假定pc指向汇编指令Call r在程序存储器的地址,节拍器初始值是0,那么连续的动作步骤如下:

(1)节拍为0时,irom→指令寄存器ir,节拍器加一;

(2)节拍为1时,ir高5位是01011,设定指令标志Call=1,将pc保存到堆栈,节拍器加一;

(3)节拍为2时,且指令标志Call=1,将ir低11位送pc,节拍器加一;

(4)节拍为3时,让标志Call=0,堆栈指针移到栈顶,节拍器归零复位。

12 . Ret指令

从被调用的子程序返回指令Ret也是程序设计不可缺少的。汇编指令Ret的功能是:这条指令执行完后,返回到前面调用子程序的下一条指令执行。Ret指令的编号为01100。

同样假定pc指向Ret在程序存储器的地址,节拍器初始值是0,那么连续的动作步骤如下:

(1)节拍为0时,irom→指令寄存器ir,节拍器加一;

(2)节拍为1时,ir高5位是01100,指令标志Ret=1,堆栈指针回移,节拍器加一;

(3)节拍为2时,且Ret=1,将堆栈顶值送pc,节拍器加一;

(4)节拍为3时,让标志Ret=0,堆栈指针移到栈顶,节拍器归零复位。

13 . Mult 指令

在程序设计中可以通过加减法指令,通过循环结构设计完成乘法或者是除法的运算。但是这样编写的程序完成乘法或除法的速度相对来说较慢。为此我们在这里还是想设计乘法和除法指令。如果我们设计的乘法汇编指令Mult r,它的功能定义为:将数据存储单元r读数据与累加器da相乘,结果低8位放入累加器da,高8位送入输出寄存器out。设乘法指令Mult的编号是01101。

假定pc指向汇编指令Mult r在程序存储器的地址,节拍器初始值是0,那么连续的动作步骤如下:

(1)节拍为0时,irom→指令寄存器ir,节拍器加一;

(2)节拍为1时,ir高5位是01101,让指令标志Mult=1,将低11位送mar,节拍器加一;

(3)节拍为2时,且指令标志Mult=1,让pc+1,节拍器加一;

(4)节拍为3时,且指令标志Mult=1,将dram送寄存器b,节拍器加一;

(5)节拍为4时,且指令标志Mult=1,将da送寄存器a,节拍器加一;

(6)节拍为5时,且指令标志Mult=1,将a*b低8位送da,将a*b高8位送out,节拍器加一;

(7)节拍为6时,让指令标志Mult=0,节拍器归零复位。

14 . Divi 指令

除法运算指令的设计与乘法运算指令基本相似。汇编除法指令Divi r的功能是:将累加器da的值除以数据存储器r单元的数,结果商放到累加器中,余数放入输出寄存器out。指令Divi的编号为01110。

假定pc指向汇编指令Divi r在程序存储器的地址,节拍器初始值是0,那么连续的动作步骤如下:

(1)节拍为0时,irom→指令寄存器ir,节拍器加一;

(2)节拍为1时,ir高5位是01110,让指令标志Divi=1,将低11位送mar,节拍器加一;

(3)节拍为2时,且指令标志Divi=1,让pc+1,节拍器加一;

(4)节拍为3时,且指令标志Divi=1,将dram送寄存器b,节拍器加一;

(5)节拍为4时,且指令标志Divi=1,将da送寄存器a,节拍器加一;

(6)节拍为5时,且指令标志Divi=1,将a/b低8位送da,将余数送out,节拍器加一;

(7)节拍为6时,让指令标志Divi=0,节拍器归零复位。

15 . Stp 指令

停机指令应该是CPU 设计中不可缺少的指令。汇编指令Stp的功能是:停止节拍器加一的动作。

假定pc指向汇编指令Stp在程序存储器的地址,节拍器初始值是0,那么连续的动作步骤如下:

(1)irom→指令寄存器ir,节拍器加一;

(2)节拍为1时,ir高5位是11111,节拍器归零复位。

我们暂时就考虑设计这15条指令,它们是任何一个CPU都不能够缺少的指令。随着任务的需求,一般CPU都会增添一些指令,这样才会使自己设计的CPU更加适用。设想指令这些细致地分析,是我们进行CPU设计程序的依据。要想能够独立地创建自己的CPU,就必须掌握好对指令系统的详尽分析,确定出每条指令执行的步骤,这样才能成为设计CPU的行家里手。

cpu设计-->cpu指令设计与全程逻辑分析