首页 圈子 我的社区 微课程 问答 积分兑换 活动 投票 搜索 文章 软件
全部 Proteus 教学

基于proteus的一个微程序CPU

zhangly
发表于 2019-05-05 16:04:40

指令集与CPU架构

本文将设计一个微程序CPU,微程序的原理请参见前述文章基于proteus的CPU控制器设计(微程序版)。设计CPU之初,首先要定义一套较完备的机器指令集,该指令集应满足用户所需的全部功能,包括程序结构(顺序、循环及分支),算术逻辑运算,IO外设控制等等。
本文所述CPU的指令集如下1所示,指令格式定义如下:指令OP码为指令第一字节的高四位,即指令寄存器IR的{I7,I6,I5,I4}位。而RA和RB是指由{I3,I2}和{I1,I0}定义的逻辑寄存器,RA或RB都可以选择四个物理寄存器(R0~R3)中的任何一个。

表1. 微程序CPU指令集

如下图1所示,微程序CPU由微程序控制器(CONTROLLER)、时序电路(CLOCK)及数据通路组成。数据通路包括:程序存储器ROM、数据存储器RAM及通用寄存器R0~R3;IO接口;算术逻辑运算器(74LS181)及附带移位寄存器(74LS194);程序计数器(PC)、ALU运算结果标志位寄存器(PSW)及其断点寄存器(BP_PC、BP_PSW)。数据通路的所有部件都共同挂在一条8位系统总线BUS上。

图1. 微程序CPU电路图

微程序CPU电路图1的架构如下图2所示,图2右侧是时序电路(CLOCK)和微程序控制器(CONTROLLER),左侧则是由8位系统总线BUS串联起来的数据通路,挂在总线BUS上的CPU部件包括:存储器ROM/RAM及其地址寄存器AR;指令寄存器IR;通用寄存器R0~R3;算术逻辑运算器ALU及其附属的缓存器DA(兼作移位功能)和DB;外设I/O接口;程序计数器PC及其断点寄存器(BP_PC);中断向量地址(IVA)。此外,数据通路还包括右边的运算结果标志位寄存器(PSW)及其断点寄存器(BP_PSW)。

图2. 微程序CPU架构

微程序控制器

微程序CPU的微指令结构如下图3所示,微指令字长24位,其中1-5位是下一条微指令地址,即下址字段[uA4, uA0];6-8位是判断字段P1~P3;9-24位则是微命令字段,对应数据通路的所有微操作信号:其中置1的位表示执行相应的微操作;反之,置0的位则是不执行相应的微操作。

图3. 微指令结构图

其中,微指令的15-13位和12-10位采用字段编译法(3-8译码),分别对应源部件输出到总线BUS和总线BUS打入目标部件的微操作信号,如下表2所示:

表2. 微指令字段编译列表


此外,由于微程序控制器数据通路相互独立,两者操作可以并行执行,微程序CPU的微指令周期只需要T1和T2两个状态,微指令状态机循环输出节拍序列{T1,T2},使状态顺序转移:T1→T2→T1→…

表3. 微指令状态机


如下图4所示, 24位微指令存储器MROM1-3共存放了32条微指令,所以微地址是MABUS_4-0。当信号ON或T1节拍上升沿,微地址下址指定的微指令的微命令字段和P字段锁存到微指令寄存器MDR1~3,输出微操作信号;而下址字段则送往微地址寄存器。
下图4中,微指令寄存器MDR2的输出端采用了两个3-8译码器74LS138进行字段译码,分别实现把数据从源部件输出到总线BUS(译码器U8)的微操作和从总线BUS打入目标部件(译码器U7)的微操作。因为,在任何一条微指令中仅有一条数据路径,该路径中只有一个源部件把数据打入总线BUS,其微操作信号互斥;也只有一个目标部件从总线BUS接收数据,其微操作信号也是互斥,因此,上述两种微操作信号可以分别用译码器实现。

图4. 微指令存储器、寄存器及译码电路

