自己动手写处理器之第一阶段(1)——计算机的简单模型、架构、指令集

将陆续上传本人写的新书《自己动手写处理器》(尚未出版),今天是第二篇,我尽量每周四篇

第1章 处理器与MIPS

时间开始了!

——胡风 · 1949

让我们以一句诗意的话,开始本书的阅读。

时间从1971年11月15日开始,那一天,Intel发布了世界上第一款单芯片微处理器4004。

1.1 计算机的简单模型

计算机很复杂,可以听歌、看电影、上网、玩游戏,内部是怎么工作的,这个问题太可怕了,太复杂了。

计算机很简单,只有加、减、乘、除、逻辑、移位、转移、存储、加载等几类可以做的操作,太简单了。

复杂?简单?其实取决于个人对事物的认识程度,认识的越多,了解的越深刻,那么就越接近本质,而本质往往都是简单的,比如大名鼎鼎的质能方程,一个简单的式子就解释了质量与能量的关系。

计算机就是一台计算的设备,而且是一台很基础的计算设备,只能计算小学数学课堂上讲授的四则运算,再加上一些并不复杂的与、或、非等逻辑运算,其余诸如平方、开方、微分、积分等等都是做不了的。有读者会有疑惑,你说的太简单的了吧,别急,且听我慢慢道来。

1.1.1 计算机的简单组成模型

计算机的组成有三大部分:处理器(CPU:Central Processing Unit)、输入输出(I/O:Input/Output)、存储器(Memory)。处理器从存储器中获取指令,然后按照指令执行一定的操作,输入输出用来提供运算数据、显示运算结果。如图1-1所示。

存储器中存储的是指令,指令就是一条运算命令,比如:将a与b相加,结果存储到c中,处理器按照命令执行即可。目前的计算机是一个二进制的世界,所有的信息都是用0、1组合来表示的,所以一条指令就是一串0、1编码,正如图1-1中所示。处理器内部具有译码功能,用来解释接收到的0、1编码表示的运算类型,据此进行运算。

1.1.2 计算机的简单使用模型

我们使用计算机上网、办公,都是通过一定的应用程序实现的,而这些应用程序实际就是一批指令的集合,当然,这里的“一批”指的是指令的数目庞大,实际上种类是非常少的,只有几百条,常用的也就几十条。通过这些指令的组织、配合,就实现了目前丰富多彩的应用。

理论上,可以直接使用0、1编码进行程序设计,但是那样显然太不方便、容易出错,于是人们使用一些助记符来表示各种指令,这就是汇编指令,使用汇编程序将汇编指令翻译为计算机可以识别的0、1编码,后来,又发明了高级语言,其语法、使用方式比汇编更加方便、更加易于理解。一般使用编译程序将高级语言编写的程序翻译为汇编指令,然后再使用汇编程序将其翻译为0、1编码。本质上是一样的。如图1-2所示。

这就是计算机的简单使用模型,无论是视频软件、浏览器,还是其他任何软件;无论是使用C#开发、Java开发,还是使用任何其他语言开发;无论是在Windows环境下运行、Android环境下运行,还是在其它任何平台下运行;无论是在ARM处理上运行、Intel处理器上运行,还是在其它任何处理器上运行;无论是在银河二号这样的大型机运行、个人使用的PC机上运行,还是在其它任何机器上运行,都遵循这样的一套使用模型。

总结一下,计算机只识别0、1编码串,任何程序最终都要转变为0、1编码串,而且0、1编码的种类是有限的,计算机按照0、1编码的命令进行工作。这样一说,读者应该觉得计算机很简单了吧。

在计算机中处于核心地位的是处理器,也称为CPU,作用是识别0、1编码,据此进行各种运算和数据处理。本书的目标就是实现一个CPU。

1.2 架构与指令集

类似于不同国家的人使用不同的文字,不同的处理器也使用不同的指令,这样,为处理器A编写的程序不能直接在处理器B上使用,需要重新编写,然后再次编译、汇编后才可使用,减低了软件的移植性。显然,极为不便。

IBM为了让自己的一系列计算机能使用相同的软件,免去重复编写软件的痛苦,在它的System/360计算机中引入了指令集架构(ISA:Instruction Set Architecture)的概念,将编程所需要了解的硬件信息从硬件系统中抽象出来,这样软件人员就可以面向ISA进行编程,开发出来的软件不经过修改就可以应用在符合该ISA的所有计算机上。ISA用来描述编程时用到的抽象机器,而非这种机器的具体实现,从软件人员的角度来看,ISA包括一套指令集和一些寄存器,知道它们就可以编写程序了。

