计算机系统设计(上册)——基于FPGA的RISC处理器设计与实现(txt+pdf+epub+mobi电子书下载)


发布时间:2020-05-28 23:11:35

点击下载

作者:魏继增

出版社:电子工业出版社

格式: AZW3, DOCX, EPUB, MOBI, PDF, TXT

计算机系统设计(上册)——基于FPGA的RISC处理器设计与实现

计算机系统设计(上册)——基于FPGA的RISC处理器设计与实现试读:

前言

本套教材的写作背景和意义

经过“复旦共识、天大行动、北京指南”,具有中国特色工程教育的新工科(Emerging Engineering Education)建设全面启动。面向新工科,计算机类专业的教学改革也势在必行。在过去的二十年间,计算机类专业在移动互联网、云计算、人工智能等领域已为我国培养了大量人才。但这些人才主要集中在计算机应用领域,而在计算机系统设计方面,包括处理器、操作系统和编译系统等,却是人才紧缺,导致我国在各类型计算机设计中所使用的核心器件、高端芯片、基础软件长期依赖进口,受制于人,严重影响了“自主可控”国家信息化发展战略的实施,严重危害国家安全,也是我国计算机领域自主创新不足的重要原因。造成这一问题的根本原因是,目前的计算机教育缺乏对学生进行系统能力的培养。让学生自己动手“设计一台功能完备、可支持简单操作系统微内核和常见应用运行的计算机系统”将十分有助于系统能力的培养,同时还可激发学生从事计算机系统设计工作的兴趣和热情。但目前,我国计算机教学中存在知识衔接脱节、缺乏工程性和综合性教学方法、缺乏具有工程规模的系统性实验等问题,无法保证学生解决这样一个极具难度和挑战性的工程问题,自然也就谈不上系统能力的培养。因此,我们需要建设一系列全新的课程、教材对其进行尝试和探索。

作者以践行系统能力培养为目标,基于DIGILENT公司的FPGA开发平台,利用软/硬件协同设计与验证方法学,围绕“设计一台功能完备、可支持简单操作系统微内核和常见应用运行的计算机系统”这个复杂工程问题,编写了这套“计算机系统设计”系列教材。这套教材由上、下两册组成,上册专注于主流RISC处理器的设计与实现,下册使用所设计的处理器结合总线和常见外设构建一个完整的计算机系统,并完成开源操作系统的移植和常见应用的开发。

本套教材的适用范围和课程

不同于国内很多高校已开设的“计算机系统基础”或“计算机系统导论”等课程,这些课程一般开设在本科低年级,旨在开始计算机各专业课学习之前对计算机系统形成初步认识。而本套教材更加专注于计算机系统的设计过程,通过真正的动手实践使学生做到对“数字逻辑”“计算机组成原理”“汇编程序设计”“操作系统”“计算机系统结构”等课程所学知识的有序衔接和综合运用,形成对计算机系统更直观、更形象、更全面的认识。因此,本套教材适用于计算机类专业(也包括微电子、集成电路与集成系统专业)本科高年级(大三、大四)或研究生阶段。在使用本套教材之前,学生应至少修完“数字逻辑”“计算机组成原理”“计算机系统结构”“操作系统”等基础课程,此外,如果具备硬件描述语言和FPGA开发知识,则将更加事半功倍。

使用本套教材开设的课程名称可以是“计算机系统设计”“计算机系统综合实验”或类似名称;也可将本套教材选为“计算机组成原理”“计算机系统结构”等课程的实验教材,或者短学期综合实践类教材。

此外,书中并非所有章节都是必需的,在教学过程中,可根据学生的实际情况有所取舍。例如,如果学生在之前的“计算机组成原理”或相关课程中已经学习了MIPS汇编语言、高级语言的机器级表示等内容,则可以跳过第2、3章,只关注处理器的硬件设计与实现;如果学生之前已经使用过Xilinx FPGA和Vivado进行开发,则可以跳过第4章;如果只需要了解基本流水线的设计细节,则可以跳过第5、6章。

本书为“计算机系统设计”系列教材的上册。虽然处理器及指令集体系结构的种类繁多、千差万别,但其设计原理和实现方法是相同的。因此,本书以设计基于MIPS 32位指令集的处理器MiniMIPS32为主线,讲授主流RISC处理器设计与实现的方法、步骤与技巧。本书将讲解处理器微架构设计、数据通路的设计与实现、流水线设计与优化、软件环境与测试环境的搭建及基于DIGILENT公司的FPGA开发板的板级设计等内容。书中将处理器及原型系统设计过程中每个环节所涉及的硬件和软件的基本概念关联起来,力争给读者建立一个功能完备、层次分明的处理器架构,也为下册教材开展SoC的软/硬件设计奠定重要基础。本书的特色表现在以下几个方面。

● 更精简的处理器结构:虽然有很多开源项目也提供基于MIPS指令集的处理器,但毕竟是商业级代码,对大多数无处理器设计经验的老师和刚接触处理器结构的学生而言,实践难度较大,本书所设计的MiniMIPS32处理器采用更精简的指令集(共56条指令),但功能完备,可支持操作系统内核等中、大规模程序的运行。

● 与前序课程的教学内容结合紧密:本书构建的MiniMIPS32处理器采用经典5级流水线,支持定向前推、相关性处理、延迟转移、暂停等常见流水线技术及异常处理机制,与多数主流的“计算机组成原理”“计算机系统结构”等教材中的理论内容保持一致。

●“增量式”教学:本书借鉴软件工程中的“增量模型”开发方法,学生无须全部从零开始,以MiniMIPS32处理器中的26条指令为例,采用循序渐进的方法,逐步添加处理器的功能,并为学生提供了详尽的软/硬件源码。学生通过参考已有代码,根据具体设计需求和目标即可完成剩余指令的设计,在降低设计难度的同时,可激发学生进行计算机系统设计的兴趣,帮助他们建立信心,也使学生更关注系统设计过程中的关键环节。

