实验五、单周期 CPU 设计与实现——十条指令 CPU

2024-01-29 19:40

本文主要是介绍实验五、单周期 CPU 设计与实现——十条指令 CPU,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一、实验目的: 

通过设计并实现支持10 条指令的CPU,进一步理解和掌握CPU 设计的基本原理和过程。 

二、实验内容: 

设计和实现一个支持如下十条指令的单周期CPU。 

Ø非访存指令
u清除累加器指令CLA
u累加器取反指令COM
u算术右移一位指令SHR:将累加器ACC 中的数右移一位,结果放回ACC 

u循环左移一位指令CSL:对累加器中的数据进行操作
u停机指令STP 

Ø访存指令 

u 加法指令ADD 

u 存数指令STA 

u 取数指令LDA 

Ø转移类指令 

u 无条件转移指令JMP imm:signExt(imm) -> PC 

u 有条件转移(负则转)指令BAN X: ACC 最高位为1 则(PC)+ X -> PC,否则PC 不变 

三、实验原理

1、约定机器字长、指令字长和存储字长均为16位。

2、约定指令格式如下图所示,高4位为指令的操作码字段,低12位为指令的地址码或者立即寻址的操作数。

3、指令和相应的操作码对照表

CPU 原理图 

四、实验步骤

4.1 CPU 各模块Verilog 实现  

1) PC 模块

输入 

时钟信号clk、重置信号 rst 、停机信号stop、无条件转移信号wr、条件转移信号judge、 pc修改量jmp(12位)

 

输出 

 

指令地址addr(12 位) 

功能 

每个时钟上升沿 addr 的值自动加 1,并输出

如果wr为1,修改addr为 jmp - 1

如果judge为1,修改addr为 addr + jmp

如果rst为1,修改addr为0

 

Verilog 关键代码:

2) 指令存储器模块 

该模块中已经初始化了10条指令,并且刚好串在一起,可以作为一组逻辑统一的整体。

输入 

12位指令地址 addr 

输出 

16 位指令 ins 

功能 

存放待执行的指令(初始化),并根据地址输出指令 

Verilog 关键代码:

3) 累加器

输入 

时钟信号clk、读写控制线 wr、输入数据 indata

输出 

输出数据outdata

功能 

ACC数据从outdata输出,如果wr有效,在clk下降沿将会把indata写入ACC中。

Verilog 关键代码:

4) ALU 

表4.4 ALU 模块功能描述 

输入 

操作数 in1 和in2、操作选择信号alu_op 

输出 

 

ALU 运算结果 Z 

 

功能 

根据操作选择信号计算in1 和in2 的运算结果 Z 

Verilog 关键代码:

5) 控制单元 

表4.5 控制单元模块功能描述 

输入 

指令(操作码) 

输出 

停机信号stop、PC读写控制线 pcwr、ACC读写控制线 accwr 、数据存储器读写控制线 datamemorywr、ALU 的操作选择信号 op 

功能 

根据当前指令功能对stop、pcwr、accwr、datamemorywr和op 赋值 

Verilog 关键代码:

6) 数据存储器模块 

该模块中初始化了2条数据,一个用于测试各种运算功能,另一个用于测试条件转移。

输入 

时钟信号clk、读写控制线wr、12位指令地址 addr、输入数据 indata 

输出 

16 位输出数据 outdata 

功能 

存放数据,可以读出,或在clk下降沿写入。 

Verilog 关键代码:

4.2 CPU 顶层文件封装实现 

在这个文件中,声明了pc,insmemory,datamemory,acc,cu,alu等模块。

并且声明了几个wire类型的变量用于连接各个部件。

Verilog 关键代码:

4.3 CPU 模拟仿真 

1、TestBench关键代码 

CPU的测试文件如下,主要功能就是产生了时钟信号,并且使用rst信号初始化pc。

clk信号每1ns反转一次,一个时钟周期2ns。

20ns后结束测试,刚好测试完10条指令。

