单周期CPU设计参考
CPU设计实践教程6-Minisys-1单周期CPU控制器的设计
指令操作码 ori
addiu
lw
sw
beq jump
RegDst
0
0
0
000000 R-format
1
RegDST = R-format
wire R_format;
assign R_format = (Opcode==6'b000000)? 1'b1:1'b0; assign RegDST = R_format; //说明目标是rd,否则是rt
output Sftmd; output[1:0] ALUOp;
// 他I-类型指令 // 为1表明是移位指令 // 是R-类型或I_format=1时位1为1, beq、bne指令则 // 位0为1
2021/9/5 P.22
单周期控制器设计
RegDST的控制电路
op 001101 001001 100011 101011 000100 000010
output nBranch; // 为1表明是Bne指令
output Jmp;
// 为1表明是J指令
output Sftmd; // 为1表明是移位指令
2021/9/5 P.25
单周期控制器设计
练习2
请给出下列控制信号电路的Verilog描述
assign Sw = ????? assign ALUSrc = ????? assign Branch = ????? assign nBranch = ????? assign Jmp = ?????
2021/9/5 P.10
创建一个项目
在打开的Default Port对话框中选择的FPGA器件为 xc7a100tfgg484-1,如图所示,点击Next。
单周期CPU设计实验报告
单周期CPU设计实验报告一、引言计算机是现代信息社会必不可少的工具,而CPU作为计算机的核心部件,承担着执行指令、进行运算和控制系统资源的任务。
随着科技的进步和计算能力的需求,CPU的设计也趋于复杂和高效。
本次实验旨在设计一种单周期CPU,探究其设计原理和实现过程,并通过实验验证其正确性和性能。
二、理论基础1.单周期CPU概述单周期CPU即每个时钟周期内只完成一条指令的处理,它包括指令取址阶段(IF)、指令译码阶段(ID)、执行阶段(EX)、访存阶段(MEM)和写回阶段(WB)等多个阶段。
每条指令都顺序地在这些阶段中执行,而不同的指令所需的时钟周期可能不同。
2.控制信号单周期CPU需要根据不同的指令类型产生不同的控制信号来控制各个阶段的工作。
常见的控制信号包括时钟信号(clk)、使能信号(En)、写使能信号(WE)和数据选择信号(MUX)等。
这些信号的产生需要通过译码器、控制逻辑电路和时序逻辑电路等来实现。
三、实验设计本次实验采用的单周期CPU包括以下五个阶段:指令取址阶段、指令译码阶段、执行阶段、访存阶段和写回阶段。
每个阶段的具体操作如下:1.指令取址阶段(IF)在IF阶段,通过计数器实现程序计数器(PC)的自增功能,并从存储器中读取指令存储地址所对应的指令码。
同时,设置PC使能信号,使其可以更新到下一个地址。
2.指令译码阶段(ID)在ID阶段,对从存储器中读取的指令码进行解码,确定指令的操作类型和操作数。
同时,根据操作类型产生相应的控制信号,如使能信号、写使能信号和数据选择信号等。
3.执行阶段(EX)在EX阶段,根据ID阶段产生的控制信号和操作数,进行相应的算术逻辑运算。
这里可以包括加法器、乘法器、逻辑运算器等。
4.访存阶段(MEM)在MEM阶段,根据EX阶段的结果,进行数据存储器的读写操作。
同时,将读取的数据传递给下一个阶段。
5.写回阶段(WB)在WB阶段,根据MEM阶段的结果,将数据传递给寄存器文件,并将其写入指定的寄存器。
单周期CPU设计总结
单周期CPU设计总结单周期CPU⼀、设计思路1、CPU的意义CPU是计算机的核⼼,因为它是计算机指令的处理单元。
计算机体系结构包含两个⽅⾯,⼀个⽅⾯是指令集,⼀个⽅⾯是硬件实现。
指令集是计算机被定义拥有的执⾏指令,计算机通过⽀持指令集的运⾏,来完成计算⼯作并为程序员编程服务。
硬件实现则是具体的硬件去实现指令集,这个硬件实现的核⼼就是CPU的设计。
这⾥写的CPU的设计是32位机器的CPU,指令和数据均为32位。
⽀持指令为简化mips指令集。
2、CPU的设计CPU的设计包含数据通路的设计和控制器的设计。
数据通路是执⾏指令必须的硬件(ALU、IM、DM、GRF等),控制器则是根据指令产⽣相应控制信号,来控制相应硬件以⽀持多条指令。
数据通路设计CPU的功能是⽀持指令集,因此硬件设计是为了执⾏指令。
设计CPU的结构的⽅法:先选择⼀条需要经过最多硬件的指令,来为它构建数据通路。
再依据其他指令在已有数据通路上添加硬件或线路,直到数据通路⽀持所有指令。
控制器设计在已有的数据通路基础上,针对每⼀条指令,列出其所需要的控制信号,每⼀组控制信号对应⼀种指令的全部执⾏。
将指令相应字段和部分计算结果作为控制器的输⼊,控制信号作为输出,依据上述映射关系(真值表)设计控制器。
⼆、实际操作0、设计说明CPU架构的设计是没有很多约束的,基本要求就是能够⽀持指令集,基于不同的考量可以有不同的设计。
举例来说:对于beq指令是否跳转的判断,可以借⽤ALU的减法计算,也可以直接增设CMP⽐较器得出,两种⽅式都可以,因为功能正确。
为了提⾼吞吐量,或者为了节省成本,会选择⼀些特别的设计,这⼀点在流⽔线CPU 的设计上可以明显地看出。
CPU具体设计的⽅法是我下⾯进⾏的⼏步:列出所需指令,写出功能模块,连接模块,构造控制器,全部连接起来。
这些表格对最终代码实现⼗分重要,因为代码量较⼤,先从表格检查起,再依据表格写码可以减少bug。
1、⽀持指令列出⽀持指令并将其分类:str ld cal_r cal_i lui b_type j jr jal jalr shamtsw lw addu ori beq sllsubu slti sraslt addiu srlsllvsravsrlv2、功能模块先按照lw指令列出所需功能模块(lw经过模块最多),再依次检查现有模块是否⽀持其余指令,若不能⽀持,则添加相应模块。
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的步骤,包括电路设计、指令集设计、时序控制等。
计算机组成原理实验报告-单周期CPU的设计与实现
1个时钟周期 Clock 电子科技大学计算机科学与工程学院标 准 实 验 报 告(实验)课程名称: 计算机组成原理实验 电子科技大学教务处制表电 子 科 技 大 学 实 验 报 告学生姓名: 郫县尼克杨 学 号: 2014 指导教师:陈虹 实验地点: 主楼A2-411 实验时间:12周-15周一、 实验室名称:主楼A2-411二、 实验项目名称:单周期CPU 的设计与实现。
三、 实验学时:8学时四、 实验原理:(一) 概述单周期(Single Cycle )CPU 是指CPU 从取出1条指令到执行完该指令只需1个时钟周期。
一条指令的执行过程包括:取指令→分析指令→取操作数→执行指令→保存结果。
对于单周期CPU 来说,这些执行步骤均在一个时钟周期内完成。
(二) 单周期cpu 总体电路本实验所设计的单周期CPU 的总体电路结构如下。
(三) MIPS 指令格式化MIPS 指令系统结构有MIPS-32和MIPS-64两种。
本实验的MIPS 指令选用MIPS-32。
以下所说的MIPS 指令均指MIPS-32。
MIPS 的指令格式为32位。
下图给出MIPS 指令的3种格式。
本实验只选取了9条典型的MIPS 指令来描述CPU 逻辑电路的设计方法。
下图列出了本实验的所涉及到的9条MIPS 指令。
五、 实验目的1、掌握单周期CPU 的工作原理、实现方法及其组成部件的原理和设计方法,如控制器、运算器等。
?2、认识和掌握指令与CPU 的关系、指令的执行过程。
?3、熟练使用硬件描述语言Verilog 、EDA 工具软件进行软件设计与仿真,以培养学生的分析和设计CPU 的能力。
六、 实验内容(一)拟定本实验的指令系统,指令应包含R 型指令、I 型指令和J 型指令,指令数为9条。
(二)CPU 各功能模块的设计与实现。
(三)对设计的各个模块的仿真测试。
(四)整个CPU 的封装与测试。
七、 实验器材(设备、元器件):(一)安装了Xilinx ISE Design Suite 的PC 机一台(二)FPGA 开发板:Anvyl Spartan6/XC6SLX45(三)计算机与FPGA 开发板通过JTAG (Joint Test Action Group )接口连接,其连接方式如图所示。
中山大学计算机组成原理实验 单周期CPU设计
《计算机组成原理实验》实验报告(实验三)学院名称:数据科学与计算机学院专业(班级):学生姓名:学号:时间:2019 年11 月8 日成绩:实验三:单周期CPU设计与实现一.实验目的(1) 掌握单周期CPU数据通路图的构成、原理及其设计方法;(2) 掌握单周期CPU的实现方法,代码实现方法;(3) 认识和掌握指令与CPU的关系;(4) 掌握测试单周期CPU的方法。
二.实验内容设计一个单周期CPU,该CPU至少能实现以下指令功能操作。
指令与格式如下:==> 算术运算指令加“加”运算。
加“加”运算。
==> 逻辑运算指令加“与”运算。
功能:GPR[rt] ←GPR[rs] or zero_extend(immediate)。
==>移位指令==>比较指令==> 存储器读/写指令==> 分支指令else pc ←pc + 4特别说明:offset是从PC+4地址开始和转移到的指令之间指令条数。
offset符号扩展之后左移2位再相加。
为什么要左移2位?由于跳转到的指令地址肯定是4的倍数(每条指令占4个字节),最低两位是“00”,因此将offset放进指令码中的时候,是右移了2位的,也就是以上说的“指令之间指令条数”。
else pc ←pc + 4(16)bltz rs, offsetelse pc ←pc + 4。
==>跳转指令(17)j addr说明:由于MIPS32的指令代码长度占4个字节,所以指令地址二进制数最低2位均为0,将指令地址放进指令代码中时,可省掉!这样,除了最高6位操作码外,还有26位可用于存放地址,事实上,可存放28位地址,剩下最高4位由pc+4最高4位拼接上。
==> 停机指令功能:停机;不改变PC的值,PC保持不变。
三.实验原理单周期CPU指的是一条指令的执行在一个时钟周期内完成,然后开始下一条指令的执行,即一条指令用一个时钟周期完成。
电平从低到高变化的瞬间称为时钟上升沿,两个相邻时钟上升沿之间的时间间隔称为一个时钟周期。
(完整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设计:精简指令集(RISC)32位单周期cpu设计
精简指令集(RISC)32位单周期cpu设计电气513摘要:该作品为一个精简指令集的32位单周期cpu,具有18条基本的指令,可以实现数据的存取、运算等基本功能。
测试程序执行过程中,CPU各部件的具体数据可以显示到FPGA的数码管上。
目录1.CPU的整体电路设计;2.CPU的指令格式;3.基本功能部件的设计;4.主要功能部件的设计;5.CPU的封装;6.FPGA测试。
1.CPU的整体电路设计CPU主要组成部分有:运算器(ALU)、控制器(Control Unit)、寄存器堆(Register Files)、取指电路及相关基础部件(如选择器)等构成。
下图为cpu的电路图。
CPU的电路包括数据路径(Data path)和控制部件(Control Unit)两大部分。
下面介绍路径的设计。
1.1 下一条指令地址的选择下一条指令的地址有3种情况:1.程序不转移时下一条指令的地址为PC+4;2.执行beq和bne指令发生转移时,下一条指令的地址是PC加4,再加上符号扩展的偏移量左移2位的和;3.执行j指令时转移的目标地址是指令中的低26位地址左移2位,再与PC+4的高4位拼接在一起。
下一条指令地址的产生和选择电路如图所示。
图中控制器(Control Unit)根据op、func和zero(对于beq和bne指令)信号产生相应的转移控制选择信号pcsource。
1.2 ALU的输入端ALU的输入端有2个:A输入端和B输入端。
A、B输入端分别有2种输入情况。
对于A输入端,有寄存器堆的A_data和移位数sa输入。
对于B输入端,有寄存器堆的B_data和符号扩展后的立即数imm输入。
其输入数据路径如图所示。
ALU的A、B端具体输入哪路数据由控制器(Control Unit)根据指令译码产生控制信号shift和aluimm 来选择。
1.3寄存器堆的输入端寄存器堆的A_addr和B_addr的输入来自指令,分别只有一种输入,W_addr有2种,而Data有4种输入。
精品单周期CPU设计.docx
■=・NINGBO UNIVERSITY短学期综合实验报告实验名称:单周期CPU设计院系:信息科学与工程学院专业:计算机科学与技术组员: XXXXXXXXXXXXXXXXXXXXXX指导老师:XXXXXXX _____________二o—一年七月八日摘要中央处理器(CPU)是计算机取指令和执行指令的部件,它是由算术逻辑单元(ALU)、寄存器和控制器组成,简称处理器(或CPU), CPU 是计算机系统的核心部件,在各类信息终端中得到了广泛的应用。
处理器的设计及制造技术也是计算机技术的核心之一。
CPU设计的第一步应当根据指令系统来建立数据路径,再定义各个部件的控制信号,确定时钟周期,完成控制器的设计。
然后建立数据路径,进而可以进行数字设计、电路设计,最后完成物理实现。
而在本次试验中,我们研究的重点是数据路径的建立和控制器的实现。
一个机器的性能由三个关键因素决定:指令数、时钟周期,以及执行每条指令所需的时钟周期数(CPI)。
然而不论是时钟周期,还是每条指令所需的时钟周期数目,都是由处理器的实现情况决定的。
在本次试验中,我们构造了单周期的数据路径和组合逻辑实现的控制器。
本次试验屮,我们运用Quartus II 8.0软件设计出了一个拥有6 条指令的单周期CPU,并对它进行了简单的测试,最终完成了一个正确的单周期CPU的设计。
关键词:数据路径,控制器,控制信号,单周期AbstractCentral processing unit (CPU) is a computer instraction fetch and execution ofcomponents, it is an arithmetic logic unit (ALU), registers and a controller, referred to as the processor (or CPU), CPU is the core component of computer systems in all type information terminal has been widely used・Processor design and manufacturing technology is one of the core computer technology.The first step should be based on CPU design instraction to create a data path, and then define the various components of the control signals to determine the clock cycle, the controller design. Then set up a data path, and then can be digital design, circuit design, physical implementation finalized. In this experiment, the focus of our research is to establish the data path and controller implementation.The performance of a machine consists of three key factors: the number of instructions, clock cycles to execute each instruction as well as the required number of clock cycles (CPI). Whether it be a clock cycle, each instruction or the number of clock cycles required are determined by the achievement of the processor. In this study, we constructed single-cycle data path and the combinational logic to achieve the controller.This experiment, we use Quartiis II 8.0 software to design a single-cycle instruction with 6 CPU, and it conducted a simple test, thefinal completion of a proper single-cycle CPU design.Keywords:Data path, Controller, Control Signal,Single-cycle实验内容:1、通过实验的学习,基本熟悉quarters II软件的使用,并能熟练运用试验所需元件。
单周期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?
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设计代码解读
单周期cpu设计代码解读⽬录写在前⾯欢迎转载,转载请说明出处。
单周期cpu设计代码讲解概念回顾⼀、电⼦计算机的部件分为:中央处理器(cpu)、内部存储器(Memory)、输⼊/输出(I/O)设备,以及连接它们的总线(Bus)。
下图为图⽰,注意⾊块的区分。
⼆、cpu⼜包括控制器(Controller)和数据通路(Data Path)。
下图为图⽰,注意⾊块区分。
三、控制器分为主控(Main Control)和局控(Local Control或ALU Control)。
将⼆进制指令输⼊控制器,⽣成控制信号,该过程称为译码。
控制信号控制数据通路⼯作。
且不同的指定对应不同的控制信号。
下图为在控制器中译码的逻辑⽰意图:下图为在控制器中译码的物理⽰意图:讲解⼀下从逻辑图到物理图的转换:1. ⾸先由主控解析op指令,如果发现该指令为“000000”则表⽰该指令是R指令,输出中间信号R-Type为1,否则为0;如果发现该指令是其他值,则按照逻辑图,为RegDst等信号赋相应的值;2. 中间信号R-Type起到⼆路选择的作⽤,如图。
3. 中间信号ALUop,在R-Type为0(选择0路)时,直接通过局控,输出成为ALUctr信号,对应上⾯逻辑图的最后⼀⾏后5列;在R-Type为1时,局控起作⽤。
4. 局控解析R指令的func部分,输出对应指令的ALUctr信号。
四、数据通路:是包括运算器、寄存器组、存储器(⾼速缓存)、多路选择器等等在内的元件的有结构的组合。
如下图所⽰:【数据通路各部分的讲解将结合代码完成】Verilog代码讲解在代码讲解之前有必要放⼏张图:shift.v/*移位*//*输⼊⼀个数,返回移位之后的结果*//*输⼊d(待移的数)、sa(移动的位数)、right(移动⽅向)、arith(空位补全⽅式)*//*输出sh(移位后的结果)*/module shift (d,sa,right,arith,sh);input [31:0] d;input [4:0] sa;input right,arith;output [31:0] sh;reg [31:0] sh;// 组合逻辑always @* beginif (!right) begin // right为逻辑0时,左移sh = d << sa;end else if (!arith) begin // right为逻辑1,且arith为逻辑0时,右移、0补空sh = d >> sa;end else begin // 右移、1补空sh = $signed(d) >>> sa;endendendmodulescinstmem.v/*从ROM(只读存储器)读数据*//*输⼊⽬标数据在ROM中的地址a*//*输出地址对应的数据inst*/module scinstmem (a,inst);input [31:0] a;output [31:0] inst;wire [31:0] rom [0:31]; // 定义32个32位的存储器ROM// 想ROM中写⼊⼀组指令,指令对应的汇编含义见⾏注释assign rom[5'h00] = 32'h3c010000; // (00) main: lui r1,0assign rom[5'h01] = 32'h34240050; // (04) ori r4,r1,80assign rom[5'h02] = 32'h20050004; // (08) addi r5,r0, 4assign rom[5'h03] = 32'h0c000018; // (0c)call: jal sumassign rom[5'h04] = 32'hac820000; // (10) sw r2,0(r4)assign rom[5'h05] = 32'h8c890000; // (14) lw r9, 0(r4)assign rom[5'h06] = 32'h01244022; // (18) sub r8, r9. r4assign rom[5'h07] = 32'h20050003; // (lc) addi r5, r0. 3assign rom[5'h08] = 32'h20a5ffff; // (20) loop2: addi r5, r5, -1assign rom[5'h09] = 32'h34a8ffff; // (24) ori r8, r5, 0xffffassign rom[5'h0A] = 32'h39085555; // (28) xori r8. r8, 0x5555assign rom[5'h0B] = 32'h2009ffff; // (2c) addi r9, rO, -1assign rom[5'h0C] = 32'h312affff; // (30) andi rlO, r9, 0xffffassign rom[5'h0D] = 32'h01493025; // (34) or r6. rlO, r9assign rom[5'h0E] = 32'h01494026; // (38) xor r8, rlO, r9assign rom[5'h0F] = 32'h01463824; // (3c) and r7, rlO, r6assign rom[5'h10] = 32'h10a00001; // (40) beq r5, r0, shiftassign rom[5'h11] = 32'h08000008; // (44) j loop2assign rom[5'h12] = 32'h2005ffff; // (48) shift: addi r5. r0, -1assign rom[5'h13] = 32'h000543c0; // (4c) sll r8. r5. 15assign rom[5'h14] = 32'h00084400; // (50) sll r8, r8, 16assign rom[5'h15] = 32'h00084403; // (54) sra r8, r8, 16assign rom[5'h16] = 32'h000843c2; // (58) srl r8. r8. 15assign rom[5'h17] = 32'h08000017; // (5c) finish: j finishassign rom[5'h18] = 32'h00004020; // (60) sum: add r8, r0, r0assign rom[5'h19] = 32'h8c890000; // (64) loop: lw r9, (r4)assign rom[5'h1A] = 32'h20840004; // (68) addi r4, r4, 4assign rom[5'h1B] = 32'h01094020; // (6c) add r8, r8, r9assign rom[5'h1C] = 32'h20a5ffff; // (70) addi r5, r5, -1assign rom[5'h1D] = 32'h14a0fffb; // (74) bne rS, r0, loopassign rom[5'h1E] = 32'h00081000; // (78) sll r2f r8f 0assign rom[5'h1F] = 32'h03e00008; // (7c) jr r31// 将地址对应的数据放⼊instassign inst = rom[a[6:2]];endmodulescdatamem.v/*将数据写⼊RAM中(随机存取存储器)的指定位置*//*输⼊待写数据datain、⽬标地址addr;写使能信号we;时钟信号clk、inclk、outclk*//*输出将被覆盖的数据dataout*/module scdatamem (clk,dataout,datain,addr,we,inclk,outclk);input [31:0] datain;input [31:0] addr ;input clk, we, inclk, outclk;output [31:0] dataout;reg [31:0] ram [0:31]; // 定义32个32位RAM// 把将被覆盖的数据放⼊dataoutassign dataout =ram[addr[6:2]];// 时序逻辑,clk的上升沿触发always @ (posedge clk) beginif (we) ram[addr[6:2]] = datain; // 如果写使能信号we为1,将数据写⼊⽬标地址end// 为RAM赋值,这⼀步不是必要的,只是欲运⾏的⾃定义程序的需要。
单周期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及其Verilog HDL设计
一、指令的设计
MIPS32的指令的三种格式的参考:
R类型:
I类型:
J类型:
R类型指令的op为0,具体操作由func指定。
rs和rt是源寄存器号,rd是目的寄存器号。
只有移位指令使用sa来指定移位位数。
I类型指令的低16位是立即数,计算时要把它扩展到32位。
依指令的不同,有零扩展和符号扩展两种。
J类型指令右边26位是字地址,用于产生跳转的目标地址。
具体的指令格式和内容请参考MIPS32。
设计报告中需自行设计所有指令的二进制格式和对应的汇编指令格式。
二、单周期CPU的设计
我们把时钟的电平从低到高变化的瞬间称为时钟上升沿,两个相邻时钟上升沿之间的时间间隔称为一个时钟周期。
单周期CPU指的是一条指令的执行在一个这样的时钟周期内完成,然后开始下一条指令的执行,即一条指令用一个周期。
2.1执行一条指令所需的硬件电路
我们的目的地是要设计CPU的硬件电路,使其能够从存储器中读出一条条指令并执行指令所描述的操作。
从存储器中读取指令的动作一般与指令本身的意义无关,可以以同样的方法把指令从存储器中取出。
而执行指令则与指令本身的意义密切相关,因此最重要是首先搞清楚CPU要执行的每条指令的意义。
下面以两种类型的电路来举例。
2.1.1与取指令有关的电路
指令存储在存储器中。
CPU取指令时把程序计数器(PC)中的内容作为存储器的地址,根据它来访问存储器,从PC值指定的存储单元中取来一条32位指令。
如果取来的指令执行时没有引起转移,PC的值要加4;如果转移,要把转移的目标地址写入PC,以便在下一个时钟周期取出下一条指令。
图2.1 取指令时用到的硬件电路和指令寄存器
如图2.1所示,PC是一个简单的32位寄存器,由32个D触发器构成。
指令存储器(Inst Mem)的输入端a是地址、输出端do是数据输出,即指令。
图中的加法器专供PC+4使用,它的输出接到多路器的一个输入端。
如果取来的指令没有引起转移或跳转,则选择PC+4,在时钟上升沿处将其打入PC;若引起转移或跳转,则用多路器选择下一条指令该打入的PC值。
2.1.2寄存器计算类型指令执行时所需电路
寄存器类型的指令有add等。
如图2.2所示是执行它们所需的部分硬件电路。
大多数MIPS指令属于三操作数指令。
指令格式中的rs和rt是两个5位的寄存器号,由它们从寄存器堆(Regfile)中读出两个32位的数据。
由于寄存器号有5位,所以能从32个寄存器中选出一个。
32个寄存器合在一起称为寄存器堆(Register File)。
从寄存器堆读出的两个32位数据分别被送到ALU的a和b的输入端。
图2.2 执行寄存器计算类型指令所需电路
具体的计算由ALU完成。
ALU的计算控制码aluc由控制部件(Control Unit)产生。
这里的控制部件是简单的组合电路,输入信号是指令的操作码op和功能码func,输出信号3个,它们分别是ALU的操作码aluc、计算结果是否写入寄存器堆的控制信号wreg和下一条指令的地址选择信号pcsource。
ALU的计算结
果要写入寄存器堆。
到底要写入32个寄存器中的哪一个,由5位目的寄存器号rd指定。
2.2寄存器堆设计
寄存器堆有两个读端口和一个写端口。
每个端口都有一个5位寄存器号,用于指定一个寄存器;还有32位的数据端,用于写数据。
寄存器堆的参考电路如图2.3,其中,dec5e是一个带有使能端的5-32译码器,mux32x32是一个32位的32选1的多路器,reg32由许多D触发器组成。
可以用功能描述风格的Verilog HDL代码来实现,关键部分是类似于二维数组的寄存器变量:reg[31:0]register[1:31](寄存器0的内容永远是0)。
图2.3 寄存器堆regfile的电路图
2.3数据存储器和指令存储器设计
我们利用Xilinx ISE自带的IP核实现数据存储器和指令存储器的设计。
在使用IP核时,可以将其作为一个黑盒子,只关注核的功能和参数配置,不需要了解核内部的实现电路。
下面以指令存储器的设计为例。
2.3.1指令存储器的设计
1、双击“ISE Design Suite 14.2”启动软件,建立好project。
2、编辑初始化存储器的文档。
在工程目录下生成一个txt文档,内容格式为:
图2.4 初始化ROM的文件格式
文件前两行是格式说明,第一行说明数据格式是16进制,第二行说明是初始向量,每个单元内的数据用逗号隔开,结束用分号。
这里的数据是机器指令代码。
完成后将后缀改成.coe。
3、在工程管理区任意位置单击鼠标右键,在弹出的菜单中选择New Source 命令。
在弹出如图2.5的窗口,选择IP(Core Generator&Architecture Wizard),设置好后点next进入IP核选择,如图2.6。
图2.5 选择源文件类型
图2.6 选择所需的存储器IP核生成器
4、IP核参数设置。
第1页,直接点next。
第2页,修改Memory Type选择项为:Single Port Rom。
其余不变。
第3页修改Write Width和Write Depth为需要的值,其余不变。
第4页在Load Init File处打钩,用之前写好的后缀为.coe的文件初始化存储器。
选择Show可以看到存储器里的内容。
以后这个关联文件内容修改后都要重新做一个Regenerate Core。
第
5、6页不用修改。
点击Generate 系统自动生成My_Rom只读存储器模块。
生成完后ISE的工程管理区会增加一个模块:My_Rom(My_Rom.xco),选中My_Rom(My_Rom.xco),在过程管理区会出现核生成器菜单。
5、双击过程管理区的View HDL Instruction Template在代码逻辑区会给出My_Rom的调用参数,你可以像一般模块那样调用。
YourInstanceName改成喜欢的名字即可。
数据存储器的设计和指令存储器类似,只是注意Memory Type要选择Single Port Ram。
设计报告中应包括完整的CPU结构图和完整Verilog HDL代码。
三、单周期CPU的测试
CPU测试分为两个内容的工作:1. 通过Xilinx的仿真环境仿真CPU的工作过程;2.编写测试程序测试CPU的功能的正确性。
对于“2.编写测试程序测试CPU的功能的正确性”要求用软件实现一个从汇编指令到二进制指令的解释器,输出的内容作为ROM的内容供CPU执行。
CPU的测试程序个数需5个以上,能够完全覆盖所设计的所有指令和寄存器。
四、课程设计要求及评分标准
1. 设计一个单周期CPU内核,至少应有10条以上指令;
2. 开发从汇编指令到二进制的解释器。
3. 设计测试程序,5个以上,能完全覆盖所有的指令和寄存器。
4. 支持指令的个数越多,内核越强大,设计报告书写越工整,测试程序越丰富,成绩越高。