本书的内容安排

本书共由8章组成,分为3个部分。(1)基础理论部分

第1章:绪论,重点介绍计算机系统的基本概念,涉及计算机系统的层次结构、计算机系统的组成、评价方法及指令集体系结构。

第2章:MiniMIPS32处理器的指令集体系结构,着重介绍MiniMIPS32指令集体系结构的构成要素。

第3章:MiniMIPS32程序的机器级表示,讲解基于MiniMIPS32的汇编程序设计和常见的C语言语法结构在机器级的表示,做到从软件的层面了解MiniMIPS32处理器的硬件结构。

第4章:现场可编程逻辑门阵列(FPGA)及其设计流程,重点介绍基于Xilinx Vivado的FPGA设计流程,为后续处理器及系统设计奠定工具使用的基础。(2)处理器设计部分

第5章:MiniMIPS32处理器的基本流水线设计与实现,重点讲述基于5级理想流水线的处理器设计方案,并给出基于Verilog HDL的实现。

第6章:MiniMIPS32处理器的流水线相关问题和暂停机制,针对流水线中常见的相关性问题,给出MiniMIPS32处理器的解决方案,在无法消除相关时,则设计暂停机制,并给出基于 Verilog HDL的实现。

第7章:MiniMIPS32处理器异常处理的设计与实现,重点讲解支持MiniMIPS32处理器精确异常处理的设计方案,并给出基于Verilog HDL的实现。

第8章:综合测试,基于DIGILENT公司的Nexys4 DDR FPGA开发平台搭建基于MiniMIPS32处理器的原型系统MiniMIPS32_SYS,并完成功能点测试和C程序测试。

致谢

本书由天津大学智能与计算学部教师魏继增、郭炜编著。在此衷心感谢在本书编著过程中给予大力支持和中肯建议的各位专家、同事和学生,正是他们的鼓励和帮助使得本书的编著工作顺利完成。来自清华大学的刘卫东教授、南京大学的袁春风教授、美国北卡罗来纳州立大学的周辉阳教授等各位专家都花费了大量的时间和精力对本书进行审阅,并从章节结构、内容及实践细节等方面提出了许多宝贵的修改意见。国防科技大学的王志英教授对本书的编著做了前瞻性的指导。天津大学2017级硕士研究生肖健、徐文富完成了书中MiniMIPS32处理器代码的编写、仿真及FPGA硬件的开发,并进行了大量的功能测试;2018级硕士研究生薛臻对全书文字进行了校对,修订了书中许多文字错误和纰漏。此外,在编著过程中,作者还参阅了很多国内外作者的相关著作,特别是本书参考文献中列出的著作,在此一并表示感谢。

本书是作者以教育部高等学校计算机类专业教学指导委员会(简称计算机教指委)系统能力培养试点校项目、DIGILENT-教育部产学合作协同育人项目和第一届“龙芯杯”全国大学生计算机系统能力培养大赛为依托编著完成的,在此感谢计算机教指委、DIGILENT公司及龙芯中科技术有限公司对本书作者的信任和支持。

结束语

新工科建设的启动呼唤适应产业需求、满足国家重大需求的全新的课程和教材。在新工科建设的历史机遇下,本书旨在培养计算机类专业及相关专业学生的系统能力,为国家培养未来可适应“自主可控”国家信息化发展战略的创新型计算机核心人才。本书广泛参考了国内相关的经典教材和著作,在内容的组织和描述上力争做到概念准确、语言通俗易懂、实践过程循序渐进,并尽量详尽地描述处理器的设计过程和注意事项。虽然作者已经尽力,但由于计算机系统设计过程十分复杂,存在很多琐碎的工程细节,加之作者水平有限,书中难免存在遗漏和不足之处,敬请广大读者批评指正,以便在后续版本中予以改进。第1章 绪论

计算机系统设计的旅程正式开始。不可否认,整个过程将充满艰辛和挑战,但每一阶段你都会有突破自我的巨大成就感。虽然道路崎岖,但会收获颇丰,让我们揭开计算机系统设计的神秘面纱,最后大家会发现其实我们每个人都可以实现一台属于自己的计算机!

现在我们先从了解计算机系统入手。在本章中,首先,对计算机系统的基本内容进行介绍,包括计算机系统的层次结构、计算机硬件系统的组成和计算机软件系统的组成;然后,从3个方面,即性能、成本和功耗去评价一个计算机系统的优劣;接着,针对计算机系统的核心部件——处理器,引出有关指令集体系结构的概念,并重点介绍MIPS指令集体系结构;最后,对本书所设计的目标处理器MiniMIPS32及原型系统MiniMIPS32_SYS进行大体介绍。1.1 计算机系统概述

究竟什么是计算机系统?大多数人可能认为计算机就是桌面电脑,但是实际上,远不止如此。除了大家熟知的个人电脑、超级计算机和服务器等通用计算机外,像手机、平板电脑、数码照相机、数字电视、游戏机、打印机、路由器等设备也都属于计算机的范畴。可见,计算机已经深入到我们生活的方方面面。总而言之,计算机可以很大,大到需要建一栋专门的大楼放置,并建设一个电站专门为其供电(如数据中心,超级计算机神威、天河等);也可以很小,小到可以放到口袋里,充电几小时就能用一周(如手机)。但无论计算机的规模多么大,种类多么繁多,其本质无非就是一台能够满足人们各种不同计算需求的自动化计算设备而已,因此各类计算机系统具有很多共性。1.1.1 计算机系统的层次结构