与ISA对应的一个概念是微架构(Microarchitecture),后者是前者的一个实现,比如Intel的许多处理器都是遵循x86的ISA,但是每一款处理器都有自己的微架构。ISA好比是设计规范,微架构则是具体实现,同样的ISA,不同的微架构,会带来不同的性能。

1.2.1 CISC与RISC

从大的方面,根据ISA的不同可以将计算机分为两类:复杂指令集计算机(CISC:Complex Instruction Set Computer)、精简指令集计算机(RISC:Reduced Instruction Set Computer)。主要区别是,CISC的每条指令对应的0、1编码串长度不一,而RISC的每条指令对应的0、1编码串长度是固定的。

在计算机发展的早期,人们使用汇编语言编程,偏好强大好用的指令集,处理器的设计人员于是将指令集设计得更强大、更灵活,并且那个时期的存储器既昂贵且速度慢,因此指令使用了变长编码,以节约存储空间,由于一条指令就能完成很多功能,从而减少了对内存的访问次数,这样也减少了缓慢的存储器访问对程序性能的影响。典型的CISC指令集架构就是Intel的x86 ISA。上世纪70年代中期,人们发现CISC 指令集中的各种指令,其使用频率相差悬殊,大约有20%的指令会被反复使用,占整个程序代码的80%。而余下80%的指令却不经常使用,只占整个程序代码的20%,显然,这种结构是不太合理的。于是人们提出将指令集和处理器进行重新设计,减少那些使用不多的指令,只保留常用的简单指令,这样处理器就不需要浪费太多的晶体管去做那些很复杂又很少使用的功能,于是产生了RISC。1979
年美国加州大学伯克利分校的David Pattern首先提出了RISC的概念,RISC 并不只是简单地减少指令,更主要的目的是研究如何使计算机的结构更加简单合理以提高运算速度。其特点是指令长度固定、指令格式种类少、寻址方式种类少、大量使用寄存器等。由于在RISC中使用的指令大多数是简单指令且都能在一个时钟周期内完成,因而处理器的频率得以大幅提升,同时易于设计流水线。RISC是计算机历史上的一个里程碑,以致有人开玩笑的把RISC定义为:1985年之后发布的所有处理器。

Intel也尝试做RISC处理器,但是因为兼容性问题,没有成功,后来在1995年,Intel的David B.Papworth和他的同事一起设计了Pentium Pro处理器,在这个处理器中,x86指令先被解码为类似于RISC指令的微操作(microoperation,简称为uops),之后的执行过程采用RISC内核,这种方式一直延续至今。

1.2.2 主要的几种ISA

目前并没有一种统一的ISA为各个处理器厂商所接受,而是存在多种ISA,就像这个世界存在多种语言一样,但是主要的语言只有几种:汉语、英语、法语、俄语等。主要的ISA也只有几种:x86、ARM、SPARC、POWER、MIPS,除了x86是CISC ISA外,其余都是RISC ISA。

      1、x86

x86架构于1978年推出的Intel 8086处理器中首度出现,三年后,Intel 8086为IBM PC所选用,之后x86便成为了个人计算机的标准平台,成为了历史上最成功的指令集架构。目前绝大多数个人计算机使用的都是兼容x86指令集架构的处理器。

      2、ARM

1985年,英国的Acorn公司设计了自己的第一代32位、6MHz处理器,命名为Acorn RISC Machine,简称为ARM1。1990年,由苹果公司、VLSI公司共同出资,改组Acorn为ARM计算机公司,同时不再涉足具体芯片生产,只出售IP核。ARM公司设计低功耗、高性能的CPU内核,然后授权给其他公司,后者设计生产具体的处理器芯片。ARM侧重于低功耗、低成本,主要面向的是嵌入式应用,随着智能手机、平板等移动设备的普及,ARM发展的非常迅速。

ARM架构从v4、v4T、v5、v5E、v6,发展到v7,其中v7又分为v7-A、v7-R、v7-M等多种,苹果公司的A9处理器采用的就是ARM v7-A架构。

      3、SPARC

SPARC(Scalable Processor ARChitecture,可扩展处理器架构)源自伯克利分校上世纪80年代的研究,由Sun公司在1985年首先提出。1989年成为商用架构,生产出SPARC系列的处理器,Sun将其用在高性能工作站和服务器上。SPARC架构目前的版本有v8、v9。