微程序控制器的微地址转移电路如下图5所示,微地址寄存器五位(MA4-MA0),由触发器74LS74组成。T2时刻,当前微指令1-5位的下一条微指令地址[uA4, uA0]打入微地址寄存器;此刻,若当前执行的微指令中的判断位P1-P3置位,则地址转移逻辑电路将根据判断位P1-P3置位微地址寄存器MA4-MA0,如下图5所示:P2位生成信号#SET_MA4,P1生成信号#SET_MA3 ~ #SET_MA1,P1和P3位共同生成信号#SET_MA0。判断位P1~P3的地址跳转逻辑如下所示(可以对照后面具体指令流程图中“菱形框”的条件判断分支过程):
P1逻辑:若当前微指令是机器指令取指周期的最后一条微指令,则判断位P1=1,从而根据指令寄存器IR的{I7,I6,I5,I4}位强制置位微地址寄存器的MA3-MA0,修改微地址[uA3, uA0]位,转向该机器指令的执行周期序列的第一条微指令地址[0,I7,I6,I5,I4]。
P2逻辑:若当前微指令是机器指令执行周期的最后一条微指令,则判断位P2=1;此时,若无中断发生,则返回取指周期第一条微指令地址[00000];若有中断发生(INT=1),则强制置位微地址寄存器的MA4,转向中断处理过程第一条微指令地址[10000]。
P3逻辑:在CPU指令集中部分单字节指令和双字节指令(LAD/POP、STO/PUSH、ALU系列和JMP系列指令)共用OP码,其执行周期的微指令序列共用第一条微指令(判断位P3=1),从第二条微指令开始分支,根据指令寄存器IR的I1I0位来决定不同微指令的分支走向:若{I1,I0}=00,微指令下址的MA0=0,操作数分别来自寄存器和存储器(双字节指令);若{I1,I0}≠00,则微指令下址的MA0=1,操作数全部来自寄存器(单字节指令)。

图5. 微地址转移电路

取指与中断处理

下图6所示是取指周期、执行周期和中断处理周期的微程序流程图,其中每个方框在时间上表示一个微指令周期,包括T1和T2两个节拍;在空间上表示数据从某个源部件经过总线BUS到达另一个目标部件的路径。每个方框的右上方是该微指令在控制存储器中的地址,右下方则是下一条微指令地址。
除了空指令(NOP)和停机指令(HLT)以外,所有的CPU指令都包括了取指周期和执行周期。因为NOP指令OP码为“0000”,所以取指周期末尾P1(0,I7,I6,I5,I4)译码的时候,直接返回取指周期(取下一条指令),没有执行周期。而HLT指令与NOP指令完全相同,唯一不同是在取指周期后CPU硬件停机,需要手动RESET重启才能跳出停机状态,进入下一条指令。此外,外部中断触发后,中断处理周期有专用的微指令使程序转向中断子程序。待到中断子程序末尾,最后一条指令必须是中断返回指令(IRET),才能返回主程序。

图6. 取指周期、执行周期和中断处理周期的微程序流程图

在上图6中,NOP指令主要用于精准延时(微程序/硬连线CPU延时4个T,流水线CPU延时1个T);而HLT指令用作程序末尾CPU停机或设置断点:程序自动运行到HLT指令时刻停机,可以观察当时CPU寄存器,运算器标志位等信息。IRET指令用于在中断处理子程序末尾返回主程序(即BP_PC保存的地址弹回PC,BP_PSW保存的标志位信息弹回PSW),因此,不允许在主程序使用IRET指令! 否则将导致程序错误跳转。上述三种单字节指令统称为系统指令,如下表4所示。
【注:x在指令格式中表示此处的二进制数值可任意为0或1】

表4. 系统指令

此外,微程序CPU的中断电路采用单级中断机制,不允许中断嵌套;同时,CPU采用中断向量表的形式保存中断向量Vector(即中断子程序入口地址)。如下图7所示,中断子程序的位置和长度随意设置,子程序的首地址(即中断向量Vector)必须放在中断向量表中。中断发生时,CPU通过二次寻址跳转到中断子程序执行。

图7. 中断向量表示意图

寄存器及IO操作指令

如下表5所示,寄存器操作指令包括单字节的寄存器间数据传送指令(MOV)和双字节的寄存器赋值指令(SET)。SET指令的第二字节是赋予寄存器RA的立即数IMM。
例:“0110 0001;” 表示把R1的内容赋值R0;“0011 0000; 0000 0101;”表示把“05H”赋予R0。

表5. 寄存器操作指令

如下表6所示,I/O操作指令包括三条单字节指令:输入指令(IN)、输出指令(OUT)及地址选择指令(OUTA)。OUTA指令的功能是把寄存器的内容作为地址输出到IO端口的地址选择电路,选择所要操作的外部设备。OUT指令选定操作的外设后,CPU可以执行两种操作指令:IN指令把外设的数据输入寄存器RA,OUT指令则是把寄存器RA的内容输出给外设。
【注:IN指令可以选择{I1,I0}指定的四个输入端 PORT0-3中的一个; 而OUT/OUTA指令只能选择I0指定的两个输出端PORT0~1中的一个。】
例:“0100 0001;”表示把端口1的输入数据传送到R0。
“0101 0001;”表示把R0的内容作为数据,输出到端口1。
“0101 0011;”则是表示把R0的内容作为地址,输出到端口1。