任何计算机系统都可以被看成图1-1所示的层次结构。计算机系统划分为应用程序、操作系统、硬件系统和晶体管4个层次,而应用程序和操作系统又可以统一为软件系统。这4个层次可通过3个抽象界面相互联系,分别是应用程序编程接口(Application Programming Interface,API)、指令集体系结构(也称为指令系统,Instruction Set Architecture,ISA)和工艺模型。采用抽象界面的原因是,计算机系统的多级层次结构使得其设计需要多方面人员的参与,包括应用工程师、系统工程师、硬件设计前端工程师、硬件设计后端工程师等,这样通过抽象层可以屏蔽下层实现细节,提取上层调用接口,使得处于各个层次的工程师更加关注本层的开发,降低设计难度,提高设计效率。

API位于应用程序和操作系统之间,是高级语言的编程接口,可便于应用程序设计人员更快速、更便捷地进行应用程序开发。常见的API包括C/C++语言、Java语言、Python语言、JavaScript脚本语言接口及OpenGL图形编程接口和Socket网络编程接口等。使用一种API编写的应用程序,经过编译后可以在支持该API的不同计算机上运行。可以说,API的优劣直接决定了应用程序的质量。

ISA位于操作系统和硬件系统之间。它是对计算机底层硬件细节的抽象,包括指令集、寄存器及系统状态切换、地址空间划分、中断异常处理等运行时环境。可以说,ISA是系统级程序员所能看到的虚拟计算机。这样,软件设计只需遵循某一ISA,而不用了解底层硬件的具体细节,从而所开发的软件就可以运行在支持该ISA的各种不同的计算机上,保证了软件的兼容性。常见的ISA包括x86、ARM、MIPS等。

工艺模型位于硬件系统和物理器件之间,是芯片生产厂家提供给芯片设计者的界面。除了表示晶体管和连线等基本参数的模型之外,它还包括该工艺所能提供的各种宏单元及IP(Intellectual Property)核,如实现PCIE接口的物理层(简称PHY)等。图1-1 典型计算机系统的层次结构1.1.2 计算机硬件系统的组成

从1946年第一台通用计算机ENIAC面世到现在,各种类型的计算机层出不穷,绝大多数的计算机硬件系统仍然沿用了1945年由美籍匈牙利数学家冯·诺依曼提出的“冯·诺依曼计算机结构”,该结构包含5个部分,分别是运算器、控制器、存储器、输入设备和输出设备。其中,运算器和控制器又合称为中央处理器(Central Processing Processor,CPU),简称处理器。冯·诺依曼计算机结构如图1-2所示。图1-2 冯·诺依曼计算机结构

冯·诺依曼计算机结构的特点:①计算机处理的数据和指令一律用二进制表示;②存储器按地址访问,且每个存储单元的位数固定,并且按线性一维编址;③采用存储程序方式,指令和数据不加区别混合存储在同一个存储器中;④指令在存储器中按顺序存放,通常,指令按顺序执行,但执行顺序也会根据运算结果或指定的条件而改变;⑤以运算器为中心,输入/输出设备和存储器之间的数据传送都要通过运算器。概括起来,冯·诺依曼计算机最重要的特点是存储程序和指令驱动执行。

1.处理器(CPU)

处理器由运算器和控制器两个部件组成,是计算机系统中最核心的运算和控制部件。运算器在计算机中负责计算,而且大部分的运算器只能做简单算术运算(加、减、乘、除,有些低端计算机中的运算器甚至不支持除法)、逻辑运算和移位运算。其他复杂运算可通过这些简单运算组合而成。控制器则根据指令发出控制命令以协调计算机各部件自动工作。控制器具有的功能包括:根据程序计数器中存放的地址从存储器中取出指令,简称为“取指”;对取出的指令进行分析和解释,并根据解释的结果从存储器或输入设备取出指令所需的数据,简称为“译码”;控制器还要向计算机各部件发出控制信号,以协调它们的工作。例如,对于运算指令,则要将数据和操作类型送到运算器;如果是访存指令,则要向存储器发出相应的读写命令;如果要与输入/输出设备进行交互,则除了发送相应的读写命令外,还要负责中断处理。随着集成电路的发展,芯片的集成度不断提高,现代的处理器除了运算器和控制器还集成了很多其他部件,如高速缓存Cache、主存控制器等,已有别于传统处理器了。

2.存储器

存储器是计算机中的存储和记忆部件,负责保存程序、初始数据和中间结果。在程序执行过程中,要求存储器可以按地址进行随机访问,并且能够以CPU处理数据的粒度(4字节或8字节)进行访问。目前,在计算机系统中被广泛采用的存储器按照存储介质可分为以下几类。

1)磁性存储器:如硬盘,其优势是存储密度极高、成本很低、具有非易失性(即断电仍可保存信息),但缺点是访问速度很慢,通常在毫秒级。

2)闪存:如固态硬盘,属于非易失性存储设备,相比磁盘,其访问速度更快,但成本更高、容量较小。

3)动态随机存储器(Dynamic Random Access Memory,DRAM):如SDRAM、DDR、DDR2等,每个存储单元为1T1C(1个晶体管1个电容)结构,其优势是存储密度较高、访问速度较快(一般在几十纳秒级),其最大缺点是数据具有易失性。

4)静态随机存储器(Static Random Access Memory,SRAM):每个存储单元为6T(6个晶体管)结构,其优势是速度极快(一般在纳秒级),但存储密度较低,且成本高。

在使用计算机时,人们总是希望用最便宜的价格(低成本)买到大容量(存放更多的程序和数据)且访问速度快(处理器可以更快地获取数据)的存储器。显然,上述任何一种存储器都无法满足这个要求。一般来说,速度越快,存储介质的成本越高,而成本越低,存储介质的速度越慢。因此,在现代计算机中通常引入了多层存储体系的概念,以缓解这一矛盾,如图1-3所示。从左向右依次为寄存器堆(采用D触发器实现,位于处理器内部)、高速缓存Cache(采用SRAM实现,通常位于处理器内部)、主存储器(简称主存,采用DRAM实现)和磁盘(采用磁介质或闪存实现),在物理距离上离CPU越来越远,其速度越来越慢,容量越来越大,价格越来越便宜。

