单周期CPU设计汇编
第5章单周期CPU及其Verilog HDL设计
op 6 bits
rs 5 bits
rt 5 bits
rd 5 bits
sa 5 bits
funct 6 bits
I Format
31
(rs, rt: Register Numbers, imm: Immediate)
26 25 21 20 16 15 0
时钟上升沿(0到 1的变化) 一个周期
Clock
下降沿
指令1
指令2
指令3
指令4
在时钟上升沿保存指令的结果和下一条指令的地址
c
5.1 执行指令所需的硬件电路
• 指令的执行过程
取指令 执行指令
—读取指令
程序计数器的值作为地址从存储器中 取指令 形 成 下 一 条 指 令 地 址
—分析指令 —按指令规定内容执行指令 —检查有无中断请求
c
取指部件(Instruction Fetch Unit)
• 每条指令都有的公共操作
– 取指令: M[PC] – 更新PC:PC ← PC + 4
转移(Branch and Jump)时,PC内容再次被更新为 “转移目标地址 ” 下地址 逻辑
Next Address Logic Address Instruction Word
rs rt P C a do Inst mem
we rna
rnb qa wn Regfile d clk qb b ALU
rd
a
aluc z r
clock
c
Sll指令 (Shift Left Logical)
sll rd, rt, sa ; rd <-- rt << sa
电子科技大学CPU设计:《单周期CPU的设计与实现》-实验指导书
电子科技大学计算机科学与工程学院单周期CPU的设计与实现实验指导书[计算机组成原理实验]张建2013-12-13目录前言 (1)1.1 实验内容 (2)1.2实验要求 (2)2. 实验环境 (3)2.1 硬件平台 (3)2.2 软件平台 (3)2.3 实验主要仪器设备连接框图 (4)3. 实验原理 (5)3.1 概述 (5)3.2 单周期CPU的总体电路 (5)3.3 MIPS指令格式 (6)3.4 数据路径设计 (7)3.4.1 下一条指令地址的选择 (7)3.4.2 ALU的输入端 (8)3.4.3寄存器堆的输入端 (8)4. 基本功能部件的设计与实现 (10)4.1 32位2选1选择器的设计与实现 (10)4.2 32位4选1选择器的设计与实现 (18)4.3 5位2选1选择器的设计与实现 (19)4.4 带有异步清零的32位D触发器的设计与实现 (19)4.5 移位器的设计 (20)4.6 32位加/减法器的设计与实现 (20)5.运算器(ALU)的设计与实现 (21)6.寄存器堆(Register File)的设计与实现 (24)7.控制器(Control Unit)的设计与实现 (27)8. CPU的封装 (30)9. 测试 (32)9.1 指令存储器及测试程序 (32)9.2 数据存储器及测试数据 (33)9.3 仿真测试 (33)9.4 下载到开发板验证 (35)附件: (39)BTN_Anti_Jitter模块 (39)Hex7seg_decode模块 (39)前言《计算机组成原理》是计算机科学专业的一门重要专业基础课。
在该课程中的理论学习中系统地阐述了计算机各组成部件的工作原理、逻辑实现和设计方法及将各部件连接成整机的方法,计算机硬件与底层软件的接口,培养了学生对计算机硬件系统的分析、开发与设计的基本技能能力。
本实验开设的目的是让学生通过设计一个单周期的CPU,加深对计算机各组成部件功能的理解和掌握,更好地理解计算机的基本工作原理,培养和锻炼学生掌握计算机硬件设计的基本方法和技能。
MIPS单周期CPU实验报告
MIPS单周期CPU实验报告一、实验目的本实验旨在设计一个基于MIPS指令集架构的单周期CPU,具体包括CPU的指令集设计、流水线的划分与控制信号设计等。
通过本实验,可以深入理解计算机组成原理中的CPU设计原理,加深对计算机体系结构的理解。
二、实验原理MIPS(Microprocessor without Interlocked Pipeline Stages)是一种精简指令集(RISC)架构的处理器设计,大大简化了指令系统的复杂性,有利于提高执行效率。
MIPS指令集由R、I、J三种格式的指令组成,主要包括算术逻辑运算指令、存储器访问指令、分支跳转指令等。
在单周期CPU设计中,每个指令的执行时间相同,每个时钟周期只执行一个指令。
单周期CPU的主要部件包括指令内存(IM)、数据存储器(DM)、寄存器文件(RF)、运算单元(ALU)、控制器等。
指令执行过程主要分为取指、译码、执行、访存、写回等阶段。
三、实验步骤1.设计CPU指令集:根据MIPS指令集的格式和功能,设计符合需求的指令集,包括算术逻辑运算指令、存储器访问指令、分支跳转指令等。
2.划分CPU流水线:将CPU的执行过程划分为取指、译码、执行、访存、写回等阶段,确定每个阶段的功能和控制信号。
3.设计控制器:根据CPU的流水线划分和指令集设计,设计控制器实现各个阶段的控制信号生成和时序控制。
4.集成测试:进行集成测试,验证CPU的指令执行功能和正确性,调试并优化设计。
5.性能评估:通过性能评估指标,如CPI(平均时钟周期数)、吞吐量等,评估CPU的性能优劣,进一步优化设计。
四、实验结果在实验中,成功设计了一个基于MIPS指令集架构的单周期CPU。
通过集成测试,验证了CPU的指令执行功能和正确性,实现了取指、译码、执行、访存、写回等阶段的正常工作。
同时,通过性能评估指标的测量,得到了CPU的性能参数,如CPI、吞吐量等。
通过性能评估,发现了CPU的性能瓶颈,并进行了相应的优化,提高了CPU的性能表现。
单周期cpu课程设计
单周期cpu课程设计一、课程目标知识目标:1. 学生能理解单周期CPU的工作原理,掌握其内部结构及功能。
2. 学生能描述单周期CPU的指令执行过程,包括取指、译码、执行、访存、写回等阶段。
3. 学生能解释单周期CPU中时钟、指令和数据的关系,并分析其性能特点。
技能目标:1. 学生能运用所学知识,设计并实现一个简单的单周期CPU。
2. 学生能运用仿真软件对单周期CPU进行功能仿真,验证其正确性。
3. 学生能通过课程学习,培养自己的逻辑思维和问题解决能力。
情感态度价值观目标:1. 学生能对计算机硬件及CPU产生兴趣,激发学习热情。
2. 学生能认识到CPU在计算机系统中的核心地位,增强对计算机科学的尊重和热爱。
3. 学生能在团队协作中发挥积极作用,培养合作精神和沟通能力。
课程性质:本课程为计算机科学与技术专业核心课程,旨在让学生了解CPU的基本原理,掌握单周期CPU的设计方法。
学生特点:学生已经具备一定的数字逻辑电路基础,具有一定的编程能力和逻辑思维能力。
教学要求:结合学生特点,注重理论与实践相结合,引导学生通过课程学习,达到课程目标所规定的知识、技能和情感态度价值观要求。
在教学过程中,关注学生的个体差异,鼓励学生积极参与,培养其独立思考和解决问题的能力。
通过课程目标的分解,确保教学设计和评估的针对性和有效性。
二、教学内容1. 单周期CPU概述:介绍CPU的发展历程,单周期CPU的概念及其在计算机系统中的作用。
教材章节:第1章 计算机系统概述2. 单周期CPU内部结构:讲解CPU的内部组成部分,包括控制单元、算术逻辑单元(ALU)、寄存器组、程序计数器等。
教材章节:第2章 CPU内部结构3. 指令集与指令执行过程:分析指令集的设计,讲解单周期CPU指令执行过程中各阶段的任务和实现方法。
教材章节:第3章 指令集与指令执行4. 时序控制与性能分析:探讨时钟、指令和数据的关系,分析单周期CPU的性能特点。
教材章节:第4章 时序控制与性能分析5. 单周期CPU设计方法:介绍设计单周期CPU的步骤,包括电路设计、指令集设计、时序控制等。
Logisim完成MIPS单周期处理器开发实验报告
Logisim完成MIPS单周期处理器开发实验报告Project3Logisim完成单周期处理器开发实验报告⼀.总体设计⼆.模块定义(1)IFU(2)GPR(3)ALU(4)EXT(5)DM(6)Controller四.控制器设计单周期真值表Func100000100010N/AOp000000000000001101100011000100001111add sub ori lw sw beq lui RegDst1100X X0 ALUSrc0011101 MemtoReg0001X X X RegWrite1111002 MemWrite0000100 nPC_sel0000010 ExtOp X X000X1ALUctr Add Subtract Or Add Add Subtract X五.测试要求16.测试程序lui$t0,0x0004#lui测试程序要实现:⽴即数0x0004加载⾄t0寄存器的⾼位lui$t1,0x0008#lui测试程序要实现:⽴即数0x0008加载⾄t1寄存器的⾼位ori$t3,$zero,0x00002000#ori测试程序要实现:zero寄存器中的内容与⽴即数0x00002000进⾏或运算,储存在t3寄存器中sw$t0,4($t3)#sw测试程序要实现:把t0寄存器中值(1Word),存储到t3的值再加上偏移量4,所指向的RAM中sw$t0,8($t3)#sw测试程序要实现:把t0寄存器中值(1Word),存储到t3的值再加上偏移量8,所指向的RAM中loop:add$t2,$t2,$t1#add测试程序要实现:t1寄存器中的值加上t2寄存器中的值后存到t2寄存器中lw$t4,4($t3)#lw测试程序要实现:把t3寄存器的值+4当作地址读取存储器中的值存⼊t4 lui$t5,0x0004#lui测试程序要实现:⽴即数0x0004加载⾄t5寄存器的⾼位sub$t7,$t6,$t5#sub测试程序要实现:t6寄存器中的值减去t5寄存器中的值后存到t7寄存器中add$t0,$t0,$t5#sub测试程序要实现:t0寄存器中的值减去t5寄存器中的值后存到t0寄存器中add$t6,$t6,$t0#add 测试程序要实现:t6寄存器中的值加上t0后存到t6寄存器中beq$t0,$t1,loop#beq测试程序要实现:判断t0的值和t1的值是否相等,相等转loopadd$t0,$t0,$t5#add测试程序要实现:t0寄存器中的值加上t5后存到t0寄存器中lui$v0,0x0001#lui测试程序要实现:⽴即数0x0001加载⾄v0寄存器的⾼位lui$v1,0x0002#lui测试程序要实现:⽴即数0x0002加载⾄v1寄存器的⾼位add$v0,$v0,$v1#add测试程序要实现:v0寄存器中的值加上v1后存到v0寄存器中add$v1,$v0,$v1#add测试程序要实现:v0寄存器中的值加上v1后存到v1寄存器中ori$a0,$v0,0xffff#ori测试程序要实现:v0寄存器中的内容与⽴即数0xffff进⾏或运算,储存在a0寄存器中sub$a1,$a0,0x0000ffff#sub测试程序要实现:a0寄存器中的值减去⽴即数0x0000ffff后存到a1寄存器中loop2:sub$a2,$v1,$v0#sub测试程序要实现:v1寄存器中的值减去v0中的值后存到a2寄存器中add$a1,$a2,$a1#add测试程序要实现:a2寄存器中的值加上a1后存到a1寄存器中beq$a1,$v1,loop2#beq测试程序要实现:判断a1的值和v1的值是否相等,相等转loop2机器码:3c0800043c090008340b2000ad680004014950208d6c00043c0d000401cd7822010d402001c870201109fff9010d40203c0200013c03000200431020004318203444ffff3c010*******ffff008128220062302200c52820 10a3fffdMARS模拟结果:Logism:GPR:DM:六、问答18.对于Figure5、Figure6中的与或阵列来说,1个3输⼊与门最终转化为2个2输⼊与门,1个4输⼊与门最终转化为3个2输⼊与门,依次类推。
(完整word版)32位单周期RISC处理器设计
第一章32 位单周期RISC处理器设计要设计一款处理器,首先要选择体系结构,本题选择的是RISC体系结构,因为它适合于流水线设计。
然后需要选择一个标准的指令集,本题选择的MIPS指令集并按照常规的五段流水的方式来实现流水线。
流水线的实现过程将在第二章介绍。
1.1目标处理器指令集与指令格式本题目标CPU以能实现部分MIPS指令为目标,具体指令如下表1:(slti)无条件跳跳转(jL)J转空操作空操作(nop)表1 目标CPU指令集1.2 从指令具体行为反推设计方案CPU要执行一条指令,不外乎需要完成以下几个过程:取指令,指令译码,将译码出的指令放到算术逻辑运算部件ALU上执行运算,根据ALU算得的访存地址进行访存和将访存的结果写回寄存器等。
当然,不同的指令类型(R、I、J)可能经过的过程稍有不同,即它们的数据通路有所不同,以下将具体介绍:1、R格式指令数据通路:1)从指令寄存器Instr MEM中取出指令,同时PC增值(即加1等待下个CLK到来);2.)寄存器单元rs1和rs2的内容从寄存器堆Reg File中读出;3.)ALU根据功能码Opcoder确定操作方式,对从寄存器堆读出的数据进行计算;4.)ALU运算结果被写入寄存器堆,由rd确定写入的寄存器堆存储单元地址。
图1 R指令数据通路2. I 指令(除lw、sw和分支指令)数据通路如图2:1.)从指令寄存器Instr Mem中取出指令,同时PC增值(即加1等待下个CLK到来);2.)寄存器单元rs1的内容从寄存器堆Reg File中读出;3.)ALU将从寄存器堆rs1单元中读出的数据与符号扩展后的指令低16位值相加;4.)ALU的运算结果被写入寄存器堆,由rt确定写入的寄存器堆存储单元地址。
图2 I 指令(除lw、sw和分支指令)数据通路3、Lw指令数据通路如图3:1.)从指令寄存器Instr Mem中取出指令,同时PC增值(即加1等待下个CLK到来);2.)寄存器单元rs1的内容从寄存器堆Reg File中读出;3.)ALU将从寄存器堆rs1单元中读出的数据与符号扩展后的指令低16位值相加;4.)将ALU的运算结果作为数据存贮器的地址读出相应单元的内容;5)把从数据存储单元取出的数据写入寄存器堆,由rt确定写入的寄存器存储单元地址。
mips单周期cpu课程设计
mips单周期cpu课程设计一、课程目标知识目标:1. 掌握MIPS单周期CPU的基本结构和工作原理;2. 了解指令集、指令执行过程和指令周期;3. 学会分析并设计简单的MIPS指令;4. 理解CPU性能指标,如时钟频率、吞吐率等。
技能目标:1. 能够运用硬件描述语言(如Verilog)进行单周期CPU的设计与仿真;2. 能够独立编写简单的MIPS汇编程序,并在单周期CPU上运行;3. 能够分析单周期CPU的性能,并进行优化;4. 培养学生的团队合作能力和问题解决能力。
情感态度价值观目标:1. 培养学生对计算机组成原理和硬件设计的兴趣,激发学生的创新意识;2. 增强学生的工程素养,使其认识到工程实践在计算机科学领域的重要性;3. 培养学生严谨、细致、负责任的科学态度,提高学生的自主学习能力。
本课程针对高中年级学生,课程性质为实践性较强的硬件课程。
结合学生特点,课程目标注重理论与实践相结合,通过设计单周期CPU,使学生深入理解计算机硬件原理,提高实践能力。
在教学要求上,注重培养学生的团队合作精神,提高学生分析和解决问题的能力,为后续计算机组成原理及相关课程打下坚实基础。
通过本课程的学习,学生将能够独立完成单周期CPU的设计与仿真,具备一定的硬件编程能力。
二、教学内容1. 引言:介绍CPU在计算机系统中的作用,引出MIPS单周期CPU的概念及其重要性。
相关教材章节:第一章 计算机系统概述2. MIPS单周期CPU基本结构:讲解CPU的基本组成部分,包括寄存器组、控制单元、算术逻辑单元(ALU)、数据通路等。
相关教材章节:第二章 计算机组成原理3. 指令集与指令执行:分析MIPS指令集特点,讲解指令执行过程和指令周期。
相关教材章节:第三章 指令系统4. 硬件描述语言与单周期CPU设计:介绍Verilog硬件描述语言,通过实例讲解如何使用Verilog设计单周期CPU。
相关教材章节:第四章 硬件描述语言与数字电路设计5. 单周期CPU仿真与优化:指导学生进行单周期CPU的仿真,分析性能瓶颈,探讨优化方案。
单总线CPU设计(定长指令周期3级时序)
单总线CPU设计(定长指令周期3级时序)1. 引言本文档将介绍一种基于单总线的CPU设计,采用定长指令周期和3级时序。
单总线CPU是一种较为简单且常见的计算机处理器设计,其内部结构相对简单,适合于一些资源受限的嵌入式系统或低功耗应用。
定长指令周期意味着每条指令的执行时间是固定的,而3级时序则指的是CPU的时序由三个阶段组成。
2. 设计概述2.1 总体结构单总线CPU设计采用冯·诺依曼结构,主要包含以下几个核心组件:•控制器(Controller):负责控制指令的执行流程和时序控制。
•运算器(ALU):负责执行算术、逻辑和位操作指令。
•寄存器组(Register File):用于暂存数据和地址等信息。
•存储器(Memory):包括指令存储器和数据存储器。
•输入/输出接口(I/O Interface):负责与外部设备进行通信。
2.2 指令格式单总线CPU设计采用定长指令格式,每条指令由固定长度的几个字段组成。
常见的指令格式包括操作码(Opcode)、目标寄存器(Destination Register)、源操作数1(Source Operand 1)和源操作数2(Source Operand 2)等。
例如,对于一条简单的加法指令,其指令格式如下:| Opcode (6 bits) | Destination Register (4 bi ts) | Source Operand 1 (4 bits) | Source Operand 2 (4 bits) |2.3 时序控制单总线CPU设计采用3级时序,将指令执行过程划分为三个阶段:取指(Fetch)、译码(Decode)和执行(Execute)。
每个阶段占据一个时钟周期,遵循时序控制的规则。
取指阶段:从指令存储器中读取指令,存放到指令寄存器中。
译码阶段:解析当前指令的操作码和操作数,并从寄存器组中读取相关数据。
执行阶段:根据操作码和操作数执行相应的操作,将结果存储到寄存器组中。
【最新】CPU实验——单周期MIPS处理器设计
单周期MIPS处理器设计实验报告完成人:笪腾飞2012011263一、实验目的1、设计一个32位的单周期MIPS处理器,具备定时器、数码管等外设;2、编写一个编译器,可以将mips代码编译为二进制机器码;3、编写一个计算两个整数的最大公约数的汇编程序。
二、设计方案根据理论课所学的单周期MIPS处理器数据通路的知识,结合本次试验的具体要求,最终设计方案如下:1、系统时钟为了综合后能够在开发板上正确运行程序,我们决定采取50MHz的CPU时钟,因此编写了一个时钟分频模块,对开发板提供的100MHz时钟进行二分频,从而得到50MHz时钟。
2、PC产生模块原理图如下:如上图左半部分所示,多路选择器由一个always语句中的if…else if…else语句实现。
其中,将ALU中的加减法部分提取出来实现一个加法器,用于产生PC+4和ConBA两个PC来源。
将I型指令中的16位立即数左移两位后再符号位j m扩展成32位地址,与PC+4相加得到分支地址ConBA 。
将跳转指令中的26位目标地址左移两位后,与当前PC的高四位拼接得到跳转地址JT。
将第一个操作数寄存器中的值取出作为PC的一个输入,这是为了实现jr和jalr指令,从$Xp和$Ra寄存器中读取跳转地址。
ILLOP和XADR分别是发生中断和异常时的跳转地址。
下一指令地址的选择由PCSrc决定,而PCSrc是译码后由控制信号模块根据每条指令的操作码(opcode)和函数码(funct)产生。
3、译码模块原理图如上图右半部分所示,将PC作为ROM模块的地址输入,输出即为PC所对应的指令。
分别取出指令中的某些片段,得到$Rs,$Rt,$Rd,shamt,funct,16位立即数和26位跳转地址。
4、控制模块控制模块即控制信号产生模块,六位操作码OpCode,六位函数码[5:0] Funct,定时器中断信号irq和PC最高位PC31作为输入,输出为以下控制信号:(1) R型指令指示信号IsR,值为1表示当前指令为R型指令,否则非R型指令;(2) PC产生的选择信号[2:0] PCSrc,取值0,1,2,3,4及其它,分别选择下一指令不同的PC;(3) 目的寄存器选择信号[1:0]RegDst,被写入的寄存器有四种选择:$Rd,$Rt,$Ra,$Xp,分别由RegDst不同取值完成选择;(4) 写寄存器使能信号RegWr,值为1表示允许对寄存器进行写操作;(5) ALU第一个操作数选择信号ALUSrc1,值为1表示选择将移位量shamt 进行0扩展后作为输入,值为0表示将$Rs寄存器中的值作为输入;(6) ALU第一个操作数选择信号ALUSrc1,值为1表示选择将扩展后的32位立即数作为输入,值为0表示将$Rt寄存器中的值作为输入;(7) ALU运算控制信号[5:0] ALUFunc,作为ALU的输入选择不同的运算操作;(8) 有无符号数指示信号Sign,值为1表示有符号数,值为0表示无符号数;(9) 写存储器使能信号MemWr,值为1表示允许对存储器进行写操作;(10) 读存储器使能信号MemRd,值为1表示允许对存储器进行读操作;(11) 写寄存器值的选择信号[1:0] MemToReg,选择ALU结果,存储器读取结果和PC+4其中之一作为写入目的寄存器的值;(12) 符号位扩展指示信号EXTOp,值为1表示对16位立即数进行符号位扩展,值为0表示0扩展;(13) 立即数高位取指令指示信号LUOp,值为1表示当前指令为lui指令,选择将立即数载入高16位低位填0的32位立即数作为ALU输入,值为0表示将正常扩展后的32位立即数作为ALU输入;控制信号的具体产生过程此处略去,在控制信号说明文件中进行详述。
单周期处理器控制器设计
ALUControl2:0 ALUSrc RegDst
RegWrite
CLK
WE3
25:21 A1
RD1
SrcA
20:16 A2
RD2
A3 WD3 Register
File
20:16
0
15:11
1
WriteReg4:0
SignImm
15:0
Sign Extend
0 SrcB 1
<<2
ALU
PCSrc
RD Instr
Instruction Memory
+
PCPlus4 4
MemtoReg
控制器 MemWrite
31:26 Op 5:0 Funct
Branch ALUControl2:0
ALUSrc RegDst
RegWrite
CLK
1
25:21 A1
WE3 RD1
20:16 A2
RD2
A3
WD3 Register
A
B
N
N
ALU 3 F
N Y
ALU功能表
F2:0
功能
000 A & B
001
A |B
010 A + B
011 not used
100 A & ~B
101 A | ~B
110
A -B
111
SLT
控制单元主译码器
Instruction
R-type lw sw beq
Op5:0
000000 100011 101011 000100
RegWrite
1 1 0 0
MIPS单周期CPU实验报告
MIPS单周期CPU实验报告一、实验目标本次实验的主要目标是设计并实现一个基于MIPS单周期CPU的计算机系统。
具体要求如下:1.能够识别并执行MIPS指令集中的常见指令,包括算术逻辑运算、分支跳转和存取指令等。
2.实现基本的流水线结构,包括指令译码阶段、执行阶段、访存阶段和写回阶段。
3.能够在基本结构的基础上添加异常处理和浮点数运算支持。
二、实验环境三、实验过程1.确定CPU的基本组成部分,包括指令存储器、数据存储器、寄存器、ALU和控制单元等,并进行电路设计。
2.编写MIPS汇编程序,并使用MARS进行仿真调试,验证指令的正确性和计算结果的准确性。
3.将MIPS汇编程序烧录到指令存储器中,并将数据存储器中的初始数据加载进去。
4.运行程序,观察CPU的工作状态,并进行时序仿真,验证CPU设计的正确性。
5.对CPU进行性能测试,包括执行时间、指令吞吐量和时钟周期等指标的测量。
四、实验结果经过实验和测试,我们成功地设计并实现了一个基于MIPS单周期CPU的计算机系统。
该系统能够正确执行MIPS指令集中的常见指令,并支持流水线结构、异常处理和浮点数运算。
1.指令执行的正确性:通过在MARS中进行调试和仿真,我们发现CPU能够正确地执行各种指令,包括算术逻辑运算、分支跳转和存取指令等。
并且,在时序仿真中,CPU的各个组件的信号波形也符合预期。
2.流水线结构的实现:我们根据MIPS指令的特点和处理流程,设计了基本的流水线结构,并在MARS中进行了时序仿真。
仿真结果表明,各个流水线级的操作都能够正确无误地进行,并且能够顺利地在一个时钟周期内完成。
3.异常处理和浮点数运算的支持:通过在MIPS汇编程序中加入异常处理和浮点数运算的指令,我们验证了CPU对这些功能的支持。
在异常处理时,CPU能够正确地转入异常处理程序,并根据异常类型进行相应的处理。
在浮点数运算时,CPU能够正确地进行浮点数的加减乘除等运算,并将结果正确地写回寄存器。
单总线CPU设计(定长指令周期3级时序)
单总线CPU设计(定长指令周期3级时序)通过本文档,读者将了解到单总线CPU设计的原理和优势。
我们将深入讨论定长指令周期3级时序的设计方案,介绍每个时序阶段的功能和操作流程。
读者还将了解到如何实现基本的指令集和数据传输机制,以及如何优化CPU性能和响应速度。
无论您是初学者还是有经验的工程师,阅读本文档都会对您的CPU设计能力和理解有所帮助。
希望本文档能为您提供有价值的信息和指导,让您在单总线CPU设计领域取得更多成功!本文档旨在概述单总线CPU的体系结构,包括寄存器、算术逻辑单元等。
本文详细描述了单总线CPU的定长指令周期3级时序设计。
单总线CPU指的是只有一个总线用于数据和指令传输的中央处理器。
第一级时序设计第一级时序设计主要涉及指令的取指和解码阶段。
在每个指令周期中,CPU首先从存储器中取得指令,并将其送入指令寄存器中。
接着,CPU对指令进行解码,确定指令所对应的操作并为执行做好准备。
第二级时序设计第二级时序设计包括指令的执行阶段。
在每个指令周期中,CPU根据第一级的解码结果进行相应操作,比如进行算术运算、逻辑运算或者数据传输。
执行阶段的时序设计需要保证每个操作可以按照正确的顺序进行。
第三级时序设计第三级时序设计涉及指令的写回阶段。
在每个指令周期中,CPU将执行结果写回到寄存器或存储器中。
这个阶段的时序设计需要保证写回操作不会影响到其他指令的执行。
总的来说,单总线CPU的定长指令周期3级时序设计包括指令取指与解码、指令执行和指令写回三个阶段。
每个阶段的时序设计都需要注意保证操作按照正确的顺序进行,以确保CPU的正常运行。
总的来说,单总线CPU的定长指令周期3级时序设计包括指令取指与解码、指令执行和指令写回三个阶段。
每个阶段的时序设计都需要注意保证操作按照正确的顺序进行,以确保CPU的正常运行。
单周期MIPS CPU实验(8条指令)
单周期M I P S C P U设计实验目的⏹掌握硬布线控制器设计的基本原理⏹能利用相关原理在Logisim平台中设计实现MIPS单周期CPU⏹主要任务☐绘制MIPS CPU数据通路☐实现单周期硬布线控制器☐测试联调核心指令集(可实现内存区域冒泡排序)#MIPS指令RTL功能描述1add$rd,$rs,$rt R[$rd]←R[$rs]+R[$rt]溢出时产生异常,且不修改R[$rd] 2slt$rd,$rs,$rt R[$rd]←R[$rs]<R[$rt]小于置1,有符号比较3addi$rt,$rs,imm R[$rt]←R[$rs]+SignExt(imm)溢出产生异常16b4lw$rt,imm($rs)R[$rt]←Mem4B(R[$rs]+SignExt16b(imm))5sw$rt,imm($rs)Mem4B(R[$rs]+SignExt16b(imm))←R[$rt]6beq$rs,$rt,imm if(R[$rs]=R[$rt])PC←PC+SignExt18b({imm,00})7bne$rs,$rt,imm if(R[$rs]!=R[$rt])PC←PC+SignExt18b({imm,00})8syscall系统调用,这里用于停机单周期MIPS 参考数据通路MemtoReg MemWrite Branch AluOP ALUSrc RegDstRegWritePCSrcCLKPCRDA指令存储器指令字4PC+45:020:1625:2115:1115:0Sign ExtendSignImmR1#R2#W#WDWE 寄存器堆R1R2101011<<2+PCBranchSrcB SrcA EqualA L UALUResult WriteDataWERD A 数据存储器WD ReadData WriteBackData++BranchAddress31:26CLK CLKPC+4控制器FuncOp rsrtrd步骤1:构建MIPS主机通路⏹在MIPS单周期CPU子电路中,利用如下组件构建MIPS 单周期CPU数据通路☐PC、IMEM、RegFile、ALU、DMEM、Controller步骤2:设计单周期MIPS控制器⏹输入信号⏹指令字Opcode,Func字段(12位)⏹输出信号⏹多路选择器选择信号⏹内存访问控制信号⏹寄存器写使能信号⏹运算器控制信号、指令译码信号⏹纯组合逻辑电路、无时序逻辑控制信号功能说明(8条核心指令集)#控制信号信号说明产生条件1MemToReg写入寄存器的数据来自存储器lw指令2MemWrite写内存控制信号sw指令未单独设置MemRead信号3Beq Beq指令译码信号Beq指令4Bne Bne指令译码信号Bne指令5AluOP运算器操作控制符加法,比较两种运算6AluSrcB运算器第二输入选择Lw指令,sw指令,addi7RegWrite寄存器写使能控制信号寄存器写回信号8RegDst写入寄存器选择控制信号R型指令9Halt停机信号,取反后控制PC使能端syscall指令完善硬布线控制器内部逻辑⏹打开CPU.circ打开单周期硬布线控制器电路⏹实现指令译码、ALU控制逻辑完善控制信号逻辑⏹增加简单的组合逻辑⏹根据给出的指令译码信号,实现所有控制信号逻辑步骤3:CPU测试⏹在指令存储器中载入排序程序sort.hex⏹时钟自动仿真,Windows:Ctrl+k Mac: command+k运行程序⏹程序停机后,查看数据存储器中排序情况,有符号降序排列下节课再见…。
MIPS指令单周期CPU设计
rd rs rt imm
sw rt rs imm Addr = R[rs] + SignExt(imm) MEM[Addr] = R[rt]
PC
Register File
ALU
+4
Data memory
4. MIPS指令——BEQ
比较指令BEQ
– beq rs rt imm
Phase 5: Register Write (WB for “write back”)
– Write the instruction result back into the Register File – Those that don’t (e.g. sw, j, beq) remain idle or skip this phase
– if R[rs] = R[rt] – then PC (PC +4)+ SignExt(imm) – Else PC PC+4
instruction memory rd rs rt imm MUX
PC
Register File
ALU
+4
Data memory
5. MIPS指令——Jump
Data memory
rd rs rt
Register File
PC
单周期CPU设计思路
指令的行
– 显然要设计一个时序逻辑电路 – 一条指令用一个CPU周期完成
执行步骤的实现
– 取指:从指令存储器中读指令(地址:PC)
– 读出一或两个源寄存器的值(寄存器组)
– 进行指令规定的运算(ALU) – 读/写数据存储器
– Zero extend imm16? – Pass imm16 to input of ALU? – Write result to rt?
单周期RISC处理器KMIPS说明文档
单周期RISC处理器KMIPS说明文档作者:老邹zbzou_xy@ KMIPS下载/s/1nt2zT3r这个设计参照了网络上的一些资料,修改了设计,现在已经能够正确执行lw、sw、and、or、add、sub、addi、beq和bne九条指令,如果需要扩充部分指令,修改controler和alu 设计就可以了,比较方便。
【适合CPU设计初学者】下面就介绍一下,这个工程的设计、仿真和验证方法。
工程目录说明如下:VHDL:设计的源文件ISE :ISE的工程文件、CoreGen产生的ROM和RAM、约束文件MIPS.ucfTB : 测试文件MSIM:ModelSim仿真要使用的文件DOC :项目说明文档CODE:测试汇编程序及相应的COE文件1.设计整个设计是按照下面的框图进行设计的:设计思想基本上是从《计算机组成与设计硬件/软件接口3版》第五章上来的,只是ALU控制部分放在了ALU里面,以后有时间再改个一样的。
每个模块对应一个设计文件,对应关系如下:2.仿真2.1说明1、仿真环境使用的是ModelSimSE 6.1f。
2、仿真使用的文件放在MSIM目录中,有三个文件:compile.do、sim.do和wave.do。
compile.do设置了要编译的文件,wave.do设置了要加入波形窗口的信号及显示方式,sim.do 设置了仿真需要的命令。
3、测试要使用的文件放在目录TB中,有MIPS.vhd(顶层文件,为了便于仿真,没有使用分频模块)、myeDmem.vhd(数据存储器,加了读使能信号)、ram.vhd(可以在ISE 下综合的ram)、myeImem.vhd(指令寄存器,要执行的指令都定义在此。
因为是16进制MIPS指令代码,很难看懂,所以要了解代码对应的程序,请看CODE目录下的all_instr.asm 文件)和test_kmips.vhd(testbench)。
2.2仿真步骤1、启动ModelSim后,改变工作目录(File Change Directory)到目录KMIPS_OK\MSIM 中,在命令窗口运行do compile.do(编译工程需要的设计文件),这样需要的设计文件就加入到库WORK中,如图所示:2、在命令窗口运行do sim.do,就开始仿真,并得到相应的仿真波形。
计算机组成原理-第11章 MIPS处理器设计(单周期、多周期)1 [兼容模式]
llxx@
12
A conceptual view – computational instructions
• Both source
operands and
Read data 2
Register File
Datapath Control Points
RegWrite (“write enable” control point)
寄存器号 Instruction
R-type指令的执行
Read
register 1
Read
Read
data 1
register 2
– beq为相对寻址:以npc为基准,指令中的 target为16位,进行32位有符号扩展后左移两 位(补“00”,字对准)。
– jump为pseudodirect:指令中的target为26位, 而PC为32位。将target左移2位拼装在PC的低 28位上,PC高4位保持不变。
J-type
op(6 bits) rs(5 bits) rt(5 bits) op(6 bits)
data
16 Sign 32 extend
I-type
MemRead
R-type
llxx@
22
Instruction
条件转移beq
PC + 4 from instruction datapath
Add Sum
Branch target
Read
register 1
Read
Read
rt:ld的目的,sw的源
P3-Logisim开发单周期CPU
九、
开发与调试技巧
26. 对于每条指令,请认真阅读《MIPS32® Architecture For Programmers Volume II: The MIPS32® Instruction Set》 ! a) 如果测试时,你无法清楚的解释所要求的指令,测试成绩将减一档! 27. 上的《M_G06B2830: 数字系统设计工具集》中有关 于 logisim 使用的课程,请学习之。 28. Figure1 中 Tunnel 的用途是将具有相同 name 的 tunnel 连接在一起。Tunnel 可以避免将图画的很乱。 29. Figure1 中 Probe 的用途是显示被 probed 信号的值,便于调试。 30. Figure1 中 Splitter 的用途是从某组信号中提取其中部分信号。例如,IFU 输 出 32 位指令, 需要提取高 6 位(OpCode)和低 6 位(Funct)分别输入 controller。 a) splitter 是有位序的! 但字号太小, 需要放大设计图(界面左下有比例设置)。 b) 建议高位永远在上,低位永远在下 31. 如果你对于 logisim 内置的某个部件的端口不明白,请: a) 仔细阅读 HelpLibrary Refrence 关于该部件的描述。 b) 放大 logisim 显示比例直至能清晰看到代表部件的各个端口的圆点, 然后 将鼠标停留相应的圆点上,就可以读取端口具体信息。 32. 建议先在 MARS 中编写测试程序并调试通过。 a) 注意 MARS 中的“SettingsMemory Configuration”只能配置指令存储器 起始地址为 0 地址,而不能将指令存储器和数据存储器的起始地址均配
定顺序取值令还是转移取值令。 (2) 模块接口
信号名 IfBeq 方向 I 描述 当前指令是否为 beq 指令标志。 1:当前指令为 beq 0:当前指令非 beq ALU 计算结果为 0 标志。 1:计算结果为 0 0:计算结果非 0 时钟信号 复位信号。 1:复位 0:无效 32 位 MIPS 指令
MIPS单周期CPU实验报告
《计算机组成原理实验》实验报告(实验二)学院名称:专业(班级):学生姓名:学号:时间:2017 年11 月25 日成绩: 实验二:单周期CPU设计与实现一.实验目的(1) 掌握单周期CPU数据通路图的构成、原理及其设计方法;(2) 掌握单周期CPU的实现方法,代码实现方法;(3) 认识和掌握指令与CPU的关系;(4) 掌握测试单周期CPU的方法;(5) 掌握单周期CPU的实现方法。
二.实验内容设计一个单周期的MIPSCPU,使其能实现下列指令:==> 算术运算指令==> 逻辑运算指令功能:rd←rs | rt;逻辑或运算。
==>移位指令==>比较指令==> 存储器读/写指令将rt寄存器的内容保存到rs寄存器内容和立即数符号扩展后的数相加作为地址的内存单元中。
即读取rs寄存器内容和立即数符号扩展后的数相加作为地址的内存单元中的数,然后保存到rt寄存器中。
==> 分支指令功能:if(rs=rt) pc←pc + 4 + (sign-extend)immediate <<2 else pc ←pc + 4特别说明:immediate是从PC+4地址开始和转移到的指令之间指令条数。
immediate 符号扩展之后左移2位再相加。
为什么要左移2位?由于跳转到的指令地址肯定是4的倍数(每条指令占4个字节),最低两位是“00”,因此将immediate放进指令码中的时候,是右移了2位的,也就是以上说的“指令之间指令条数”。
12特别说明:与beq不同点是,不等时转移,相等时顺序执行。
功能:if(rs>0) pc←pc + 4 + (sign-extend)immediate <<2 else pc ←pc + 4==>跳转指令==> 停机指令三.实验原理1.时间周期:单周期CPU指的是一条指令的执行在一个时钟周期内完成,然后开始下一条指令的执行,即一条指令用一个时钟周期完成。
单周期CPU——verilog语言实现
单周期CPU——verilog语⾔实现⼀. 实验内容设计⼀个单周期CPU,要求:1. 实现MIPS的20条指令2. 在该CPU上实现斐波那契函数计算机每执⾏⼀条指令都可分为三个阶段进⾏。
即取指令(IF)——>分析指令(ID)——>执⾏指令(EXE)取指令:根据程序计数器PC中的指令地址,从存储器中取出⼀条指令,同时,根据控制信号,决定选择某个来源的指令地址作为下⼀条指令的地址。
分析指令:对取指令操作中得到的指令进⾏分析并译码,确定这条指令需要完成的操作,从⽽产⽣相应的操作控制信号,⽤于驱动执⾏状态中的各种操作。
执⾏指令:根据指令译码得到的操作控制信号,具体地执⾏指令动作。
⼆. 20条指令的情况R指令I指令J指令三. 取指令(IF)的相关模块代码//PCmodule PC(input [31:0] next_addr,input rst,input clk,output reg [31:0] addr);always @(posedge clk)beginif(rst==1'b1)beginaddr<=next_addr;endelsebeginaddr<=32'b0;endendinitial$monitor($time,,"PC:addr=%h",addr);endmodule//ROMmodule rom(input [31:0] addr,output [31:0] data);reg[31:0] romdata;always @(*)case(addr[31:2])4'h0:romdata=32'b10001100000000110000000000100000; //lw $0,$3,32 *4'h1:romdata=32'b00110100000100000000000000000010; //ori $0,$16,2 *4'h2:romdata=32'b00000000000000111000100000100101; //or $0,$3,$17 * 4'h3:romdata=32'b00110100000100110000000000000001; //ori $0,$19,1 *4'h4:romdata=32'b00110100000001000000000000000001; //ori $0,$4,1 *4'h5:romdata=32'b00010010001100110000000000001011; //beq $17,$19,11 * 4'h6:romdata=32'b00000000000001000100000000100101; //or $0,$4,$8 *4'h7:romdata=32'b00100010011100110000000000000001; //addi $19,$19,1 * 4'h8:romdata=32'b00110100000001000000000000000001; //ori $0,$4,1 *4'h9:romdata=32'b00010010001100110000000000000111; //beq $17,$19,7 * 4'ha:romdata=32'b00000000000001000100100000100101; //or $0,$4,$9 * 4'hb:romdata=32'b00000001000010010010000000100000; //add $8,$9,$4 * 4'hc:romdata=32'b00000000000010010100000000100101; //or $0,$9,$8 *4'hd:romdata=32'b00000000000001000100100000100101; //or $0,$4,$9 *4'he:romdata=32'b00100010000100000000000000000001; //addi $16,$16,1 * 4'hf:romdata=32'b00010110000100011111111111111011; //bne $16,$17,-5 * default:romdata=32'b10101100000001000000000000010000; //sw $0,$4,16 endcaseassign data=romdata;initial$monitor($time,,"rom:romdata=%h",romdata);endmodule//Selectormodule selector(input [31:0] addr0,input [31:0] addr1,input [31:0] addr2,input [31:0] addr3,input [1:0] pcsource,output reg [31:0] next_addr);always @(*)begincase(pcsource)2'b00:beginnext_addr=addr0;end2'b01:beginnext_addr=addr1; //bne,beqend2'b10:beginnext_addr=addr2; //jend2'b11:beginnext_addr=addr3; //jal,jrendendcaseendinitial$monitor($time,,"selector: pcsource=%h, next_addr=%h",pcsource,next_addr); endmodule四. 所使⽤的控制信号pcindex: pc值的来源ram2reg: 是否将数据从RAM写⼊到寄存器中,=1为是,否则为否ramWE: 是否写内存,=1为是,否则为否aluOP: ALU的运算类型regWE: 是否写寄存器,=1为是,否则为否imm: 是否产⽣⽴即数,=1为是,否则为否shift: 是否移位,=1为是,否则为否isrt: ⽬的寄存器地址,=1选择rt,否则选择rdsign_ext: ⽴即数拓展,=1为符号数拓展,否则为零拓展jal: 是否调⽤⼦程序跳转,=1为是,否则为否五. 各指令对应产⽣的控制信号pcindex ram2reg ramWE aluOP regWE imm shift isrt sign_ext jal add 0 0 0 0001 1 0 00 00 sub 0 0 0 0010 1 0 0 0 0 0 and 0 0 0 00111 0 00 0 0 or0 0 0 0100 1 0 0 0 0 0 xor0 0 0 01011 0 0 0 0 0 sll0 0 0 01101 0 1 1 0 0 srl0 0 0 01111 0 1 1 0 0 sra0 0 0 1000 1 0 1 1 0 0 jr10 0 0 0 0 0 0 0 0 0 addi0 0 0 00011 1 0 1 1 0 andi0 0 0 0011 1 1 0 1 0 0 ori0 0 0 01001 1 0 1 0 0 xori0 0 0 01011 1 0 1 0 0 lw0 1 0 0001 1 1 0 1 1 0 sw 0 0 1 000101 0 1 1 0 beq00/01 0 0 00100 0 0 0 1 0 bne00/01 0 0 0010 0 0 0 0 1 0 lui 0 0 0 100111 0 1 0 0 j 11 0 0 00 0 0 0 0 0 jal 11 0 0 01 0 0 0 0 1六. 分析指令(ID)相关模块代码//IDmodule ID(input [31:0] instrument,output reg [5:0] opcode,output reg [5:0] func,output reg [4:0] rs,output reg [4:0] rt,output reg [4:0] rd,output reg [4:0] sa,output reg [15:0] immediate,output reg [25:0] addr);always @(*)beginopcode=instrument[31:26];rs=5'b0;rt=5'b0;rd=5'b0;sa=5'b0;immediate=16'b0;addr=25'b0;case(opcode)6'b000000: //R类型beginfunc=instrument[5:0];sa=instrument[10:6];rd=instrument[15:11];rt=instrument[20:16];rs=instrument[25:21];end6'b001000,6'b001100,6'b001101,6'b001110,6'b100011,6'b101011,6'b000100,6'b000101,6'b001111: beginimmediate=instrument[15:0];rt=instrument[20:16];rs=instrument[25:21];end6'b000010,6'b000011:beginaddr=instrument[25:0];enddefault: rs=5'b00000;endcaseendendmodule//CUmodule CU(input [5:0] opcode,input [5:0] func,input z,output reg [1:0] pcindex,output reg ram2reg,output reg ramWE,output reg [3:0] aluOP,output reg regWE,output reg imm,output reg shift,output reg isrt,output reg sign_ext,output reg jal);always @(*)begin//设置默认值shift=1'b0;ram2reg=1'b0;ramWE=1'b0;regWE=1'b0;imm=1'b0;isrt=1'b0;sign_ext=1'b0;pcindex=2'b00;aluOP=4'b0000;jal=1'b0;case(opcode)//R指令6'b000000:begincase(func)6'b100000: //add指令beginaluOP=4'b0001;regWE=1'b1;end6'b100010: //sub指令beginaluOP=4'b0010;regWE=1'b1;end6'b100100: //and指令beginaluOP=4'b0011;regWE=1'b1;end6'b100101: //or指令beginaluOP=4'b0100;regWE=1'b1;end6'b100110: //xor指令beginaluOP=4'b0101;regWE=1'b1;end6'b000000: //sll指令beginaluOP=4'b0110; regWE=1'b1;shift=1'b1;isrt=1'b1;end6'b000010: //srl指令beginaluOP=4'b0111; regWE=1'b1;shift=1'b1;isrt=1'b1;end6'b000011: //sra指令beginaluOP=4'b1000; regWE=1'b1;shift=1'b1;isrt=1'b1;end6'b001000: //jr指令beginpcindex=2'b10;endendcaseend//I指令6'b001000: //addi指令beginaluOP=4'b0001;imm=1'b1;regWE=1'b1;sign_ext=1'b1;isrt=1'b1;end6'b001100: //andi指令beginaluOP=4'b0011;imm=1'b1;regWE=1'b1;isrt=1'b1;end6'b001101: //ori指令beginaluOP=4'b0100;imm=1'b1;regWE=1'b1;isrt=1'b1;end6'b001110: //xori指令beginaluOP=4'b0101;imm=1'b1;regWE=1'b1;isrt=1'b1;end6'b100011: //lw指令beginram2reg=1'b1;aluOP=4'b0001;imm=1'b1;regWE=1'b1;sign_ext=1'b1;isrt=1'b1;end6'b101011: //sw指令beginramWE=1'b1;aluOP=4'b0001;imm=1'b1;sign_ext=1'b1;isrt=1'b1;end6'b000100: //beq指令beginaluOP=4'b0010;sign_ext=1'b1;if(z==1'b1)beginpcindex=2'b01;endend6'b000101: //bne指令beginaluOP=4'b0010;sign_ext=1'b1;if(z==1'b0)beginpcindex=2'b01;endend6'b001111: //lui指令beginregWE=1'b1;imm=1'b1;isrt=1'b1;aluOP=4'b1001;end//J指令6'b000010: //j指令beginpcindex=2'b11;end6'b000011: //jal指令beginjal=1'b1;regWE=1'b1;pcindex=2'b11;endendcaseendinitial$monitor($time,,"CU:imm=%b,op=%h, isrt=%h, pcindex=%h, regWE=%h, shift=%h, ram2reg=%h, ramWE=%h ",imm,aluOP,isrt,pcindex,regWE,shift,ram2reg,ramWE); endmodule七. 总体电路图⼋. 执⾏指令(EXE)相关模块的代码//selector_5module selector_5(input [4:0] a,input [4:0] b,input choice,output [4:0] f);assign f=(choice==1'b0)?a:b;initial$monitor($time,,"selector_5: a=%h, b=%h, f=%h",a,b,f);endmodule//selector_32module selector_32(input [31:0] a,input [31:0] b,input choice,output [31:0] f);assign f=(choice==1'b0)?a:b;initial$monitor($time,,"selector_32: f=%h",f);endmodule//ext_immmodule ext_imm(input [15:0] immediate,input sign_ext,output [31:0] imm);//sign_ext为1时,有符号拓展;为0时,0拓展assign imm=(sign_ext==0)?{{16{1'b0}},immediate}:{{16{immediate[15]}},immediate}; initial$monitor($time,,"ext_imm: imm=%h",imm);endmodule//alu_add_4module alu_add_4(input [31:0] a,output [31:0] f);assign f=a+32'b0100;initial$monitor($time,,"alu_add_4:f=%h",f);endmodule//registersmodule registers(input clk,input oc,input [4:0] raddr1,input [4:0] raddr2,input [4:0] waddr,input [31:0] wdata,input we,output reg [31:0] rdata1,output reg [31:0] rdata2);reg[31:0] regts[1:31];always @(*)beginif(oc==1'b1)beginrdata1=32'bz;endelse if(raddr1==5'b00000)beginrdata1=32'b0;endelsebeginrdata1=regts[raddr1];$monitor($time,,"Read R %d data1=%d",raddr1,rdata1); endalways @(*)beginif(oc==1'b1)beginrdata2=32'bz;endelse if(raddr2==5'b00000)beginrdata2=32'b0;endelsebeginrdata2=regts[raddr2];end$monitor($time,,"Read R %d data2=%d",raddr2,rdata2); endalways @(posedge clk)begin#1if((we==1'b1)&&(waddr!=5'b00000))beginregts[waddr]<=wdata;$monitor($time,,"write %h to data=%d",waddr,wdata);endendendmodule//isimmmodule isimm(input [31:0] rt,input [31:0] immediate,input imm,output [31:0] b);assign b=imm?immediate:rt;initial$monitor($time,,"isimm:b=%h",b);endmodule//ALUmodule alu(input [31:0] a,input [31:0] b,input [3:0] op,output [31:0] f,output z);reg [31:0]result;always@(*)begincase(op)4'b0000:result=32'b0;4'b0001:result=a+b;4'b0010:result=a-b;4'b0011:result=a&b;4'b0100:result=a|b;4'b0101:result=a^b;4'b0110:result=b<<a;4'b0111:result=b>>a;4'b1000:result=$signed(b)>>>a;4'b1001:result={b,{16{1'b0}}};default:result=32'b0;endcaseendassign f=result;assign z=~(|result);initial$monitor($time,,"alu:a:%h,b:%h,op:%h,",a,b,op);initial$monitor($time,,"alu:f:%h,z:%b",f,z);endmodulemodule IOManager(input [5:0] addr,input [31:0] din,output [31:0] dout,input we,input clk,input [3:0] switch,output reg[31:0] displaydata);reg [31:0] indata,outdata;wire [31:0] ramdout;wire ramWE;wire enable;assign enable=(|addr[5:4]);ram dram(addr[3:0],din,clk,enable,ramWE,ramdout);assign dout=(addr[5]==1'b1)?{{28{1'b0}},switch}:ramdout;assign ramWE=we&(~addr[4]);always @(posedge clk)beginif((addr[4]==1'b1)&&we)displaydata<=din;endinitial$monitor($time,,"IOM: addr=%h, din=%h, dout=%h",addr,din,dout); initial$monitor($time,,"IOM: switch=%h, displaydata=%h",switch,displaydata); endmodule//rammodule ram(input [3:0] addr,input [31:0] wdata,input clk,input ce,input we1,output reg[31:0] rdata);reg [31:0] ram[0:30];always @(*)beginif(ce==1'b0)beginrdata=ram[addr];endendalways @(posedge clk)begin#1if((ce==1'b0)&&(we1==1'b1))beginram[addr]<=wdata;endendinitial$monitor($time,,"ram: ram=%h,rdata=%h",ram[addr],rdata); endmodule//leftmodule left(input [31:0] a,output [31:0] b);assign b=a<<2;endmodule//alu_add_bmodule alu_add_b(input [31:0] addr,input [31:0] immediate,output [31:0] f);assign f=addr+immediate;initial$monitor($time,,"alu_add_b: addr=%h, immediate=%h, f=%h ",addr,immediate,f); endmodule//ext_addermodule ext_adder(input [25:0] address,output [27:0] f);assign f={address,{2{1'b0}}};initial$monitor($time,,"ext_addr: address=%h, f=%h ",address,f);endmodule//mixaddrmodule mixAddr(input [31:0] addr,input [27:0] address,output [31:0] f);assign f={{addr[31:28]},address};initial$monitor($time,,"mixAddr: addr=%h, address=%h, f=%h",addr,address,f);endmodule九. TOP⽂件代码1module top(2input clk,3input rst,4input [4:0] n,5output [31:0] result6 );78wire [31:0] next_addr;9wire [31:0] addr,addr0,addr1,addr2,addr3;10wire [31:0] immediate;11wire [27:0] fAddress;12wire [31:0] instrument;13wire [5:0] opcode,func;14wire [4:0] rs,rt,rd,sa;15wire [15:0] imm;16wire [25:0] address;17wire z;18wire [1:0] pcindex;19wire ram2reg,ramWE,regWE,isimm,shift,isrt,sign_ext,jal;20wire [3:0] aluOP;21wire [4:0] waddr;22wire [4:0] tmp_waddr;23wire [4:0] regs31=5'b11111;24wire [31:0] wdata,rdata1,rdata2,f,tmp_f;25wire oc=1'b0;26wire [31:0] a,b;27wire [31:0] dout;28wire [31:0] lImmediate;29wire [31:0] fsa;3031 PC myPC(next_addr,rst,clk,addr);32 rom myRom(addr,instrument);33 ID myID(instrument,opcode,func,rs,rt,rd,sa,imm,address);34 CU myCU(opcode,func,z,pcindex,ram2reg,ramWE,aluOP,regWE,isimm,shift,isrt,sign_ext,jal);35 ext_imm myExtImm(imm,sign_ext,immediate);36 selector_5 mySelector5_1(rd,rt,isrt,tmp_waddr); //⽬的寄存器是否rt37 selector_5 mySelector5_2(tmp_waddr,regs31,jal,waddr); //是否调⽤⼦程序调转wa38 alu_add_4 myAdd4(addr,addr0);39 selector_32 mySelector32_1(f,addr0,jal,wdata); //是否调⽤⼦程序调转wd40 registers myRegs(clk,oc,rs,rt,waddr,wdata,regWE,rdata1,rdata2);41 isimm myIsImm(rdata2,immediate,isimm,b);42assign fsa={{27{1'b0}},sa};43 selector_32 mySelector32_2(rdata1,fsa,shift,a); //选择sa和rs数据44 alu myAlu(a,b,aluOP,tmp_f,z);45 IOManager myIOM(tmp_f,rdata2,dout,ramWE,clk,n,result);46 selector_32 mySelector32_3(tmp_f,dout,ram2reg,f); //是否将数据从ram中写⼊reg47 left myLeft(immediate,lImmediate);48 alu_add_b myAddb(addr0,lImmediate,addr1);49 ext_adder myExtAddr(address,fAddress);50 mixAddr myMixAddr(addr,fAddress,addr3);51 selector mySelector(addr0,addr1,rdata1,addr3,pcindex,next_addr);525354initial55 $monitor($time,,"top: n=%h, result=%h",n,result);5657endmodule。
单周期CPU设计实验报告
《计算机组成原理与接口技术实验》实验报告学院名称:学生姓名:学号:专业(班级):合作者:时间:2016年4月25日成绩:实验二:一.实验目的1.掌握单周期CPU数据通路图的构成、原理及其设计方法;2.掌握单周期CPU的实现方法,代码实现方法;3.认识和掌握指令与CPU的关系;4.掌握测试单周期CPU的方法。
二.实验内容设计一个单周期CPU,该CPU至少能实现以下指令功能操作。
需设计的指令与格式如下:==> 算术运算指令说明:以助记符表示,是汇编指令;以代码表示,是机器指令功能:rd←rs + rt。
reserved为预留部分,即未用,一般填“0”。
功能:rt←rs + (sign-extend)immediate;immediate符号扩展再参加“加”运算。
完成功能:rd←rs - rt==> 逻辑运算指令做“0”扩展再参加“或”运算。
(5)and rd , rs , rt功能:rd←rs & rt;逻辑与运算。
==> 传送指令(7)move rd , rs功能:rd←rs + $0 ;$0=$zero=0。
==> 存储器读/写指令(8)sw rt ,immediate(rs) 写存储器功能:memory[rs+ (sign-extend)immediate]←rt;immediate符号扩展再相加。
(9) lw rt , immediate (rs) 读存储器功能:rt ← memory[rs + (sign-extend)immediate ];immediate 符号扩展再相加。
==> 分支指令(10)beq rs,rt,immediate功能:if(rs=rt) pc ←pc + 4 + (sign-extend)immediate <<2;特别说明:immediate 是从PC+4地址开始和转移到的指令之间指令条数。
immediate 符号扩展之后左移2位再相加。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
信息科学与工程学院课程设计报告课程名称:计算机组成原理与结构题目:单周期CPU逻辑设计年级/专业:XXXXXXXXXXXXXXX X 学生姓名:王侠侠、李怀民学号:XXXXXXXXXXXXXXXXXXX 指导老师:XXXX开始时间:2016年9月15日结束时间:2016年11月15日摘要一、设计目的与目标1.1 设计目的1.2 设计目标二、课程设计器材2.1 硬件平台2.2 软件平台三、CPU逻辑设计总体方案3.1 指令模块3.2 部件模块四、模块详细设计4.1 指令设计模块4.2 部件设计模块五、实验数据5.1 初始数据5.2 指令数据六、结论和体会七、参考文献本CPU设计实验以Quartus II 9.0为软件设计平台,以Cyclone 采III型号EP3C16F484C6为FPGA实测板。
此CPU设计采用模块化设计方案,首先设计指令格式模块,此模块决定CPU各个部件的接口数据容量及数量,再对CPU各个部件独立设计实现,主要涉及的部件有:寄存器组、控制器、存储器、PC计数器、数据选择器、ALU单元以及扩展单元。
分部件的设计通过软件平台模拟仿真各部件的功能,在确保各部件功能正确的情况下,将所有部件模块整合在一起实现16位指令的CPU功能。
再按照指令格式设计的要求,设计出一套能完整运行的指令,加载到指令存储器中,最终通过在FPGA实测板上实现了加2减1的循环运算效果,若要实现其他效果,也可更改指令存储器或数据存储器的数据而不需要对内部部件进行更改元件。
关键词:CPU设计、16位指令格式、模块化设计、Quartus软件、CPU各部件一、设计目的与目标1.1设计目的1)了解Quartus II软件的使用,学习软件环境下设计CPU的基本过程;2)在Quartus II平台上完成各个单元的设计,加深对每个单元(控制器、寄存器、存储器等)工作原理的理解;3)对各个单元组合而成的CPU进行指令测试,配合使用模拟仿真,了解指令和数据在各个单元中的传输过程及方向。
1.2设计目标1)设计一个单周期CPU,能实现基本的指令功能,如ADD,SUB指令实现对操作数加减功能,LW,SW指令实现从存储器取数和存数,J指令实现指令间的跳转。
2)采用模块化设计CPU,通过模拟仿真保证各模块的正确性,以保证最终CPU功能的正确性,能正确地在FPGA板上完成指令设计的效果。
3)通过设计合理的16位指令,实现从存储器取初始数和存数,对初始数进行加减操作,通过修改存储器初始数据,实现FPGA上LED显示无限加n减m 的效果。
二、课程设计器材2.1 硬件平台本实验所需的硬件主要有:PC微型计算机和FPGA板--Cyclone III系列,型号EP3C16U484C6实验开发板以及USB连接线。
2.2 软件平台1)操作系统:Win 7;2)开发平台:Quartus II 9.0集成开发软件;3)编程语言:VerilogHDL硬件描述语言。
三、 CPU逻辑设计总体方案单周期CPU设计方案从宏观上把握主要分为器件模块和指令/数据模块这两大模块,器件模块是指令模块的载体,指令数据在器件上流动,指令数据的格式是器件模块的主宰。
所以当设计CPU时,我们采用模块化设计,单独对着两模块进行设计,考虑到指令数据模块的格式决定指令器件模块接口的数据容量大小,所以应先完成指令数据模块的格式设计。
图1 CPU宏观设计方案3.1指令模块3.1.1指令格式简要设计本CPU实验是针对16位指令数据设计的,所以应当合理划分指令数据区间段的指令相应的功能。
从下图2可以看出,16位指令数据划分为5个区间段,指令的[15-12]位作为控制位传入控制器产生控制信号,指令[11-9]位作为地址1从寄存器取数输出数据到寄存器1号输出口,指令[8-6]位作为地址2从寄存器取数输出数据到寄存器2号输出口,指令[5-3]位与指令[8-6]位作为数据选择器选择地址输入寄存器写地址口,指令[5-0]位作为扩展单元输入,扩展数据成16位。
另外指令[11-0]位作为扩展输入,扩展成16位数据作为PC计数器的选择器一端。
图2 指令格式简要设计图3.2 器件单元模块此模块的设计是CPU设计的核心部分,它主要涉及到CPU中多个器件的设计。
我们依然采用模块设计方案,把总体设计拆分成多个相互独立的器件,再对每部分器件单独设计。
在此模块中包括:寄存器组、控制器、存储器、PC计数器、数据选择器、ALU单元这六大主要单元。
如下图2所示,展示出六大单元的设计方案以及六大单元之间的联系。
图3 器件模块设计方案图从上图我们可以看出各单元之间的联系:初始数据从数据存储器RAM中取出,通过两种数据传入方式:一种是不经过数据选择器,另一种是经过数据选择器,数据传入到寄存器组中作为寄存器数据。
而后当传入的是地址数据时,就从寄存器取出,经过ALU运算单元,将数据传入寄存器组中保存或传入数据存储器中保存。
在整个过程中,PC计数器自动加1作为地址去指令存储器ROM中取指令作为此轮执行的指令数据,而控制器在整个过程中依据指令数据的指令码产生相应的控制信号(操作码)控制器件的运作,从而完成整个CPU的执行功能。
下面我们将对主要的单元进行简要概述。
3.1.1寄存器组寄存器组是作为保存数据的器件,故应使用时钟触发的D触发器(DFFE),等待一个时钟到来将数据传出去。
本实验设计为16位CPU,故每个寄存器应为16位,即每个寄存器是由16个D触发器扩展而成。
考虑到指令从寄存器取数位数为3位,所以可以设置8个寄存器用于保存数据,如果是写地址的3位指令通过74138(3-8译码器)译码作为寄存器的有效EN使能端输出数据;如果是读地址的3位指令数据通过8位扩展数据选择器(LPM-MUX)选择数据输出。
3.1.2控制器控制器是作为CPU控制信号产生的器件,通过产生控制信号,使其他器件有效或无效,因此控制器的设计显得尤为重要。
控制器的设计主要如下:先必须自己设计好各功能指令的4位01码(指令的[15-12]),然后针对某个控制信号,找出使其为1的功能指令,对每个功能指令的0位上取非,然后4位相与,之后将所有为1的功能指令相或,结果作为此控制信号。
对每个控制信号执行重复操作,控制器也就是这些信号的组合。
3.1.3存储器存储器分为两种类型:一种是数据存储器RAM,另一种是地址存储器ROM。
考虑到设计的方便,否则使用寄存器设计存储器也是可行的。
3.1.3.1数据储存器数据存储器为RAM型,表示可读可写,所以数据储存器有4个端口,当写信号有效时,应给出写的地址及数据,再加上时钟信号,这里的数据存储器采用软件封装好的RAM-1-PORT存储器。
3.1.3.2指令存储器指令存储器为ROM型,表示只读,所以地址存储器有2个端口,应给出读的地址信号以及时钟信号这里的数据存储器采用软件封装好的ROM-1-PORT存储器。
3.1.4PC计数器PC计数器主要作为执行一条指令后,地址自动加1到指令存储器中取16位指令作为此轮操作。
故PC计数器应能等待一个时钟后将加1后的数据送至指令存取器中,所以它应包括ALU累加器(一端为1)和寄存器(当一个时钟信号到来,将数据输出),书中还包括一个数据选择器,用于设置PC的值,以至于不会无限增长,实现J指令。
3.1.5数据选择器数据选择器主要是解决数据来源问题,通过控制信号使数据选择器选择的数据端口不同,此数据选择器可选用软件封装的2选1选择器。
3.1.6ALU单元ALU单元主要用于将输入端的两个数做加减操作,通过控制信号01的变化产生运算,该ALU可以使用软件封装的加减ALU(LPM-ADD-SUB),当控制信号为1时作加法,为0时作减法。
3.1.7符号扩展单元符号扩展单元主要用于将不够16位的指令数据扩展成16位,作为输入数据的一端参与数据选择器运算,这里我们仅考虑最简单的扩展方式:将不足16位的指令数据由高位向低位依次补0直至数据长度为16位。
四、模块详细设计4.1指令设计模块4.1.1 指令处理流程一般来说,CPU在处理指令时需要经过以下几个过程:(1)取指令(IF):根据程序计数器PC中的指令地址,从指令存储器中取出一条指令,同时PC根据指令字长度自动递增产生下一条指令所需要的指令地址,但遇到“地址转移”指令时,则控制器把“转移地址”送入PC,当然得到的“地址”需要做些变换才送入PC。
(2)指令译码(ID):对取指令操作中得到的指令进行分析并译码,确定这条指令需要完成的操作,由指令的[15-12]位产生相应的操作控制信号,用于驱动执行状态中的各种操作。
(3)指令执行(EXE):根据指令译码得到的操作控制信号,具体地执行指令动作,然后转移到结果写回状态。
(4)存储器访问(MEM):所有需要访问存储器的操作都将在这个步骤中执行,该步骤给出存储器的数据地址,把数据写入到存储器中数据地址所指定的存储单元或者从存储器中得到数据地址单元中的数据。
(5)结果写回(WB):指令执行的结果或者访问存储器中得到的数据写回相应的目的寄存器中。
图4 单周期CPU指令处理过程4.1.2 指令格式详细设计本次CPU设计主要有5条功能指令,分别为ADD、SUB、LW、SW、J指令,对这5个功能指令的控制码分别设定为0101/0110/1001/0001/1010,现对5条指令各自的指令格式进行设计:寄存器的数相加,结果数据存放至rd3位对应的寄存器的位置,reserved作为保留位。
寄存器的数相减,结果数据存放至rd3位对应的寄存器的位置,reserved作为保留位。
成16位数据相加,结果作为数据存储器地址,取出地址对应的数据存放到rt3位对应的寄存器中。
成16位数据相加,结果作为数据存储器地址A,将rt3位对应的寄存器的数据取出来,存放到A地址对应的存储器单元中。
4.2 器件单元模块此模块的设计是CPU设计的核心部分,它是将众多模块整合在一起,在此模块中主要包括:寄存器组、控制器、存储器、PC计数器、数据选择器、ALU单元这六大单元。
如下图5所示,展示出模块间整合的总体效果,可以看出,每个模块的功能还是显而易见的,各模块间通过命名一致达到数据双向传输效果。
图5 CPU综合模块示意图4.2.1寄存器组由上面总体设计方案中指出,每个寄存器应该由16个D触发器构成,为了避免设计复杂,我们采用迭代的设计方法,即先由单个D触发器设计成包含2个D触发器模块,图6示出了由单个D触发器构成2个D触发器模块。
为了避免篇幅颇多,这仅展示由8个D触发器构成最终16个D触发器的示意图,如图7,以及最终16位D触发器综合模块效果,如图8。
图6 单个D触发器构成2个触发器图7 8个D触发器构成16个D触发器图8 16位D触发器综合模块寄存器组作为数据保存的器件,当读取寄存器中的数据时,涉及读地址端口以及对应的输出数据端口,故应该有两个读地址端口,两个写地址端口;当写入寄存器数据时,涉及写的信号、写的地址以及写的数据也应该准备好,故应有一个写地址端口,一个数据准备端口以及一个写信号,同时数据的传送需要在一个时钟信号到来的上升沿操作,故应有一个时钟信号CLK,所以总共端口共有8个。