2、ModelSim仿真及分析 

指令1 LDA 取数指令

这条指令在指令存储器的地址000000000000处。传送给ALU的命令是0110。

将数据地址为000000000000处的数据0000000000000010存储进ACC中。

CU会向ACC发出写信号,在时钟的下降沿写入数据。

指令2 COM 取反指令

这条指令在指令存储器的地址000000000001处。传送给ALU的命令是0001。

将ACC中的数据0000000000000010取反后得到1111111111111101。

CU会向ACC发出写信号,在时钟的下降沿写入数据。

指令3 SHR 算数右移指令

这条指令在指令存储器的地址000000000010处。传送给ALU的命令是0010。

将ACC中的数据1111111111111101算数右移后得到1111111111111110。

CU会向ACC发出写信号,在时钟的下降沿写入数据。

指令4 CSL 循环左移指令

这条指令在指令存储器的地址000000000011处。传送给ALU的命令是0011。

将ACC中的数据1111111111111110循环左移后得到1111111111111101。

CU会向ACC发出写信号,在时钟的下降沿写入数据。

指令5 CLA 清除指令

这条指令在指令存储器的地址000000000100处。传送给ALU的命令是0000。

将ACC中的数据1111111111111101清零后得到0000000000000000。

CU会向ACC发出写信号,在时钟的下降沿写入数据。

指令6 ADD 加法指令

这条指令在指令存储器的地址000000000101处。传送给ALU的命令是0100。

将ACC中的数据0000000000000000和数据存储器的地址为000000000001处的数据相加得到1000000000000000再保存到ACC中。

CU会向ACC发出写信号,在时钟的下降沿写入数据。

指令7 STA 存数指令

这条指令在指令存储器的地址000000000110处。传送给ALU的命令是0101。

ACC中的数据存储到数据存储器地址为000000000010的单元。

可以从图中看到000000000010单元的值由不确定变为1000000000000000。

CU会向数据存储器发出写信号,在时钟的下降沿写入数据。

指令8 JMP 无条件转移指令

这条指令在指令存储器的地址000000000111处。传送给ALU的命令是1111。

这条指令使用地址码采用立即寻址方式向PC传送跳转的目标地址。

这里我们跳转到指令存储器地址为000000001001的单元(该单元保存了条件转移指令)。

可以看到下降沿的时候PC的值被修改为000000001000而不是000000001001,因为下一个时钟周期上升沿PC自动加1会进行修正。

CU会向PC发出写信号,在时钟的下降沿写入数据。

指令9 BAN 条件转移指令

这条指令在指令存储器的地址000000001001处。传送给ALU的命令是0111。

这里我这条指令设置为会判断ACC最高位是否位1,如果为1,会把PC增加2。

注意这里不需要进行PC的修正,直接在下降沿将PC加2修改000000001011。

因为在相对寻址中,位移量是以条件转移指令的下一条指令的地址为基准的做偏移的。

而指令字长刚好是一个存储字,所以最终会跳转到地址为000000001100的指令存储器单元。该单元内的指令为停机指令。

ALU会根据判断的结果向PC发出写信号judge,如果为1,在时钟的下降沿修改PC。

指令10 STP 停机指令

这条指令在指令存储器的地址000000001100处。传送给ALU的命令是1111。

这条指令会将PC内的标志位state设置为0。

如果state为0的话,PC在每个时钟上升沿将不会自动加1。

在图中可以看到下一个时钟上升沿到来的时候,地址保持000000001100无变化。

CU会向PC发出停机信号STOP,使PC不再自动增加。

五、总结

Verilog语法简洁优雅大方,给人以美的享受。

 

譬如CU中的这一段关键代码,既滴水不漏地实现了功能,还十分简洁。

 

这篇关于实验五、单周期 CPU 设计与实现——十条指令 CPU的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/657974

相关文章

Flutter实现文字镂空效果的详细步骤