程序的局部性表现为两个方面:时间局部性和空间局部性。时间局部性指如果一个指令或数据被访问,那么其在不久的将来很可能被再次访问;空间局部性指如果一个指令或数据被访问,那么地址与其邻近的指令或数据也可能被访问。利用局部性原理,将近期会用到指令或数据存放在靠近CPU的、访问速度较快的存储层次,把近期用不到的指令或数据存放在远离CPU、访问速度较慢但存储容量较大的存储层次,从而在整体上达到一个大容量高速单级存储器的效果。图1-3 多层存储体系

多层存储体系之所以能够缓解访问速度、存储容量和成本之间的矛盾,得益于程序访问的局部性。

3.输入/输出设备

输入/输出设备(I/O设备)用于计算机系统与外界之间进行信息交互。输入设备是为计算机提供程序、数据的设备。常用的输入设备包括键盘、鼠标、扫描仪等。输出设备是从计算机中将运算结果传送出来的设备。常用的输出设备包括打印机、显示器、扬声器等。I/O设备的种类十分繁多,其信号类型和时序也千差万别,通常需要通过标准接口控制器与CPU相连,如GPIO、USB、UART串口、PS/2接口、PCIE接口等。CPU对I/O设备进行访问既可通过专用I/O指令(如x86系统),也可通过访存指令(如大多数嵌入式系统)。1.1.3 计算机软件系统的组成

硬件系统为计算机提供了基本的运算能力、控制机制、存储空间及与外界的交互能力,而软件系统构建于硬件系统之上,控制和管理各个硬件模块实现各种具体计算任务。软件系统可以分为系统软件和应用软件,而系统软件又可进一步细分为操作系统和支撑软件。

操作系统是一种管理和保护各类软硬件资源、控制程序执行、改善人机界面、合理组织计算机工作流程和为用户使用计算机提供良好运行环境的系统软件,通常由进程管理、线程管理、存储管理、设备管理、文件管理等几大模块组成。另外,现代操作系统通过虚拟化技术为用户提供一个比实际更为强大的计算机,例如,将单处理器虚拟化为多个处理器以适应多任务的需求,而基于段页式的虚拟存储器为程序员提供了一个远大于物理存储空间的编程空间,使其从繁重的存储管理中解放出来。

支撑软件包括用于处理软件语言的语言处理系统(如编译器等)、用于支持数据管理和存取的软件(如数据库)、用于用户与计算机系统之间进行信息交互的软件系统,以及其他事先编写好的各种标准子程序组成的函数库、中间件等。

应用软件是指用户为解决各种问题而利用计算机及其他系统软件编写的软件。

并不是所有的计算机都需要具备这些软件,一些简单的计算机系统,如用于工控的计算机系统,就可能没有操作系统和支撑软件,而直接由应用程序对硬件进行控制。1.2 计算机系统的评价指标

评价一个计算机优劣的指标有很多,其中性能、成本和功耗是较为重要的3个指标。

1.性能

通常说一台计算机速度很快,这个“快”就是指计算机的性能。那如何评价这个“快”呢?对于不同的对象,评价方式可能不同。对于普通计算机用户而言,速度快指的是执行一个程序运行的时间短,即响应速度快。例如,一台Core i7的机器和一台Pentium Pro的机器相比,对一个大文件进行压缩,前者完成的时间更短。而对于亚马逊、淘宝、京东这样的电子商务网站,评价其背后的数据中心性能的指标通常是每秒可以完成的交易事务,即吞吐率。

现在,我们仅考虑将计算机的性能定义为“完成一个任务所需的时间”,即计算机系统的执行时间。这个执行时间由多方面因素决定,包括CPU时间、磁盘的访问、主存的访问、输入/输出和操作系统开销等。在理想情况下,计算机执行一个任务的时间可以等同于CPU时间,即仅考虑处理器的计算时间,而忽略访存时间和等待I/O的时间。这样就可以得出CPU时间的计算公式。一个程序的CPU时间可以描述为

CPU时间越短,说明相应的计算机系统速度越快,性能越高。从CPU时间公式可以看出,CPU的性能由3个参数决定。这3个参数之间相互依赖,很难只改变一个参数而不影响其他两个参数。时钟周期与工艺技术及计算机组织有关;平均每条指令的时钟周期数(Clock cycles Per Instructions,CPI)则与计算机组织及指令集体系结构相关;程序所含的指令数目则与指令集体系结构及编译技术相关。例如,相比RISC指令集,CISC指令集的指令格式更为复杂,因此CPI会较高,但由于CISC指令集的功能更强大,因此相比RISC,其实现同一程序所花费的指令数更少,因此计算机的性能需要综合评价。

除了上述公式外,还可以通过CPI、每秒执行百万条指令数(MIPS)、每秒执行百万次浮点运算数目(MFLOPS)、每秒执行的事务数(TPS)等多种指标来评价计算机的性能。

2.成本

计算机的成本和芯片的成本直接相关。芯片的成本包括制造成本和一次性成本(如研发成本)的分摊部分。因此,芯片的产量直接影响最终的成本。随着集成电路工艺水平的逐步提升,生产成本可以持续地降低。此外,随着工艺技术的发展,实现相同功能所需要的晶片面积呈指数级降低,从而单个晶片的成本也呈指数级降低。但成本降到一定程度就不再下降,甚至还会缓慢地上升,这是因为厂家为了保持利润不再生产和销售该产品,转而生产和销售升级产品。

3.功耗