SPARC架构对外完全开放,在此基础上出现了一些开放源代码的处理器,比如:Sun公司的UltraSPARC T1、LEON等。其中,LEON是一种SPARC v8架构的处理器,至今已发布到了LEON4。最初的LEON1与LEON2由欧洲航天局发布,LEON3由Gaisler Research公司设计发布,2008年Aeroflex收购了Gaisler Research公司,并于2010年1月发布了LEON4,不过LEON4至今还没有公布源代码。LEON系列使用VHDL编写代码,原计划是使用在航天器上。

      4、POWER

POWER(Performance Optimization With Enhanced RISC)是由IBM公司设计开发的一种RISC结构的指令集架构。IBM生产的很多服务器、大型机、小型机及工作站都采用POWER架构的微处理器作为其主CPU使用。

1991年成立了AIM联盟(AIM为Apple、IBM、Motorola的首字母),对POWER架构进行了修改,形成了PowerPC架构。2004年IBM发起了Power.org联盟,发布了统一的指令集架构,将POWER与PowerPC统一到新的Power架构中。

      5、MIPS

MIPS的含义是无内锁流水线微处理器(Microprocessor without Interlocked Piped Stages),是上世纪80年代诞生的RISC CPU的重要代表,其设计者John Hennessy时任斯坦福大学的教授。当初的设计基于以下理念:使用相对简单的指令,结合优秀的编译器以及采用流水线执行指令的硬件,就可以用更少的晶元面积生产更快的处理器。这一理念是如此的成功,以至于1984年就成立了MIPS计算机系统公司对MIPS架构进行商业化。在随后的十几年中,MIPS架构在很多方面得到发展,在工作站和服务器系统中得到了很多应用。MIPS架构也从MIPS
I、MIPS II、MIPS III、MIPS IV、MIPS V、MIPS32发展到MIPS64。John Hennessy与RISC概念的提出者David Pattern合著了计算机领域影响甚广的教科书《计算机体系结构——量化研究方法》,该书至今已出到第五版。

国内的龙芯处理器采用的就是MIPS架构。本书计划实现的处理器也采用MIPS架构,这里涉及到两个问题。

(1)为什么要采用一个现有的指令集架构?

这是因为现有的指令集架构已经形成了一套完善的环境,其中既有成熟的编译器,还有大量的应用程序,采用现有的指令集架构,都可以直接使用这些环境。反之,如果设计自己独有的一套指令集架构,那么编译器、应用软件都需要自己重新开发,工作量巨大。还是以语言作比喻,一个人当然可以发明、使用自己独有的语言,但是如何与别人交流呢?无法与人交流,再优秀的语言也注定会消失。

(2)为什么要采用MIPS架构?

首先MIPS的设计是RISC架构中的经典之作,很多处理器都吸收了其中的设计思想,其次,MIPS架构中指令的专利期已过,可以自由使用。

本章接下来将重点介绍MIPS指令集架构。

明天继续!

自己动手写处理器之第一阶段(1)——计算机的简单模型、架构、指令集

时间: 2024-10-08 11:13:04

自己动手写处理器之第一阶段(1)——计算机的简单模型、架构、指令集的相关文章

自己动手写处理器之第一阶段(3)——MIPS32指令集架构简介