表6. I/O操作指令

下图8是MOV、SET指令和IN、OUT/OUTA指令的微程序流程图,其中(P1判断前)取指周期和若有中断触发的(P2判断后)中断处理周期参见上图6。此外,OUT和OUTA指令的微指令序列完全相同,由硬件逻辑区分。

图8. 寄存器及I/O操作指令的微程序流程图


存储器及堆栈操作指令

如下表7所示:存储器操作指令包括两条双字节指令:取数指令(LAD)和存数指令(STO)。LAD指令把数据从地址ADDR(指令第二字节)的存储器单元取出,存入逻辑寄存器RA;而STO指令把逻辑寄存器RA的数据取出,存入地址ADDR(指令第二字节)的存储器单元。
堆栈操作指令包括两条单字节指令:出栈指令(POP)和入栈指令(PUSH)。此处提到的“堆栈”是基于存储器ROM/RAM的软堆栈,其指针就是逻辑寄存器RB。出栈和入栈指令即是把寄存器RB存放的内容作为存储器地址,把该地址单元的数据弹出到逻辑寄存器RA(POP指令)或把逻辑寄存器RA的内容弹入到该地址单元(PUSH指令)。
【注:因为LAD和POP指令共用OP码,STO和PUSH指令也共用OP码;所以共用OP码的指令间区别在于{I1,I0}位指定的内容。LAD和STO指令的{I1,I0}=00,故POP和PUSH指令的{I1,I0}≠00,即其指定的逻辑寄存器RB(指针)不能选择R0】
例:“1000 0000; 0000 0101;”表示把存储器地址[05H]存放的数据弹出到寄存器R0。
“1000 0001;”表示把堆栈指针R1指向的地址[R1]存放的数据弹出到寄存器R0。

表7. 存储器及堆栈操作指令

下图9是存储器操作指令LAD/STO和堆栈操作指令POP/PUSH的微程序流程图。从图中可以看出,POP指令只需要[11011]和[11101]两条微指令就够了,但是为了节省OP码,POP和LAD指令共用OP码“1000”,即共用第一条微指令[01000](即使POP指令其实并不需要微指令[01000])。从而可以在第一条微指令的末尾采用P3(I1,I0)判断LAD和POP指令的不同路径:若{I1,I0}=00,执行直接根据第二字节目标地址ADDR从存储器取数的双字节LAD指令;若{I1,I0}≠00,则执行根据逻辑寄存器RB(R1~R3)内容指定的目标地址从存储器取数的单字节POP指令。STO和PUSH指令的关系类似LAD和POP指令。

图9. 存储器及堆栈操作指令的微程序流程图

跳转系列指令

如下表8所示:无条件跳转指令JMP/JMPR的功能是程序必须跳转到目标地址执行,而有条件跳转指令Jx/JxR的功能则是程序是否跳转需要条件判断:当运算器结果标志位CF(溢出)、ZF(零)或SF(符号位)为1时,程序跳转到目标地址执行;反之,标志位为0则程序不跳转,继续顺序执行。根据判断标志位的不同,共有JC、JZ和JS三个有条件跳转指令。
跳转系列指令共用OP码0001,指令{I3,I2}位规定是无条件跳转指令(JMP/JMPR)还是有条件跳转指令(Jx/JxR)其中一种;而指令{I1,I0}位则指定目标地址是来源于寄存器RB(单字节JMPR/JxR指令)还是来源于地址ADDR的存储器单元(双字节JMP/Jx指令)。
【注:双字节跳转指令{I1,I0}=00,故单字节跳转指令{I1,I0}定义的逻辑寄存器RB不能选择R0】
例:“0001 0100; 0000 0101;”表示当CF=1时,程序跳转到第二字节指定的目标地址05H。
“0001 1001;”表示当ZF=1时,寄存器R1存放数据作为目标地址,程序跳转到该地址。

表8. 跳转系列指令