目前,对于各种类型的计算机系统,功耗显得越来越重要。例如,手机等移动设备需要电池供电,想延长电池的工作时间,低功耗显得十分重要。再如,位于天津的天河-1A 超级计算机,满负荷运转时,每天总耗电近10万千瓦时,费用高达数十万元,再次凸显低功耗的重要性。此外,近年来,由于峰值功耗等约束,芯片上能够同时工作的晶体管数目呈指数趋势减少,芯片上的多个处理器无法按照设计频率满负荷运转,不得已必须关闭一些处理器或降低工作主频,那些不能工作的晶体管就形成了所谓的“暗硅”。这说明当前的计算机设计不能再一味追求性能,而需要着重考虑性能功耗比(Performance per Watt),即每瓦的性能。

芯片功耗是计算机功耗的重要组成部分,主要由CMOS晶体管产生,分为动态功耗和静态功耗。动态功耗主要是由电路的翻转(0→1/1→0)产生的。静态功耗主要是指漏电功耗,它是指MOS管不能严格关闭而发生漏电产生的功耗。随着晶体管特征尺寸的减小,处理器内的漏电流持续增加。

升级工艺是降低动态功耗的有效方法,因为工艺升级可以降低电容和电压,从而成倍地降低动态功耗。通过选择低功耗工艺可以降低芯片的静态功耗,芯片生产一般会提供高性能工艺和低功耗工艺,低功耗工艺速度稍慢,漏电功耗呈数量级降低。1.3 处理器概述

处理器是计算机系统中最核心的运算和控制部件。它负责计算机内部主要的计算任务,并根据指令发出控制命令以保证计算机各部件协调、自动地工作。本书的核心任务就是设计一款基于MIPS指令集的处理器。1.3.1 指令集体系结构和微体系结构

处理器依靠执行指令来控制计算机的运行,不同的处理器具有不同的指令集,就好比不同国家的人拥有不同的语言一样。这就造成针对某一个处理器编写的程序,不能直接运行于另一个处理器上,必须重新编写,并重新编译后才能运行,大大降低了软件的可复用性和可移植性。

IBM为了避免上述重新编写软件的问题,使相同的软件可以不经任何修改就能运行在其出品的各种计算机之上,在它的System/360计算机中首次引入了指令集体系结构(ISA)的概念,这是世界上首个指令集可兼容的计算机,具有跨时代的意义。从图1-1所示的计算机层次结构中可以看出,ISA是软件系统和硬件系统的分界面,它将程序员编程时所需要了解的硬件细节从硬件系统中抽象出来,这样程序员只要面向ISA进行编程,开发出的软件就能运行在符合该ISA的所有计算机之上。而对于处理器设计者,只需要依照ISA进行硬件设计,就可保证符合该ISA的各种软件能够正常运行。具体而言,从程序员的角度来看,ISA主要包括指令集结构、基本数据类型、一组编程规范、寄存器、寻址模式、存储管理、异常和中断处理、运行时环境、运行级别控制等,涉及软硬件交互的各个方面。

微体系结构(microarchitecture,简称微结构)是ISA的一个具体硬件实现。具有相同ISA的处理器,可能具有不同微结构,从而表现出不同性能。例如,Intel酷睿系列处理器遵循IA-32或IA-64的ISA,但微结构可能有多种,如Sandy Bridge、Ivy Bridge、Haswell等。1.3.2 CISC 和RISC

当前的ISA可以分为两类:复杂指令集计算机(Complex Instruction Set Computer,CISC)和精简指令集计算机(Reduced Instruction Set Computer,RISC)。CISC的指令长度可变,而RISC的指令长度固定。

早期的处理器全部是CISC架构,倾向于使用功能强大的指令集,一条指令能够完成很多功能,也就是说,其设计的目的就是用最少的机器指令来完成所需的计算任务。采用CISC架构的处理器包括Intel的80x86和Motorola的68K系列。这种指令集结构的出现与当时的时代特点有关,早期的处理器昂贵且处理速度慢,设计者不得不加入越来越多的复杂指令来提高执行速度,部分复杂指令甚至与高级语言中的操作直接对应。此外,那个时代的主存容量有限,访问速度较慢且价格昂贵,CISC采用变长指令字,节约了存储空间,而复杂的指令也减少了对主存的访问次数,从而降低了缓慢的访问速度对程序性能的影响。总地来说,CISC指令集简化了软件和编译器的设计难度,但也提高了硬件复杂度。

随着计算机结构的不断改进,指令的功能和数目不断增加,CISC指令集变得异常庞大,有些处理器的指令数目甚至达到300多条。1975年,IBM Thomas J.Watson研究中心在研究指令系统的合理性时发现,日趋庞杂的指令系统不但不易实现,而且还可能降低系统性能。1979年,美国加州大学伯克利分校的David Patterson教授研究发现,在CISC指令集中,各种指令的使用率相差悬殊,只有20%的指令被经常使用,而这些指令在程序中占到指令总数的 80%,这就是著名的“20%~80%”准则,可见消耗了大量精力的复杂设计只带来了很少的回报。因此,研究人员开始对指令集和处理器进行重新设计,只保留常用的简单指令,使得处理器的结构更简单,也更合理,从而提升CPU的处理速度,这就是RISC指令集。RISC指令集的特点包括:

● 减少指令集中的指令种类,编译器或程序员通过几条指令完成一个复杂的操作。

● 采用简单的指令格式和寻址方式,指令长度固定,大多数指令能在一个时钟周期内完成。

● 相比CISC指令集,拥有更多的通用寄存器,例如,MIPS拥有32个通用寄存器。

● 除了Load/Store指令可以访问存储器,其他指令都不能访问存储器,操作数要么来自寄存器,要么来自立即数。

● 硬件结构简单,采用硬布线逻辑,可通过流水线、多发射等技术提高处理器的主频和效率。