将陆续上传本人写的新书<自己动手写处理器>(尚未出版),今天是第四篇,我尽量每周四篇 1.4 MIPS32指令集架构简介 本书设计的处理器遵循MIPS32 Release 1架构,所以本节介绍的MIPS32指令集架构指的就是MIPS32 Release 1. 1.4.1 数据类型 指令的主要任务就是对操作数进行运算,操作数有不同的类型和长度,MIPS32提供的基本数据类型如下. 位(b):长度是1bit. 字节(Byte):长度是8bit. 半字(Half Word):长度是16bit. 字(

自己动手写处理器之第一阶段(2)——MIPS指令集架构的演变

将陆续上传本人写的新书<自己动手写处理器>(尚未出版),今天是第三篇,我尽量每周四篇 MIPS指令集架构自上世纪80年代出现后,一直在进行着更新换代,从最初的MIPS I到MIPS V,发展到可支持扩展模块的MIPS32.MIPS64系列,再到集成代码压缩技术的microMIPS32.microMIPS64.每个MIPS ISA都是其前一个的超集,没有任何遗漏,只有增加新的功能.       1.MIPS Ⅰ 提供加载/存储.计算.跳转.分支.协处理及其它特殊指令.该指令集架构用于最初的MIP

自己动手写处理器之第四阶段(1)——第一条指令ori的实现

将陆续上传本人写的新书<自己动手写处理器>(尚未出版),今天是第11篇,我尽量每周四篇 第4章 第一条指令ori的实现 前面几章介绍了很多预备知识,也描绘了即将要实现的OpenMIPS处理器的蓝图,各位读者是不是早已摩拳擦掌,迫切希望一展身手了,好吧,本章我们将实现OpenMIPS处理器的第一条指令ori,为什么选择这条指令作为我们实现的第一条指令呢?答案就两个字--简单,指令ori用来实现逻辑"或"运算,选择一条简单的指令有助于我们排除干扰,将注意力集中在流水线结构的实现

自己动手写处理器之第二阶段(3)——Verilog HDL行为语句

将陆续上传本人写的新书<自己动手写处理器>(尚未出版),今天是第七篇,我尽量每周四篇 2.6 Verilog HDL行为语句 2.6.1 过程语句 Verilog定义的模块一般包括有过程语句,过程语句有两种:initial.always.其中initial常用于仿真中的初始化,其中的语句只执行一次,而always中语句则是不断重复执行的.此外,always过程语句是可综合的,initial过程语句是不可综合的.       1.always过程语句 always过程语句的格式如图2-10所示.

自己动手写处理器之第二阶段(1)——可编程逻辑器件与PLD电路设计流程

将陆续上传本人写的新书<自己动手写处理器>(尚未出版),今天是第五篇,我尽量每周四篇 通过上一章的介绍,读者应该知道CPU内部有一些基本的电路,比如:译码电路.运算电路.控制电路,此外还有一些寄存器等.这些电路怎么实现呢?当然可以通过一大堆分立的元器件实现,实际上在2008年,美国加州的游戏开发人士Steve Chamberlin就自己制造了一款8位CPU,耗时18个月,花费1000美元,总共使用了1253条线缆,如图2-1所示,Steve Chamberlin为它起了一个十分贴切的名字--B

自己动手写处理器之第二阶段(2)——Verilog HDL简介

将陆续上传本人写的新书<自己动手写处理器>(尚未出版),今天是第六篇,我尽量每周四篇 2.3 Verilog HDL简介 本书实现的OpenMIPS处理器是使用Verilog HDL编写的,所以本章接下来的几节将介绍Verilog HDL的一些基本知识,包括语法.结构等.因为本书并不是一本讲授Verilog HDL的专门书籍,所以此处介绍的内容并不是Verilog HDL的全部,只是一些基础知识,以及在OpenMIPS处理器实现过程中会使用到的知识.读者如果对Verilog HDL有进一步了解

《自己动手写框架4》:分布式锁的简单实现

分布式锁在分布式应用当中是要经常用到的,主要是解决分布式资源访问冲突的问题.  一开始考虑采用ReentrantLock来实现,但是实际上去实现的时候,是有问题的,ReentrantLock的lock和unlock要求必须是在同一线程进行,而分布式应用中,lock和unlock是两次不相关的请求,因此肯定不是同一线程,因此导致无法使用ReentrantLock. 接下来就考虑采用自己做个状态来进行锁状态的记录,结果发现总是死锁,仔细一看代码,能不锁死么. public synchronized

自己动手写处理器之第三阶段——教学版OpenMIPS处理器蓝图

将陆续上传本人写的新书<自己动手写处理器>(尚未出版),今天是第十篇,我尽量每周四篇 从本章开始将一步一步地实现教学版OpenMIPS处理器.本章给出了教学版OpenMIPS的系统蓝图,首先介绍了系统的设计目标,其中详细说明了OpenMIPS处理器计划实现的5级流水线.3.2节给出了OpenMIPS处理器的接口示意图,及各个接口的作用.3.3节简单解释了各个源代码文件的作用.最后描述了OpenMIPS处理器的实现方法,读者将发现本书给出的实现方法与现有书籍的方法完全不同,更加易于理解.便于实践

自己动手写CPU之第九阶段(5)——实现加载存储指令2(修改执行阶段)

将陆续上传新书<自己动手写CPU>,今天是第42篇,我尽量每周四篇,但是最近已经很久没有实现这个目标了,一直都有事,不好意思哈. 开展晒书评送书活动,在亚马逊.京东.当当三大图书网站上,发表<自己动手写CPU>书评的前十名读者,均可获赠<步步惊芯--软核处理器内部设计分析>一书,大家踊跃参与吧!活动时间:2014-9-11至2014-10-30 9.3.2 修改执行阶段 1.修改EX模块 在执行阶段的EX模块会计算加载存储的目的地址,参考图9-19可知,EX模块会增加部