下图10是JMPR/JxR指令和JMP/Jx指令的微程序流程图。从图中可以看出,JMPR/JxR指令只需要[11111]微指令就够了,但是为了节省OP码,两条跳转指令共用OP码0001,即共用第一条微指令[00001](即使JMPR/JxR指令其实并不需要 [00001] 微指令)。从而可以在第一条微指令的末尾采用P3(I1,I0)区分两种跳转指令的不同路径:若{I1,I0}=00,执行直接根据第二字节目标地址ADDR跳转的双字节JMP/Jx指令;若{I1,I0}≠00,则执行根据逻辑寄存器RB(R1~R3)内容指定的目标地址跳转的单字节JMPR/JxR指令。

图10. 跳转系列指令的微程序流程图

算术逻辑运算系列指令

如下表9所示:单字节移位指令SHT可以把逻辑寄存器RA中存放的数据向左或向右移动一个位(bit),移入的位是0(逻辑移位)或是数据另一端的位(循环移位)。四种SHT指令共用OP码1010, 指令I0位指定逻辑移位还是循环移位,而指令I1位则是指定移位的方向。
【注:此处右移位是指寄存器输出Q3Q2Q1Q0往小端移动,而左移位是指寄存器输出Q3Q2Q1Q0往大端移动,跟时序发生器74LS194的右移和左移的定义相反】

表9. 移位指令

如下表10所示:单字节单操作数运算指令SOP可以把寄存器RA递增(INC)、递减(DEC)、取反(NOT)和直通(THR)。如下表所示,四个SOP指令共用OP码0010,由指令{I1,I0}位指定具体功能。
【注:THR指令一般用于根据某个寄存器的数据判断ZF和SF标志位,从而决定是否跳转】

表10. 单操作数运算指令

如下表11所示:双字节双操作数运算指令可以把两个操作数进行算术运算:加法(ADD)、减法(SUB),以及逻辑运算:与(AND)、或(OR)、异或(XOR)。指令的{I1,I0}位指定两个操作数全部来自寄存器或是操作数分别来源于寄存器和立即数IMM(指令第二字节)。前者是单字节指令(ADD、SUB、AND、OR、XOR),后者是双字节指令(ADDI、SUBI、ANDI、ORI、XORI)。
【注:双字节指令的I1I0=00,故单字节指令{I1,I0}位定义的逻辑寄存器RB不能选择R0。】
例:“1101 0000; 0000 0101;”表示加法运算“R0=(R0)+05H”。
“1101 0001;” 表示加法运算“R0=(R0)+(R1)”。

表11. 双操作数运算指令

算术逻辑运算系列指令的微程序流程图如下图11所示:为了节省微指令,所有的运算指令都在第一条微指令期间锁存74181运算器的控制端逻辑[S3,S2,S1,S0,M,CN]。此外,五种双操作数的运算指令都采取在第一条微指令的末尾采用P3(I1,I0)判断双字节和单字节指令的不同路径:若{I1,I0}=00,执行操作数分别来自逻辑寄存器RA和指令第二字节(立即数IMM)的双字节指令;若{I1,I0}≠00,则执行操作数全部来自寄存器的单字节指令。

图11. 算术逻辑运算系列指令的微程序流程图

参考资料

本文的内容节选自作者编撰的教材专著《基于Proteus的计算机系统实验教程——逻辑、组成原理、体系结构、微机接口》(机械工业出版社),更详细的内容可以直接在书中查阅。
读者如有兴趣,可以在 当当网图书, 京东图书,亚马逊 上搜索作者姓名赖晓铮即可找到这本著作。 

本书详细描述了在proteus虚拟仿真环境中,从逻辑电路开始,一步一步构造运算器、存储器、控制器,最终用三种CPU体系架构(微程序、硬布线、流水线)实现了一个8位的CPU。并且,这个CPU不仅可以做逻辑、算术运算,拥有循环、分支、堆栈等程序结构,还可以完整实现对8086所有外设的控制,即替代8086完整实现了传统《微机原理》里讲到的所有外设实验。
本书的全部proteus工程文件,PPT,实验视频以及配套的两种形式课程设计(纯汇编、硬件改动)的资料都放在 百度网盘,提取密码:34ad
广州风标为本书配套了实验箱(如下图所示),可以让学生在电脑的proteus虚拟仿真环境中设计CPU或选择已有的8086、8051、ARM等CPU模型,然后通过虚拟总线映射到实验箱的物理总线,控制实验箱面板上的真实外设。有兴趣的读者可以自行联系 广州风标教育技术股份有限公司




作者:华南理工大学 赖晓铮教授


228 0

你的回应