虽然RISC指令集有很多优点,但其自身也有缺点。例如,RISC简化了硬件设计,但增加了编译器设计的复杂度。完成同样的任务,基于RISC指令集的程序相比CISC程序需要更多的指令,使得编译器的优化变得更为重要。

现代处理器对CISC和RISC进行了融合。例如,Intel处理器先将复杂指令分解为若干类似于RISC指令的微操作,然后采用RISC结构实现这些微操作。而一些RISC处理器,如PowerPC,也加入了一些功能强大的专用指令(如向量指令、多媒体指令等)。1.3.3 指令集体系结构中的“五朵金花”

在当今计算机系统中,处理器的种类成千上万,但ISA相对固定。其中5种ISA较为常见,分别是x86、ARM、POWER、SPARC和MIPS。除了x86是CISC ISA外,其他都是RISC ISA。

1.x86

x86是史上最成功、最赚钱的指令集体系结构。目前,绝大多数个人计算机都使用基于 x86指令集的处理器。

1978年,Intel推出了8086、8088处理器,IBM-PC采用8088作为其计算机的核心。1982年,Intel推出了80286,被IBM PC/AT所采用。从此以后,x86成为个人计算机的标准平台。后来,由于IBM在选择供应商时为了减少风险,要求至少两家公司同时提供产品,因此Intel将x86架构开放给了AMD。为了与AMD相区别,Intel后来采用IA(Intel Architecture)来代替x86,即32位指令集IA-32和64位指令集IA-64。

Intel处理器之所以成功,得益于其著名的tick-tock(工艺年-架构年)战略。两年为一周期,第一年提高工艺,晶体管变小,第二年在维持相同工艺的前提下,推出新的处理器微结构。工艺和架构交替改善,既避免了设计风险,也加快了新产品的发布周期,提升了产品的竞争力。

2.ARM

ARM指令集体系结构属于ARM Holding,这是一家总部位于英国剑桥的公司,在1990年由Acorn Computers、Apple、VLSI Technology 3家公司合资组建。早在1985年Acorn公司就设计了代号为Acorn RISC的32位处理器,由VLSI负责生产,这就是ARM1。

与x86更加关注处理器的性能不同,ARM更侧重于低功耗、低成本,主要面向嵌入式市场,如手机市场的90%采用的是ARM指令集的处理器。因此,ARM指令集也是当今销量最大的指令集。

ARM公司本身不生产芯片,而是向半导体公司提供指令集授权、内核授权,其他公司使用ARM内核设计自己的处理器芯片,如三星、高通及我国的飞腾等。目前,ARM的指令集体系结构包括ARMv4、ARMv5、ARMv6、ARMv7及ARMv8,前4种是32位指令集,最后一种是64位指令集。

3.POWER

最早提出RISC思想的IBM公司,在1990年提出了高性能的POWER(Performance Optimized With Enhanced RISC)系列处理器,并一直用于IBM公司的服务器之上。

1991年,IBM与Apple、Motorola一起成立AIM联盟,进军PC市场,并对POWER处理器进行改进,形成了PowerPC。到了2004年,Motorola将其半导体部门分拆,成立了Freescale,继续对PowerPC进行支持。IBM 生产的 POWER 和 PowerPC 处理器侧重于服务器和游戏机领域,如Sony(索尼)、Microsoft(微软)的游戏机,Freescale的PowerPC更侧重嵌入式市场,如通信、汽车电子等。2004年IBM发起了Power.org联盟,发布了统一的指令集体系结构,将POWER和PowerPC体系结构统一到新架构中。目前,IBM开放了POWER8指令集,并开始向外提供内核授权。

4.SPARC

SPARC(Scalable Processor ARChitecture,可扩展处理器架构)源自美国加州大学伯克利分校20世纪80年代的研究,并由Sun公司在1985年首先提出,于1989年成为商用架构。Sun公司将SPARC系列处理器用在了高性能工作站和服务器之上,指令集包括v8、v9等。

SPARC指令集架构完全开放,在此基础上出现了一些开放源代码的处理器,如Sun公司的UltraSPAC T1、LEON等。其中,LEON是一种SPARC v8架构的处理器,至今已发布到了LEON4,是一种计划用在航天器上的处理器。

5.MIPS

MIPS(Microprocessor without Interlocked Piped Stages,无内部互锁流水级处理器)是最经典的RISC处理器,被视为处理器教科书的典范。

MIPS是由John L.Hennessy领导的研究小组在1981年开始设计的。其设计理念是使用相对简单的指令,结合优秀的编译器及采用流水线技术执行指令,从而使用更少的晶体管生产出更快的处理器。这一理念在20世纪80年代取得了巨大的成功,于是1984年成立了MIPS计算机系统公司,开始对MIPS架构进行商业化。随后,基于MIPS指令集架构的处理器在工作站、服务器系统中得到了广泛的应用。MIPS指令集也从MIPS Ⅰ、MIPS Ⅱ、MIPS Ⅲ、MIPS Ⅳ、MIPS Ⅴ、MIPS32发展到了MIPS64。目前,MIPS公司已经被英国的Imagination公司收购。

虽然,在商业上MIPS远不如Intel、ARM公司成功,不过它的学术地位很高,很多处理器吸收了其中的设计思想,而且MIPS架构中的指令专利已经过期,可以自由使用。我国的龙芯系列处理器采用的就是MIPS架构。本书设计的就是基于MIPS指令集架构的处理器。

