科学网

 找回密码
  注册

tag 标签: CPU设计

相关帖子

版块 作者 回复/查看 最后发表

没有相关内容

相关日志

姜老师带你设计CPU之13
accsys 2014-8-10 06:27
5.3. 带指针的计算机 在进行存储器的访问中,经常会碰到处理连续的若干个存储单元数据的问题,这种连续的地址变化常用到具有加 1 和减 1 功能的计数器,一般把处理存储地址的计数器叫指针。 5.3.1. 间接寻址与指针 所谓的指针是一种间接确定存储单元地址的工具。指针可以是某个存储单元组成的变量,但变量作为指针的操作比较慢,处理过程要访问存储器。采用计数器放置存储单元地址,不需要用访问存储器,处理速度极快。 在前面的计算机指令格式中,操作数只能是地址。如果将存储单元地址能够放在变量或计数器中,用这个变量或计数器作操作数,那么当变量或计数器的值改变时,操作的地址就会发生改变,这在处理连续的数据存放时是十分方便的。 汇编程序设计用括号来表示用变量的内容作为存储单元的地址,例如, STR ( X ),当 X 的值为 5 时,就表示把累加器 A 的值送到 5 号存储单元, X 的值是 8 时,就表示把 A 的值送到 8 号存储单元。 变量 X 在存储器中有一个固定的地址 X ,( X )表示 X 的值是实际地址,用这种形式寻找存储器地址的方法就叫变量间接寻址。如果用计数器作操作数来访问存储器,那么计数器的值就是要访问的存储器地址。用计数器或寄存器的值作为存储器的地址,叫寄存器间接寻址。 5.3.2. 带指针计算机的 设计 用通用计数器作为指针来访问存储器,会给计算机处理成块数据带来极大的方便。带指针的计算机能够实现的功能较多,因而指令系统也相对庞大。为了能够扩大指令集,增加对数据的处理能力,将带指针的计算机内部总线改成 16 条,这样处理的数据就可以是 16 位的。如果让运算器、存储器、让寄存器和计数器等都是 16 位的,这种计算机称为全总线结构计算机。 计算机整体结构 全总线计算机数据和地址信号宽度一样,十分方便处理数据和地址信号的转化。 图6‑12 的计算机中,粗实线代表 16 位的内部总线。为适应全总线结构的指令分析的需要,用两个寄存器 COM 和 IR 进行指令分析,寄存器 COM 主要接收操作码,寄存器 IR 主要接收操作数。 图 6‑12 带指针计算机 这个计算机还增加了两个数据寄存器 X 、 Y 和一个通用计数器 PTR 充当指针,这些设备都有 L 门和 E 门,可以自由地进行数据输入输出。 PTR 有加 1 控制端 C t 和减 1 控制端 D t ,因此能够进行加 1 和减 1 操作,这样就可以用它实现连续的地址变化。 这个计算机控制字不包括输入寄存器 IN 的 L 门,控制线共有 29 条。 这种全总线结构的计算机显然不能在 16 位的数据中划分出地址信号和操作码,因为要传输 16 位的地址信号就得单独地利用总线一次,操作码的传输再要一次,所以指令中如果有地址信号,至少需要通过总线传送两次。为了说明问题简单,将完整指令取出需要访问存储器的次数,定为指令的次数。指令的次数可以反映出指令占用的存储单元的数量。 指令格式 由于 16 位的地址需要单独占用一个存储单元,所以涉及访问存储器的指令最少得用 32 位表示,其中有 16 位要表示地址信号,高 16 位要用来表示操作码。假如指令的次数可以是 1 、 2 、 3 、 4 ,那么要区分它们至少要占用 2 位,如果再考虑最多有 64 条指令,这需要占用 6 位,那么高 16 位除了指令代码使用的 8 位之外,还会剩下 8 位可以它用。一次、二次、三指令的格式设计如 图 6‑13 的 (a) 、 (b) 、 (c) 所示,四次指令格式在冯 . 诺依曼计算机中较少使用,所以没有列出。 图 6‑13 指令格式设计 指令格式中的最高 2 位的 00 、 01 、 10 、 11 ,分别代表 1 ~ 4 次指令。指令的存放要高 16 位放在低存储单元,低 16 位要放在高存储单元,这样可以先将指令次数取出,先让计算机分析出指令的长度,以便决定是否再次进行取指令操作。 带指针的计算机只有一次和二次指令,由于没将寄存器编址管理,所以寄存器操作数的位置暂时不用。如果是 8 位的全总线计算机,还要安排 64 条指令,那么这种指令格式就没有了寄存器操作数的位置。 取指过程 有多次指令存在的计算机的取指过程,已经不像前面讲的取指周期那样简单了。由于指令已经不能够一次从存储器中取出,所以就必须判断还要访问几次存储器来取指令。指令格式的最高 16 位最先从存储器中读出的目的,就是要尽早获得几次访问存储器的信息,以便决定计算机的动作。 区分指令次数仍然使用译码器, 2 位的译码器连接在指令寄存器 COM 的最高 2 位上,第一次访问存储器的 16 位指令数据放在这里时,立即可以译出是几次指令,进而决定是否要再次访问存储器取指令。如果高 2 位译出的是 0 ,则不再到存储器中取指令数据,如果译出的是 1 ,则再次到存储器取一次指令数据,当然译出的是 2 ,就再进行两次访问存储器取指令数据。 5.3.3. 立即数指令 全总线结构计算机非常容易设计在指令中放入数据,这种指令一般被称为立即数指令。这台计算机设计一条直接将数值赋给累加器 A 的指令。 “将数 n 放在累加器 A 中”的助记符记作“ SDA n ”, n 是一个 16 位的二进制数,十进制的值是 0 ~ 65535 或 -32768 ~ 32767 的整数,当然也可以认为是小数。有了这条指令,今后程序中要将一个整数赋给某个变量,就不必通过键盘操作来完成,可以由程序设计人员直接编程序时写出,这样既加快了程序运行速度,又避免操作出错。 SDA n 是一个 2 次指令,需要两次访问存储器才能够将指令的数 n 取出。例如, SDA 125 表示的是“将 125 送到累加器 A ”。如果 PC 的值正是指令 SDA 125 的存放地址,那么在这个计算机中这个指令实现的过程是: (1) PC → MAR ; (2) RAM → COM ; (3) PC+1 ; (4) RAM → IR ; (5) PC+1 ; (6) IR → A 。 这个指令第一次从存储器中取出高 16 位,放在指令寄存器 COM 中,程序计数器 PC 加 1 。当 COM 的高 2 位被译出是 2 时,计算机会再次从存储器的下一个存储单元中取出数 125 ,放在寄存器 IR 中,程序计数器 PC 再次加 1 。最后将 IR 的内容 125 送到累加器 A 。 5.3.4. 指令系统 这台计算机的结构较前面介绍的计算机有很大的变化,因而不能使用指令扩充的方法来进行指令系统设计。原来功能的指令助记符不变,指令功能、指令次数、指令编码如 表6‑5 所示。 从表6‑5可以看到,操作码有指令次数码和指令代码两部分组成,而且指令次数码一定要放在前面。 一次指令没有操作数,因为数据所在的位置是隐含的。例如“POPP”隐含的数据位置是堆栈的栈顶下面一个位置,数据传送到通用指针PTR。 二次指令一定有一个操作数,并且一定是存储器的地址。如果要设计三次指令,操作数就要有2个,并且都应该是存储器的地址。 现在许多计算机的设计都使用编址的寄存器堆来存放临时数据,或者为了扩大存储器的容量,用寄存器间接寻址,这样在指令格式中就会有寄存器操作数。这里设计的计算机暂时还不包括寄存器操作数。 表 6‑5 指令系统 序号 功能 助记符 次数 指令编码 1 将数据装入当前存储单元 LOD 01 000001 2 将存储单元R的内容送到累加器A LDA R 10 000010 3 将存储单元R的内容与累加器A相加,结果送累加器A ADD R 10 000011 4 将累加器A与存储单元R的内容相减,结果送累加器A SUB R 10 000100 5 将累加器A的内容送到存储单元R STR R 10 000101 6 跳到R单元取指令 JMP R 10 000110 7 如果累加器A的值是0则跳到R单元取指令 JZ R 10 000111 8 如果累加器A的值为负则跳到R单元取指令 JN R 10 001000 9 将存储单元R的内容输出 OUT R 10 001001 10 读入数据并送到存储单元R IN R 10 001010 11 将累加器 A 的内容入栈 PUSH 01 001011 12 将堆栈的内容送到累加器 A POP 01 001100 13 调用 R 子程序 CALL R 10 001101 14 返回指令 RET 01 001110 15 将 PTR 的内容入栈 PUSP 01 001111 16 将 PTR 的内容出栈 POPP 01 010000 17 指针寄存器PTR加1 INC 01 010001 18 指针寄存器PTR减1 DEC 01 010010 19 将PTR所指单元的内容送到累加器A MPA 01 010011 20 将累加器A的内容送到PTR所指单元 APM 01 010100 21 将累加器A的内容送到PTR ATP 01 010101 22 将PTR的内容送到累加器A PTA 01 010110 23 将存储单元R的地址送累加器A ARA R 10 010111 24 将累加器A的内容送到当前存储单元 ATR 01 011000 25 将当前存储单元的内容送到累加器A RTA 01 011001 26 输入数据送到PTR所指单元 INP 01 011010 27 将寄存器X的内容送到累加器A XTA 01 011011 28 将累加器A的内容送到寄存器X ATX 01 011100 29 将寄存器Y的内容送到累加器A YTA 01 011101 30 将累加器A的内容送到寄存器Y ATY 01 011110 31 将数n送到累加器A SDA n 10 011111 32 停机 STP 01 111111 复杂的指令系统会使控制矩阵的设计更加复杂,然而取指周期变化不大,而指令的执行周期又多了访问存储器次数的内容。 (1) PC → MAR ; (2) RAM → COM ; (3) PC+1 ; (4) 如果次数是 01 , PC → MAR ; (5) 如果次数是 01 , RAM → IR , PC+1 ; 可见指令执行周期增加了判断是否再次访问存储器的内容。 5.3.5. 数组访问的程序设计 有了通用计数器充当指针和相关的指令,处理存储器中连续存放的数据就十分方便了。 数组访问的例子 【例 6‑5 】 将 100 以内的正整数放入内存 DATA 开始的数组内。 这个例子主要是说明指令 SDA n 、 ARA 和 APM 的使用,由于比较简单,可以直接用汇编指令写出。 START : SDA 100 STR N ;N=100 SDA 1 STR ONE ;ONE=1 ARA DATA ATP LOOP : LDA N APM ;将数送到数组单元 SUB ONE ;N=N-1 JZ EXIT ;如果N=0结束 STR N INC ;处理数组的下一个单元 JMP LOOP EXIT: STP 环行栈 使用指针之后,在计算机程序设计中出现了栈和环行栈概念。 定义 6‑9 计算机中用指针指示位置进行数据读写操作的一块存储空间叫 栈 。如果一个栈能够环行操作,就称为 环行栈 。 环行栈的示意图如 图 6‑14 所示,实际中只有( a )而没有 (b) ,( b )是( a )的示意图。图中只有 8 个存储单元,用一个 3 位的地址指针就可以完成环行操作。 图 6‑14 环行栈 由限位记数法知道, 3 位的地址指针的值为 7 时,再加 1 后的值就变成了 0 ,这样地址指针就又指向了第一个存储单元。同样,在地址指针的值为 0 时,再减 1 就会使它的值变成 7 ,地址指针就又指向了最后一个存储单元。地址指针就可以用不断加 1 的方式或不断减 1 的方式实现对栈的循环指示,地址指针不断地加 1 就可以实现栈的增量环行,同样不断地减 1 就可以实现栈的减量环行。 由栈的定义立即可以知道,队列和堆栈都是栈的特殊情况。 起泡排序 下面以起泡排序程序设计来说明指针的应用,通过这个例子来解释运用指针的程序设计技巧。 【例 6‑6 】 从键盘输入 n 个数,用起泡排序法将其由小到大排好。 图 6‑15 是将 n (这里 n=6 )个数连续放入堆栈,从栈顶的第一个数开始将前面的数与后面的数进行比较,后面的数小就进行交换位置,不然保持原序。这样从前比较到后面要比较 n-1 次,于是可以将最大的数放在最下面(图中第 2 列),再将剩余的 n-1 个数进行同样的比较,最终可将所有的数由小到大排列好,这就是著名的起泡排序。 在起泡排序中应注意每一列比较都是从同一个堆栈位置开始的,不同的是后次比前次少比较一次而已。 n 个数要比较 n-1 趟(列),第 i 趟(列)要比较 n-i 次,其中 1 ≤ i ≤ n-1 。 图 6‑15 起泡排序 这个 例 题构造了两个子程序,它们是输入子程序和排序子程序。输入子程序将输入的数依次送入堆栈,排序子程序将堆栈内的连续存放的数用起泡排序法排好。 主程序如下: MAIN : IN N ;输入n个数 LDA N STR I ;存入I IN ONE ;将1送入ONE CALL INPUT ;调用输入子程序 CALL SORT ;调用排序子程序 STP ;停机 输入子程序: INPUT : IN X0 ;输入第一个数并放入X0 LDA I ;计算输入个数 SUB ONE ;减1 JZ EXIT1 ;为零退出 STR I ARA X0 ;将X0的地址送到A ATP ;X0地址送PTR INPUT1 : INC ;PTR+1 INP ;输入数据到PTR所指单元 LDA I ;计数 SUB ONE JZ EXIT1 STR I JMP INPUT1 EXIT1 : RET 排序子程序: SORT : LDA ONE STR I ;1送I,用I做比较趟数变量 COLUMN : LDA N ;判断超过n-1次 SUB I JZ EXIT2 ;I=N时退出 ROW : LDA ONE ;J初值是1 STR J ;J是比较次数变量 ARA X0 ;将X0地址送到A ATP ;X0地址送PTR COMPARE : LDA N ;下面确定比较次数是否超过n-i次 ADD ONE ;因为是先计数后比较, ;所以要看n-i+1=j SUB I SUB J JZ NEXT ;进入下一列比较 COMP0 : MPA ;前一个数送A STR X ;放在X中 INC MPA ;后一个数送A STR Y ;放在Y中 SUB X ;Y-X比较大小 JN CHANGE ;XY转 JMP COMP1 ;转到下一次比较 CHANGE : LDA X APM ;将大数送入后一单元 DEC ;指针PTR减1指向前一单元 LDA Y APM ;将小数送入前一单元 INC ;指向大数位置 COMP1 : LDA J ;J+1 ADD ONE STR J JMP COMPARE ;下一次比较 NEXT : LDA I ;列数加一 ADD ONE STR I JMP COLUMN EXIT2 : RET 主程序将输入数据的数组单元个数放在 N 中,并把这个数放入 I 中,以便输入数据时计数,再将“ 1 ”送到 ONE 中,然后调用 INPUT 和 SORT 子程序分别完成输入数据和排序的任务。 子程序 IUPUT 先输入一个数放入数组的第一个单元 X0 ,并把数组的首地址放入了指针 PTR ,然后利用指针 PTR 增量变化输入数据,直到 I=0 结束。 排序子程序要注意次数的计算,总的比较列(趟)数是 n-1 ,第 i 列比较的次数是 n-i ,还要注意是“先比较,后计算次数”还是“先计算次数,后比较”,后者要比前者的控制变量多一次。程序中标号 COMPARE 下面的计数是后者,因为第 i 趟总共要比较 n-i 次,如果是先比较,那么计数次数 j=n-i ,但因为是先计数后比较,所以应该有 j=n-i + 1 。
个人分类: 计算机核|2853 次阅读|0 个评论
姜老师带你设计CPU之12
accsys 2014-8-9 18:38
5.2. 可转子程序的计算机 上节所介绍的计算机仍然是十分简单的,还不能够实现子程序调用,存储容量还不够大。实际上计算机的存储器容量是相当大的,现在人们使用的微型电子计算机的存储器都达到了几百兆甚至上千兆以上,大型的计算机存储器使用则可以达到数千兆以上。本节要介绍的带有转子程序功能的计算机,对存储容量进行了适当的扩大,以满足程序设计的要求。 5.2.1. 功能设计 和计算机结构 要实现子程序调用,计算机必须有相应的功能,而要实现子程序调用的功能,计算机必须有相应的组织结构。因此对于能够实现子程序调用的计算机,要先来说明这台计算机新增的功能和计算机结构的变化。 功能设计 这台 计算机欲增加的功能有两条。 (1) 在执行某个程序的过程中暂时停下来,而转去执行另一段程序,当另一段程序执行完之后,又恢复原来的程序执行。这一过程叫子程序调用。 定义 6‑4 如果有一个程序执行过程中在某固定位置停下来,将另外一个程序执行一遍,然后再从停下来的位置继续执行,这种现象叫 子程序调用 。被调用的程序叫 子程序 ,调用的程序叫 主程序 。 (2) 它还可以将某些数据以“叠放”的形式保存起来,当需要的时候再以“后进先出”的规则拿出来。这就是堆栈的问题。 主程序运行过程中会有一些数据在后面的执行中还要使用,而子程序的执行很可能破坏这些数据,因此必须把有用的数据以“后进先出”的规则保存起来,在恢复主程序执行时,要先恢复这些原来的数据,这种过程叫“保护现场”和“恢复现场”。 新计算机设计的新指令如 表 6‑4 所示,通过这些指令才能够具体实现上述的功能。 表 6‑4 增加的指令 功 能 助记符 操作码 将累加器 A 的内容送入栈 PUSH 1010 将栈顶的内容送到累加器 A POP 1011 调用子程序 R CALL R 1100 从子程序返回 RET 1101 将寄存器 B 的值送到 R 单元 STB R 1110 计算机的结构 程序执行的过程中如果调用子程序,那么必须将主程序的下一条指令的位置记住,还要记住它恢复运行的环境,以便将来恢复运行时不至于出错。由于保护现场是主程序来完成的,而恢复现场必需由子程序来完成,故保护现场的设备必须具有独立性,主程序可以顺序地将数据放进去,子程序又能够按着后进先出的规则进行恢复,保证主程序的运行条件。 图 6‑9 就是一个带有转子程序功能的计算机结构,它也是在前面计算机的基础上改造而来的,图中没标的双线一律为 12 条线的组合。这台计算机的总线由 8 条线增加到 12 条(数据线用 12 条,地址线用 8 条);寄存器 B 新增了 E 门,这样可将 B 中数据输出;新增加了一个计数器 SP ,它叫堆栈指针。 SP 的预置端连在 Clr 线上,当 Clr=1 时, SP 的值为 11111111 ( 2 ) 。 SP 具有加 1 控制线 C s 和减 1 控制线 D s ,当 C s =1 时,使 SP 加 1 ,当 D s =1 时,使 SP 减 1 。 图 6‑9 具有子程序调用功能计算机 指令寄存器 IR 输入线有 12 条,直接连接在总线上。输出时 IR 的低 8 条线用来传送地址信号,高 4 条线仍然与指令译码器的输入端相连,放置 4 位的指令代码。 这台计算机的控制字已经达到了 20 位。如果 L n 由其他设备控制,那么计算机控制器发出的控制字应该是 19 位。 5.2.2. 队列与堆栈 堆栈是计算机执行子程序时保存现场和恢复现场的必要设备,队列在计算机的发展中也担当了十分重要的角色,下面就来介绍队列与堆栈相关的问题。 队列 在资源管理,数据处理中经常要用到队列的概念,队列涉及先进先出的优先顺序。 定义 6‑5 按照先进先出原则进行数据处理的存储设备叫做 队列 。 队列在计算机中应用很广,在多个程序使用一个设备或其他不能同时使用的资源时,常常用队列来处理使用的先后顺序。 堆栈 在日常生活中人们把物品放入箱子或口袋时,一般后放入的物品反而被先拿出来,这种情况叫“后进先出”。 定义 6‑6 按照后进先出的原则进行数据处理的存储设备叫做 堆栈 。 堆栈的组织形式如 图 6‑10 所示。 图 6‑10 堆栈 往堆栈里放数据,就如同往箱子里装东西一样,堆栈最底下位置叫栈底,就是第一个数据放入的 地方( 图 6‑10 中的 7 号地址单元)。堆栈最上面要放数据的位置叫栈顶,就是将要放入数据的地方(它的下面位置都已经放入了数据或者没有数据)。指示栈顶的计数器叫堆栈指针。本计算机中的计数器 SP 就是用来指示栈顶的堆栈指针,它指示的位置就是将要放置新数据的位置。 图 6‑10 就是堆栈 STACK 的示意图, SP 是堆栈指针,它指示的位置 3 是栈顶,栈底的位置是 7 。 由于规定栈顶是将要放入数据的存储单元,可以想到,按照这样的规定,如果 堆栈的栈顶和栈底的地址相同,那么堆栈就是空的或者全部存储单元都放满了数据。全部存储单元都放满了数据,而堆栈指针指回了栈底,堆栈指针一定有“环绕”功能。这个问题留在后面的环行栈问题再讨论。 入栈与出栈 堆栈的 数据处理是指把数据放进堆栈,或者将数据从堆栈取出来。为了说明问题方便,今后在不作特殊声明的情况下,就规定堆栈的栈底在高地址端,数据装入将向低地址端延伸。 定义 6‑7 向堆栈里面放数据的过程,称之为 入栈 。 根据堆栈指针应该指向空位置的规定,入栈时堆栈指针 SP 应该减 1 。实际的操作过程是,先将数据放入 SP 所指示的单元,然后 SP 减 1 。入栈的结果会破坏堆栈中原来位置的数据。 定义 6‑8 从堆栈里取出数据的过程称之为 出栈 。 因为出栈的意思是将堆栈中的数据取出,而堆栈指针一般总是指向没有数据的地方,所以要先将堆栈指针指向应该读走的数据。因为数据入栈的时候,堆栈指针 SP 进行了减 1 操作,所以此时堆栈指针 SP 要先加 1 。实际上操作过程是:先将 SP 加 1 指向要输出的数据,然后将数据输出,此后 SP 指向的这一位置可以放新的数据。 值得一提的是数据出栈只是数据的复制,因而堆栈内的数据在没有新的数据覆盖的情况下,会完好地保留。这种情况被用在利用堆栈进行排序的 例 题中,望读者能够留意。 5.2.3. 子程序调用 在计算机程序设计中,常常会碰到一个程序的一段内容,正好是以前设计好的程序,这时就不必将这一段程序重新写了。在程序执行中,只要把那个程序在适当的位置执行一次就可以了,这就是子程序调用的问题。 为保证主程序能够准确地在子程序执行完成之后,回到调用子程序的下一条指令执行,一般需要在子程序执行前保存下一条指令执行的条件,这是保护现场。保护现场最重要的是把调用子程序之后要执行的那条指令的地址保存起来,这个工作在设计的调用子程序指令中来完成。当然保护现场也要将有关的其他数据保存起来,比如各种标志位的数值等,这可以设计专门的指令操作。 子程序执行完成后,要将执行前的数据恢复,还要将保存起来的那条指令的地址送回程序计数器,将各种标志恢复到调用子程序之前的样子,这是现场恢复。 在子程序 调用的问题中,利用入栈出栈可以保护现场和恢复现场。具体的作法是将要执行的指令的地址入栈,也就是将 PC 的值入栈,然后将子程序的首地址送到程序计数器 PC 中,下一个指令周期就开始执行子程序了。当子程序执行完之后,再把入栈的地址回送到程序 计数器 PC 中,使计算机能够接着执行原先的要执行的指令。子程序调用中,如果有数据需要放在堆栈中保存,那么恢复现场时,要注意数据入栈出栈的顺序,不要将位置颠倒了。 可以看出,子程序调用和堆栈是分不开的。尽管堆栈的多少和大小,开口的方向设置的方法不尽相同,但它们要完成的任务是一样的。 5.2.4. 转子程序计算机新增的指令 根据这个计算机的结构和需求,新增加了入栈指令 PUSH ,出栈指令 POP , R 子程序调用指令 CALL R ,返回指令 RET ,还有将寄存器 B 的值送到存储单元 R 的指令 STB R ,在上节能判断计算机的基础上,加上这新增加的这 5 个指令,现在共有 16 个指令了。 这个计算机的指令编码和指令格式仍然延续前一节的假设,指令操作码还是 4 位,而操作数是 8 位的。 8 位的操作数表明的是存储单元的地址,这样指令就能够访问存储器的 256 个存储单元。 下面来看一下这些新增指令执行周期的基本动作。 PUSH 的例行程序 这条指令的作用是将累加器A的内容入栈。它的执行周期是 (4) E s =1 L m =1 (SP →MAR选择栈顶) (5) E a =1 M e =1 IO=1 (A →RAM将A的内容入栈) (6) D s =1 (SP-1→SP) 微指令(4) 是将堆栈指针的内容送到地址寄存器,选中栈顶存储单元。微指令 (5)是将累加器的内容送到栈顶。微指令 (6)是写存储器后将堆栈指针的值减1。 POP 的例行程序 这条指令的作用是将堆栈的内容送到累加器A中。它的执行周期是 (4) C s =1 (SP+1 →SP) (5) E s =1 L m =1 (SP →MAR选择栈顶数据) (6) L a =1 M e =1 (RAM→A将栈顶数据送A) 微指令(4)是将堆栈指针加1以便指向出栈的存储单元。微指令 (5)是选中存储单元。微指令 (6)是将存储器的内容送到A。 调用子程序指令 CALL R 的例行程序 这条指令是中断当前程序的执行,保存下一条将执行指令的地址,即将当前程序计数器的内容入栈,到R单元去取指令执行。它的执行周期是 (4) E s =1 L m =1 (SP →MAR选择栈顶) (5) D s =1 E p =1 M e =1 IO=1 (SP-1→SP,PC→RAM) (6) E i =1 L p =1 (IR→PC将子程序地址送到PC) 微指令(4)和微指令 (5)是将下一条执行指令的地址,即将当前程序计数器的内容入栈。微指令(6)是将子程序的地址送入PC。这里将堆栈指针减1的控制放在微指令 (5)或微指令 (6)都可以,不会影响指令的执行效果。 返回主程序指令 RET 这条指令的任务是从当前执行的位置返回到中断的位置。它的执行过程要把保存在堆栈的指令地址弹回到程序计数器。它的执行周期是 (4) C s =1 (SP+1→SP) (5) E s =1 L m =1 (SP →MAR选择栈顶) (6) L p =1 M e =1 (RAM→PC将中断地址送到PC) 这三条微指令的作用是在子程序执行完之后返回到主程序。 STB R 的例行程序 这台机器为了能灵活地传送数据,还设计了一个将寄存器B的值送到存储单元R的指令STB。 它的执行周期是 (4) E i =1 L m =1 (IR→MAR选中存储单元地址) (5) E b =1 M e =1 IO=1 (B→RAM) (6) 5.2.5. 子程序设计 由于这个计算机的地址线已经是 8 位的,故可以访问 256 个存储单元。就利用现有这 256 个存储单元就能设计出一些带有调用子程序的例子。 【例 6‑3 】 输入 3 个数比较它们的大小,输出其中最大的。 这个程序的流程图如 图 6‑11 所示,具体编写的程序也在下面。为了熟悉存储器的分配,这个例子特地使用了实际地址。将数据区定在 150 号地址单元开始,代码区设计了一个主程序,两个子程序。其中,一个子程序用来判断程序是否停止,具体的说,就是当 3 个输入数字都输入 0 时,停止程序执行。另一个子程序是找出最大的数。 主程序 : 0 : IN 150 ;输入地址为150地址单元存放的数据 IN 151 ;输入地址为151地址单元存放的数据 IN 152 ;输入地址为152地址单元存放的数据 CALL 20 ;调用判断结束子程序 CALL 50 ;调用找最大数子程序, ;并将最的数放入153号地址单元。 OUT 153 ;输出大数 6 : JMP 0 ;循环执行 图 6‑11 程序流程 检查结束的子程序 ( 输入的 3 个数都是 0 就结束 ) : 20 : LDA 150 ;第一个数放入A JZ 23 ;是0跳到23号单元 22 : RET ;返回主函数,对3个数的大小进行判断 23 : LDA 151 ;第二个数放入A JZ 26 ;是0跳到26号单元 JMP 22 ;不然跳到22返回 26 : LDA 152 ;第三个数放入A JZ 29 ;为0跳到29 JMP 22 ;不然跳到22返回 29 : STP ;输入的3个数均为0则结束 比较大小的子程序 (大数放在 153 号单元): 50: LDA 150 ;第一个数放入累加器A STR 153 ;再放到153单元 SUB 151 ;减去第二个数 JN 55 ;为负跳到55号单元 54 : JMP 56 ;不然跳到56号单元 55 : STB 153 ;第二个数放入153号单元 56 : LDA 153 ;第一第二的大数放入累加器A SUB 152 ;减第三个数 JN 60 ;为负跳到60 JMP 61 ;不然跳到61 60 : STB 153 ;第三个数放入153 61 : RET ;返回主程序 【例 6‑4 】 编程输出 n! ( n 是正整数)。 解答:考虑用乘法子程序 MULT ,将 N 放入 X , (N-1) 放入 Y , N(N-1) 放在 POW 中,最终结果由 POW 输出。 ONE 、 POW 的初值是 1 , RESULT 的初值是 0 。 MAIN : IN N IN ONE ;输入值是1 IN POW ;输入值是1 IN RESULT ;输入值是0 CALL MAKE OUT POW END: STP MAKE: LDA N JZ EXIT STR X LDA POW STR Y CALL MULT LDA N SUB ONE STR N JMP MAKE EXIT: RET MULT: LDA X JZ EXIT1 SUB ONE STR X LDA RESULT ADD Y STR RESULT JMP MULT EXIT1: LDA RESULT STR POW SUB RESULT STR RESULT ;置零 RET
个人分类: 计算机核|3058 次阅读|0 个评论
姜老师带你设计CPU之11
accsys 2014-8-9 10:58
6. 满足程序设计的 CPU 结构 前面给出的原型 CPU 实际只能够执行顺序结构的程序。计算机 CPU 能够替代人脑工作,需要有判断分析的功能,还要能够循环地考虑问题。这就是程序设计的分支与循环。这一部分我们将进入复杂一些的 CPU 结构设计,如果你的基础不够,就要多下一点功夫了。 6.1. 实现分支循环的计算机 判断是智能的标志,计算机能够实现程序运行的有条件跳转,就是智能的表现。本节介绍的能判断计算机可以完成数据的自动输入和地址的不连续变化,具有了一定的判断能力,能够实现跳转和循环结构的程序设计。 6.1.1. 能判断计算机的逻辑 人类进行判断要依据某种变化的信息,计算机实现判断也要依靠某种变化的标志信号,实现判断的计算机必须提供这种标志机制。 能判断计算机的结构 这里给出的电子计算机是在前面加减运算计算机的基础上改造的,它的结构如 图 6‑1 所示。为了实现程序运行中数据的输入,结构中将 EROM 换成了 RAM 。 RAM 有一条复位线 Clr 可以使所有的存储单元的值为 0 。前面的加减运算计算机只能从存储器的 0000 号单元开始执行指令,执行程序的方式只能是顺序的,不能改变顺序,不具有灵活性。这个计算机将行波计数器换成了程序计数器,目的在于能够实现程序的跳转和循环。程序计数器 PC 有 L 门,能够通过 L 门控制数据的输入,实现程序指令的不连续执行。结构中增加了输入寄存器 IN ,它可以从外部接收数据,然后送到 RAM 和其他寄存器。另外,为使该计算机有一定的判断能力,还为累加器 A 的值为 0 和为负设置了标志, A 为负数时由线 NF=1 标出, A 为 0 时由线 ZF =1 标出,这样可以根据这两条线的值实现程序的有条件跳转。 计算机控制字 显然这台简单的计算机的计算机控制字已经长了许多,由于增加了控制线,使原来的加减运算计算机的 12 位计算机控制字扩展成了 15 位: L p E p C p L m M e IOL i E i E n L a E a E u S u L b L o 由于输入寄存器 IN 的数据装入不是由控制器 CON 进行管理的,所以输入寄存器的控制线 L n 不包含在这个计算机的控制字当中。 图 6‑1 能判断计算机的结构 标志线 为了判断运算的结果,本计算机设计了判断累加器 A 中内容是 0 还是负数的识别线。 图 6‑2 中, ZF 是累加器 A 的所有数据位的或非门电路的输出端,它的值能够确定 A 中的数据是否为 0 。 NF 是累加器 A 的数据最高位的输出端,可以用它来确定 A 中的数是正数还是负数。这两条线都是为跳转指令准备的。由逻辑电路可以分析出, ZF=1 表示存放在累加器 A 中的数据是一个 0 ; NF=1 表示存放在累加器 A 中的是一个负数。可见通过 ZF 、 NF 可以知道累加器 A 的状态。 图 6‑2 标志线 定义 6‑1 能够标明设备状态的线叫 标志线 。 ZF , NF 就是标志线。标志线并不是机器的控制字,但它们是确定控制矩阵的依据,直接成为控制矩阵的自变量,属于自变量集中的元素,它们能对控制矩阵的输出端进行相应的逻辑控制。 根据标志线的定义可以知道,指令线也是标志线的一种。 计算机中的标志线一般都用 1 表示确认的状态,用 0 表示对那种状态的否定。 输入寄存器 为了使问题简单,能判断计算机结构增加了一个输入数据寄存器 IN 。输入数据寄存器 IN 的 E 门是主管向总线输送数据的,而 L 门则是主管从外部接收数据的,不受 CPU 的管理。假设输入数据寄存器 IN 的 L 门一打开就有数据进入,这些数据是事先准备好的。实际当中数据如何进入到数据寄存器,等到讲键盘缓冲区的时候再阐述。 6.1.2. 能判断计算机的指令 能判断计算机是具有条件判断功能的计算机设计,主要表现为依据一定的标志线信息,来决定后面的指令应该执行那一条。 指令的设计 根据需要,能判断计算机的指令比加减运算计算机的指令多设计了 6 个,在此将全部指令也列出一张表来说明这这些指令的设计内容(见 表 6‑1 )。 表 6‑1 指令代码设计 功 能 助记符 操作码 将数据装入当前存储单元 LOD 0000 将存储单元 R 的内容送到累加器 A LDA R 0001 将存储单元 R 的内容与累加器 A 相加,结果送累加器 A ADD R 0010 将累加器 A 与存储单元 R 的内容相减,结果送累加器 A SUB R 0011 将累加器 A 的内容送到存储单元 R STR R 0100 跳到 R 单元取指令 JMP R 0101 如果累加器 A 的值是 0 则跳到 R 单元取指令 JZ R 0110 如果累加器 A 的值为负则跳到 R 单元取指令 JN R 0111 将存储单元 R 的内容输出 OUT R 1000 读入数据并送到存储单元 R IN R 1001 停机 STP 1111 LOD 称为装入指令,它的作用是将 8 位的外部数据放入本指令所在的存储单元。由于这个地址是隐含的,故其指令格式中不要操作数。 这里把装入指令 LOD 的代码编为 0000 是因为存储器 RAM 带有 Clr 端,在开机时会将全部存储器单元的数据都变成 00000000 ,使每一个存储单元就都放置了 LOD 指令,这样通过 LOAD 可以将和存储器一样大小程序和数据一次性放入存储器。 有了指令 LOD ,在编程序时就不必用手去拨动 EROM 的开关了,可以按照存储器的形式将一条条的指令和数据书写好,放在某个外部介质上,开机时就会一次性地被读到存储器 RAM 中来,这样就能完成程序的自动输入任务。 为了能够自由地将输入数据放在指定的存储单元,这里又设计了数据输入指令 IN ,该指令可以在操作码的后面直接指出存储单元的地址,这样就可以将数据输入到 RAM 存储器的指定地方。 为了能够存放运算的结果,能判断计算机还设计了将累加器 A 的内容送到指定存储单元的指令 STR ,存储单元的地址作为操作数写在指令操作码的后面。 该计算机的结构已经使它具有逻辑判断的功能,于是就设计了两条按照一定条件改变程序执行顺序的指令,这就是有条件跳转指令 JN 和 JZ 。 JN 的意思是当累加器 A 的内容是负数时发生跳转,转移的地址由 JN 后面的操作数指出,形式是“ JN R ”。 JZ 的意思是当累加器 A 的内容是零时发生跳转,转移的地址也由 JZ 后面的操作数指出,形式是“ JZ R ”。 为了灵活地按照程序设计者的意愿进行程序执行,还设置了无条件跳转指令 JMP ,要跳转执行的下一条指令的地址由 JMP 后面的操作数指出,形式是“ JMP R ”。 条件跳转 从能判断计算机的结构可以看到,如果要改变指令的执行顺序,那么应设法将下一条要执行的指令的存储地址放在程序计数器 PC 中。根据跳转指令的格式,当跳转指令被放在指令寄存器 IR 后,就可以将 IR 的低 4 位传送给 PC 来达到跳转执行指令的目的(见 图 6‑1 )。在这个过程中,涉及到两条控制线 E i 和 L p 。如果无条件产生跳转,那么应该有 E i =1 , L p =1 。但是如果是条件转移, Ei 、 Lp 是否为 1 还要看条件,也就是 NF 和 ZF 两条标志线的具体值。 6.1.3. 指令例行程序 在加减运算计算机中已经提到过的指令,在这个能判断计算机中都有,它们的例行程序稍有变动。因为这里使用的是随机存储器 RAM ,如果需要访问 RAM ,就必须令 M e =1 ,这一点在它们的例行程序中都必须得以体现。在 EROM 的使用中没有提到块选择线 M e ,那是因为 EROM 的输出有输出控制线 E r 管理是否向总线输出, EROM 没有输入,不会引起总线数据的混乱。在块存储器组织的 RAM 中,使用时还必须要求存储器选择线 enable=1 。 为了分析和设计简单,指令可以分成几部分来研究它们的例行程序。 原指令的例行程序 加减运算计算机的指令在这个计算机中,例行程序略有变化,其中 E r 控制线变成了 M e 控制线,还有输出指令不再是将累加器 A 的内容输出,而是采用了更加灵活的将存储单元内容输出的形式。 为了使指令过程分析简化,以后值为 0 的控制线不写出,而只将值为 1 的控制线用等式表达出来。 指令 OUT R 的 例行程序如下: (1) E p =1 L m =1 (PC →MAR) (2) M e =1 L i =1 (RAM →IR) (3) C p =1 (PC+1) (4) E i =1 L m =1 (IR→MAR) (5) M e =1 L o =1 (RAM→ O ) (6) OUT R 的第 4 拍是将 指令寄存器 IR 的输出送到地址寄存器 MAR ,第 5 拍 将 RAM 的输出送到输出寄存器 O 。 新增指令的例行程序 这个计算机新增加的指令 LOD 、 JMP 、 JZ 、 JN 、 STR 、 OUT 、 IN 的例行程序仍然是 6 拍,它们的取指周期为: (1) E p =1 L m =1 (PC →MAR) (2) M e =1 L i =1 (RAM →IR ) (3) C p =1 (PC+1 ) 下面分别给出新指令例行程序的执行周期。 装入指令LOD 的执行周期 (4) M e =1 IO=1 E n =1 (IN →RAM) (5) (6) 需要指出的是,在LOD的执行周期中地址寄存器MAR的值一直都没变,故从输入寄存器读到的指令或数据,会放回LOD指令的那个存储单元。 无条件转移指令 JMP R 的执行周期 (4) E i =1 L p =1 (IR的低4位送到PC) (5) (6) A 中内容为零转移指令 JZ R 的执行周期 (4) 如果ZF=1,那么E i =1 L p =1 (A中内容为零IR的低4位送到PC) (5) (6) A 中内容为负转移指令 JN R的执行周期 (4) 如果NF=1,那么E i =1 L p =1 (A中内容为负IR的低4位送到PC) (5) (6) 指令 STR R 的执行周期 (4) E i =1 L m =1 (IR→MAR) (5) E a =1 M e =1 IO=1 (A→ RA M ) (6) 指令 IN R 的执行周期 (4) E i =1 L m =1 (IR→MAR) (5) E n =1 M e =1 IO=1 (IN→RAM) (6) IN 指令和 LOD 指令的不同之处是, LOD 指令是将数据回送到原来 LOD 指令所在的存储单元,而 IN 指令是将数据送到指令操作数所指出的那个存储单元。 6.1.4. 能判断计算机控制器 控制矩阵分组 计算机控制矩阵的设计是很复杂的,但如果新设计的计算机只是在原有的计算机中增加了设备,新增加了一些指令,并且原有的指令例行程序没有变化,那么只要设计增加的一部分指令的控制矩阵,然后将新增的控制矩阵与原控制矩阵连接。具体的连接方法,是把重复出现的控制线用或门连接,新增的控制线添加进去,这样就可以得到新设计计算机的控制矩阵。 能判断计算机的指令系统中虽然包括加减运算计算机的全部指令,然而例行程序都有一定的变化,所以不能够采用增添设计控制矩阵的方法。但为了减轻控制矩阵整体设计的压力,采用分块设计会使设计工作变得容易,并且适合多人参与的团队作战。 表 6‑2 和 表 6‑3 就是将指令分成两部分,分成 2 组的例行程序真值表,通过这两个真值表可以设计出控制矩阵的两部分。为了方便直接书写表达式,节拍前面增加一个字母“ p ”。 表 6‑2 原指令的例行程序 指令 机器动作 节拍 C p E p L m M e IO L i E i L a E a S u E u L b L o PC →MAR p1 1 1 RAM →IR p2 1 1 PC+1 p3 1 LDA R IR →MAR p4 1 1 RAM →A p5 1 1 p6 ADD R IR →MAR p4 1 1 RAM →B p5 1 1 A+B →A p6 1 1 SUB R IR →MAR p4 1 1 RAM →B p5 1 1 A -B→A p6 1 1 1 OUT R IR →MAR p4 1 1 RAM →O p5 1 1 p6 表 6‑3 新增指令例行程序 指令 机器动作 节拍 ZF NF E a C p E p L p L m M e IO L i E i E n L o PC →MAR p1 1 1 RAM →IR p2 1 1 PC+1 p3 1 JMP R IR →PC p4 1 1 p5 p6 JZ R IR →PC p4 1 1 1 p5 p6 JN R IR →PC p4 1 1 1 p5 p6 STR R IR →MAR p4 A →RAM p5 1 1 1 p6 IN R IR →MAR p4 1 1 IN →RAM p5 1 1 1 p6 LOD IN →RAM p4 1 1 1 p5 p6 控制矩阵设计 这个能判断计算机的控制矩阵完全可以像加减运算计算机那样来设计出来, 表 6‑2 表 6‑3 有底纹的部分变量属于自变量,由 表 6‑2 可得: C p =p3 E p =p1 L m =p1+p4(LDA+ADD+SUB+OUT) M e =p2+p5(LDA+ADD+SUB+OUT) L i =p2 E i =p4(LDA+ADD+SUB+OUT) L a = p5 ·LDA+p6(ADD+SUB) S u =p6 ·SUB E u =p6(ADD+SUB) L b =p5(ADD+SUB) L o =p5 ·OUT 这些函数的逻辑电路如 图 6‑3 所示。 图 6‑3 控制矩阵一组 由 表 6‑3 可得: E a =p5 ·STR C p =p3 E p =p1 L p =p4(JMP+ZF ·JZ+NF·JN) L m =p1+p4 ·IN M e =p2+p5(STR+IN)+p4 ·LOD IO= p5(STR+IN)+p4 ·LOD L i =p2 E i =p4(JMP+JZ+JN+IN) E n =p5 ·IN+p4·LOD 这些函数的逻辑电路如 图 6‑4 所示 图 6‑4 控制矩阵二组 根据逻辑等式 A+A=A 知道,以上两组逻辑函数中,完全相同的函数只在一组里表示出来即可,因而 C p 、 E p 、 L i 在后面一组中可以不必设计电路 控制器 这台能判断计算机的控制器如 图 6‑5 所示,指令译码器译出的指令线有 11 条,除去 STP 还有 10 条。 10 条指令线、 6 条节拍线和 2 条标志线,自变量共有 18 条线,其中标志线 ZF 、 NF 只对控制矩阵二组起作用。 图 6‑5 能判断计算机控制器电路 对于分组进行控制矩阵设计的方法,最后组织在一起的时候不要忘记,同名输出端要用或门组织成一个输出端。 能判断计算机控制器的工作过程,与加减运算计算机的控制器的工作过程基本一样,读者可以自己叙述整机的运行过程。 6.1.5. 跳转和循环的程序设计 能判断计算机已经有了条件跳转的指令,于是可以利用跳转指令和条件跳转指令设计一些分支程序和循环程序了。 标号和变量 前面的 例 题中,曾用括号将数值括起来表示该数值的地址,其实可以用某种标识符来表示某一个存储单元的地址。 定义 6‑2 在程序设计中表示可以存放数据的存储单元的标识符叫 变量 。 在编程中,有时仅仅是为了指明某一个暂时还不知道的存储单元的位置,这时也使用符号,这个符号后面要加上冒号以示与变量的区别。 定义 6‑3 在程序设计中,只用来指示存储单元位置的符号叫 标号 。 标号和变量在后面的汇编程序设计中经常会用到。另外,在汇编程序设计中,一般用以 “ ; ” 开始的部分来说明程序的功能,分号后面的部分是注释。 【例 6‑1 】 编程计算前 n 个自然数的和。 此 例 题可以从第 n 个自然数开始向 1 的方向求和。设置变量 N 放置自然数 n ,变量 ONE 放置 1 ,变量和 SUM 放置最后的结果, SUM 的初值是 0 。根据本计算机的指令系统写出的汇编程序如下,存储器分配如 图 6‑6 所示。 START : LDA N ;N→A JZ EXIT ;N值为0跳转 ADD SUM ;SUM+N→A STR SUM ;A→SUM LDA N ;N→A SUB ONE ;N-1→A STR N ;A→N JMP START ;循环执行求和 EXIT : OUT SUM ;输出结果 STP ;停止 这个程序先要进行编译,形成二进制代码后,才能放在存储器中执行。为了说明问题方便,这里就用汇编形式加以说明。程序和数据的存储器分配如 图 6‑6 所示,这是一个逻辑分配,实际应将二进制代码在输入设备上放置好,开机时一次性装入存储器执行。 怎样分配存储器?一般过程是先设计一个与存储器同样大小的逻辑空间,在逻辑空间上从前向后的安排每条指令,在此过程中确定标号的位置。将指令分配之后,可以在没有占用的存储单元放置数据,从而确定出变量的位置。 图 6‑6 存储器分配 程序的输入与执行 假如已经像 图 6‑6 那样安排好了二进制程序,现在如何把它放在 RAM 中执行呢?本计算机是采用如下的方法来完成的。 当电源打开之后, Clr 瞬间为 1 ,于是将各个设备进行了初始化。初始化的结果使 RAM 的每一个单元的值都是“ 00000000 ”, PC=0 ,环行计数器的值是“ 000001 ”。于是时钟启动时就开始执行 0 号单元的 LOD 指令。由于送到 MAR 的地址在后面的指令执行节拍中没变化,故读入的内容被写在 0 号单元中。此后由于 PC 自动加 1 和节拍循环的结果,使得 16 个存储单元像 图 6‑6 那样装好的程序和数据,从而完成了装填工作。当将最后一个存储单元的内容处理完成之后, PC 的值又回到了 0 ,再一次去取 0 号单元的指令,就开始执行程序了。 乘法程序 虽然这台计算机的运算器只能做加减法,但可以设计程序让它能够完成乘法和除法。 【例 6‑2 】 编程求整数 M N 的积。 仍然假定输入的数据 M 、 N 不会使结果产生溢出。乘法的问题可以用加法实现,具体思想是把 M × N 看作 N 个 M 的和。 此程序除了变量 M 、 N 之外,还要用到变量 ONE 和存放结果的变量 RESULT ,结果变量 RESULT 的初值是 0 , ONE=1 。 IN M IN N ;输入M、N LOOP : LDA N ;N→A,用N作循环计数 JZ EXIT ;若A为零,结束程序,跳转 SUB ONE ;否则,N-1→A STR N ;A→N LDA RESULT ;RESULT→A ADD M ;RESULT+M→A STR RESULT ;A→RESULT JMP LOOP ;循环执行,直到满足条件结束 EXIT : OUT RESULT ;输出结果 STP ;停止 几乎同样的编程可以求得 M/N 的结果。由 【例 6‑2 】看到只做加减法的计算机可以通过相应的程序设计,而达到实现乘除法运算。因此也就不难理解“软件是硬件的完善扩充和发展”这句话的涵义。 6.1.6. 程序流程图 在计算机编程时,人们常用流程图来说明程序的运行结构。从设计的几个汇编程序中,能够看到执行的指令之间的顺序关系基本有三种,一种是先后的顺序结构,一种是分支结构,还有一种是循环结构。 基本程序结构图 程序中的这三种结构用图来表示,就是 图 6‑7 所示形式。图中矩形框表示操作,菱形框表示条件,条件成立用“ Y ”标注,不成立用“ N ”标注,线表示流向,一般上面是入口,下面是出口。 图 6‑7 ( a )是顺序程序结构,所表达的语义是: A 操作完成之后,接着完成 B 操作。 图 6‑7 ( b )是分支程序结构,所表达的语义是:条件成立,从“ Y ”执行 A 操作,不然从“ N ”执行后面的操作。 图 6‑7 ( c )是循环程序结构,所表达的语义是:条件成立,从“ Y ”执行 A 操作,然后返回到条件,再次判断进入循环;如果条件不成立,执行从“ N ” 执行后面的操作。 图 6‑7 程序流程基本结构 流程图的应用 在进行程序设计的时候,可以先不去考虑具体的指令,集中精力思考操作的相互关系,用流程图表达出来,然后再用具体的指令书写成汇编程序。实际上这种方法在较大的程序设计中是一种有效的手段。作为例子,将上面的两个 例 题的流程图画出(见 图 6‑8 )。 例题 【例 6‑1 】的详细流程图是将每一个指令的操作都画出了操作框( 图 6‑8 ( a )),实际上完全可以将一个完整的动作画成一个操作框,这样就可以得到简单一些的流程图(见 图 6‑8 ( b )),后者比起前者来,语义表达自然清楚,也比较简练。 图 6‑8 程序流程 例题 【例 6‑2 】的求 MN 乘积的流程图,就可以应用简单的画法给出,结果如 图 6‑8 ( c )所示。实际的流程图就常用自然的语言来描述。操作框有时可以代表一个简单的操作,也可以表示一个很复杂的操作,甚至代表一个程序。对于操作框,需要时可以再用流程图将复杂的操作过程画出来,程序设计的子程序调用问题,就使用这种方法在流程图中表示。操作框的层层深入,可以作到程序描述的由粗到细,有利于程序的结构化设计。
个人分类: 计算机核|3007 次阅读|0 个评论
姜老师带你设计CPU之10
accsys 2014-8-6 06:48
5. 原型 CPU 设计 这一部分将介绍 CPU 的整体设计,这种设计现在被称为微体系结构。自从有了高速缓存 cache 之后, CPU 的概念已经转化成“核”,即能够运行程序的单位。为了简单先设计一个原型 CPU ,存储器是特制的只读存储器。 5.1. 原型 CPU 的结构 5.1.1. EROM 将程序预先以某种工艺放入某种存储器,使用时只能读而不能写,这种存储器叫只读存储器( ROM )。 图 5‑1 是有 16 个存储单元的 8 位只读存储器。每个地址线 ad i 就是一个存储单元。数据线 d k 与地址线 ad i 之间用带开关的二极管连接,被选中单元开关接通,那一位数据就是 1 ,不然是 0 。这个 ROM 可以事先手动输入数据和程序,因而叫可输入只读存储器,简记为 EROM 。 图 5‑1 可输入的 ROM 以只读存储器 EROM 代替输入设备,以发光二极管组代替输出设备,并且只能作加、减法运算的计算机,应该是最简单的 CPU 了。这种计算机实际上是省略了输入输出设备,突出了计算机的核心部件。 5.1.2. 整体结构 能够做加减运算 CPU 的整体结构如 图 5‑2 所示。它是在加减法运算器的基础上改造而来的,比计算器要复杂一些,特别是增加了控制器,从而使这个机器的自动化程度比计算器有了本质的提升。 图 5‑2 加减运算 CPU 结构 这个计算机包括可输入只读存储器 EROM 、地址寄存器 MAR 、程序计数器 PC 、指令寄存器 IR 和控制器 CON ,时钟直接由控制器 CON 给出。这个计算机的内部总线 Bus 由 8 条导线组成,指令寄存器 IR 、输出寄存器 O 、数据寄存器 B 、 A 和加减运算器 ADD/SUB 都是 8 位的,它们都和内部总线相连,通过总线交换数据;地址寄存器 MAR 和程序计数器 PC 都是 4 位的,直接和总线的低 4 位相连。这样内部总线既可以传输 8 位的数据,也可以传输 4 位的地址信号。输出寄存器 O 的输出直接连接发光二极管组,通过发光二极管组显示输出寄存器 O 的内容。图中以 L 开头的短线,代表寄存器的写数据控制端,称为 L 门;以 E 开头的短线代表寄存器的输出控制三态门,叫做 E 门。 5.1.3. 逻辑组成 加减运算 CPU 的逻辑组成的五部分,分别是 (1) 运算器。它包括 ADD/SUB 、 A 、 B 。 (2) 存储器。它包括 MAR 和 EROM 。 (3) 控制器。它包括 PC 、 IR 、 CON 。 (4) 输入装置 EROM 的开关组。 (5) 输出寄存器 O 和发光二极管。 运算器和控制器过去一般统称为 CPU ,现在的 CPU 还包括 cache (静态存储器)。 5.1.4. 设备功能 这个原型 CPU 比加减法计算器增加了累加器、可输入只读存储器、程序计数器、指令寄存器和控制器。 累加器 寄存器 A 不但可以存放运算器运算前的数据,而且用来存放每次运算的结果,在多次连续的加法运算中,寄存器 A 起到了累加的作用,因而把 A 叫累加器。它有 L 门、 E 门控制数据的输入输出,能与总线直接进行数据交换。它的另一个输出端与 ADD/SUB 的输入端数据线直接相连,这个输送没有 E 门的控制。 寄存器 B 是与寄存器 A 配合使用的缓冲寄存器,它的输出端直接与 ADD/SUB 的另一个输入端相连,故可以把从总线接收的数据直接送到 ADD/SUB 的另一个输入端。寄存器 B 只是从总线上接收数据,而不需要将内容直接送到总线,故不用 E 门控制。 可输入只读存储器 可事先输入数据的输入只读存储器 EROM ,既充当存储器,也充当输入装置。 EROM 共有 16 个存储单元,前端有地址译码器,通过 4 位的存放存储单元地址的寄存器 MAR ,确定正在使用的存储单元,并且 EROM 的 E 门能控制存储单元的数据向总线输出。 地址寄存器 MAR 通过 L 门从内部总线 Bus 接收地址数据,并将地址数据直接送到 EROM 的地址译码器,从而选中需要的存储单元。 程序计数器 程序计数器 PC 的初始值是 0 ,它的加 1 功能,可以使它连续地指向每一个存储单元。假如若干个指令是从 0 号存储单元开始存放的,那么开始时将 PC 的值送到 MAR ,就可以选中第一条指令,在执行指令的过程中使 PC 加 1 ,那么在执行完一条指令之后,就又会将下一条指令执行,这样计算机就会不断地自动地运行下去。 指令寄存器 可控缓冲寄存器 IR 是专门放置指令的,因而被称为指令寄存器。在指令放到 IR 中的时候,有指令译码器翻译指令编码,这样就能够知道这时执行的是什么指令,以及数据放在哪里等。指令寄存器 IR 从总线接收指令数据,能够将指令数据的高 4 位和低 4 位分开。如果它的高 4 位放置指令编码,低 4 位放置数据的地址,那么高 4 位直接送到控制器的指令译码器,低 4 位可以再通过内部总线送到 MAR 或 PC 。 控制器 控制器 CON 是发出控制信号的地方,它有 12 条输出线,分别连接在各个设备的控制线上,它同时发出 Clr 和 Clk 控制信号,其中还包括电源开关等,其详细结构下面将专门讨论。 5.1.5. 计算机控制字 完整计算机的基本动作是由它的所有控制线的值来决定的,计算机所有控制线排列所成的字,在计算机状态变化中起着决定性的作用,也就是说计算机的一切动作发生都由这个排列字指挥。 定义 5‑1 除了 Clr 和 Clk 之外的全部控制线排列所成的一个字,叫 计算机控制字 。 这个加减运算 CPU 的计算机控制字是: C p E p L m E r L i E i L a E a S u E u L b L o 这个计算机控制字有 12 线,每一条线的取值不是 0 就是 1 ,所以每条线又是一个逻辑变量,这些变量的值是一个 12 位的二进制数,它的有序变化,就决定着这个计算机的全部运动。 例如, C p E p L m E r L i E i L a E a S u E u L b L o =100000000000 ,当 Clk 由 0 变到 1 的瞬间,计算机 PC 的值会加 1 ,而 C p E p L m E r L i E i L a E a S u E u L b L o =011000000000 ,当 Clk 由 0 变到 1 的瞬间,程序计数器的值会通过总线传输到地址寄存器,通过 MAR 直接输送到连接的地址译码器,选中只读存储器 EROM 中由 PC 指示的存储单元。 5.2. 计算机功能设计 5.2.1. 可实现功能分析 计算机能够干什么事情,实现怎样的功能,这和计算机的结构直接相关。 图 5‑2 的总线结构能够进行数据传送,所以可以让 EROM 存储的数据送到累加器 A ,以便从 A 分发到各处,比如将数据从 A 送到输出寄存器 O 显示输出。当然也可以选择让 EROM 存储的数据直接送到输出寄存器 O 显示输出,或者让 EROM 存储的数据直接送到寄存器 B 或寄存器 IR 等。 由于有加减法运算器,自然这个计算机具备加减法运算的功能。要实现 EROM 的数据能进行加法或减法运算,必须现将 EROM 的数据送到寄存器 A 和 B 中,这种能力这个计算机是完全具备的。 由于寄存器 O 、 B 、 MAR 都没有输出控制的 E 门,因而也就都没有向总线输出数据的功能,不能够将它们接收的数据再分发到总线上的其他设备。相反, PC 和 EROM 没有从总线上接收数据的 L 门控制线,所以它们没有从总线接收数据的功能。 指令寄存器 IR 有输入输出控制线,所以可以从总线接收数据,也可以将数据送到总线。它的高 4 位直接送到了控制器 CON ,这样放在其中的数据,就能够将高 4 位和低 4 位分开,并且通过总线可以将低 4 位数据送到 MAR 或 PC 。虽然 IR 输出的数据是 8 位的,但 MAR 或 PC 只通过连线接收 4 位,不至于出现混乱。 IR 的值可以传输到寄存器 A 、 B 、 O 。 地址寄存器 MAR 能够从总线接收 PC 、 A 、 IR 、 EROM 送到总线上的低 4 位数据,并将这 4 位数据做为地址信号,送到 EROM 的地址译码器,选中存储单元。 程序计数器 PC 可以通过控制线 C p 实现加 1 的功能,初始化控制线 Clr 会使它的初始值为 0 。 Clk 时钟线连接在每个设备的时标线上,可以控制整个系统按着时间要求工作。 5.2.2. 指令系统 设计 计算机结构能够提供的功能并不是我们都需要的,根据实际需要可以将一些功能组织到一起,形成对我们有用的工作模式。这就是计算机的指令设计问题。 指令执行过程 指令和数据都要存放在计算机的存储器中,执行指令的一般过程: (1) 将程序计数器的内容送到地址寄存器,选中指令存储单元; (2) 将存储器选中单元的内容送到指令寄存器进行译码和分析; (3) 将程序计数器加 1 ,准备取下一条指令; (4) 根据译出的指令线和节拍线的变化,完成该指令的模式动作。 这其中( 2 )的实现在这个原型 CPU 中是 IR 的高 4 位和低 4 位的可分性。如果将指令写成“指令编码 数据地址”的形式,那么就可以用 4 位的二进制编码表示指令,同时用 4 位的二进制数指出存储单元的地址。例如,“将某存储单元的内容送到累加器 A ”这个指令用二进制数 0000 来表示,那么具体的地址就可以写在这个编码的后面。这样将“将 5 号存储单元的内容送到累加器 A ”,就可以写成 0000 0101 。 用二进制数表示的指令编码,一般叫操作码,操作码后面写出的二进制数叫操作数。这种先写操作码后写操作数的形式就叫做指令格式。冯 . 诺依曼计算机中指令格式是实现程序执行的重要一环,正是由于指令两部分的合写和拆分,形成了计算机的各种基本动作,从而使指令功能的实现,能通过一连串变化的基本动作完成。 指令 设计 依据计算机的硬件构成(不包括控制器),来确定计算机能完成的基本任务,体现在计算机指令设计的过程当中。 定义 5‑2 一台计算机所能够识别的全部指令叫这台机器的 指令系统或指令集 。 一台计算机的指令系统设计,既和计算机的硬件构成有直接关系,也和设计者要求及计算机能完成那些基本任务有关。因而会出现即使是相同的计算机结构也会有不同的指令系统的现象。计算机的指令设计是很有学问的,一般地应将那些最基本的任务设计成指令,也就是说通过这些基本任务的指令组合,可以完成更加复杂的任务。 根据需要,加减运算 CPU 的指令系统设计,具体如 表 5‑1 所示。由于计算机能够完成的基本任务,会形成计算机的一种运行模式,成为一种功能,所以表中不标注基本任务,而是标注功能。 表 5‑1 的助记符一栏体现了指令的格式,其中 OUT 、 STP 没有操作数部分,可以认为是操作数隐含的一种特殊情况。 表 5‑1 指令系统设计 功 能 助记符 操作码 把某存储单元 R 的内容送到累加器 A LDA R 0001 把某存储单元 R 的内容与累加器 A 的内容相加结果送 A ADD R 0010 用累加器 A 的内容减去某存储单元 R 的内容结果送 A SUB R 0011 将累加器 A 的内容送到输出寄存器 O 输出 OUT 1000 停机 STP 1111 指令功能的设计中,首先考虑如何实现加法或减法的运算。因为数据是放在 EROM 中的,因此要先将一个数送到累加器 A ,然后再将另一个数送到寄存器 B 与 A 中的数相加,这样就设计了指令 LDA R 和 ADD R ,自然 SUB R 也是这样考虑出来的。运算的结果可以直接送到寄存器 O 输出,但如果是连续计算, A 要放中间结果,故而让累加器 A 的内容输出更加方便。 助记符表述的指令也是是由两部分组成的,前面是表示功能的指令码,指令码后面的部分是指令的辅助说明,辅助说明可以有多项,这里的辅助说明只有一项 R ,它表示存储器的地址。指令码和指令辅助说明组成的指令形式就是指令格式。指令格式的复杂度,取决于指令辅助说明的项目多少,一般地说,项目越多,指令的越复杂。用助记符表示的指令和计算机实际设计的指令是一一对应的,指令助记符在程序设计中称为汇编指令。 汇编指令组成的两部分,也分别叫操作码和操作数。计算机的指令可以带操作数,也可以不带操作数,但不能没用操作码。在进行指令处理时,总是要将操作码和操作数分开,由操作码来确定指令的一般功能,由操作数来指出具体的实施内容。 指令 全程分析 将多条指令从 EROM 的 0 号单元顺序存放,用程序计数器 PC 来指示将要执行的那条指令,并在执行指令的过程中让 PC 加 1 ,这样就能重复地通过 PC 的指示执行全部的指令,这一过程是计算机自动执行程序的要点。根据本计算机的结构的特点,现在来分析每条指令的执行过程。指令的执行的整个过程叫指令全程。 LDA 的指令全程 LDA 指令的执行过程如下: ( 1 )将程序计数器 PC 的值送到地址寄存器 MAR ; ( 2 )将 EROM 输出的内容送到指令寄存器 IR ; ( 3 ) PC 加 1 ; ( 4 ) IR 的低 4 位送到 MAR ; ( 5 ) EROM 输出的内容送到累加器 A 。 ADD 的指令全程 ( 1 )将程序计数器 PC 的值送到地址寄存器 MAR ; ( 2 )将 EROM 输出的内容送到指令寄存器 IR ; ( 3 ) PC 加 1 ; ( 4 ) IR 的低 4 位送到 MAR ; ( 5 ) EROM 输出的内容送到数据寄存器 B ; ( 6 ) A + B 的结果送到累加器 A 。 SUB 的指令全程 ( 1 )将程序计数器 PC 的值送到地址寄存器 MAR ; ( 2 )将 EROM 输出的内容送到指令寄存器 IR ; ( 3 ) PC 加 1 ; ( 4 ) IR 的低 4 位送到 MAR ; ( 5 ) EROM 输出的内容送到数据寄存器 B ; ( 6 ) A-B 的结果送到累加器 A 。 OUT 的指令全程 ( 1 )将程序计数器 PC 的值送到地址寄存器 MAR ; ( 2 )将 EROM 输出的内容送到指令寄存器 IR ; ( 3 ) PC 加 1 ; ( 4 ) A 的内容送到输出寄存器 O 输出。 上面各指令的指令全程的每一步都对应着一个计算机的基本动作,由此可见计算机的基本动作是计算机能够完成各种任务的基础。 从 LDA 、 ADD 、 SUB 的指令全程步骤( 4 )可以看到,要取出在存储器中的数据,都要将指令寄存器 IR 中的指令操作数回送到地址寄存器 MAR ,这是访问存储器的通行作法。将指令操作码和操作数进行拆分,是计算机指令分析不可缺少的一步。 微指令驱动 总线结构的计算机基本状态的变化,是由计算机控制字的值来确定的。这台计算机的控制字是 C p E p L m E r L i E i L a E a S u E u L b L o ,共 12 位,指令全程的每一步都可以用一个控制字的值来指挥,因此把计算机控制字的一个值称为一条微指令。 微指令的集合称为微指令程序。例如 LDA 的指令全程用微指令写出是: 011000000000 000110000000 100000000000 001001000000 000100100000 指令的微指令程序一般称为例行程序。 指令例行程序中的微指令必须严格地按着一定的顺序出现,每次微指令出现就会使计算机完成一个基本动作,这就是微指令的执行过程。由于每一个指令所包含的微指令是固定的,指令的执行就会重复执行例行程序的微指令,加上微指令执行的时间往往是固定的,所以顺次执行的微指令时间被称为机器节拍。 显然例行程序的微指令是节拍和指令的函数,也就是说,指令一定,节拍一定,那么微指令也就确定了。再进一步分析,微指令是计算机控制字的一个值,微指令的每一位数都是对应控制线的一个值,因此控制线的值也是由节拍和指令来确定的。如果将每条控制线理解成逻辑变量,那么它们就都是指令和节拍的函数。 将这台加减运算 CPU 的每条指令的例行程序都罗列出来进行分析,可以明确地反映这种函数关系。为了方便分析,把全部指令的节拍凑成一样的 6 拍,多余的节拍用空操作微指令“ 000000000000 ”填充, 表 5‑2 所示的就是这种情况。 由 表 5‑2 可以看出指令的执行是通过计算机控制字的变化来实现的,而计算机控制字的变化会随着节拍和指令的不同而不同,计算机控制字的每一个逻辑变量都是机器节拍变量和指令变量的函数。 无论是从指令全程的分析还是 表 5‑2 都可以看到,每个指令的前 3 拍都是一样的,这 3 拍的计算机控制字只随节拍变化,与指令无关。这 3 拍仅是将指令从 EROM 中取出来,放到指令寄存器 IR 中, PC 加 1 ,所以被认定只是一个取出指令的过程,叫指令的取指周期。每个指令的取指周期以外的动作过程叫指令的执行周期。取指周期和执行周期合起来的过程就是指令周期。计算机之所以能够自动地执行指令,从而完成任务,和指令的取指周期只在节拍的驱动下进行动作有关。 加减运算 CPU 的指令取指周期占 3 个节拍,而指令执行周期最多也是 3 个节拍,所以指令周期是 6 个节拍。 表 5‑2 指令和计算机控制字变化表 指令助记符 机器动作 节拍 C p E p L m E r L i E i L a E a S u E u L b L o LDA R PC → MAR 1 0 1 1 0 0 0 0 0 0 0 0 0 EROM → IR 2 0 0 0 1 1 0 0 0 0 0 0 0 PC+1 3 1 0 0 0 0 0 0 0 0 0 0 0 IR → MAR 4 0 0 1 0 0 1 0 0 0 0 0 0 EROM → A 5 0 0 0 1 0 0 1 0 0 0 0 0 6 0 0 0 0 0 0 0 0 0 0 0 0 ADD R PC → MAR 1 0 1 1 0 0 0 0 0 0 0 0 0 EROM → IR 2 0 0 0 1 1 0 0 0 0 0 0 0 PC+1 3 1 0 0 0 0 0 0 0 0 0 0 0 IR → MAR 4 0 0 1 0 0 1 0 0 0 0 0 0 EROM → B 5 0 0 0 1 0 0 0 0 0 0 1 0 A+B → A 6 0 0 0 0 0 0 1 0 0 1 0 0 SUB R PC → MAR 1 0 1 1 0 0 0 0 0 0 0 0 0 EROM → IR 2 0 0 0 1 1 0 0 0 0 0 0 0 PC+1 3 1 0 0 0 0 0 0 0 0 0 0 0 IR → MAR 4 0 0 1 0 0 1 0 0 0 0 0 0 EROM → B 5 0 0 0 1 0 0 0 0 0 0 1 0 A - B → A 6 0 0 0 0 0 0 1 0 1 1 0 0 OUT PC → MAR 1 0 1 1 0 0 0 0 0 0 0 0 0 EROM → IR 2 0 0 0 1 1 0 0 0 0 0 0 0 PC+1 3 1 0 0 0 0 0 0 0 0 0 0 0 A → O 4 0 0 0 0 0 0 0 1 0 0 0 1 5 0 0 0 0 0 0 0 0 0 0 0 0 6 0 0 0 0 0 0 0 0 0 0 0 0 STP PC → MAR 1 0 1 1 0 0 0 0 0 0 0 0 0 EROM → IR 2 0 0 0 1 1 0 0 0 0 0 0 0 STOP 3 0 0 0 0 0 0 0 0 0 0 0 0 5.3. 控制矩阵设计 计算机的动作都是由微指令来指挥的,而微指令的产生又是由机器节拍和指令来决定的,因此计算机的动作和它们之间的逻辑关系密切相关。由机器节拍和指令变动产生微指令的逻辑电路是计算机控制的核心,这个核心逻辑电路称为计算机的控制矩阵。 5.3.1. 控制矩阵中的 函数 用线表示指令 分析 表 5‑2 可以看出自变量就应该有 11 个,那就是节拍 1 、 2 、 3 、 4 、 5 、 6 ,指令 LDA 、 ADD 、 SUB 、 OUT 、 STP 。为了方便书写,将节拍和指令都设置成一位的代码,各自的代码就如 表 5‑3 所示那样。 STP 指令的作用是停止计算机运行,它的作用不通过计算机控制字来完成,因此设计机控制矩阵不用设置 STP 的代码,这样自变量考虑 10 个就可以了。因变量就是每个设备的控制线,这里一共有 12 条。 表 5‑3 节拍和指令代码 节拍名称 代码 变量名称 代码 第六拍 A LDA G 第五拍 B ADD H 第四拍 C SUB I 第三拍 D OUT J 第二拍 E STP 第一拍 F 前面的分析多次说明要将指令的操作码和操作数放到指令寄存器 IR 中,其目的有两个。其一,将指令码转化成一条能够标志该指令执行的线;其二,将指令的操作码和操作数分离,以便进行相应的处理。 指令操作码可以通过译码器转化成各自的标志线 。 图5‑3 是将指令寄存器的高4位引出线通过译码器译出指令线的逻辑电路 。实际当中,只要哪一个指令的操作码进入指令寄存器 IR ,立即在 的输出端就会有相应的指令线为1,表明执行的是这一条指令。 图 5‑3 指令译码器 节拍器 例行程序的 6 个节拍可以用一个 6 位的环行计数器的输出端表示。 图 5‑4 中当 Clr=1 时输出端 F=1 ,进入第一个节拍,以后每一次 Clk=1 都会使为 1 的输出端向左移动一位,从而顺次表示 2 、 3 、 4 、 5 、 6 拍。 图 5‑4 节拍器 控制矩阵真值表 将这些自变量和因变量的值变化过程列成真值表,就得到 表 5‑4 。根据逻辑变量运算式 A+A=A 知道,在真值表中相同的部分作用是相同的,所以表中每个指令的指周期的 3 个节拍就简写成一个。由于前 3 个节拍因变量的变化是与指令无关的,因而表中这部分指令变量的值用空白表示。表中 1~3 行是各指令的取指周期, 4~6 行是指令 LDA 的执行周期, 7~9 行是指令 ADD 的执行周期, 10~11 行是指令 SUB 的执行周期, 13~15 行是指令 OUT 的执行周期。 表 5‑4 控制矩阵真值表 机器动作 A B C D E F G H I J C p E p L m E r L i E i L a E a S u E u L b L o PC → MAR 0 0 0 0 0 1 0 1 1 0 0 0 0 0 0 0 0 0 EROM → IR 0 0 0 0 1 0 0 0 0 1 1 0 0 0 0 0 0 0 PC+1 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 IR → MAR 0 0 1 0 0 0 1 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0 EROM → A 0 1 0 0 0 0 1 0 0 0 0 0 0 1 0 0 1 0 0 0 0 0 无动作 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 IR → MAR 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 1 0 0 0 0 0 0 EROM → B 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 1 0 A+B → A 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 1 0 0 IR → MAR 0 0 1 0 0 0 0 0 1 0 0 0 1 0 0 1 0 0 0 0 0 0 EROM → B 0 1 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 1 0 A - B → A 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 1 1 0 0 A → O 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 1 无动作 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 无动作 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 逻辑函数 根据 表 5‑4 各行之间是或的关系,同行自变量的值是与的关系,应用因变量的逻辑函数求法,得 C p =A'B'C' D E'F' E p =A'B'C'D'E' F L m =A'B'C'D'E' F +A'B' C D'E'F'( G H'I'J'+G' H I'J'+G'H' I J') E r =A'B'C'D' E F'+A' B C'D'E'F'( G H'I'J'+G' H I'J'+G'H' I J' ) L i =A'B'C'D' E F' E i =A'B' C D'E'F' ( G H'I'J'+G' H I'J'+G'H' I J') L a =A' B C'D'E'F' G H'I'J'+ A B'C'D'E'F'(G' H I'J'+G'H' I J') E a =A'D' C E'F'G'H'I' J S u = A B'C'D'E'F'G'H' I J' E u = A B'C'D'E'F'(G' H I'J'+G'H' I J') L b =A' B C'D'E'F'(G' H I'J'+G'H' I J') L o =A'B' C D'E'F' G'H'I' J 在环形计数器中,因为 E=1 必有 A=B=C=D=F=0 从而 A'B'C'D'EF'=1 而当 E=0 时,不论、 A 、 B 、 C 、 D 、 F 为何值都有 A'B'C'D'EF'=0 于是有 A'B'C'D'EF' =E 同理 A'B'C'D'E'F=F A'B'C'DE'F'=D A'B'CD'E'F'=C A'BC'D'E'F'=B AB'C'D'E'F'=A 对于一台计算机来说,各指令之间也是两两互相排斥的,故也有 GH'I'J' =G G'HI'J' =H G'H'IJ' =I G'H'I'J =J 这样,上面的逻辑表达式可以化成 C p =D E p =F L m =F+C(G+H+I) E r =E+B(G+H+I) L i =E E i =C(G+H+ I) L a =BG+A(H+ I) E a =CJ S u =AI E u =A(H+I) L b =B(H+I) L o =CJ 5.3.2. 控制矩阵电路 根据上面计算机控制字的 12 个因变量的函数,很容易画出这台加减运算 CPU 的控制矩阵电路图。 图 5‑5 的上面 6 条线是节拍线,接下来的 4 条是指令线,下面的输出是计算机控制字的 12 条线。这种能够发出计算机控制字的电路,设计起来总是纵横交错的形式,看起来很像矩阵,因而称为计算机的控制矩阵。 加减运算 CPU 的控制矩阵相对是比较简单的,复杂计算机的纵横导线会成百上千,设计图会非常庞大。实际设计中可以将控制矩阵的设计分块进行,然后根据块间的逻辑关系进行增添。在不同的块之间控制线会出现重复,根据重复的控制线之间是逻辑或的关系,再大的控制矩阵也容易设计出来。 图 5‑5 控制矩阵的电路 5.4. 控制器 和整机工作过程 5.4.1. 控制器 这台加减运算 CPU 的控制器在 6 个节拍中有序地发出微指令,从而完成每条指令的执行过程。整个控制器的电路如 图 5‑6 所示,这里指令寄存器 IR 的高 4 位直接连接在指令译码器的输入端,而指令译码器的输出端就是 4 个指令的指令线。指令线和 6 位环行计数器的输出端,直接成为了控制矩阵的输入端。 图 5‑6 控制器电路 5.4.2. 整机工作过程 这台计算机的整机工作过程如下: 当使用的人合上电源开关之后,由 图 5‑6 可以看出瞬间有一个高电位使得触发器置位,于是接在这个触发器 Q 端的时钟脉冲振荡器马上开始工作,不断地发出高频的时钟脉冲。在启动开关合上同时, Clr 端也瞬间为 1 ,于是相应的设备被初始化,在时钟震荡之前形成程序计数器 PC=0000 ,环形计数器的值为 000001 等。 ( 1 ) Clr 是瞬间作用的,故当有效时钟脉冲到来的时候,机器的各种设备已经进入了正常工作状态。由于 F=1 ,于是从控制矩阵发出的计算机控制字是 011000000000 ,即 E p =1 , L m =1 。这样,当第 1 个时钟脉冲到来时, PC 中的值 0000 送到了 MAR ,于是就选中了 0000 号单元。 ( 2 ) 与此同时, Clk 到来使环行计数器的值变成了 000010 ,即 E=1 ,于是第 2 个时钟脉冲到来之前, E r =1 , L i =1 。当第 2 个时钟脉冲到来之时, 0000 号单元的内容被送到了指令寄存器 IR ,这时 IR 将其高 4 位送到 CON 的指令译码器。 ( 3 ) 与此同时,环形计数器的值变成了 000100 ,即 D=1 ,于是第 3 个时钟到来之前只有 C p =1 。当第三个时钟脉冲到来之时 PC 加 1 ,第 4 个节拍变量 C=1 。 以上( 1 ) ~ ( 3 )是取指周期的工作,继后到来的时钟脉冲将要完成对取出的 0000 号单元的指令的执行工作,( 4 ) ~ ( 6 )进入执行周期。 ( 4 ) 假如 0 号存储单元存储的指令是: LDA 1010 ,那么从第 2 个节拍之后,通过指令译码器的工作, LDA 的指令线 G 就一直为 1 。它和节拍 C 合作使 E i =1 , L m =1 ,当第 4 个时钟脉冲到来时,使第 5 个节拍线 B=1 ,从而使 E r =1 , L a =1 。 ( 5 )第 5 个时钟脉冲到来之前 E r =1 , L a =1 ,当 Clk 由 0 变到 1 的瞬间,就将 1010 存储单元的内容送到累加器 A 了。与此同时节拍线 A=1 。 ( 6 ) 在节拍变量 A=1 之后的第 6 个 Clk=1 到来之后,又会有节拍线 F=1 。 ( 1 ) ~ ( 6 )的循环重复,可以不断地执行在存储器中顺序存放的指令。 如果指令寄存器 IR 中得到的指令代码是 1111 ,那么指令译码器译出的高电位线直接送到启动停止触发器的 R 端,至使 Q=0 , 于是就停止了时钟脉冲振荡器的震荡,也就使这台计算机停止了工作。 5.4.3. 时序 一台计算机有许多部件组成,要使这些部件有条不紊地进行工作,就必须要它们按照一定的时间顺序动作,这就是计算机时序问题。计算机中信息的流动有先有后,如果传输的过程中颠倒了顺序,必然会出现错误的结果。因此计算机的设计分析中,将时序都放在一个很重要的位置考虑,尤其是在多条信息通路进行数据传送时,更要注意哪一路数据先到达,是否会错序。如果发生了时序的错误,那么或者设法加快较慢的一路传输速度,或者降低较快的一路传输速度,以便调整到正确的时间顺序。 主频与节拍 计算机的时间顺序是由计算机的频率时钟来确定的。控制器中石英振荡器产生的震荡频率一般叫计算机的主频。计算机的主频表明计算机的 CPU 运行速度,是计算机十分重要的参数。主频的一个振荡周期决定计算机的一个基本动作,因而称之为一个机器节拍。计算机的时序是用节拍来量度的。 为了研究方便,在总线结构的计算机系统中,又提出总线周期、指令周期、取指周期、执行周期等概念。 所谓的总线周期是指总线传输一个单位数据所需要的节拍数。设计的加减运算 CPU ,传送一个单位数据只要一个节拍,而有的计算机可能需要两个以上的节拍。 取指周期是从存储器中取出指令所需要的节拍数。加减运算 CPU 的取指周期是 3 个节拍。执行周期是执行取出的指令所需要的节拍数。加减运算 CPU 执行周期也是 3 个节拍。取指周期和执行周期组成了计算机的指令周期。加减运算 CPU 的指令周期是 6 个节拍。 时序图 为了研究时序,人们常用图来表示,这种图叫时序图(见 图 5‑7 )。图中从上到下分别代表主频,取指周期,执行周期和指令周期。从图上可以看到取指周期占 3 个节拍,执行周期占 3 个节拍并且是在取指周期之后。指令周期占 6 个节拍。 一般的时序图都要反映出主要部件间在时间上的相互协作关系,因而一个计算机的时序图要比 图 5‑7 复 杂得多,可以从时序图上清楚地知道各个部件工作的先后顺序,这在计算机仿真设计中有十分重要的作用。有兴趣的读者可以参考相关资料,在此不详细描述。 图 5 ‑ 7 时序 5.5. 顺序程序设计 一台计算机的控制矩阵确定了,也就相当于确定了这台计算机的指令集。根据计算机的指令集,就可以进行程序设计。下面就以例子来说明利用这台加减运算 CPU 如何来进行程序设计。 5.5.1. 汇编源程序 利用汇编指令进行程序设计,就叫做汇编程序设计。由于汇编指令是与具体的计算机直接相关的,因此实际使用的计算机汇编程序设计也比较复杂,当然这里给出的汇编程序设计就简单多了。为了方便,把数用方括号括起表示这个数所在的存储单元地址。 【例 5‑1 】 用汇编程序完成 3 + 2 + 1 - 4 的计算。 依据加减运算 CPU 的指令系统,可以设计如下的程序: LDA ADD ADD SUB OUT STP 这个程序解释是很容易的。第 1 条指令是说将数 3 装入累加器 A ;第 2 条指令是把数 3 和 2 相加结果 5 放在 A 里面;第 3 条指令是说将 1 与 A 的内容 5 相加,结果 6 放在 A 里面;第 4 条指令是说将 A 的内容 6 减去 4 ,并把结果 2 放在 A 中;第 5 条指令是说将 A 的内容 2 输出;第六条指令是说停止机器运行。 上面的程序可以说仅仅是逻辑上的设计,实际上这台计算机怎样执行程序还不清楚。怎样才能让计算机完成这项任务?这涉及到指令和数据在存储器中怎样存放的问题。 5.5.2. 存储器分配 根据指令程序的特点,可以把存储器分为两个区域,一个是存放指令的区域,叫代码区,另 一个存放要操作的数据的地方,叫数据区(见 图 5‑8 ) 。根据这台计算机的结构特点,代码 区一定要放在前面,从 0000 号存储单元开始。因为这台计算机一开机就去取 0000 号单元的数据,所以程序一定要从 0000 号单元开始存放。 由指令的格式知道,操作数是数据的地址,所以可以将数据放在代码区后面的任何位置,只要不和代码区重叠放置就可以。此题数据的起始地址是 1011 (2) ,顺序地存放了 3 、 2 、 1 和 4 ,当然放在存储器中的都要是二进制数。 图 5‑8 存储器分配 5.5.3. 编译 因为计算机只能识别二进制数,所以放入计算机存储器的指令和数据必须都是二进制数。用二进制数表示的计算机指令才能够被计算机识别,这种指令又叫机器指令。将汇编源程序翻译成可以被机器识别的二进制机器指令程序和数据的过程叫编译。把 【例 5‑1 】中的汇编源程序变成二进制数放在存储器中,得到 图 5‑8 所示 的存储形式,可以看到存储器中除了二进制数之外,没有别的东西( 图 5‑8 最右边的二进制数是地址编号)。 在将汇编指令翻译成机器指令的过程中,必须根据数据在存储器中的位置,确定指令的操作数,这要从前到后至少“扫描”两次。第一次,从前到后将操作码和数据翻译好,暂不确定操作数,并将这样的指令和数据在存储器中放好,确定出数据的地址。第二次,从前到后才能将每个指令的操作数确定。可见数据位置的确定,要求对数据的存放位置进行编排,所以整个翻译的过程是“边编排,边翻译”,因而将这一过程叫“编译”。 5.5.4. 程序执行 由于这台加减运算 CPU 是手动输入的,因此在拨动开关时必须位置准确。程序和数据都输入存储器的相应单元后,就可以让计算机来运行这个程序了。 将 【例 5‑1 】的具体的执行过程列成表,就是 表 5‑5 所示的情形。 表 5‑5 程序执行情况一览 节拍 指令 指令周期 取指周期 执行周期 F E D C B A 00011011 LDA PC=0000 PC=0001 L m , E p L i , E r C p L m , E i L a , E r PC → MAR ROM → IR PC+1 IR → MAR ROM → A 00101100 ADD PC=0001 PC=0010 L m , E p L i , E r C p L m , E i L b , E r L a , E u PC → MAR ROM → IR PC+1 IR → MAR ROM → B A+B → A 00101101 ADD PC=0010 PC=0011 L m , E p L i , E r C p L m , E i L b , E r L a , E u PC → MAR ROM → IR PC+1 IR → MAR ROM → B A+B → A 00111110 SUB PC=0011 PC=0100 L m , E p L i , E r C p L m , E i L b , E r S u , L a , E u PC → MAR ROM → IR PC+1 IR → MAR ROM → B A-B → A 1000 OUT PC=0100 PC=0101 L m , E p L i , E r C p E a , L o PC → MAR ROM → IR PC+1 A → O 1111 STP PC=0101 L m , E p L i , E r PC → MAR ROM → IR
个人分类: 计算机科普|3755 次阅读|0 个评论
姜老师带你设计CPU之9
accsys 2014-8-5 05:49
4. 计数器设计 计算机中的程序计数器和各种指针都属于计数器。计数器本质上是加减法运算器和寄存器的结合体。计数器最基本的是加 1 和减 1 功能,并且带有置数或清零功能。 4.1. 计数单元设计 一位数计数器叫计数单元,其结构如 图 4‑1 所示。计数单元由一位寄存器、加减法运算单元和两个二选一电路构成。 图 4‑1 计数单元结构 加减单元在此标注名称不同, ci 是下进位, co 是上进位, sub 是加减法控制线, a 、 b 是输入二数, s 是加减运算本位。一位寄存器使用 clr 低电位有效初始化。二选一电路如 图 4‑2 所示。 k=1 则 q=x ;而 k=0 则 q=y 。二选一电路封装起来是 xz 。 图 4‑2 二选一电路 图 4‑1 中连接两个二选一电路的作用是解决外部数据输入和内部数据加一或减一计算的处理。左面一个 xz 的控制端 we=1 ,则选择外部输入数据 d ,只要右部 xz 的 sele=1 ,那么外部数据就会进入一位寄存器保存。否则, we=0 且 sele=1 ,那么就是加减单元计算的结果保存在一位寄存器中。当在 sele=0 时,寄存器的 q 值反馈保持,前端计算的结果或外部数据都不能进入寄存器。初始化时, clr 瞬间为 0 ,使寄存器的初值为 0 ,此后 clr 一直保持 1 状态。 4.2. 计数器设计 将计数单元的电路封装起来(见 图 4‑3 ),起名叫 jshdy 。将 4 个 jshdy 如 图 4‑3 所示连接起来,就得到了一个 4 位的计数器。最低进位与 sub 连接,最低 b 端连接高电位 vcc ,保持值为 1 。其余 b 端都连在一起接地 GND ,保持 0 值。这样当 sub=0 时,加减法运算器的 b 端值是 1 , ci=0 ,所以是做 q +0001 ;而当 sub=1 时,就是做 q -0001 的计算。 图 4‑3 4 位计数器设计 这个 4 位计数器的输入是 d ,输出是 q ,向上进位是 co 。 4 位计数器的计数范围是 0 ~ 15 。 4.3. 程序计数器 程序计数器要增量顺序选中程序存储器的地址,因而是只做加法的计数器。只要将 图 4‑3 的 sub 端接地,也就是让它总为 0 ,那么得到的就是一个程序计数器。 4.4. 堆栈与堆栈指针 堆栈是一段存储器,犹如往箱子里面放东西,后放进去的时间,需要先拿出来。如果堆栈与数据组织在同一存储器中,指示要存放数据位置的堆栈指针的初始值一般要最大,这样担当堆栈指针的计数器, 图 4‑3 的初始化线要连到寄存器的置位端。
个人分类: 计算机科普|3446 次阅读|0 个评论
姜老师带你设计CPU之7
accsys 2014-8-2 08:34
2. 线路控制设备设计 2.1. 通断控制电路 运算器的各种运算结果一般需要在固定的地方输出到总线,要在一个固定的地方得到不同运算的结果,可以使用开关控制。计算机中使用的开关要能够容易控制,反应迅速。电子计算机有许多的部件,这些部件并不是时刻都在使用中,甚至有些部件是经常处在交替的使用状态中,要解决设备的交替使用问题,也要用到能够实现通断控制的电子设备。常用的通断控制电路叫三态门电路,也叫 E 门电路。 2.1.1. 三态门电路 组成 三态门实际上就是一个可以控制的电路开关,它的电路如 图 2‑1 所示。它是由两个或非门 、一个非门和两个 MOS 晶体三极管组成的,电路连接的方式基本上是对称的。两个三极管连接处引出的 B 线是它的输出端,一个或非门的输入线 A 是三态门的输入端,而非门的输入线 E 是三态门通断的控制端。正是由于 E 线起着通断的决定作用,所以这个电路被俗称为“ E 门电路”。 图 2‑1 E 门电路结构 2.1.2. 三态门工作原理 三态门电路实际上是一个 A 到 B 的开关,这个开关是怎样起作用的呢? (1) 当 E=0 时,由于前端非门 N 和两个或非门 Q 1 、 Q 2 的作用,使 G 1 =G 2 =0 。于是三极管 T1 , T2 都截止,故 A 和 B 之间就如同断开一般,这叫高阻状态。 (2) 当 E=1 时,通过非门加在两个或非门一个输入端的都是低电位,这时两个或非门的输出状态取决于 A 。 (a) 当 A=1 时,有 G 2 =0 , G 1 =1 ,于是 T 1 导通, T 2 截止,故 B=V=1 ,这叫 1 状态。 (b) 当 A=0 时,有 G 2 =1 , G 1 =0 ,于是 T 2 导通, T 1 截止,故 B=0 (相当于 B 点接地),这叫 0 状态。 由( 1 ),( 2 )的分析知道 图 2‑1 的通断控制电路有三种状态,并且这三种状态都是稳定的,因而这个电路才叫三态门电路。 三态门通断控制电路的符号如 图 2‑2 所示, E 是控制端, A 是输入端, B 是输出端。 图 2‑2 E 门电路符号 用两个不同材质的三态门反方向连接,合并控制端,可以作成一个双向三态门电路。双向三态门可以像普通电路开关一样将导线接通或断开,它的工作原理涉及到 P 沟道 MOS 和 N 沟道 MOS 三极管的问题,牵扯到电子电路的更多知识,又由于本书中极少使用双向三态门电路,故而不加以讨论。 需要指出,逻辑电路的通与断是不能直接用一个三极管替代的,原因是三极管连接在电路中,发射极和集电极的电位一般是固定的,用基极虽然能够决定通和断,但不能在接通时传递电路中任意地变化的 0 或 1 数据。 2.1.3. 三态总线的数据传输 利用三态门可以组织三态总线上的数据传送。如 图 2‑3 所示,用一条公共线路将 A3 、 A2 、 A1 、 A0 和 B3 、 B2 、 B1 、 B0 这 8 条线路用三态门连接起来,由于三态门的单向数据传输性,可以将任意 A 表示端的数据通过公共线路 bus 传递到 B 表示端的线路,条件是相应的三态门电路的控制端为高电位即可。 图 2‑3 三态总线结构 例如,要将 A3 线路上的数据传递给 B0 线路,那么只要让 a3=b0=1 就可以达到目的。假设有 a3=b3=b2=b0=1 ,则 A3 线路的数据会同时发送到 B3 、 B2 、 B0 。这种结构的线路连接,如果每个三态门都关闭,那么公共线路 bus 上就没有数据信号,就如同 bus 线路没有连接一样,这种情况叫高阻, bus 的值用“ z ”表示。 三态总线上不能够同时有多个数据送到公共线路 bus 上,如果那样就无法确定是那一个数据,会造成数据混乱,因此利用三态总线进行不同数据的传输,必须划分出先后顺序。由于三态总线结构线路上的数据可以同时被连接在公共线路上的传出三态门输送出去,这种效果如同进行广播一样,所以三态总线的连接方式的数据传输又称为“广播式”。 将一路数据转化成多路数据传输出去,被形象地称为“扇出”。 2.1.4. 两态扇出总线 如果将 图 2‑3 的三态门都用与门电路替换,并且只有一个数据输入端,那么就得到了一个两态扇出总线的数据传输电路。两态扇出总线在输入的与门没有打开时,总线 bus 的值是 0 ,只有输入控制端 a0=1 时,且输入数据 A0=1 ,那么 bus 的值才是 1 。 图 2‑4 两态扇出总线 2.2. 译码器和多路选择器 计算机的设计中经常要遇到将二进制数信息转换成一条导线高电位的情况,完成这一工作的设备就是所谓的译码器。另外还会遇到将多个输出数据送往一个端口的情况,这时只能根据需要选择其中之一,完成这一任务的设备叫选择器。 2.2.1. 译码器 n 位的二进制数可能有 2 n 个,每一个数用一条导线来对应,那么就需要 2 n 条导线。译码器的问题是当给出二进制数的时候,就能够立即找出这个数所对应的导线,并使之为高电位。 图 2‑5 是三位数 cba 的译码器,三位二进制数 000 ~ 111 译出的线分别是 y0 、 y1 、 y2 、 y3 、 y4 、 y5 、 y6 、 y7 , cba 给出的三位数会使对应译出的导线为 1 。 图 2‑5 译码器 例如, cba=011 ,则有 y3=1 ,其余的输出导线都为 0 。 译码器多用在多种情况互斥发生的电路当中。 2.2.2. 多路选择器 在电路的数据传输中,经常会出现一个端口要输出多条线路上的数据,为了不使数据传输出现混乱,需要选择其中的一条线路处理,而将其他线路暂时切断,这种情况用三态门就可以实现(见 图 2‑6 )。 图 2‑6 三态多路选择器 用三态门控制的多路选择器在不选择的情况下,共用端线路的值是 z 。如果要想共用线路的值不是 1 就是 0 ,那么可以像 图 2‑7 那样用与门通过连接或门实现。 图 2‑7 逻辑多路选择器 图 2‑6 和 图 2‑7 电路的根本不同点是,当 a3=a2=a1=a0=0 时,前者 B=z ,而后者 B=0 。
个人分类: 计算机科普|2895 次阅读|0 个评论
姜老师带你设计CPU之6
热度 1 accsys 2014-8-2 07:44
1.6. 加减法运算器设计 机器能够代替我们进行运算是其最神奇的部分之一,下面我们就来设计加减法运算器。 我们知道用限位数,可以将减法变成加法计算,方法是将减数用它对应的对称码代替,然后与被减数做加法即可。还知道:一个限位数的对称码等于其反码加一。为此,我们可以将全加器改造成既能够做加法,又能够做减法的一位加减运算器件。 1.6.1. 设计加减运算单元 我们先从最简单的一位数加减法考虑,我们称之为加减单元。它的设计如图 1-19 所示。 图 1-19 加减单元电路设计 我们在全加器的 B 端连接一个异或门,一个输入端仍然用 B 来记,另一个输入端我们用 J 来记。在原理图设计中,要对输入输出线加上双箭头表示的引脚。写着 input 的是输入引脚,写着 output 的是输出引脚。引脚上标注的名称就是连接导线的名称。 输入端增加的 J 线是加减法运算控制端。当 J=1 时,连接 B 、 J 端的异或门的输出值就是 B 的反码。这一点可以从下面异或门的真值表看出。 表 1-9 J 、 B 异或真值表 J B J ⊙ B 0 0 0 0 1 1 1 0 1 1 1 0 把 J 看成控制端,容易看出 J=0 时,异或门输出 B 的值,而当 J=1 时,异或门输出的是 B 的反码。 1.6.2. 加减单元的解释 从图 1 - 9 我们看到:当 J=0 时,输出端得到的就是 A+B+C ,若 C=0 ,则输出是 A+B 的运算结果。但 J=1 时,原来全加器的 B 输入端现在变成了 B 的反码。全加器实际做的是 A 与 B 的反码相加,即是 A+B'+C 。如果此时让 C=1 ,则图 1 - 9 的电路就是在做 A+B'+1 ,也就是在做 A-B 运算。 象 J 这样的能够控制器件状态变化的导线,我们叫“控制线”。 加减单元内部结构固定之后,可以用图 1-20 的矩形框图简化表示。图中左面的短线是输入端,右面的短线是输出端。 图 1-20 加减单元简图 1.6.3. 加减法运算器设计 将 4 个加减单元如图 1-21 那样连接起来,就组成了一个 4 位二进制数的加减法运算器。 图 1-21 4 位加减法运算器 今后我们用向量的形式记录多位输入输出。这里向量 A 、 B 、 S 都表示 4 位二进制数,其余 J 、 C 、 D 都是一位数。 由于电信号传输速度极快,输入端的信号一旦加上,各全加器就会立即得到本位和及向上的进位,故瞬间就会得到运算的结果。至于信号传输过程的延时,我们在此暂不讨论。我们认为,只要在输入端加入 A 、 B 和 C 的数,马上就会得到 S 和 D 的值。 总结加减法运算器的工作: ( 1 )让 J=C=0 ,那么做 A+B; ( 2 )让 J=C=1 ,那么做 A-B 。 1.6.4. 超长数计算 图 1-21 的加减法运算器是 4 位的,因而能够直接计算加减法的范围是 。能够用它计算 8 位数或 16 位数吗?回答是肯定的。 例如,计算 10010101+01011101 ,我们将数按 4 位分段,先做低 4 位 0101+1101 ,将结果 0010 放在一旁,记住进位 C=1 ;接下来再做 1001+0101+C=1001+0101+1=1111 ,这次进位 C=0 ;那么最终的结果是 11110010 。这个结果是 -14 。由于结果的符号与第一个数符号相同,因而不溢出。 通过此例,我们看到机器计算的实际范围并不取决于位数,不是说“位数越多,越精确”。实际上我们可以依据机器运算器的位数进行分段计算,这里设计的加减法运算器,使用时只要将进位考虑到分段计算中,就能够计算任何长度的二进制数加减法。 1.6.5. 溢出判断设计 由于限位数计算总是在一定范围内进行的,当计算发生溢出,结果就是错误的。避免错误,就要知道何时产生溢出。限位数加减法运算,异号两数相加,或者同号两数相减都不会溢出。溢出只发生在同号两数相加和异号两数相减的情况下。根据前面介绍的判断溢出:结果与第一个数符号不同,则溢出。可以设计溢出判断电路(见图 1-22 )。注意:图中导线标注相同,则表示它们是同一条导线,我们可以将图 1-22 和图 1-21 放在一起。 图 1-22 溢出判断电路 只要 OUT=1 ,则四位运算结果溢出。 如果是超长数的多段计算,溢出判断只在最高段有用。为了不出现溢出情况,多段计算时,将原数都扩展一段,就不用再考虑是否溢出了。为什么? 1.6.6. 超长数减法讨论 分段计算超长数减法,要注意低段计算时 J=C=1 ,而其他段要令 J=1 , C i =D i-1 ,也就是要将前次的进位加上。这其中的道理,请读者用 10010101-01011101 为例分段计算,分析一下吧。 1.6.7. 小结 运算器的设计完全在运用限位数的理论。我们用 4 位加减法运算器来说明一般加减法运算器的设计,它给出了机器计算的基本原理的最核心部分。象图 1-21 那样,相信你会设计出 8 位、 16 位、 32 位或 64 位的加减法运算器。但是,我们已经见到数值计算的精确度不是靠机器的位数决定的,在机器基本条件具备的情况下,通过分段、小数点移位等方法,就是用 4 位的加减法运算器,也可以完成实数计算。 读者也许会问:“数怎么输入?”“前次运算的进位怎么保持?”这些问题需要用到寄存器的知识,以后再逐渐分解。
个人分类: 计算机科普|3383 次阅读|2 个评论
姜老师带你设计CPU之5
热度 1 accsys 2014-8-1 11:54
如何设计逻辑电路 1.5. 真值表与逻辑 函数 在计算机的电路设计中,往往会根据分析逻辑变量的值的变化,找到变量之间的因果关系,进而写出逻辑函数,最终再画出它们的电路图。 1.5.1. 真值表 在逻辑代数中常把相关的一些逻辑值列成一张表,也就是真值表(参考 表1‑8 )。一些变量间的因果关系,可以从它们的逻辑值间的关系找,也就是从它们的真值表中找到变量之间的关系。这种真值表内的数值关系,可以归纳成通过变量写成的函数。由二进制数真值表归纳出来的函数就是逻辑函数。 1.5.2. 由真值表求逻辑 函数 在进行计算机逻辑电路设计时,往往是先给出电路相关各点变化的值,并列出一张真值表,然后根据真值表来求逻辑函数,最后画出逻辑电路。 由真值表求逻辑函数的具体作法,可以归纳成下面三点: (1) 将逻辑变量(见 表 1‑8 中 A 、 B 、 C 、 D 、 S )的变化值分为行列一一列出来,形成真值表; (2) 表中逻辑值为 1 时就认为是对变量的肯定,用变量自身的符号来记,当逻辑值为 0 时认为是对变量的否定,用变量自身的符号求反来记; (3) 在真值表中,各行之间的值是不同时出现的,因而各行之间是逻辑或的关系,而同一行的自变量( A 、 B 、 C )的值是同时性的,故同一行自变量之间是逻辑与的关系。 下面通过例子来具体地说明从真值表如何来求逻辑函数。 【例 1‑19 】 带进位的一位二进制数相加,可以用逻辑变量 A , B , C 与 D , S 之间的值变化 表 1‑8 给出。其中 A 、 B 是加数, C 是下面进位, S 是和, D 是向上的进位。求 S 是和 D 由 A , B , C 表示的函数。 表 1‑8 一位数加法运算真值表 A (加数) B (加数) C (下进位) D (上进位) S (本位和) 0 0 0 0 0 0 0 1 0 1 0 1 0 0 1 0 1 1 1 0 1 0 0 0 1 1 0 1 1 0 1 1 0 1 0 1 1 1 1 1 根据上面的求逻辑函数的做法,所求变量 S 的值就是各行自变量值的或。从 S 的值来看,使 S 为 1 的情况有: A ' B ' C 、 A'BC' 、 AB'C' 、 ABC ,而 D 为 1 的情况有: A'BC 、 AB'C 、 ABC' 、 ABC 。于是有 S = A ' B ' C+A'BC'+AB'C'+ABC = A ⊙ B ⊙ C D = A'BC+AB'C+ABC'+ABC = AB+AC+BC 逻辑化简过程如下: 根据真值表直接得到的逻辑表达式一般是较复杂的,为要得到简单的逻辑电路,就应该依据逻辑运算的基本规律进行化简,从而得到最简单的逻辑表达式,以便得到最简单的逻辑电路。 【例 1‑22 】 将 D = A'BC+AB'C+ABC’+ABC 化简。 D = A’BC+AB'C+ABC'+ABC = A'BC+ABC+AB ' C+ABC+ABC'+ABC ( 根据 A+A=A) = (A'+A)BC+AC(B ' +B)+AB(C'+C) = BC+AC+AB ( 根据 A+A ’ =1 ,A·1=A ) 我们再来看 S 的化简。这是因为 A ⊙ B ⊙C = (A ⊙ B) ’ C+(A ⊙ B)C ’ = (A ' B+AB ' ) ' C+(A ' B+AB ' )C ’ = ((A ' B) ' (AB ' ) ' )C+A ' BC ' +B ' AC' ( 摩根定理 ) = (A+B ' )(A ' +B)C+A ' BC'+B ' AC' ( 摩根定理 ) = ABC+A'CB'+A ' BC'+B ' AC' 逻辑表达式的化简的技巧性很强,实际中要有一定的经验。 1.5.3. 全加器电路 二进制数的加法是由下向上按位相加的,最低位的下端进位可以认为是 0 。例如 1 1 0 1 …… A + 1 0 1 0 …… B 1 0 0 0 0 ……. C\D ――――――――――――――― 0 1 1 1 …… S 每一位相加时,都要加上右面一位的进位(最低位下面进位是 0 )。我们将每次一位加用逻辑电路来完成,相加时不同值的相加变化就如表 1-8 所示。按照所得的函数,就可以做出每位二进制数相加的电路。这个电路叫全加器。 图 1 - 19 全加器电路设计 为什么用逻辑电路就可以完成二进制数运算呢?关键的问题是它们都只有两个数码 0 和 1 ,所以可以用逻辑值替代二进制数。
个人分类: 计算机科普|3301 次阅读|1 个评论
姜老师带你设计CPU之4
热度 2 accsys 2014-8-1 06:25
辑电路及画法 1.4. 逻辑电路 实现计算机最关键的一步,是将信息的表示和处理都能够用物理设备完成。电脑要替代人脑进行工作,必须能够用物理器件完成布尔代数的基本运算。 由于布尔代数中集合的元素只有 0 和 1 ,这样就很容易用电器元件的两种状态来表示,进而制成逻辑电路。利用许多电子元件都可以作出布尔代数中或、与、非运算的器件,但是设计计算机所使用的器件必须满足易检测,易控制修改的要求才行。了解半导体知识的人都知道,半导体晶体管就可以达到这些要求,因此在此仅以理想的半导体晶体管电路来说明或、与、非逻辑电路的组成及工作原理。 1.4.1. 二极管和三极管 不论是否学习过晶体管电路知识,下面叙述的内容要认真记住,因为这些内容是学习逻辑电路最基本的内容,掌握好这些内容是理解计算机电路的重要条件。 简单电路知识 在电路的研究中一般使用电路图。 图 1‑6 是一个直流电路图,图中“ a ”表示导线,长短线段组“ GB ”表示直流电源, GB 的长线一端是正极,矩形(或弹簧线)“ R ”表示电阻,斜线“ S ”表示开关。直流电源的长线段一端是高电位,另一端是低电位,当开关 S 接通时,就有电流从上到下流过电阻 R 。中学的电学知识指出“电阻的电流流入端是高电位,流出端是低电位”,“连接在一起的电路如果没有电流通过,那么各点的电位相同”,“只用导线连接的电路各点任何情况下电位都相同”。 二极管电路 图 1‑7 是晶体二极管的电路符号,它的特性是 a 端高电位、 b 端低电位时, a 到 b 有电流通过,这种情况叫导通。如果 a 端是低电位、 b 端高电位,那么 ab 之间就没有电流,这种情况叫截止。二极管是组成逻辑电路的重要元件。 三极管电路 三极管的简单符号如 图 1‑8 所示, b 端叫基极, e 端叫发射极, c 端叫集电极。使用中 c 端和 e 端要加固定的电位。三极管的特性是:当 b 为高电位时, ec 之间导通,而 b 为低电位时, ec 之间截止,即 ec 之间几乎是断开状态。 关于二极管和三极管的详细特性及工作原理,在逻辑电路问题中,不必深究,只要掌握上面提到的这些属性,就可以理解逻辑电路的相关问题。如果想要了解更多的细节,可以查阅相关电路知识的书籍和资料。 1.4.2. 基本逻辑门电路 利用二极管和三极管可以组成能够实现逻辑运算的基本电路,这些基本逻辑电路分别称为或门电路、与门电路和非门电路。 或门电路 图 1‑9 ( a )所示的是或门电路,它是用两个二极管并联再和电阻串联组成的电路,粗短线表示接地,接地表示低电位。如果将 a 、 b 、 c 高电位用 1 记,低电位用 0 记,那么由二极管的单向导电性可知,当 a 或 b 有一个是高电位时(即 a=1 或 b=1 时),至少就有一个二极管导通,于是 R 就有从上往下的电流通过, R 的上端 c 相对于另一端是高电位,即有 c=1 。 只有当 a 和 b 都是低电位时( a=0 且 b=0 ),两个二极管都不导通, R 上就没有电流通过, R 的上端和 R 的下端电势相同,都为低电位,即 c=0 。容易验证或门电路的状态和或运算的真值表的值是一样的,因而或门电路可以表达逻辑的或运算。 或门电路今后用 图 1‑9 中 (b) 所示的简单符号来记, a , b 叫输入端, c 叫输出端。 图 1‑9 ( b )的左图是我国规定的符号,右图是设计软件中使用的符号。 与门电路 同或门电路一样,可以用 2 个三极管组成 图 1‑10 (a) 所示的与门电路。这个电路的工作原理是:当两个三极管的基极 a , b 同时加上高电位时,两个三极管都导通,于是电阻 R 才有由上向下的电流,这样 c 端就是高电位(即 c=1 ),不然,或者 a=0 ,或者 a=b=0 ,或者 b=0 ,此任何一种情况都会使两个三极管至少有一个处在截止状态,这样电路就处于断开状态,电阻 R 没有电流通过。由于 c 端通过电阻 R 和“地”相连,地是低电位,故而 c 端是低电位。 从数值上看,与门电路的 a , b 任何一端为 0 都可以使 c 端的值为 0 。例如令 a=0 ,则 c=0 ,这样 a 就起一个控制端的作用,它能够控制 c 端使之为 0 。同样, b 端也有相同的作用。 容易验证与门电路的状态和与运算的真值表的值是一样的,因而与门电路可以表达逻辑的与运算。 与门电路的符号如 图 1‑10 (b) 所示,同样 a 、 b 是输入端, c 是输出端。 图 1‑10 (b) 的左图是我国规定的符号,右图是设计软件中使用的符号。 非门电路 非门电路也用三极管组成。 图 1‑11 (a) 中的非门电路的 R 是负载电阻。当 a 端高电位即 a=1 时,由于三极管导通,相当于 c 与地直接相连,于是 c 点的电位和地一样,就是 0 。而当 a=0 时,由于三极管处在截止状态, c 通过 R 与下端高电位一样,则有 c=1 。 非门电路的符号如 图 1‑11 中的 (b) ( c )( d )所示。在电路图的描述中,本书推荐使用图中( c )的画法,因为它描述简单利落,容易和其他电路组合在一起,能直观地表达复杂的逻辑关系。图中( d )的画法在软件中使用。 1.4.3. 组合电路 有了基本的或、与、非三种逻辑门电路,就可以组织一些较复杂的逻辑电路了。设计逻辑电路时,如果先知道逻辑表达式,那么要确定好自变量与因变量,弄清楚逻辑运算的先后次序,这样就会很容易根据基本的逻辑电路,做出逻辑表达式的电路图。 导线连通的表示 图 1‑12 导线连接与交叉 在电路的绘制中经常会碰到导线交叉,交叉的导线有时是连通的,有时又不是连通的。为了区分交叉的两条导线是否连接在一起,电路图中这样规定:当有两条导线连通时,可以错开画,也可以在交点涂一黑点( 图 1‑12 (a) ),不涂黑点,就表示两条导线没有连通( 图 1‑12 (b) )。如果电路中导线出现丁字连接,则规定一律是连接在一起的,为了美观,画图中经常将十字连接的导线改成 2 个丁字连接的形式。 简单组合电路 简单常用的组合逻辑电路有或非门、与非门、异或非门等。 或非门 根据逻辑等式 C=(A+B) ’ 画出的电路如 图 1‑13 所示,( a )是我国规定画法,( b )是软件中的画法,四周围的虚线不起作用,主要是为了辅助识别。这个电路叫或非门。或非门电路是由一个或门电路和一个非门电路连接在一起组成的。画逻辑电路图,要根据逻辑表达式的运算顺序,从输入端画起,到输出端为止。或非门要先画或门电路,然后再画非门电路。 图 1‑13 或非门符号 与非门 根据逻辑等式 C=(AB) ’ 画出的电路如 图 1‑14 所示,( a )是我国的符号,( b )是软件中使用的符号,这个电路叫与非门。 图 1‑14 与非门符号 异或门 根据逻辑表达式 C=A B=A ’ B+AB ’ ,可以画出异或门电路。 图 1‑15 ( a )是异或门的组成电路, (b) 是它的电路符号(左端是我国规定的符号,右端是软件使用的符号)。 图 1‑15 异或门电路及符号 异或非门 图 1‑16 异或非门的符号 用符号来表达电路可以达到简单清晰的效果。 图 1‑16 是用异或门符号和非门符号组合到一起表达的异或非门运算 C=(A B) ’ 的电路,( a )是我国的符号,( b )是软件中使用的符号。 通过简单组合电路的画法,可以初步了解逻辑电路的组合形式,依据这种组合方式可以画出更复杂的逻辑电路。 1.4.4. 逻辑电路 的画法 逻辑电路是依据表达式画出的,画逻辑电路时要依据逻辑运算的先后顺序,先画自变量的部分,每一个自变量用一条导线表示,然后根据逻辑关系用逻辑门连接,最后得到因变量的输出线。下面举两个根据逻辑表达式画出电路图的例子。 【例 1‑17 】 逻辑表达式 Y=AB+A ’ BC ’ +AC ,画出电路图。 用导线 A 、 B 、 C 表示自变量 A 、 B 、 C ,按着逻辑函数右面的运算顺序,先用与门连接,然后再用或门连接,最后得到输出线 Y ,它就是逻辑变量 Y 。最后的结果如 图 1‑17 所示。 图 1‑17 组合逻辑电路 当表达式有异或运算时,可以先根据公式 A ’ B+AB ’ =A B 将表达式化简整理后再画电路图。 【 例 1‑18 】 Y= ( A ’ B+AB ’ ) C+A ’ C+AC ’ 根据这个表达式画出电路图。 根据这个表达式得到 图 1‑17 的逻辑电路。 图 1‑18 用异或画出的逻辑电路 此 例 的化简并不是一定是最简单的,假如手中有许多的异或门,这种化简是合适的。逻辑电路设计中常要根据手中的门电路元件来确定化简方向。
个人分类: 计算机科普|6950 次阅读|8 个评论
姜老师带你设计CPU之3
accsys 2014-7-31 06:01
姜老师带你设计 CPU 之 3 1.3. 布尔代数 计算机能够替代人脑进行工作的另一快基石,是布尔代数的理论和方法。布尔代数是人的思维判断与逻辑推理的一种数学抽象,因而它又叫逻辑代数。布尔代数是只有逻辑值“ 0 ”和“ 1 ”的代数,也可以说是最简单的代数。人们的逻辑思维活动,主要表现为判断和推理,用布尔代数就可以描述人脑的判断和推理。 1.3.1. 布尔代数 的概念 在布尔代数的学习中,将使用系统这个概念。何为系统?严格地说现在尚无定论。一个系统可以认为是所涉及的对象全部,其中包括对象和对对象的各种处理操作。理论研究中,时常将对数据的各种处理操作称为运算。 定义 1‑12 在一个非空集合上定义了若干个运算,那么所成的系统叫代数系统,简称 代数 。 实际当中人们研究的代数系统很多,由于课程的需要,在此只研究逻辑代数,也就是布尔代数。下面给出布尔代数的定义。 定义 1‑13 布尔代数是在集合 {0 , 1} 上定义了运算: 或运算 与运算 非运算 0 + 0 = 0 0 · 0 = 0 1 = 0 0 + 1 = 1 0 · 1 = 0 0 = 1 1 + 0 = 1 1 · 0 = 0 1 + 1 = 1 1 · 1 = 1 所构成的系统。其中“+”、“ · ”、“ ’ ”是“或”、“与”、“非”逻辑运算符。 在布尔代数中的 0 , 1 叫逻辑值,它们是逻辑常量。 0 常用来表示否定, 1 常用来表示肯定。例如,一盏灯的状态可以用 0 表示不亮,用 1 表示亮。再如,电路中某一点的电势相对某一个标准低就用 0 来表示,而这一点的电势高,就用 1 来表示。 1.3.2. 布尔代数的基本运算规则 布尔 代数中逻辑值有或、与、非三种运算,这些运算是最基本的,通过它们的组合定义出一些新的运算都叫组合运算。就这三种基本运算来说,掌握好它们之间的运算规律,就足以使人们对逻辑代数有一个较全面的了解,特别是掌握这些运算之间的规律,对于进行逻辑运算的化简有着十分重要的意义。 逻辑变量与逻辑表达式 逻辑运算问题将涉及逻辑表达式的有关概念,为此要给出逻辑变量和逻辑表达式的定义。 定义 1‑14 在布尔代数中取值 0 , 1 的变量就称为 逻辑变量 。 同一般代数中的变量一样,逻辑代数中的逻辑变量也用英文字母表示。例如 , A , B , a , b , a1 , b2 等都取值 0 或 1 ,它们都是逻辑变量。逻辑变量之间可以进行基本的逻辑运算,从而组成了各种运算关系式,这些关系式就是逻辑表达式。 定义 1‑15 逻辑表达式是把逻辑常量、逻辑变量用逻辑运算符和表明运算顺序的括号连接起来组成的式子。 逻辑表达式的运算最终结果叫 逻辑表达式的值 。不论什么样的逻辑表达式,运算的最终结果,不是 0 ,就是 1 ,不会出现第三种结果,这种情况的逻辑代数又被称为二元逻辑。 在逻辑表达式中如果没有括号限制,三种基本逻辑运算的优先顺序是“非”、“与”、“或”,如果有括号存在,要从内向外的顺序进行运算。 按照习惯,在逻辑表达式中与运算的“ · ” 号可以不写。 用或运算连接的逻辑表达式,又可以叫逻辑多项式,只包含变量自身或者变量的非的与运算的逻辑表达式,今后称为逻辑项。例如, x 、 y 、 z 是逻辑变量,那么 xy+yz+xz+xyz + x’z’ 是逻辑多项式, xy 、 yz 、 xz 、 xyz 、 x’z’ 都是逻辑项。 在计算机的设计问题讨论中,一个逻辑变量常用一条线来表示。 基本逻辑等式 有了逻辑表达式的概念,容易验证下面的基本逻辑运算规律。假设 A 、 B 、 C 、 D 为取值 0 , 1 的逻辑变量,则 (1) 0-1 律: A+ 0 =A A+ 1 = 1 A 1= A A 0=0 (2) 重叠律: A+A=A AA=A (3) 互补律: A + A ’ =1 AA ’ =0 (4) 双重否定律: A ’’ = A (5) 交换律: A+B=B+A AB=BA (6) 结合律: (A+B)+C=A+(B+C) (AB)C=A(BC) (7) 分配律: A(B+C)=(AB)+(AC) (A+B)(C+D)=AC+AD+BC+BD A+(BC)=(A+B)(A+C) (8) 摩根定理: (A+B) ’ =A’ B’ (AB)’ =A ’ +B’ 由于变量只是取值 0 , 1 , 所以上面的诸等式都十分容易验证。这里仅对几个公式进行验证 。 【例 1‑14 】 验证 A+ ( BC ) = ( A+B )( A+C ) 。 将变量 A 、 B 、 C 的全部可能值列在 表 1‑5 的左边,而将等式两边的表达式列在右边。从表中可以看出 A+ ( BC ) 和 ( A+B )( A+C ) 不论 A 、 B 、 C 取得何值时都是相等的。如此就证明了等式的正确性。 表 1‑5 验证 A+ ( BC ) = ( A+B )( A+C ) A B C A+(BC) (A+B)(A+C) 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 1 1 1 1 1 0 0 1 1 1 0 1 1 1 1 1 0 1 1 1 1 1 1 1 今后,把逻辑变量及逻辑表达式值变化的表叫真值表。 【例 1‑15 】 验证摩根定理 (A+B) ’ =A’ B ’ 和 (AB) ’ =A ’ +B ’ 。 将 A 、 B 的可能值和两等式的 4 个表达式都列成真值表( 表 1‑6 ),从表上可以看到,不论 A , B 取怎样的值,摩根定理的两个等式都是成立的。也就是总有 (A+B) ’ =A ’ B ’ (AB) ’ =A ’ +B ’ 摩根定理验证完毕。 表 1‑6 摩根定理验证 A B (A+ B) ’ A ’ B ’ (AB) ’ A ’ +B ’ 0 0 1 1 1 1 0 1 0 0 1 1 1 0 0 0 1 1 1 1 0 0 0 0 【例 1‑16 】 化简 A ’ B+AB ’ +AB 。 解法 1 : A ’ B+AB ’ +AB = (A ’ B+AB)+(AB+AB ’ ) ( 根据 A+A=A ) = (A ’ +A)B+A(B+B ’ ) ( 根据分配律 ) =B+A ( 根据互补律和 0-1 律 ) 解法 2 : A ’ B+AB ’ +AB =A ’ B+A(B ’ +B) ( 根据分配律 ) = A ’ B+A ( 根据互补律 ) =(A+A ’ ) (A+B) ( 根据分配律 ) =A+B 由 【例1‑16 】可见,逻辑表达式的化简可以有多种方法,实际当中要能够熟练运用基本公式来化简逻辑表达式。 1.3.3. 异或 异或是一个很有用的逻辑运算,在许多问题当中都会用到。异或实际上是一种特殊的组合逻辑运算,其表达式为 A⊙ B=A ’ B+AB ’ 。 逻辑的异或运算表达的是两个互斥事件间的关系,“⊙ ”是异或运算符。 表 1‑7 所示的是 变量 A 、 B 异或值的变化真值表。由表可以看出: A , B 的值相同时, A⊙ B 为 0 ,当 A , B 的值不相同时, A⊙ B 的值为 1 。 表 1‑7 异或运算的真值表 A B A⊙ B 0 0 0 0 1 1 1 0 1 1 1 0
个人分类: 计算机科普|2999 次阅读|0 个评论
姜老师带你设计CPU之2
accsys 2014-7-31 05:50
姜老师带你设计 CPU 之 2 1.2. 二进制数 计算机是由电子器件构成的,电子器件的电位,在电路中最容易检测和控制,并且有十分清楚的两种对立状态。如果将低电位用“ 0 ”来记,高电位用“ 1 ”来记,那么用电子器件排列就可以记录数,这就是计算机为什么使用二进制数的道理。 下面提到的二进制运算对设计运算器很有用。 1.2.1. 二进制数的加减法 用数码 0 、 1 按着“逢二进一”的规则记数,得到的就是一个二进制数。二进制数只有数码 0 、 1 ,顶码是 1 ,所以 0 、 1 互为反码。可以理解,如果进制的基数越小,值相同数的记数位数就越长。二进制是记数位数最多的数制,然而由于数码只有两个,故用机器记数非常方便。 2 n 的二进制表示是10^ (n-1) 的形式,将一个十进制数化成二进制数,可以拆分成2 n 的加法。 【例 1‑11 】 将123化成二进制数。 由于123=64+32+16+8+3,所以 123=1000000 (2) + 100000 (2) + 10000 (2) + 1000 (2) + 11 (2) =1111011 (2) 因为二进制数只有数码0和1,二进制固定n位数全体的中分点是一个10^ (n-1) 的数,所以二进制数的对称制表示下正负数判断非常简单,只要看最高位是“0”还是“1”就可以。最高位是“1”一定是负数,否则是正数。 一种流行的错误将最高位的数码说成是“符号”,造成许多误解。 【例 1‑12 】 对称制下计算10111101 (2) +11000100 (2) 。 同十进制数一样,采用对位加 10111101 (2) +11000100 (2) ———————————— 10000001 (2) 两个负数相加的结果仍然是一个负数,没有发生溢出。结果10000001 (2) 是一个负数,它是-01111111 (2) 的对称制表示,所以最后的值是 -127。 为了能够和我们日常的认识一致,手工计算求值的结果一定要化成带符号的十进制数,这样容易理解数值的大小。 【例 1‑13 】 对称制下计算10101101 (2) -00100010 (2) 。 根据对称制下减法可以变成加法的运算方法,现求减数的对称码。 00100010 (2) 的反码是11011101 (2) ,因此它的对称码是这样 10101101 (2) -00100010 (2) = 10101101 (2) + 11011110 (2) ó 10001011 (2) 两负数相加的结果是一个负数,没有溢出。结果的值是 -01110101 (2) ,这不是对称制表示,它的值是 - (64+32+16+5)= - 117 。结果是否正确,我们可以用值运算来验证。 10101101 (2) =-83 ,00100010 (2) =34,-83-34=-117。 1.2.2. 超长二进制数 由于同样值的数二进制表示的位数最长,并且计算机使用的就是二进制数,所以就以超长的二进制数来说明如何处理一般位数的数。 以 8 位的二进制数为例,假如一个数的长度是 64 位,那么必须用 8 个 8 位来分别记录其中的一部分,而且要按着顺序排列。在对称制下,这个 64 位数的正负,要看最高 8 位的最高位,此位是 0 ,就表示 64 位数的值是正数,此位是 1 ,就表示这个 64 位数是负数,负数的表示要通过“求反加一”并添加负号来求值。 超长数的加法运算,要通过限位数的多次计算完成,方法是由低向高逐次进行。除了第一次加运算之外,每次进行的都是带前次进位数的加法,这样才能保证整体的一致性。在运算中如果某些数位数少,那么按着最高位来添加高位数码即可。例如 10110+101110110101 ó 111111110110+101110110101 这种事情也可以反过来作,如果从高位过来的 二进制数有连续若干个相同的数码,那么在对称制下可以只保留一个。 超长数的加法运算溢出判断同一般的限位数,只要对同号两数值符号的变化进行判断即可。减法的运算是通过加法完成的,因而用加法判断溢出。 如果二进制数带有小数点,那么可以用 2 n 去乘( n 是正整数),使之成为一个整数处理,最后再将结果用 2 n 去除化成相应的小数。由于这种乘或除只是认识上的小数点移动,实际操作中并不需要产生动作,因而记住小数点的位置,将带小数点的数作为整数处理没有任何问题。 n 位二进制数的表数范围是 ,表面值是对称点 2 n-1 ,用二进制来表示是 10^ (n-1) 。
个人分类: 计算机科普|3016 次阅读|0 个评论
姜老师带你设计CPU开始了
热度 3 accsys 2014-7-30 06:35
开头的话 为把更多的青少年带入计算机核心设计的殿堂,消除对神秘机器智能系统的崇拜。有三十多年计算机教学经验,现在还从事 CPU 等计算机核心设计的姜老师,愿带领具有高中文化水平的计算机爱好者,一起来做一次 CPU逻辑 设计。 借助于科学网的平台,姜老师会以博文的方式,连续给出 CPU 的基本设计,如果你有兴趣,那么就一起来吧。 2014-7-30
个人分类: 计算机核|2935 次阅读|6 个评论
自己设计制作CPU与通用单片机
热度 5 accsys 2014-3-1 06:37
我经过半年的努力,《 自己设计制作 CPU 与通用单片机 》 一书终于脱稿上交,期待5月见到书。 这是一本为有志于计算机 CPU 设计的人员所写的书,不论你是狂热的发烧友,还是精明的计算机专业工作者。 本书以作者几十年设计制作 CPU 与通用单片机的经历,来告诉你如何从无到有地设计属于你自己的 CPU 和可以运行用户程序的单片机。书中以作者的十几个 CPU 设计工程为主线,展示了精简指令系统 RISC 和复杂指令系统 CISC 计算机 CPU 的设计方法。既有硬件编程,又有原理图设计,适合软硬件人员学习计算机高级技术使用。书中通过实例告诉读者,如何创造性地进行计算机高端产品 CPU 立意和设计。书中还介绍了人机交互和操作系统内核的设计方法。这是一本全面掌握计算机高端技术人员必读的计算机专业书籍。书中工程附带源码设计光盘,方便初学者学习。 下面是这本书的章目录: 上篇 程序设计制作 CPU.......................................................................................................... 3 第 1 章 自己就能设计制造 CPU................................................................................................ 3 第 2 章 进入硬件设计的天地 ................................................................................................... 12 第 3 章 自己创造 CPU 的方法 ................................................................................................. 44 第 4 章 一个简单 CPU 设计 ..................................................................................................... 63 第 5 章 自制通用 CPU 与单片机 ............................................................................................. 90 第 6 章 流水线C PU 设计 ....................................................................................................... 142 第 7 章 非透明流水线通用单片机 ......................................................................................... 179 第 8 章 流水线编程的透明设计 ............................................................................................. 199 中篇 深入 CPU 设计 ............................................................................................................. 216 第 9 章 信息与信息处理 ......................................................................................................... 216 第 10 章 机器表示数和运算 ................................................................................................... 221 第 11 章 逻辑代数是 CPU 的基石 ......................................................................................... 231 第 12 章 万能的逻辑电路 ....................................................................................................... 235 第 13 章 元器件与线路设计原理 ........................................................................................... 245 第 14 章 CPU的器件设计 ................................................................................................... 261 第 15 章 X86 型 CPU 及单片机设计 ..................................................................................... 341 第 16 章 带 LCD 的通用单片机 ............................................................................................. 388 第 17 章 动态 CPU 的思想方法 ............................................................................................. 410 第 18 章 动态 CPU 设计实例 ................................................................................................. 422 第 19 章 PMC 计算机应用 ..................................................................................................... 459 第 20 章 汇编语言程序设计 ................................................................................................... 474 下篇 自己制作单片机 ........................................................................................................... 506 第 21 章 自制单片机器件与环境 ........................................................................................... 506 第 22 章 PMC110 计算机电路设计 ........................................................................................ 517 第 23 章 计算机组装与下载 ................................................................................................... 558 附 录 ......................................................................................................................................... 570
个人分类: 计算机实验|13195 次阅读|21 个评论
一个理论会让我们在技术上有多大收益?
accsys 2010-10-2 05:54
姜咏江 我们常说理论对技术有巨大的推动作用,限位数理论与方法对机器计算的设计就产生了这样的效果。我举两个实际设计的例子: 1. 流行的补码制硬是给数的机器表示加上一个正负号数码,因而不仅出现了正负零的概念,而且影响了实际的数值计算。长期以来让许多人搞不清楚正负号是如何参加机器数值计算的。例如,8位二进制数10000000的值是多少?是-0还是128?这种二义性是补码制的悲哀,会在计算中出现边缘错误!限位数理论会认定8位有符号二进制机器数不能表示128,10000000的值是-128,与0不搭界! 2. 将8位二进制数保值扩充成16位二进制数,在补码制中什么理由要添加符号数码? 两个极为简单且在电路设计中碰到的问题,却很少有人提出异议。其实这样简单的理论问题,会深刻影响数值电子电路设计与计算的发展。 限位数理论指出:位数固定的机器数,除去0(每位数码都是0)之外,较小的一半是值是正数,较大的一半值是负数,分界点上的数永远是负数。值相反数的数码形式相加为数的个数。 在限位数此种规定之下,我们容易推断出机器有符号数扩充的方法:正数左面添0,负数左面添最大数码。 就是在这样的理论指导之下,会让我们实际逻辑电路的设计变得更有效和容易。首先,不论对任何进制,我们不再用一个数码来表示符号,只要是一个机器数,我们就可以知道它表示的是正数还是负数,从而增加了值域。其次,值避免了二义性,软硬件结合会让我们真正实现机器的精确计算。 限位数的理论使我们精确了对机器数的认识,在浮点运算器设计上的应用(请参考http://www.sciencenet.cn/m/user_content.aspx?id=367010),你会看到使用限位数理论使数值电路的设计变得更加简单和精确。 一个理论可能会让我们改变整个技术设计方法。 2010-10-2
个人分类: 教学笔记|3734 次阅读|0 个评论
电子工程设计又进入了个人化时代
accsys 2010-9-26 14:00
姜咏江 学多人认为现代科研越来越群体化、团队化,其实不然,代表人类尖端的微电子设计工程如今又回到了个人化时代。自从有了EDA软件和FPGA器件,那种多人合作进行工程设计的场面越来越少了。这其中最为突出的是包括计算机CPU 在内的SoC设计。 SoC被广泛地应用在医疗、家电、汽车、航天等人类生活的各个领域,当然也包括计算机自身的设计和实现。说句实话,自己用EDA软件和FPGA设计一个专用的计算机并不十分困难,关键是看我们自己是否有这个勇气。5年前我曾劝某理工大学和某工业大学的同行,希望他们能够参加到计算机CPU芯片设计研究,想不到他们居然先后都说:CPU设计的水太深。5年的时间过去了,EDA技术和FPGA在我国更加普及了,我不知道我的这两位同行是不是还这样认为? 我认为我们急需在青少年之中开展FPGA设计,让他们自己设计出一些计算机来,提高他们对高科技的认识。当年轻人让自己设计的计算机运行起来的时候,那么一切游戏的魅力就会骤减。在青少年中开展计算机核心设计活动,更重要的是会让未来的中国人不再是美国高科技的奴隶! 计算机核心技术并不难,难的是我们对计算机技术缺乏认识。本人认为计算机原理和基本设计的技术课程完全可以放到中学中去讲,这不是什么无稽之谈,而是现实。当前最大的问题是掌握科技教育大全的人物,太缺乏这方面的知识了。 2010-9-26
个人分类: 教学点滴|3534 次阅读|1 个评论
可精确计算的浮点加减法运算器硬件设计程序
accsys 2010-9-26 08:56
姜咏江 1. 说明 这里给出正确的程序设计,朋友们可以与上次中秋节给出的有缺欠的设计程序对比,也许会有深刻一点的体会。下面程序的输出omov、osign只是为了设计时参考,并非必要。实际使用时,尾数加减法运算器要带上溢出标志,有兴趣的朋友将这里给出的程序稍加修改就可以做到。以下设计是在Quartus II上进行的。读者可将下面的程序直接复制到Quartus II中进行测试。 浮点乘除法运算器不用对阶,只要尾数乘除,阶码加减,因而相对设计难度不大,朋友可以自己去设计试试。 2. 设计的Verilog HDL语言描述 /*这是我65岁年初编写的程序:限位数32位浮点加减法运算器设计。阶码的变化范围是-128~127,尾数右移损失有效码由mov_f监控。这里的浮点数表数范围是 -0.16777216 *2exp127 ~+0.16777216 *2exp127 */ module fudian(f_a,f_b,clk,rst,me,f_out,sub,omov,mov_f,space,osign); input f_a,f_b; //输入浮点数 input clk, //时钟 me, //选择使用 rst, //复位信号 sub; //减法控制 output f_out; //结果浮点输出 output omov; //参考:移动后的尾数 output mov_f; //参考:甩掉有效数字尾标志 output space; //参考:甩掉的尾数,可以提供精确计算数据 output osign; //参考:移位数 reg f_out; //寄存器型输出 reg osign; reg exp_out; reg exp_a,exp_b; reg sign,ep_b; //保证不溢出用9位判断 reg man_out; reg a_a,b_b,c_c; reg tru,zero,shift; reg mov_flg; reg one=1'b1; assign space = shift; assign mov_f = mov_flg; assign omov = c_c; always @(posedge clk or negedge rst) begin if (!rst) begin exp_a = 8'h00; exp_b = 8'h00; a_a = 24'h000000; b_b = 24'h000000; tru = 256'hffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff; zero = 256'h0000000000000000000000000000000000000000000000000000000000000000; sign = 9'b000000000; ep_b = 9'b000000000; end else if (me) begin exp_a = f_a ; exp_b = f_b ; a_a = f_a ; b_b = f_b ; if (exp_b ) ep_b={one,exp_b}; else ep_b=exp_b; sign = exp_a - ep_b; end end always @(posedge clk ) begin if (!sign ) //exp_a exp_b begin osign = sign; exp_out = f_a ; //取f_a原阶码 if (b_b ) //f_b的尾数为负数 {c_c,shift} = {tru,b_b,zero} sign; //需要按负数扩充,然后右移 else {c_c,shift} = {b_b,zero} sign; end else //差为负 begin osign = -sign; exp_out = f_b ; //取f_b原阶码 if (a_a ) {c_c,shift} = {tru,a_a,zero} -sign; //需要按正负数扩充 else {c_c,shift} = {a_a,zero} -sign; end end always @(posedge clk ) begin if (!sub) //加 if (!sign ) man_out = a_a + c_c; else man_out = b_b + c_c; else //减 if (!sign ) man_out = a_a - c_c; else man_out = b_b - c_c; end always @(posedge clk ) begin f_out = {exp_out,man_out}; //输出 if (!shift) mov_flg =1'b0; else mov_flg =1'b1; //移位有损失,影响精度 end endmodule 3. 仿真 下面是十六进制的浮点加减法运算器仿真。图1是阶码符号相反的运算,求的是十六进制的0.1543292 08 0.7345662 FA ;图2是阶码符号相同的运算,求的是十六进制的0.1543292 08 0.9245662 11 。 图 1 阶码符号相反的运算 图 2 阶码符号相同的运算仿真 2010-9-26
个人分类: 计算机核|5221 次阅读|0 个评论
计算机中如何比较数的大小?
accsys 2010-9-25 06:31
姜咏江 计算机的位长是固定的,在使用硬件描述语言进行CPU设计时要特别注意。假如你定义了16位数据长度的运算器,要比较两个数的大小,用EDA语言描述时就会出现预想不到的结果。 例如,要比较有符号数16he0a0与16h60a0的大小,显然前者是一个负数,会小于后者。但当你用Verilog HDL进行比较时,就会得出前者大于后者的结论。这是为什么?原来我们使用的计算机是32位的,不论你设计的位长是多少,都要变成32位数到处理器中进行比较。因而比较之前要先将这两16位数扩充成32位数。由于Verilog HDL认定扩充位数前面添0,故而会得出有符号的16he0a0 16h60a0的结论。 此例在32位Verilog HDL中做减法,会得到差为32h00008000,其中的变化过程是: 16he0a0 - 16h60a0 = 32h0000e0a0 32h000060a0 = 32h0000e0a0+32hffff9f60 =32h00008000 依据最高位是0,因而判断出有符号数16he0a0 16h60a0。 按着限位数正负数判断和扩充位数方法,16he0a0是负数,因而扩充成32位应是32hffffe0a0。所以用32位计算机比较这两个16位正负数大小用减法应是: 16he0a0 - 16h60a0 = 32hffffe0a0 32h000060a0 =32hffffe0a0+32hffff9f60 =32hffff8000 用这种方法才能正确地比较出不足32位正负数的大小。 2010-9-25
个人分类: 教学笔记|14392 次阅读|0 个评论
精确浮点运算需要监控的信号
accsys 2010-9-24 07:47
姜咏江 计算机加减法运算器的设计需要给用户留出溢出的监控信号,以便用户能够利用存储器进行位数扩充,然后进行分段处理。计算机浮点数运算源自a2 b 的科学记数法,其中a、b是一定位数的二进制数。浮点数加减法运算需要对阶,如果采用小数(尾数)右移的方式对阶,由于位数的限制,会丢失移位小数的部分有效数字,解决的办法是监测这种丢失有效数字的情况,并及时用标志线的信号报告。 8位阶码的浮点数尾数最大的位移是255,因而需要用一个256位的寄存器来承接移出的部分,监控标志线就是标示这个寄存器是否不是0。如果移出的部分小数不是0,且要保持精确计算,那么就需要扩充尾数的位数,进行分段的加减运算(注意,这种向右的位数扩充并不改变阶码,而加减运算的结果溢出,是向左的位数扩充,需要改变阶码)。 如果尾数加减运算的结果溢出,同样需要扩充尾数的位数,但由于尾数是纯小数表示,因而必须将两个尾数都右移同样的位数,同时阶码要增加位移量。 由于浮点加减运算的过程是先对阶,尾数加减之后才能发现运算溢出的,故求结果的阶码非常简单,只要将原先的大阶码加上移位数,就可以得到运算的结果的阶码。 设计浮点运算器要注意右移尾数要先判断正负,二进制右移时,正数高位添0,而负数高位应该添1。 2010-9-24
个人分类: 教学笔记|3668 次阅读|0 个评论
CPU设计我要让更多的人掌握它
accsys 2010-1-2 08:00
姜咏江 这个小小的芯片从国外购买的价格最高可以到几万元,占到整个服务器成本的70%以上。我们国家信息产业就是因为这项核心技术的缺失,基本没钱可赚,利润率只有2%到3%,还不如传统产业。国外大公司每年从中国赚走100多亿美元,比我国购买飞机、石油、汽车花的钱还要多。这是中国龙芯芯片设计专家胡武伟某年月日说道一段话,是从网上搜到的。 发展我国自己的计算机芯片产业,要同时作两件事,一是发展超大规模集成电路制造技术,二是发展计算机核心芯片设计技术。前者个人无法办到,需要国家从战略的角度出钱购买技术设备,尽快创建我国自己的高端集成电路产业基地。后者如今可以通过个人的努力完全办到。 我国将计算机产业叫高科技产业,该产业这样叫,足显出我们过去对计算机制造业的无知和无能。过去,因为技术和设备的原因,我们一直没有能力去设计和制造计算机的核心部件。现在,芯片设计的基础技术发生了变化,有了可编程阵列器件FPGA/CPLD,个人设计计算机CPU芯片的时代已经到来了! 为了能够让更多的人进入计算机芯片设计行列,让更多的人掌握CPU的设计方法,我要借助于科学网,通过我的博客,将我的设计经验告诉那些有志于此项技术的初学者,将他们领进计算机核心设计的大门。 现在就开始! 1. CPU设计使用的软件和硬件 通过计算机进行CPU设计工作需要EDA软件,目前这种软件有几家公司的产品,这里就介绍自己常用的Altera公司的Quartus II吧。 Quartus II软件很人性化,电子电路产品的设计可以使用原理图方式,也可以使用硬件编程语言编程方式,还可以这两种设计方式混合使用。Quartus II构造的是一个电子电路设计的集成环境,可以很方便地进行电路设计的编辑、编译、仿真验证检查、下载到FPGA芯片上实际运行测试等。Altera公司还提供配套的电子电路设计开发板。其实,用买来的FPGA芯片,自己就可以制作开发板,或者干脆自己制作计算机。Altera公司的推荐的开发板DE2-70约售价5000元,DE1开发板要1000元左右。我主张自己做开发板,成本也就要几百元,还可以根据自己需要取材,当然这需要有一些电子电路制作方面的技术。 2. 软件人员搞CPU设计 我的经验是计算机软件人员可以从事CPU设计,甚至他们做起来要比学习电子电路的人员搞CPU设计更容易。因此我呼吁那些有抱负的软件科技人员,如果有能力,一定要进入CPU设计领域,因为软硬件一体化的计算机技术已经成为了计算机设计的主流。我先给你一个用Verilog HDL语言设计的例子。Verilog HDL语言借鉴了c语言,因而很适合软件工程师使用。找一本Verilog HDL语言的书看看,下面描述的能够运行程序的计算机核就可以弄懂了,或者看一下我写的《计算机原理综合课程设计》一书,也许会理解的更快。 2.1 最简单的计算机核设计 这里给出用Verilog HDL语言设计的一个能够运行简单程序的计算机核,是我在研究生班教学中作为设计实例完成的。这个设计已经在Quartus II软件的环境下测试通过,并且下载到自制的开发实验板上运行过。其中存储器是哈佛结构,直接使用了Quartus II给的存储器元件组织的。 【程序】 //基本输入时钟clock //复位控制:reset_n,低电位有效 //基本输出:o //程序存储器iram,16位,高5位是类指令代码,用imem16.mif初始化 //数据存储器dram,16位,不用数据文件初始化 //用lpm存储器的地址信号要稳定1拍,才可以读写数据 //指令格式:高5位指令代码,11位地址码,16位立即数(分高低8位) module test ( clock, reset_n, o, //调试输出(可以不要): opc, omar, ojp, oqw, olda, oadd, oout ); input clock; input reset_n; output o; output oqw; output opc,omar; output ojp; output olda,oadd,oout; wire dwren; wire q_w; wire q_data; reg b,a,ir,da,oo,ddata; reg pc,mar; reg jp; //节拍 reg dwrit; //写控制 //指令: reg lda, //取数:从数据单元取数到da add, //加:da与数据单元相加,结果放入da out, //输出:将数据单元内容输出到输出寄存器 sdal, //低8位立即数:将8位立即数扩充为16位送da sdah,//高8位立即数:将8位立即数作为高8位,与原da低8位连接成16位放在da中 str; //da送数据存储单元: //仿真信号输出: assign o = oo; assign opc = pc; assign omar = mar; assign ojp = jp; assign oqw = q_w; assign olda=lda; assign oadd=add; assign oout=out; assign dwren = dwrit; //指令存储器: lpm_rom iram(.address(pc),.inclock(clock),.q(q_w)); //程序存储器 defparam iram.lpm_width = 16; defparam iram.lpm_widthad = 11; defparam iram.lpm_outdata = UNREGISTERED; defparam iram.lpm_indata = REGISTERED; defparam iram.lpm_address_control = REGISTERED; defparam iram.lpm_file = imem16.mif; //初始化文件,放置程序 //数据存储器: lpm_ram_dq dram(.data(ddata),.address(mar),.we(dwren),.inclock(clock),.q(q_data)); defparam dram.lpm_width = 16; defparam dram.lpm_widthad = 11; defparam dram.lpm_outdata = UNREGISTERED; defparam dram.lpm_indata = REGISTERED; defparam dram.lpm_address_control = REGISTERED; always @(posedge clock or negedge reset_n) begin if (!reset_n) begin pc = 0; lda = 0; add = 0; out = 0; sdal = 0; sdah = 0; str = 0; jp=0; end else begin jp=jp+1; case (jp) 0: begin end 1: begin case (q_w ) 5'b00001: lda = 1; //lda:00001 5'b00010: add = 1; //add:00010 5'b00011: out = 1; //out:00011 5'b00100: sdal = 1; //低8位,扩充有符号16位 5'b00101: sdah = 1; //高8位,与前面低8位输入合成16位 5'b00110: str = 1; //da送数据单元 endcase end 2: begin if (lda || add || out || str) mar=q_w ; end 3: pc=pc+1; 4: begin if (lda) begin da=q_data; jp = 0; lda= 0; end else if (add) begin b=q_data; a=da; end else if (out) begin oo = q_data; jp = 0; out= 0; end else if (sdal) begin da = {{8{q_w }},q_w }; //扩充成16位有符号数 sdal= 0; end else if (sdah) begin da = {q_w ,da }; sdah = 0; end else if (str) begin ddata = da; dwrit = 1; end end 5: begin if (add) begin da=a+b; jp = 0; add= 0; end else if (str) begin str = 0; dwrit = 0; end end endcase end end endmodule ///////////// 仿真或执行程序实例 /////////// // 汇编 编译 // // sdal 5 2005 // // sdah 62806 // // str 10 300a // // sdal 3 2003 // // add 10 100a // // str 15 300f // // out 15 180f // //将编译的16进制数写入imem16.mif // /////// 16进制结果输出:0608 ///////////// 【练习】用本机语言自己编一个程序,自己编译,然后用Quartus II检验一下。 --- 待续 ---
个人分类: 计算机核|14028 次阅读|6 个评论
CPU控制矩阵自动生成器
accsys 2009-12-21 04:20
对外经济贸易大学 姜咏江 CPU控制逻辑一般都可以用真值表分析,用有限状态机FSM进行描述。就逻辑电路而言,各种逻辑描述最终都得转化成逻辑与门、或门、非门的组合形式。给大家介绍一个本人设计的CISC指令系统的控制逻辑电路自动生成器,可以免去FSM描述的麻烦,又不会出错,大家不妨试试。按照这个思路也可以设计RISC指令系统的控制逻辑电路生成器,因一直较忙,尚未动手。 1 指令分析真值表 无论何种CPU设计都离不开图1所示的指令分析真值表。 图 1 指令分析真值表 指令分析真值表分为左端的自变量部分和右边的因变量部分。自变量一般包括机器指令线、节拍线和标志线。因变量部分包括计算机的所有控制线。本设计中用复位线res作为自变量部分和因变量分界,使用中一定要确定好分界。表格中前四项的位置不能变,特别是助记符和节拍不能和基本动作后面的自变量混序。除了编号助记符节拍基本动作和res之外,变量的名称可以自己随便更改。节拍必须用向量的方式p p; input LDA,ADD,SUB,OUT,JMP,JZ,JN,CALL,IN,STR,SDA,PUSH,POP,RET,INC,DEC,ZERO,INP,STRP,JEND,LNOT,LAND,LOR,STPK,JK,MULT,DIVI,DATX,XTDA,STP; input EMPTY,ENDF,ZF,NF; output RES,PCE,PCL,PCINC,IMARL,DMARL,IRAML,IWRIT,IRAME,DRAML,DWRIT,DRAME,DAE,DAL,ZEO,COML,AL,BL,A_SE,SU,SPE,SPINC,SPDEC,PTRE,PTRL,PTRINC,PTRDEC,OL,INE,IRE,IRL,XL,XE,NOTE,ANDE,ORE,CHENGE,CHUE,GAOWEIE,STOP; assign RES=LDA p |ADD p |JMP p |JZ p |JN p |CALL p |STR p |SDA p |PUSH p |POP p |RET p |INC p |DEC p |ZERO p |INP p |STRP p |JEND p |LNOT p |LAND p |DATX p |XTDA p ; assign PCE=p |LDA p |ADD p |SUB p |OUT p |JMP p |JZ p |JN p |CALL p |CALL p |IN p |STR p |SDA p |JEND p |LAND p |LOR p |JK p |MULT p |DIVI p ; assign PCL=JMP p |JZ p ZF|JN p NF|CALL p |RET p |JEND p ENDF|JK p EMPTY; assign PCINC=p |LDA p |ADD p |SUB p |OUT p |JZ p |JN p |CALL p |IN p |STR p |SDA p |JEND p |LAND p |LOR p |JK p |MULT p |DIVI p ; assign IMARL=p |LDA p |ADD p |SUB p |OUT p |JMP p |JZ p |JN p |CALL p |IN p |STR p |SDA p |INP p |JEND p |LAND p |LOR p |JK p |MULT p |DIVI p ; assign DMARL=LDA p |ADD p |SUB p |OUT p |CALL p |IN p |STR p |PUSH p |POP p |RET p |LAND p |LOR p |MULT p |DIVI p ; assign IRAML=INP p |MULT p ; assign IRAME=p |LDA p |ADD p |SUB p |OUT p |JMP p |JZ p ZF|JN p NF|CALL p |IN p |STR p |SDA p |JEND p ENDF|LAND p |LOR p |JK p EMPTY|MULT p |DIVI p ; assign DRAML=CALL p |IN p |STR p |PUSH p ; assign DWRIT=CALL p |IN p |STR p |PUSH p ; assign DRAME=LDA p |ADD p |SUB p |OUT p |POP p |RET p |LAND p |LOR p |MULT p |DIVI p ; assign DAE=ADD p |SUB p |STR p |PUSH p |STRP p |LNOT p |LAND p |LOR p |MULT p |DIVI p |DATX p ; assign DAL=LDA p |ADD p |SUB p |SDA p |POP p |LAND p |LOR p |MULT p |DIVI p |XTDA p ; assign ZEO=ZERO p ; assign COML=p ; assign AL=ADD p |SUB p |LNOT p |LAND p |LOR p |MULT p |DIVI p ; assign BL=ADD p |SUB p |LAND p |LOR p |MULT p |DIVI p ; assign A_SE=ADD p |SUB p ; assign SU=SUB p ; assign SPE=CALL p |PUSH p |POP p |RET p ; assign SPINC=POP p |RET p ; assign SPDEC=CALL p |PUSH p ; assign PTRE=INP p ; assign PTRL=STRP p ; assign PTRINC=INC p ; assign PTRDEC=DEC p ; assign OL=OUT p ; assign INE=IN p |INP p ; assign IRE=CALL p ; assign IRL=CALL p ; assign XL=MULT p ; assign XE=XTDA p ; assign NOTE=LNOT p ; assign ANDE=LAND p ; assign ORE=LOR p ; assign CHENGE=MULT p ; assign CHUE=DIVI p ; assign GAOWEIE=MULT p EMPTY|STP p ; endmodule 这个CPU控制矩阵描述的指令系统,可参考如下指令系统设计: 表 1 参考指令系统 序号 功能设想 助记符16进制操作码2进制操作码 1 把ram存储单元R的内容送到累加器da LDA R 0100000001 2 把ram存储单元R的内容与累加器da的内容相加结果送da ADD R 0200000010 3 用累加器da的内容减去ram存储单元R的内容结果送daSUB R 0300000011 4 将R存储单元内容输出到外设 OUT R 0400000100 5 跳到iram的R单元取指令执行 JMP R 0500000101 6 如果累加器da的值是0则跳到iram的R单元取指令 JZ R 0600000110 7 如果累加器da的值为负则跳到iram的R单元取指令 JN R07 00000111 8 调用iram中R子程序 CALL R 08 00001000 9 输入数据到ram的R存储单元 IN R09 00001001 10 将累加器da的内容送到ram存储单元R STR R 0A 00001010 11 将数N送到累加器da SDA N 0B00001011 12 将累加器da的内容入栈 PUSH 0C00001100 13 将堆栈的内容送到累加器da POP 0D00001101 14 从子程序返回指令 RET 0E00001110 15 将PTR的内容加1INC 0F00001111 16 将PTR的内容减1 DEC 1000010000 17 将da复位为0 ZERO1100010001 18 将数据输入到ptr指示的iram存储单元 INP 1200010010 19 将累加器da的内容送到ptr STRP 1300010011 20 如果输入的数据是h80则跳转到iram的R单元指令 JEND R14 00010100 21 将累加器da内容取反,结果放入da LNOT 1500010101 22 将累加器da与R单元内容作逻辑与,结果放入daLAND R16 00011100 23 将累加器da与R单元内容作逻辑或,结果放入da LOR R 1700010111 24 缓冲区空暂停 STPK 1800011000 25 缓冲区空跳转到R执行 JK R 19 00011001 25 程序输入结束 END 8010000000 26 停机 STP 3F 00111111 参考文献 姜咏江.PMC计算机设计与应用.北京,清华大学出版社,2008.5. 姜咏江.计算机原理教程.北京,清华大学出版社,2005.12. David Money Harrisy.数字设计和计算机体系结构.北京,机械工业出版社,2008.1. 姜咏江.计算机原理综合课程设计.北京,清华大学出版社,2009.6. 注:本文附录提供安装软件。 2009-12-20 生成器安装软件
个人分类: 计算机核|5708 次阅读|0 个评论

Archiver|手机版|科学网 ( 京ICP备07017567号-12 )

GMT+8, 2024-6-2 00:55

Powered by ScienceNet.cn

Copyright © 2007- 中国科学报社

返回顶部