CPU的设计与实现(1)--方案设计
一、动机
我的动机很简单,因为自己从小对电子设备工作原理的兴趣,以及动手实现自己的计算机的愿望,促使我想做这个项目。另外,由于最近大半年在加拿大这边大学里给本科生指导Digital System Architecture相关的实验课,有了更多的自己探索和研究这方面的机会和资料,在业余时间里尝试现实这个目标并已在模拟软件里实现了该计算机原型。
二、目标
从这篇文章开始,我想分享我设计与实现一个CPU,以及进一步实现基于该CPU的计算机(取名Gater8)的整个过程,。这个CPU的每个部分实现将全都由最基本的各种门电路芯片(7400系列门电路芯片)搭建而成。它将是一个非常底层与粗糙的CPU,你将会见到一个体积由若干面包板,7400系列芯片,以及几百根杜绑线搭建而成的CPU。同时将为CPU添加RAM和ROM的访问能力,并添置输入输出设备,使之成为一个完整的计算机。该计算机将不会非常复杂,即会有4位或8位的数据总线和处理能力,非常少的寄存器,一至两个不超过8位的输入和输出设备连接能力,CPU的时钟周期估计为1MHz左右,初步设计约平均4个左右时钟周期完成一条机器指令。但是,该计算机的设计非常容易扩展成为32位甚至64位的CPU和处理能力,我将在整个设计过程中加以说明。
通过这个系列的文章,将逐步透彻和详细得向读者阐述如何制做一个真正的原创计算机,而非使用现成的CPU组装。并且最后完成的成品除了计算机本身的硬件之外,还将包含若干软件。项目完成后将包括:
设计文档部分:
(1)自制计算机原型设计原型文档,可在数字设计软件中运行。
(2)该计算机原型的7400系列芯片的设计版本。
(3)全部过程设计说明文档,即本系列博文。
硬件部分:
(1)一台自制计算机,包括控制器、运算器、存储器、输入设备、输出设备。
软件部分:
(1)配套的汇编器,将为自制计算机写的汇编语言程序翻译成对应的可执行机器码。
(2)一个或几个程序,这些程序能在自制计算机上运行演示,比如猜数字小游戏、播放音乐等。
项目包含的以上所有内容都将在项目完成后开源。目标开源地址:SourceForge 或 GitHub。
很重要的一点是,通过阅读本系列博文,你将会深入理解很多计算机特别是CPU的实现和工作原理,并有能力设计与实现符合自己需求的CPU以及基于这个CPU的功能完整的计算机。
三、市面上关于自制CPU的书籍
如果你想尝试找一本书讲如何教你设计与实现一个CPU,截止目前,市面上你能找到中文的或翻译成中文的书主要有以下3本(截止笔者写作时):
以上几本书据我了解几乎都是利用流形的FPGA芯片入手,先讲解大概的计算机组成和原理,然后利用VHDL硬件描述语言实现每一个CPU或计算机内的部件,如运算器,控制器等,再将程序编译后烧写到FPGA芯片上,使之成为定制的CPU。由于FPGA芯片本身由非常多的互联的门电路构成,甚至现流形的这些芯片内还集成了RAM和ROM,因此这种方案定制CPU是比较可行的。
而关于直接从门电路入手制做CPU乃至计算机的书籍主要是一些以讲计算机组成原理,体系结构为主的教科书。一些国产教科书过多教本宣科,并没有多大实际指导作用,而国外引进的一些里确有些不错的,比如:
(1)《Computer Architecture & Organisation Semester - V (Electronics & Telecommunication》作者:D.A.Godse A.P.Godse,出版社:Technical Publications Pune, 第一版: 2003, 重印: 2005.
上面这本书还有国内翻译版。
另外还有一本是以讲解从半导体原件的最底层工作原理到上层数字电路原理的书,是本难得的好书,不过可能没有汉化翻译版,但我仍然高度推荐:
(2)《Bebop to the Boolean Boogie: An Unconventional Guide to Electronics》第三版,作者:Clive Maxfield,出版社:Newnes,2008.
其它的很多书籍并没有引进,因此,我高度建议英语不错的读者多多参阅国外的相关书籍,定能获益菲浅。
四、两种自制CPU和计算机的方法的优缺点
下面我们来比较一下我的方案(通过7400系列芯片搭建)和FPGA的方案之间的区别,以及各自的优缺点:
通过7400构造计算机的优点:
(1)能更好理解计算机构造的原理,这是计算机科学的最根基的基础。
(2)能提升读者动手能力。
(3)能了解很多实际芯片的细节,为后续自制复杂数字电路做好铺垫。
(4)更有成就感,这是几乎最底层的完全由你自创的计算机。
通过7400构造计算机的缺点:
(1)计算机运算速度相对较慢。
(2)计算机对外设扩展功能相对较弱。
通过FPGA构造计算机的优点:
(1)CPU速度更快。
(2)联接外设能力较强。
通过FPGA构造计算机的缺点:
(1)相对不能更好理解计算机内部电路之间的互联和工作原理。
(2)直接从FPGA芯片定制到计算机需要很强的焊接和其它外围设备联接等知识,一般读者不可能清楚,除非使用开发板,但失去了CPU联接到外部设备的动手能力。
其实以上两种方案的优缺点互为相反。相对来说,用7400实现的方案更为底层,掌握了这种方法后很容易学会其它方法。
下面我要给大家介绍几款国外作者制做的基于7400系列门电路芯片的计算机,国内貌似还没有见到类似作品,也许有但我不清楚。
5.1 Mik-Prof
项目链接地址(含youtube演示DEMO):https://sites.google.com/site/eedramlib/mik-pro
详细信息:
CPU位宽:4 bit
运算速度:580 Hz
指令数:8条
RAM:8KB SRAM(采用芯片为CY系列DIP 28直插芯片)
ROM:未知
输入设备:12按键电话键盘
输出设备:5*7点阵的LED
演示程序:赛车小游戏等。
开源状态:80%开源,开源了电路设计图,所使用的芯片,部分文档,但详细的基于芯片级的连接设计并未公开(有能力的读者可以自己完成这个工作)。
原型机如图1所示: 详细信息:
CPU位宽:4 bit
运算速度:2.46 MHz, 1.23 MIPS
指令数:16条
RAM:4K*4bit SRAM(采用CY7C168A直插芯片)
ROM:4KB (芯片为28C64,芯片容量为8KB,但由于使用12位地址总线,因此只使用低4KB)
输入设备:4按键
输出设备:1602 LCD、压电扬声器
演示程序:猜数字、青蛙过河等小游戏。
开源状态:100%开源,配套软件和文档齐全,包括汇编器源码、模拟器源码、微指令生成器源码、详细设计图等。
原型机如图2所示: 以上两个都是4位的计算机。虽然Nibbler的地址总线达到12位,但仍为4位计算机,因为它采用了4位的算术逻辑单元(即ALU运算器),芯片为74LS181。
下面我要给大家介绍一下我将要设计和实现的CPU和计算机的详细结构和细节,并命名该项目为Gater8,其含意即为用门做的8位计算机,类似于Nibbler,即4位计算机。
以下分别分析CPU设计中4大部件的细节。
另外,任一时刻,对于连接在总线的部件来说,只能有一个部件向总线输出数据,不然就会发生冲突,CPU就无法继续运行。为了实现这一点,对于每一个连接在总线上的部件来说,都需要用一组三态缓冲器来控制其是否向总线输出数据,而每个部件所需的三态缓冲个数和这个部件的位数对应,每个三态缓冲控制1位数据的输出。所有这些部件的三态缓冲的协同工作,保证不发生冲突的任务是由控制器完成的。
(1)A寄存器,即累加器Accumulator。用作2个ALU数据来源中的其中一个,并同时也用来保存ALU的计算结果。
(2)T寄存器,即临时寄存器(Temporary Instruction)。用作2个ALU数据来源中的另一个,并同时也用来保存从RAM中取回的数据,即相当于MD寄存器(Memeory Data)。
(3)B寄存器,通用寄存器(General-Purpose Register)。用户可任意使用,也可用作栈顶指针。
另外,肯定还有以下寄存器用于完成取指和程序计数功能:
(4)IR寄存器,即指令寄存器(Instruction Register),8 bit。用于保存从内存中取回的待执行的指令。
(5)PC寄存器,即程序计数器(Program Counter),12 bit。用于保存下一个位于内存中的待取字节的地址。
(6)MA寄存器,即内存地址寄存器(Memory Address),12 bit。用于保存访问内存数据的地址。在实际实现时,这个寄存器可以简化去掉。
以上寄存器列表是初步设计,实际实现时可能略有删减。比如Nibbler的设计中没有T、B、MA这三个寄存器,即Nibbler只有一个数据寄存器:A寄存器。
在逻辑电路设计阶段,8 bit寄存器可用8个flip-flop(12 bit的则用12个flip-flop),即触发器联接而成。将每一个寄存器的输入端口都连接到相应的总线上,输出端口通过相应位宽的三态缓冲器再连接到对应总线上。由于flip-flop种类较多,我将主要使用D flip-flop。
图4. 8位累加寄存器A通过8个三态缓冲连接到8位数据总线上。
6.1.3 ALU设计
算术运算中,加法是最基本的运算,而减法、乘法运算都可以化为加法运算。而逻辑运算中,与和非两个运算可以组合出其它的逻辑运算。因此,在指令数有限的情况下无需实现所有的算术和逻辑运算,只需选择部分便可。另外,指令的选择还和具体应用有关,因此并不是一定要包含逻辑运算指令(Mik-Prof就没有)。
在数字电路的设计角度来看,逻辑运算最好实现,只要用各种门一搭马上就出来了,而算术运算的电路相对复杂一些,需要通过分析基本的位运算再到数与数之间的算术规则,从而再用K-map或布尔代数求出相应的布尔表达式,再转化为逻辑电路。不过也并不太复杂,在后面的博文中,我会详细而清楚得说明设计过程。
关于ALU在CPU中是如何连接的:根据具体运算指令,ALU需要1至2个Operand,即操作数,我将使用A和T寄存器来提供这两个操作数。运算结果保存回A寄存器。Nibbler的设计中,由于没有T寄存器,它是将A寄存器内的数和数据总线上的数直接计算,然后再将结果保存回A寄存器。这样的设计省掉了T寄存器的存和取,电路简化,计算反而速度更快,前提是这样的设计能满足实际需求。
6.1.4 控制器(Control Unit)设计
控制器CU,即Control Unit,是CPU中第二大部件,没有它的话,CPU不能自动完成计算和取指等一系列操作。控制器的设计必须在完成所有以上步骤之后再开始,它肯定是CPU设计中的最后一个环节。控制器是时序电路,必须借助时钟信号来驱动(区别于ALU的组合电路)。
没有控制器的CPU,其实也可以用于计算,不过得人工有序得拨动各个部件的控制开关能才协调这些部件完成相应的指令。控制器的作用就是代替人的手动拨动开关,变为由时钟信号驱动的自己拨动开关。
控制器发出的每一组时序控制信号都和具体的指令运行阶段有关,因此必须先得完成指令集、以上各CPU部件的连接,设计好Data path(即数据通道)等工作后才能开始设计控制器。
控制器的实现方式有两种:
(1)微代码(Micro Code)方式。这是早期CISC型CPU广泛采用的方式,比如80X86系列CPU。
(2)硬布线(Hard Wired)方式。这是后期RISC型CPU所广泛使用,比如ARM系列CPU。
微代码的实现方式在70,80,90年代的CPU中使用较为常见。其优点是:比较灵活,定制能力强,当指令集发生某些变更无需改变硬件设计,而是通过重新设计微代码烧进ROM中即可。缺点是:速度相对较慢,因为它的每一次CPU状态都要访问ROM来输出该状态对应的控制信号,而访问ROM的速度肯定比直接运行门电路要慢。这个访ROM取控制信号的时间可能会是速个CPU运行环节中最慢的一环,因此可能直接导制整体CPU的速度的下降。因为CPU的时钟频率必须要按最慢的那个部件的时间来设置。
硬布线方式在90年代以后的RISC型CPU中较上常见。其优点是:速度快,因为无需访问ROM,而是直接通过逻辑门电路生成每一个CPU状态对应的控制信号。缺点是:它的门电路比较复杂,对于想用7400系列芯片搭建出来比较困难。比如,假设Gater8有16条指令,除了每条指令都会有固定的取指状态之外,不同的指令还会有:立即数寻址、直接寻址、执行等其它状态,假设平均每条指令有3个状态,那么一共将有16×3=48个状态。因此,我们的控制器需要一个6位的计数器,即Counter(为什么是6位:因为48介于2的5次方和2的6次方之间,5位不够,6位就够了)来生成足够48个的状态,然后还需要一个6->64的译码器,即Decoder,将每一个状态都对应到唯一的输出信号端口上,而每一个输出信号端口则连接着不同CPU部件的控制端口。光是6->64的这个Decoder的引脚数就至少要70根以上,是没有这样的7400芯片的,但也许能找位数少的Decoder拼接出来,不过还是比较复杂的。
Nibbler采用的是微代码方式,它使用两片28C16 EEPROM芯片,共同输出16位的控制信号(即16位宽的控制总线)。Mik-Prof应该是硬布线方式,这和它的指令集非常简单也有关系。
那么我要制做的Gater8现在先不限制在逻辑电路设计阶段要使用哪一种方式,可能两种都设计。而在实现阶段根据方便程度选择其中一种实现,即可能优先考虑硬布线,但如果过于复杂,可能改用微代码方式。
按图8中所示的连接方式,当计算机需要向输出设备OUT0输出信号时,只需打图中下方的74HCT173芯片,数据将从数据总线输出到对应的Q1至Q4端口。合理的设计输出数据和输出频率就能使这个压电扬声器发出需要的音乐。
需要考虑的一个问题是,存储架构是采用冯诺依曼架构呢,还是采用哈佛架构。
冯诺依曼架构是将数据和代码都存在一起,而哈佛架构则将两者分开存储。早期计算机几乎都采用冯氏架构,目前已有非常多的CPU和计算机采用哈佛架构了,比如ARM中的Cortex-M系列CPU,被广泛应用到嵌入式计算中。
Nibbler采用的是哈佛架构。从分析Nibbler的逻辑电路图来看,似乎它把4KB的ROM和4K*4bit的RAM连接在了同一地址空间,总共提供了4KB或4K*4bit的存储空间。
这两个架构都有各自优点,Gater8在此不作限定,待下一步逻辑电路设计时再确定。本系列博文不打算自己设计RAM和ROM的细节,而是直接采用现成芯片。由于Gater8预计支持12位宽的地址总线,因此地址空间为4KB,芯片暂定为:
RAM:CY62256LL,SRAM,DIP-28直插封装。数据手册参考:CY62256LL Data Sheet。
ROM:28C64,EEPROM,直插封装。数据手册参考:28c64 Data Sheet。
以上芯片容量均超过4KB,实现时,多余的不使用的地址端口将被接地。
七、小结
以上为初步的方案设计,主要介绍了自制CPU的现状,以及展示了两个国外较为成功的基于自制CPU的自制计算机。功能相对完整,包含完整的计算机所需的控制器、运算器、存储器、输入设备、以及输出设备五大部分。
后续博文将从逻辑电路设计开始逐步完善成为一个实际的计算机,敬请期待。