需要特别注意的是,在计算机发展的几十年间,曾经出现过数量庞大的指令集,但最终被人们所接受的屈指可数。其根本原因并不是那些指令集不够出色,而是缺乏一套完善的生态体系,包括成熟的编译器、操作系统、虚拟机及大量的应用软件。这就好比一个人当然可以发明、使用自己的语言,但是如何与别人交流才是真正的问题。如果无法交流,再优秀的语言也注定会失败。因此,重新定义一套指令集并不难,难的是与之配套的编译器、操作系统、各种应用软件都需要重新编写,也就是重新构建生态体系,这样的工作量和难度都是巨大的。如果没有生态体系,再优秀的指令集体系结构也不会有人使用。这也是为什么本书选择MIPS指令集作为目标指令集的原因。1.3.4 MIPS 指令集体系结构的发展

自20世纪80年代MIPS指令集体系结构出现后,其不断地更新换代,从最初的MIPS Ⅰ到MIPSⅤ,发展到目前可支持扩展模块的MPS32和MIPS64系列。每一代都兼容前一代指令集。各代MIPS指令集体系结构的概况如下所示。

1.MIPS Ⅰ

MIPS Ⅰ提供加载/存储、计算、跳转、分支、协处理器及其他特殊指令,最初用于MIPS早期的R2000和R3000处理器,其中R2000是首款支持MIPS指令集的处理器。

2.MIPS Ⅱ

MIPS Ⅱ添加了自陷指令、链接载入指令、条件存储指令、同步指令、可能分支指令、平方根指令,为后来MIPS32指令集体系结构奠定了基础。

3.MIPS Ⅲ

MIPS Ⅲ提供了32位指令集,同时支持64位指令集,最初用于首次添加了浮点处理单元的MIPS R4000处理器。

4.MIPS Ⅳ

MIPS Ⅳ增加了条件移动指令、预取指令及一些浮点指令,最初用于MIPS处理器R8000,后来应用于R5000/R10000。其中,R5000采用的是经典的5级流水线、顺序运行,R10000采用的是乱序运行。

5.MIPS Ⅴ

添加了能够提高代码生产效率和数据转移效率的指令。可是没有任何一款处理器是基于该指令集体系结构的。MIPSⅤ为后来的MIPS64指令集体系结构奠定了基础

6.MIPS32和MIPS64

MIPS32和MPS64指令集体系结构是定位于高性能、低功耗的MIPS指令集,第一版于1998年提出,称为MIPS32/64 Release 1。MIPS32以MIPSⅡ架构为基础,选择性地增加了MIPS Ⅲ、MIPSⅣ、MIPSⅤ中的指令。MIPS64以MIPSⅤ架构为基础,同时兼容MIPS32。该ISA第一次包括了被称为协处理器0(CP0)的“CPU控制”功能。2003年。MIPS32/64指令集体系结构的第二版(Release 2)被公布,也称为MIPS32/64 R2。目前,最新版本是第五版(Release 5),也称为MIPS32/64 R5。采用MIPS32的处理器包括MIPS32 4K、MIPS32 4KE、MIPS32 24K等。采用MIPS64的处理器包括MIPS64 5K、MIPS64 20Kc等。

7.microMIPS32/64

microMIPS32/64 指令集体系结构集成了16位和32位优化指令的高性能代码压缩技术,保持了98%的MIPS32性能,同时减少了至少30%的代码体积,从而减少芯片成本,也有助于减少系统功耗。MIPS M14K处理器内核是2009年公布的首款遵循microMIPS指令集架构的MIPS32兼容内核。

整个MIPS指令集体系结构的发展过程如图1-4所示。图1-4 MIPS指令集体系结构的发展1.4 本书的主要内容

本书将基于 MIPS32 Release 1 指令集,设计一款采用经典5级流水线的32位RISC处理器——MiniMIPS32,并基于所设计的处理器、存储器和简单外设搭建一个简易原型系统MiniMIPS32_SYS来对处理器的功能进行验证和评估。1.4.1 目标处理器MiniMIPS32

MiniMIPS32处理器支持MIPS32 Release 1指令集的一个子集,共计56条整数指令。基于这56条指令的MiniMIPS32可运行很多常见应用,以及简单操作系统内核。MiniMIPS32采用小端模式,数据线和地址线均为32位。MiniMIPS32采用经典5级流水线结构,支持定向前推、分支延迟及暂停等常见流水线技术。内部具有32个通用寄存器、2个特殊寄存器及CP0协处理器中的部分寄存器,并具有硬件乘法器和除法器。MiniMIPS32还支持6种异常和6个外部中断,并且实现了精确异常处理流程。此外,本书所实现的MiniMIPS32不支持MMU和虚实地址变换,处理器不支持特权级别切换,始终工作在内核模式。1.4.2 原型系统MiniMIPS32_SYS

原型系统MiniMIPS32_SYS的整体架构如图1-5所示,由1个MiniMIPS32处理器、2个存储器、若干I/O设备、1个设备接口模块和1个I/O设备译码模块组成。

MiniMIPS32_SYS采用哈佛结构,指令存储器和数据存储器分开,其中指令存储器采用ROM,数据存储器采用RAM,并支持字节写使能。两个存储器都按字节进行编址。由于存储器都将基于Xilinx FPGA内部的块存储器进行构建,因此读写操作都是同步的,其中读指令存储器和读数据存储器都是以32位(4字节)为单位与处理器进行数据交互,而写数据存储器则是根据字节使能位完成的。

MiniMIPS32_SYS目前仅支持两类I/O设备:GPIO和定时器。其中GPIO包括16个LED灯、4个七段数码管和2个三色LED,用于显示程序执行结果。定时器为32位,可用于对程序的执行时间进行计时。I/O 地址空间采用和存储器统一编址的方式,这样可以通过和访问存储器相同的加载/存储指令去访问I/O设备。图1-5 原型系统MiniMIPS32_SYS的整体架构

设备接口模块类似于总线,负责处理器与存储器和I/O设备进行信息交互。其最主要的功能是对处理器发送来的访问地址进行翻译,并将其转发到相应的设备上。I/O设备译码模块则是对I/O地址进行译码,确定所需要访问的具体I/O设备。