《Flutter实现文字镂空效果的详细步骤》:本文主要介绍如何使用Flutter实现文字镂空效果,包括创建基础应用结构、实现自定义绘制器、构建UI界面以及实现颜色选择按钮等步骤,并详细解析了混合模... 目录引言实现原理开始实现步骤1:创建基础应用结构步骤2:创建主屏幕步骤3:实现自定义绘制器步骤4:构建U

SpringBoot中四种AOP实战应用场景及代码实现

《SpringBoot中四种AOP实战应用场景及代码实现》面向切面编程(AOP)是Spring框架的核心功能之一,它通过预编译和运行期动态代理实现程序功能的统一维护,在SpringBoot应用中,AO... 目录引言场景一:日志记录与性能监控业务需求实现方案使用示例扩展:MDC实现请求跟踪场景二:权限控制与

Android实现定时任务的几种方式汇总(附源码)

《Android实现定时任务的几种方式汇总(附源码)》在Android应用中,定时任务(ScheduledTask)的需求几乎无处不在:从定时刷新数据、定时备份、定时推送通知,到夜间静默下载、循环执行... 目录一、项目介绍1. 背景与意义二、相关基础知识与系统约束三、方案一:Handler.postDel

使用Python实现IP地址和端口状态检测与监控

《使用Python实现IP地址和端口状态检测与监控》在网络运维和服务器管理中,IP地址和端口的可用性监控是保障业务连续性的基础需求,本文将带你用Python从零打造一个高可用IP监控系统,感兴趣的小伙... 目录概述:为什么需要IP监控系统使用步骤说明1. 环境准备2. 系统部署3. 核心功能配置系统效果展

Python实现微信自动锁定工具

《Python实现微信自动锁定工具》在数字化办公时代,微信已成为职场沟通的重要工具,但临时离开时忘记锁屏可能导致敏感信息泄露,下面我们就来看看如何使用Python打造一个微信自动锁定工具吧... 目录引言:当微信隐私遇到自动化守护效果展示核心功能全景图技术亮点深度解析1. 无操作检测引擎2. 微信路径智能获

Python中pywin32 常用窗口操作的实现

《Python中pywin32常用窗口操作的实现》本文主要介绍了Python中pywin32常用窗口操作的实现,pywin32主要的作用是供Python开发者快速调用WindowsAPI的一个... 目录获取窗口句柄获取最前端窗口句柄获取指定坐标处的窗口根据窗口的完整标题匹配获取句柄根据窗口的类别匹配获取句

在 Spring Boot 中实现异常处理最佳实践

《在SpringBoot中实现异常处理最佳实践》本文介绍如何在SpringBoot中实现异常处理,涵盖核心概念、实现方法、与先前查询的集成、性能分析、常见问题和最佳实践,感兴趣的朋友一起看看吧... 目录一、Spring Boot 异常处理的背景与核心概念1.1 为什么需要异常处理?1.2 Spring B

判断PyTorch是GPU版还是CPU版的方法小结

《判断PyTorch是GPU版还是CPU版的方法小结》PyTorch作为当前最流行的深度学习框架之一,支持在CPU和GPU(NVIDIACUDA)上运行,所以对于深度学习开发者来说,正确识别PyTor... 目录前言为什么需要区分GPU和CPU版本?性能差异硬件要求如何检查PyTorch版本?方法1:使用命

Python位移操作和位运算的实现示例

《Python位移操作和位运算的实现示例》本文主要介绍了Python位移操作和位运算的实现示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一... 目录1. 位移操作1.1 左移操作 (<<)1.2 右移操作 (>>)注意事项:2. 位运算2.1

如何在 Spring Boot 中实现 FreeMarker 模板

《如何在SpringBoot中实现FreeMarker模板》FreeMarker是一种功能强大、轻量级的模板引擎,用于在Java应用中生成动态文本输出(如HTML、XML、邮件内容等),本文... 目录什么是 FreeMarker 模板?在 Spring Boot 中实现 FreeMarker 模板1. 环