四指令RSIC-CPU的设计
学 号 09700227
EDA技术及应用
设计
说明书
房屋状态说明书下载罗氏说明书下载焊机说明书下载罗氏说明书下载GGD说明书下载
四指令RSIC-CPU设计
起止日期: 2012 年 12 月 31 日 至 2013 年 1 月 4 日
学生姓名 刘扬 班级 09电信2班 成绩 指导教师(签字)
计算机与信息工程学院
2013年1月4日
天津城市建设学院
课程设计任务书
2012 —2013 学年第 1 学期
计算机与信息工程 学院 电子信息工程 专业
课程设计名称: EDA技术及应用
设计
题
快递公司问题件快递公司问题件货款处理关于圆的周长面积重点题型关于解方程组的题及答案关于南海问题
目: 四指令RSIC-CPU设计
完成期限:自 2012 年 12月 31 日至 2013 年 1 月 4 日共 1 周 一(课程设计依据
在掌握常用数字电路原理和技术的基础上,利用EDA技术和硬件描述语言,EDA开发软件(Quartus
?)和硬件开发平台(达盛试验箱Cyclone?FPGA)进行初步数字系统设计。 二(课程设计内容
用状态机设计实现一个有“读入A”,“A输出”,“加法(输入+A)”,“等待”4条指令的8位CPU,实现连续10个数据加法后输出,输出接至数码管显示运行结果:提示:输入输出数据都经过累加器A,运算器就是加法器,结果存于A,缓冲器B暂存结果。扩展设计:实现这4个指令的任意组合。 三(课程设计要求
1. 要求独立完成设计任务。
2. 课程设计说明书封面格式要求见《天津城市建设学院课程设计教学工作规范》附表1 3. 课程设计的说明书要求简洁、通顺,计算正确,图纸表达内容完整、清楚、规范。 4. 测试要求:根据题目的特点,采用相应的时序仿真或者在实验系统上观察结果。 5. 课设说明书要求:
1) 说明题目的设计原理和思路、采用
方法
快递客服问题件处理详细方法山木方法pdf计算方法pdf华与华方法下载八字理论方法下载
及设计流程。
2) 系统框图、VHDL语言设计清单或原理图。
3) 对各子模块的功能以及各子模块之间的关系作较详细的描述。
4) 详细说明调试方法和调试过程。
5) 说明测试结果:仿真时序图和结果显示图。并对其进行说明和分析。
指导教师(签字):
教研室主任(签字):
批准日期: 年 月 日
目录
第一章:设计背景及要求.................................................................................................................. 1 1.1 RSIC-CPU的简介 ................................................................................................................. 1 1.2 设计要求 .............................................................................................................................. 2 第二章:设计原理及总体
方案
气瓶 现场处置方案 .pdf气瓶 现场处置方案 .doc见习基地管理方案.doc关于群访事件的化解方案建筑工地扬尘治理专项方案下载
.......................................................................................................... 3 2.1 RISC-CPU 基本架构 ............................................................................................................. 3 2.2四指令RSIC-CPU
设计方案
关于薪酬设计方案通用技术作品设计方案停车场设计方案多媒体教室设计方案农贸市场设计方案
................................................................................................. 5 第三章:RISC-CPU的各个模块......................................................................................................... 7 3.1 时钟发生器 .......................................................................................................................... 7 3.2 指令寄存器 .......................................................................................................................... 7 3.3 累加器................................................................................................................................... 8 3.4 算术运算器 .......................................................................................................................... 8 3.5 数据控制器 ......................................................................................................................... 9 3.6 地址多路器 .......................................................................................................................... 9 3.7 程序计数器 .........................................................................................................................10 3.8 状态控制器 .........................................................................................................................10 第四章 各模块程序设计...................................................................................................................12 4.1 时钟发生器程序 .................................................................................................................12 4.2 指令寄存器程序 .................................................................................................................14 4.3 累加器程序 .........................................................................................................................14 4.4 算术运算器程序 .................................................................................................................15 4.5 数据控制器程序 .................................................................................................................16 4.6 地址多路器程序 .................................................................................................................16 4.7 程序计数器程序 .................................................................................................................16 4.8 状态控制器程序 .................................................................................................................17 第五章 仿真设计及结果...................................................................................................................22 5(1 时钟发生器仿真图 ...........................................................................................................22 5(2 指令寄存器仿真图 ...........................................................................................................22 5.3 累加器仿真图 .....................................................................................................................23 5.4 算术运算器程序仿真图 .....................................................................................................23 5.5 数据控制器仿真图 .............................................................................................................24 5.6 地址多路器仿真图 .............................................................................................................24 5.7 程序计数器程序仿真图 .....................................................................................................25 5.8 状态控制器仿真图 .............................................................................................................25 5.9 模块综合图 .........................................................................................................................26 第六章:总结及体会.........................................................................................................................27
第一章:设计背景及要求
1.1 RSIC-CPU的简介
集成电路(Integrated Circuit,IC)是电子电路,但它又不同于一般意义上的电子电路,它把成千上万的电子元件包括晶体管、电阻、电容甚至电感集成在微小的芯片上。正是这种奇妙的设计和制造方式使得集成电路为人类社会的进步创造了空前的奇迹,它不仅给人类的生产建设和科学研究带来了巨大便利,而且也彻底改变了人类文明和人们日常生活的面目,可以毫不夸张地说,现今每个人生活的方方面面或多或少都和集成电路有关。CPU 作为集成电路的高端产品,随着半导体工艺水平的发展,遵守摩尔定律发展规律,CPU 性能每过 18 个月就会翻一番。CPU 从最初发展至今已经有几十年的历史了,这期间,按照其处理信息的字长,CPU 可以分为:四位微处理器、八位微处理器、十六位微处理器、三十二位微处理器以及六十四位微处理器。CPU 是 Central Processing Unit,,中央处理器的缩写,它是计算机中最重要的一个部分,由运算器和控制器组成,其内部结构归纳起来可以分为控制单元、逻辑单元和存储单元三大部分,这三个部分相互协调,便可以进行分析,判断、运算并控制计算机各部分协调工作。现代计算机体系结构不再着重于设计计算机中各个部件,而是“向上”与对应的指令集、编译码和操作系统更加紧密地结合在一起,“向下”与更加先进的芯片结构设计和设计方法结合在一起。VLSI 的设计“向上”更高层次发展,计算机的设计同时“向下发展”,两者发展的领域越来越近,甚至在很多方面交叠在一起。计算机体系结构中的一个根本性的变革是 RISC 处理器的出现。RISC 即精简指令集计算机(Reduced Instruction
Set Computer)的缩写。RISC-CPU 与一般的 CPU 相比不仅只是简化了指令系统,而且是通过简化指令系统使计算机的结构更加简单合理,从而提高了运算速度。从实现的途径看,RISC-CPU 与一般的 CPU 的不同处在于:它的时序控制信号形成部件是用硬布线逻辑实现的而不是采用微程序控制的方式。所谓硬布线逻辑也就是用触发器和逻辑门直接连线所构成的状态机和组合逻辑,故产生控制序列的速度比用微程序控制方式快得多,因为这样做省去了读取微指令的时间。RISC 有一套优化过的指令架构,它是根据著名的 80/20 法则所订立。
早在上世纪 60 年代,计算机科学家们发现,计算机中 80%的任务只是动用了大约 20%的指令,而剩下 20%的任务才有机会使用到其他 80%的指令。如果对指令系统作相应的优化,就可以从根本上快速提高处理器的执行效率。IBM 公司在 1975 年成功开发出第一款 RISC 处理器,从此 RISC 架构开始走进超级计算机中。由于指令高度简约,RISC 处理器的晶体管规模普遍都很小而性能强大,深受超级计算机厂商所青睐。很快,许多厂商都开发出了自己的 RISC 指令系统,除了 IBM 的 Power 和 PowerPC 外,还有 DEC 的 Alpha、SUN 的 SPARC、HP 的 PA-RISC、MIPS 技术公司的 MIPS、ARM公司的 ARM 等。它的应用范围也远比 X86 来得广泛,大到各种超级计算机、工作站、高阶服务器,小到各类嵌入式设备、家用游戏机、消费电子产品、工业控制计算机,都可以看到 RISC 的身影。RISC 处理器可以说既简单又复杂:简单之处在于,相比于复杂指令集CISC(Complex Instruction Set Computer,复杂指令系统计算机),这种处理器的指令和变量非常少,正如它的英文字母缩写 RSIC 所代表的“精简指令集”的含义一样;说RSIC 复杂,是因为它们容易实现更高的并行性,而这个特点只有与设计得很好的编译器结合起来,才能显现出其优越性。RISC 与 CISC(复杂指令,一般指普通的 X86CPU)比较,有以下优势指令简单而且少。指令系统选用那些使用频度高的简单指令和一些实用的但不十分复杂的指令,一般指令不超
1
过100条。指令字长固定,寻址方式一般不超过四种,指令格式也不超过四种。所有指令(几乎所有指令)均在单指令周期完成。指令系统中只允许存(STORE)和取(LOAD)指令访问主存,其它指令均在寄存器之间进行。CPU中设置大量的寄存器,称作寄存器堆。指令的运行采用高效的流水线方式。以硬布线控制逻辑为主,不用或少用微码。优化的编译程序,简单有效地支持高级语言,超低功耗。 1.2设计要求
用状态机设计实现一个有“读入A”,“A输出”,“加法(输入+A)”,“等待”4条指令的8位CPU,实现连续10个数据加法后输出,输出接至数码管显示运行结果:提示:输入输出数据都经过累加器A,运算器就是加法器,结果存于A,缓冲器B暂存结果。扩展设计:实现这4个指令的任意组合。
2
第二章:设计原理及总体方案 2.1 RISC-CPU 基本架构
一个基本的 CPU 要包括三部分功能:数据的存储、数据的运算和控制部分。与之相对应的硬件结构也分为三部分:存储器、数据通路和控制器。存储器存放指令和数据;数据通路包括 ALU、程序计数器等,主要功能是对操作数进行运算,得到结果,并产生程序计数器的值,作为要执行的下一条指令的地址;控制器内有指令寄存器,它对指令进行译码,产生相应的控制信号,完成对存储器和数据通路部分的控制。存储器、数据通路和控制器这三部分的基本关系如图 2-1 所示。
图 2-1 CPU 基本结构
存储器中存放了要执行的指令和相应数据。存储器的读写信号由控制器给出。存储器的地址来源有两个:程序计数器和指令寄存器。在取新指令时,用程序计数器的值作为存储器地址;在执行指令时,用指令中的地址部分作为存储器地址。数据通路主要包括累加器、程序计数器和算术逻辑单元。累加器用于保存参加运算的数据以及运算的中间结果。实际上,累加器也是寄存器,不过,它有特殊性,即许多指令执行过程以累加器为中心。往往在运算指令前,累加器中存放一个操作数,指令执行后,由累加器保存运算结果。另外输入输出指令一般也通过累加器来完成。程序计数器指向下一条要执行的指令。由于程序一般存放在内存的一个连续区域,所以,顺序执行程序时,每取一个指令字节,程序计数器便加一。算术逻辑单元是专门用来处理各种运算的数据信息的,它可以进行加、减、乘、除算术运算和与、或、非、异或等逻辑运算。控制器产生相应的控制信号送到时序和控制逻辑电路,从而,组合成外部电路所需要的时序和控制信号。这些信号送往其他部件,以控制这些部件协调工作。对图 2-1 中的结构进行细化,可以得到一个简单 CPU的架构,如图 2-2 所示。该 CPU 采用总线结构,即控制器所需的指令,数据通路所需的数据都是从总线上得到的。
3
图 2-2 CPU 简单架构
计算机进行信息处理可分为两个步骤:1) 将数据和程序(即指令序列)输入到计算机的存储器中。2) 从第一条指令的地址起开始执行该程序,得到所需结果,结束运行。CPU的作用是协调并控制计算机的各个部件执行程序的指令序列,使其有条不紊地进行。因此它必须具有以下基本功能:1) 取指令:当程序已在存储器中时,首先根据程序入口地址取出一条程序,为此要发出指令地址及控制信号。2) 分析指令:即指令译码。是对当前取得的指令进行分析,指出它要求什么操作,并产生相应的操作控制命令。3) 执行指令:根据分析指令时产生的“操作命令”形成相应的操作控制信号序列,通过运算器,存储器及输入/输出设备的执行,实现每条指令的功能,其中包括对运算结果的处理以及下条指令地址的形成。本设计的 RSIC-CPU 数据总线为 8 位,而每条指令为两个字节(高 3 位为操作码,低 13 位是地址),所以每条指令需取两次。CPU 每次取到指令后,其状态控制器(CPU 控制中心)分析操作码后,产生一系列控制信号,启动或停止某些部件。其中时钟发生器利用外来时钟信号进行分频生成一系列时钟信号,送往其他部件用作时钟信号。由功能分析,RISC-CPU 是一个复杂的数字逻辑电路,但是它的基本部件的逻辑并不复杂,可把它分成以下八个基本部件,各个模块之间的互连关系如图 2-3。
1( 时钟发生器(clkgen):产生一系列的时钟信号送往 CPU 其他部件;
2( 指令寄存器(register):存储指令;
3( 累加器(accum):存放算术逻辑运算单元当前的结果,它也是算术逻辑运算单元双目运算中的一个数
据来源;
4( 算术逻辑运算单元(alu):根据输入的 8 种不同操作码分别实现相应的加、与、读、写、异或,跳转
等指令;
5( 数据输出控制器(datactl):控制累加器的数据输出;
6( 状态控制器(control):CPU 的控制核心,用于产生一系列的控制信号,启动或停止某些部件; 7( 程序计数器(counter):提供指令地址,以便读取指令;
8( 地址多路器(adr):选择输出的地址是 PC(程序计数)地址还是跳转的目标地址。
4
图 2-3 RISC-CPU 结构图
2.2四指令RSIC-CPU设计方案
根据设计要求和指导,因为使用的是状态机实现四指令,就有必要对状态机是什么以及状态机的特点进行一下说明。有限状态机是指输出取决于过去输入部分和当前输入部分的时序逻辑电路。一般来说,除了输入部分和输出部分外,有限状态机还含有一组具有“记忆”功能的寄存器,这些寄存器的功能是记忆有限状态机的内部状态,它们常被称为状态寄存器。在有限状态机中,状态寄存器的的下一个状态不仅与输入信号有关,而且还与该寄存器的当前状态有关,因此有限状态机又可以认为是组合逻辑和寄存器逻辑的一种组合。其中,寄存器逻辑的功能是存储有限状态机的内部状态;而组合逻辑又可以分为次态逻辑和输出逻辑两部分,次态逻辑的功能是确定有限状态机的下一个状态,输出逻辑的功能是确定有限状态机的输出。四条指令分别是读取数据,进行加法运算,等待,最后输出。而且要求是等待十个数据然后相加以后一起输出。还需要一个缓冲器临时存储数据。根据以上的要求的目标。设计出来基本的四指令RSIC-CPU的各个功能。图中各个部分的说明如下:当上升沿到来的时候,取指令部件接到了取指命令,开始进行数据的读入,读入的数据先进行缓存处理,然后缓存器将数据读入运算器里进行相加,同时计数器进行计数处理,当十个数据全部读入之后,计数器发出指令,不再读取指令,待到一个时钟的到来将运算器里的数据进行输出处理。整个过程中,在复位时钟以后开始进行。如果在其中出现错误,会再进行一次复位,重新开始,这确保了状态机的顺利工作。而且四个状态也就明确了,分别是数据读入状态, 加法状态,等待状态,输出状态,然后需要一个缓存器进行数据的临时缓存。整个状态机就设计出来了。所以对此采取的方法也是分模块进行处理。可把它分成八个基本部件:(1)时钟发生器(2)指令寄存器(3)累加器(4)RISC CPU算术逻辑运算单元(5)数据控制器(6)状态控制器(7)程序计数器(8)地址多路器。
5
图2-4 RISC-CPU的设计方案
6
第三章:RISC-CPU的各个模块
3.1 时钟发生器
时钟发生器 clkgen 利用外来时钟信号clk 来生成一系列时钟信号clk1、fetch、alu_clk 送往CPU的其他部件。其中fetch是外来时钟 clk 的八分频信号。利用fetch的上升沿来触发CPU控制器开始执行一条指令,同时fetch信号还将控制地址多路器输出指令地址和数据地址。clk1信号用作指令寄存器、累加器、状态控制器的时钟信号。alu_clk 则用于触发算术逻辑运算单元。由于在时钟发生器的设计中采用了同步状态机的设计方法,不但使clk_gen模块的源程序可以被各种综合器综合,也使得由其生成的clk1、clk2、clk4、fetch、alu_clk 在跳变时间同步性能上有明显的提高,为整个系统的性能提高打下了良好的基础。
CLK1
CLK1 CLKGEN CLK ALU_CLK ALU_CLK CLK
RESET FETCH FETCH RESET
图3-1 时钟发生器
3.2 指令寄存器
顾名思义,指令寄存器用于寄存指令。指令寄存器的触发时钟是clk1,在clk1的正沿触发下,寄存器将数据总线送来的指令存入高8位或低8位寄存器中。但并不是每个clk1的上升沿都寄存数据总线的数据,因为数据总线上有时传输指令,有时传输数据。什么时候寄存,什么时候不寄存由CPU状态控制器的load_ir信号控制。load_ir信号通过ena 口输入到指令寄存器。复位后,指令寄存器被清为零。每条指令为2个字节,即16位。高3位是操作码,低13位是地址。(CPU的地址总线为13位,寻址空间为8K字节。)本设计的数据总线为8位,所以每条指令需取两次。先取高8位,后取低8位。而当前取的是高8位还是低8位,由变量state记录。state为零表示取的高8位,存入高8位寄存器,同时将变量state置为1。下次再寄存时,由于state为1,可知取的是低8位,存入低8位寄存器中。
7
INSTRUCTION REGISTER
DATA[7:0]OPCODE[2:0] DATA[7:0]
LOAD_IR opc_iraddrs[15:0]ENA CLK1REGISTERIR_ADDR[12:0]CLK1 RESETRST
图3-2 指令寄存器
3.3累加器
累加器用于存放当前的结果,它也是双目运算其中一个数据来源。复位后,累加器的值是零。当累加器通过ena口收到来自CPU状态控制器load_acc信号时,在clk1时钟正跳沿时就收到来自
于数据总线的数据。
ACCUMULATOR
ALU_OUT[7:0]DATA[7:0]ACCUM[7:0]LOAD_ACCACCUM[7:0]ENA
CLK1ACCUMULATORCLK1
RSTRST
图3-3 累加器
3.4算术运算器
算术逻辑运算单元 根据输入的8种不同操作码分别实现相应的加基本操作运算。利用这几种基
本运算可以实现很多种其它运算以及逻辑判断等操作。
图 DATA[7:0]ZERODATA[7:0] ZERO
ALU_OUT[7:0]ALUALU_OUT[7:0]
ACCUM[7:0]ACCUM[7:0]ALU_CLOCK OPCODE[2:0]
ALU_CLOCKOPCODE[2:0]
图3-4算术运算器
8
3.5 数据控制器
数据控制器的作用是控制累加器数据输出,由于数据总线是各种操作时传送数据的公共通道,不同的情况下传送不同的内容。有时要传输指令,有时要传送RAM区或接口的数据。累加器的数据只有在需要往RAM区或端口写时才允许输出,否则应呈现高阻态,以允许其它部件使用数据总线。 所以任何部件往总线上输出数据时,都需要一控制信号。而此控制信号的启、停,则由CPU状态控制器输出的各信号控制决定。数据控制器何时输出累加器的数据则由状态控制器输出的控制信号datactl_ena决定。
DATACTL
ALU_OUT[7:0]
IN[7:0]DATA[7:0]
DATA[7:0]DATACTL_ENADATA_ENA
图3-5数据控制器
3.6 地址多路器
地址多路器用于选择输出的地址是PC(程序计数)地址还是数据/端口地址。每个指令周期的前4个时钟周期用于从ROM中读取指令,输出的应是PC地址。后4个时钟周期用于对RAM或端口的读写,该地址由指令中给出。地址的选择输出信号由时钟信号的8分频信号fetch提供。
ADDRPC_ADDR[12 : 0]PC_ADDR[12 : 0]ADDR[12 : 0]ADDR[12 : 0]
IR_ADDR[12 : 0] IR_ADDR[12 : 0]
FETCH
FETCH
图3-6 地址多路器
9
3.7程序计数器
程序计数器用于提供指令地址。以便读取指令,指令按地址顺序存放在存储器中。有两种途径可形成指令地址:其一是顺序执行的情况,其二是遇到要改变顺序执行程序的情况,例如执行JMP指令后,需要形成新的指令地址。下面就来详细说明PC地址是如何建立的。复位后,指令指针为零,即每次CPU重新启动将从ROM的零地址开始读取指令并执行。每条指令执行完需2个时钟,这时pc_addr已被增2,指向下一条指令。(因为每条指令占两个字节。)如果正执行的指令是跳转语句,这时CPU状态控制器将会输出load_pc信号,通过load口进入程序计数器。程序计数器(pc_addr)将装入目标地址(ir_addr),而不是增2。
COUNTER
IR_ADDR[12 : 0]IR_ADDR[12 : 0]
LOAD_PCLOADPC_ADDR[12 : 0]PC_ADDR[12 : 0]INC_PCCLOCK
RESETRST
图3-7 程序计数器
3.8 状态控制器
状态控制器由两部分组成:状态机(上图中的MACHINE部分)状态控制器(上图中的MACHINECTL部分)状态机控制器接受复位信号RST,当RST有效时通过信号ena使其为0,输入到状态机中停止状态机的工作。
CLK1INC_PCCLK1INC_PC
ZEROLOAD_ACCZEROLOAD_ACC
LOAD_PCFETCHLOAD_PCFETCHMEM_RD machinectlENAENARDRSTRSTMEM_WRMACHINEWROPCODE[2:0]OPCODE[2:0]LOAD_IRLOAD_IR
HALTINT_FLAGHALTINT_FLAGDATACTL_ENADATACTL_ENA
图3-8 状态控制器
状态机是CPU的控制核心,用于产生一系列的控制信号,启动或停止某些部件。CPU何时进行读指令读写I/O端口,RAM区等操作,都是由状态机来控制的。状态机的当前状态,由变量state记录,state的值就是当前这个指令周期中已经过的时钟数(从零计起)。指令周期是由8个时钟周期组成,每个时钟周期都要完成固定的操作。(1)第0个时钟,因为CPU状态控制器的输出:rd和load_ir为高电平,其余均为低电平。指令寄存器寄存由ROM送来的高8位指令代码。(2)第1个时钟,与上一
10
时钟相比只是inc_pc从0变为1故PC增1,ROM送来低8位指令代码,指令寄存器寄存该8位代码。(3)第2个时钟,空操作。(4)第3个时钟,PC增1,指向下一条指令。若操作符为HLT,则输出信号HLT为高。如果操作符不为HLT,除了PC增一外(指向下一条指令),其它各控制线输出为零。(5)第4个时钟,若操作符为AND、ADD、XOR或LDA,读相应地址的数据;若为JMP,将目的地址送给程序计数器;若为STO,输出累加器数据。(6)第5个时钟,若操作符为ANDD、ADD或XORR,算术运算器就进行相应的运算;若为LDA,就把数据通过算术运算器送给累加器;若为SKZ,先判断累加器的值是否为0,如果为0,PC就增1,否则保持原值;若为JMP,锁存目的地址;若为STO,将数据写入地址处。(7)第6个时钟,空操作。(8)第7个时钟,若操作符为SKZ且累加器值为0,则PC值再增1,跳过一条指令,否则PC无变化。各个模块之间的关系如图3-9所示:
3-9 各个模块之间的关系
11
第四章 各模块程序设计 4.1时钟发生器程序
module clk_gen (clk,reset,clk1,clk2,clk4,fetch,alu_clk);
input clk,reset;
output clk1,clk2,clk4,fetch,alu_clk; wire clk,reset;
reg clk2,clk4,fetch,alu_clk; reg[7:0] state;
parameter S1 = 8'b00000001,
S2 = 8'b00000010,
S3 = 8'b00000100,
S4 = 8'b00001000,
S5 = 8'b00010000,
S6 = 8'b00100000,
S7 = 8'b01000000,
S8 = 8'b10000000,
idle = 8'b00000000;
assign clk1 = ~clk;
always @(negedge clk)
if(reset)
begin
clk2 <= 0;
clk4 <= 1;
fetch <= 0;
alu_clk <= 0;
state <= idle;
end
else
begin
case(state)
S1:
begin
clk2 <= ~clk2;
alu_clk <= ~alu_clk;
state <= S2;
end
S2:
begin
clk2 <= ~clk2;
12
clk4 <= ~clk4;
alu_clk <= ~alu_clk;
state <= S3;
end
S3:
begin
clk2 <= ~clk2;
state <= S4;
end
S4:
begin
clk2 <= ~clk2;
clk4 <= ~clk4;
fetch <= ~fetch;
state <= S5;
end
S5:
begin
clk2 <= ~clk2;
state <= S6;
end
S6:
begin
clk2 <= ~clk2;
clk4 <= ~clk4;
state <= S7;
end
S7:
begin
clk2 <= ~clk2;
state <= S8;
end
S8:
begin
clk2 <= ~clk2;
clk4 <= ~clk4;
fetch <= ~fetch;
state <= S1;
end
idle: state <= S1;
default: state <= idle;
endcase
end
endmodule
13
4.2指令寄存器程序
module register(opc_iraddr,data,ena,clk1,rst);
output [15:0] opc_iraddr;
input [7:0] data;
input ena, clk1, rst;
reg [15:0] opc_iraddr;
reg state;
always @(posedge clk1)
begin
if(rst)
begin
opc_iraddr<=16'b0000_0000_0000_0000;
state<=1'b0;
end
else
begin
if(ena) //如果加载指令寄存器信号load_ir到来,
begin //分两个时钟每次8位加载指令寄存器
casex(state) //先高字节,后低字节
1’b0: begin
opc_iraddr[15:8]<=data;
state<=1;
end
1’b1: begin
opc_iraddr[7:0]<=data;
state<=0;
end
default: begin
opc_iraddr[15:0]<=16'bxxxxxxxxxxxxxxxx;
state<=1'bx;
end
endcase
end
else
state<=1'b0;
end
end
endmodule
4.3累加器程序
module accum( accum, data, ena, clk1, rst);
14
output[7:0]accum;
input[7:0]data;
input ena,clk1,rst;
reg[7:0]accum;
always@(posedge clk1)
begin
if(rst)
accum<=8'b0000_0000; //Reset
else
if(ena) //当CPU状态控制器发出load_acc信号
accum<=data; //Accumulate
end
endmodule
4.4算术运算器程序
module alu (alu_out, zero, data, accum, alu_clk, opcode);
output [7:0]alu_out;
output zero;
input [7:0] data, accum;
input [2:0] opcode;
input alu_clk;
reg [7:0] alu_out;
parameter HLT =3’b000,
SKZ =3’b001,
ADD =3’b010,
ANDD =3’b011,
XORR =3’b100,
LDA =3’b101,
STO =3’b110,
JMP =3’b111;
assign zero = !accum;
always @(posedgealu_clk)
begin //操作码来自指令寄存器的输出opc_iaddr<15..0>的低3位
casex (opcode)
HLT: alu_out<=accum;
SKZ: alu_out<=accum;
ADD: alu_out<=data+accum;
ANDD: alu_out<=data&accum;
XORR: alu_out<=data^accum;
15
LDA: alu_out<=data;
STO: alu_out<=accum;
JMP: alu_out<=accum;
default: alu_out<=8'bxxxx_xxxx;
endcase
end
endmodule
4.5数据控制器程序
module datactl (data,in,data_ena);
output [7:0]data;
input [7:0]in;
input data_ena;
assign data = (data_ena)? in : 8'bzzzz_zzzz;
endmodule
4.6地址多路器程序
module adr(addr,fetch,ir_addr,pc_addr); output [12:0] addr;
input [12:0] ir_addr, pc_addr; input fetch;
assign addr = fetch? pc_addr : ir_addr;
endmodule
4.7程序计数器程序
module counter ( pc_addr, ir_addr, load, clock, rst);
output [12:0] pc_addr;
input [12:0] ir_addr;
input load, clock, rst;
reg [12:0] pc_addr;
always @( posedge clock or posedge rst )
begin
if(rst)
pc_addr<=13'b0_0000_0000_0000;
else
16
if(load)
pc_addr<=ir_addr;
else
pc_addr <= pc_addr + 1;
end
endmodule
4.8状态控制器程序
module machinectl( ena, fetch, rst); output ena;
input fetch, rst;
reg ena;
always @(posedge fetch or posedge rst)
begin
if(rst)
ena<=0;
else
ena<=1;
end
endmodule
总程序见下面模块:
//------------------------------------------------------------------------------
module machine( inc_pc, load_acc, load_pc, rd,wr, load_ir,
datactl_ena, halt, clk1, zero, ena, opcode );
output inc_pc, load_acc, load_pc, rd, wr, load_ir;
output datactl_ena, halt;
input clk1, zero, ena;
input [2:0] opcode;
reg inc_pc, load_acc, load_pc, rd, wr, load_ir;
reg datactl_ena, halt;
reg [2:0] state;
parameter HLT = 3 'b000,
SKZ = 3 'b001,
ADD = 3 'b010,
ANDD = 3 'b011,
XORR = 3 'b100,
LDA = 3 'b101,
STO = 3 'b110,
JMP = 3 'b111;
17
always @( negedge clk1 )
begin
if ( !ena ) //接收到复位信号RST,进行复位操作
begin
state<=3'b000;
{inc_pc,load_acc,load_pc,rd}<=4'b0000;
{wr,load_ir,datactl_ena,halt}<=4'b0000;
end
else
ctl_cycle;
end
//-----------------begin of task ctl_cycle--------- task ctl_cycle;
begin
casex(state)
3’b000: //load high 8bits in struction begin
{inc_pc,load_acc,load_pc,rd}<=4'b0001;
{wr,load_ir,datactl_ena,halt}<=4'b0100;
state<=3’b001;
end
’b001: //pc increased by one then load low 8bits instruction 3
begin
{inc_pc,load_acc,load_pc,rd}<=4'b1001;
{wr,load_ir,datactl_ena,halt}<=4'b0100;
state<=3’b010;
end
3’b010: //idle
begin
{inc_pc,load_acc,load_pc,rd}<=4'b0000;
{wr,load_ir,datactl_ena,halt}<=4'b0000;
state<=3’b011;
end
3’b011: //next instruction address setup 分析指令从这里开始
begin
if(opcode==HLT) //指令为暂停HLT
begin
{inc_pc,load_acc,load_pc,rd}<=4'b1000;
{wr,load_ir,datactl_ena,halt}<=4'b0001;
end
else
begin
{inc_pc,load_acc,load_pc,rd}<=4'b1000;
{wr,load_ir,datactl_ena,halt}<=4'b0000;
18
end
state<=3’b100;
end
3’b100: //fetch oprand
begin
if(opcode==JMP)
begin
{inc_pc,load_acc,load_pc,rd}<=4'b0010;
{wr,load_ir,datactl_ena,halt}<=4'b0000; end
else
if( opcode==ADD || opcode==ANDD ||
opcode==XORR || opcode==LDA)
begin
{inc_pc,load_acc,load_pc,rd}<=4'b0001;
{wr,load_ir,datactl_ena,halt}<=4'b0000;
end
else
if(opcode==STO)
begin
{inc_pc,load_acc,load_pc,rd}<=4'b0000;
{wr,load_ir,datactl_ena,halt}<=4'b0010;
end
else
begin
{inc_pc,load_acc,load_pc,rd}<=4'b0000;
{wr,load_ir,datactl_ena,halt}<=4'b0000;
end
state<=3’b101;
end
3’b101: //operation
begin
if ( opcode==ADD||opcode==ANDD||
opcode==XORR||opcode==LDA )
begin //过一个时钟后与累加器的内容进行运算
{inc_pc,load_acc,load_pc,rd}<=4'b0101;
{wr,load_ir,datactl_ena,halt}<=4'b0000; end
else
if( opcode==SKZ && zero==1)
begin
{inc_pc,load_acc,load_pc,rd}<=4'b1000;
{wr,load_ir,datactl_ena,halt}<=4'b0000;
end
else
19
if(opcode==JMP)
begin
{inc_pc,load_acc,load_pc,rd}<=4'b1010;
{wr,load_ir,datactl_ena,halt}<=4'b0000;
end
else
if(opcode==STO)
begin
//过一个时钟后把wr变1就可写到RAM中
{inc_pc,load_acc,load_pc,rd}<=4'b0000;
{wr,load_ir,datactl_ena,halt}<=4'b1010;
end
else
begin
{inc_pc,load_acc,load_pc,rd}<=4'b0000;
{wr,load_ir,datactl_ena,halt}<=4'b0000;
end
state<=3’b110;
end
3’b110: //idle
begin
if ( opcode==STO )
begin
{inc_pc,load_acc,load_pc,rd}<=4'b0000;
{wr,load_ir,datactl_ena,halt}<=4'b0010; end
else
if ( opcode==ADD||opcode==ANDD||
opcode==XORR||opcode==LDA)
begin
{inc_pc,load_acc,load_pc,rd}<=4'b0001;
{wr,load_ir,datactl_ena,halt}<=4'b0000;
end
else
begin
{inc_pc,load_acc,load_pc,rd}<=4'b0000;
{wr,load_ir,datactl_ena,halt}<=4'b0000;
end
state<=3’b111;
end
3’b111: //
begin
if( opcode==SKZ && zero==1 )
begin
20
{inc_pc,load_acc,load_pc,rd}<=4'b1000;
{wr,load_ir,datactl_ena,halt}<=4'b0000;
end
else
begin
{inc_pc,load_acc,load_pc,rd}<=4'b0000;
{wr,load_ir,datactl_ena,halt}<=4'b0000;
end
state<=3’b000;
end
default:
begin
{inc_pc,load_acc,load_pc,rd}<=4'b0000;
{wr,load_ir,datactl_ena,halt}<=4'b0000;
state<=3’b000;
end
endcase
end
endtask
endmodule
21
第五章 仿真设计及结果 5(1 时钟发生器仿真图
5-1 时钟发生器 5(2指令寄存器仿真图
图5-2指令寄存器
22
5.3累加器仿真图
5-3 累加器
5.4算术运算器程序仿真图
5-4算术运算器
23
5.5数据控制器仿真图
5-5数据控制器
5.6地址多路器仿真图
5-6 地址多路器
24
5.7程序计数器程序仿真图
5-7程序计数器 5.8状态控制器仿真图
5-8状态控制器
25
5.9模块综合图
5-9模块综合图
26
第六章:总结及体会
这次EDA课程设计,让我对RSIC-CPU有了初步的认识。更为重要的是,这次是用状态机实现四指令CPU的设计,对状态机的工作方式有了跟深刻的认识。刚开始,由于没有采用模块化处理导致错误,在老师的指导下,将这四个状态分步进行,并采用模块化处理。虽然没有得出最后结果,但是对每个模块分部进行仿真,了解了其工作方式。正如我的刚开始的设计思路,刚开始我只想到了,状态机的四个状态,却没有想到,如何去取数,如何去行进计数,到最后的输出,思维是混乱的。但是设计使用了时钟发生器、指令寄存器、累加器、RISC CPU算术逻辑运算单元、数据控制器、状态控制器、程序计数器、地址多路器这几个控制模块以后,使得状态机的工作每一步过程更加的清晰。通过这次EDA课程设计,让我认识到了自己专业课知识学习上的不足。对状态机的工作过程思路也没有理清就盲目去设计,几次失败以后,才找到了正确的设计思路。从了解状态机的工作过程然后设计流程图到利用Verilog语言进行编程再到利用Quartus软件进仿真,进行了完整的处理,这个过程中对EDA有了更深层次和系统的了解。设计当中克服了很多困难,也培养了我的解决问题的能力和与困难进行斗争的耐力。在此也要感谢耐心帮助我的老师和同学们。
27
28