在软件工具方面,由于MIPS32指令集兼容MiniMIPS32指令集,因此,可直接选用现有的MIPS交叉编译器编译程序。整个MiniMIPS32_SYS硬件系统将在Xilinx Vivado集成开发环境中,采用Verilog HDL进行描述和仿真,并部署到Diglient公司的Nexys4 DDR FPGA开发平台上进行实现和验证。为了保证系统功能的正确性,本书采用多种方法进行测试。首先,进行MiniMIPS32处理器设计时,将采用手工编写汇编程序,利用Vivado进行软件仿真,并结合指令集仿真器QtSpim进行协同验证。搭建完成MiniMIPS32_SYS系统后,我们将提供具有较高覆盖率的随机功能点测试和常见C程序测试。第2章 MiniMIPS32处理器的指令集体系结构

在第1章所介绍的计算机系统的层次结构中,指令集体系结构(ISA)位于软件和硬件之间,是软硬件的分界面。ISA对计算机系统的底层硬件细节进行了抽象和屏蔽,为软件提供调用接口,而软件需要根据ISA的规定来使用底层硬件,可以说ISA在计算机系统中是起到承上启下重要作用的一层。因此,在进行处理器设计时,首先需要了解的就是它所依赖的ISA,所以,本章就来学习本书所设计的MiniMIPS32处理器的指令集体系结构。

本章将从寄存器的结构、存储器的编址方式、指令格式、指令集、寻址方式、处理器的操作模式、协处理器及异常处理等几个方面,全面地了解MiniMIPS32处理器的指令集体系结构。除上述内容外,本书所设计MiniMIPS32处理器将不支持TLB、MMU和操作模式的切换。2.1 操作数的数据类型

MiniMIPS32指令集体系结构所支持的操作数均是整数类型,根据操作数位宽的不同,操作数可分为以下5种基本类型。

● 比特(bit,b):位宽为1位。

● 字节(byte,B):位宽为8位。

● 半字(half word,H):位宽为16位,2字节。

● 字(word,W):位宽为32位,4字节。

● 双字(double word,D):位宽为64位,8字节。2.2 寄存器概述

相比主存等外部存储器,寄存器在存储层次中最靠近处理器内核,其数据访问速度最快,可在一个时钟周期内完成存取。因此,RISC处理器通常会配置大量寄存器,除访存指令外,其他指令的操作数均来自寄存器或立即数。

MiniMIPS32 ISA所提供的寄存器可以分为以下3类。

● 通用寄存器:共计32个,每个通用寄存器为32位,它们均为程序员(这里指位于操作系统及以下层面的程序员)可见的寄存器。

● 特殊寄存器:包括一对用于存储整数乘/除法结果的寄存器HI和LO,以及1个用于存放指令地址的PC寄存器(也称为程序计数器)。其中,HI和LO对程序员是可见的,而PC寄存器对程序员是不可见的。

● 系统控制寄存器:主要指CP0协处理器中的寄存器。

本节只介绍MiniMIPS32处理器中的通用寄存器和特殊寄存器,其布局如图2-1所示。有关协处理器CP0中的系统控制寄存器详见7.1.2节。

1.MiniMIPS32的通用寄存器

MiniMIPS32 ISA有32个32位可见的通用寄存器可供使用,通过$0~$31表示。其中,两个寄存器被分配了特殊的用途。图2-1 通用寄存器和特殊寄存器

● $0寄存器:0号通用寄存器被硬件连线至0值,在指令执行过程中,不能更改这个寄存器的值,其值永远是“0”。该寄存器可作为任何需要0值指令的源寄存器。

● $31寄存器:一般情况下,31号通用寄存器会被JAL、BLTZAL和BGEZAL指令隐式地用作目的寄存器,用于存放返回地址。当然,$31寄存器也可作为普通寄存器使用。

除上述两个寄存器外,其他通用寄存器都可被用作一般的寄存器,在任何指令中使用。需要注意的是,虽然在处理器的硬件设计上对通用寄存器($0和$31除外)的使用规则没有强制规定,但实际应用中(特别是使用第三方子程序,设计编译器、操作系统,进行C语言/汇编混合编程时)还是要遵循一系列的寄存器使用约定,并且为了配合这些约定,每个通用寄存器除了编号,还有一个约定的名称(也称“助记符”)。其命名和使用约定如表2-1所示。表2-1 通用寄存器的命名和使用约定

$at:这个寄存器由汇编器生成的宏指令(也称合成指令)使用(宏指令的介绍详见3.2.3节)。当必须显式地使用它(如在异常处理程序中保存和恢复某些寄存器的值)时,可以通过汇编伪指令“.noat”来阻止汇编器使用$at寄存器,但这可能导致汇编程序中的一些宏指令不可用。

$a0~$a3:用来传递子程序调用时所需要的前4个非浮点参数,当参数多于4个时,通过存储器进行参数传递。

$t0~$t9:临时寄存器,也称为调用者保存寄存器。当一个程序调用子程序时,子程序可以不用保存这些寄存器的值而随意使用,可用来暂存计算过程中的中间结果。因此,为了防止子程序破坏这些寄存器的值,需要由调用者保存这些寄存器的值,并在子程序调用返回后恢复这些值。

$s0~$s9:子程序寄存器变量,也称子程序保存寄存器。子程序必须保证这些寄存器的值在调用前后维持不变。因此,要么在子程序执行过程中不使用这些寄存器,要么在子程序开头将这些寄存器的值存储在堆栈中,并在子程序返回时将这些寄存器的内容恢复到调用前的值。

$gp:全局指针寄存器,是一个十分特殊的寄存器。它指向运行

试读结束[说明:试读内容隐藏了图片]

下载完整电子书


相关推荐

最新文章


© 2020 txtepub下载