实验五、单周期 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

相关文章

Python使用Tenacity一行代码实现自动重试详解

《Python使用Tenacity一行代码实现自动重试详解》tenacity是一个专为Python设计的通用重试库,它的核心理念就是用简单、清晰的方式,为任何可能失败的操作添加重试能力,下面我们就来看... 目录一切始于一个简单的 API 调用Tenacity 入门:一行代码实现优雅重试精细控制:让重试按我

Redis客户端连接机制的实现方案

《Redis客户端连接机制的实现方案》本文主要介绍了Redis客户端连接机制的实现方案,包括事件驱动模型、非阻塞I/O处理、连接池应用及配置优化,具有一定的参考价值,感兴趣的可以了解一下... 目录1. Redis连接模型概述2. 连接建立过程详解2.1 连php接初始化流程2.2 关键配置参数3. 最大连

Python实现网格交易策略的过程

《Python实现网格交易策略的过程》本文讲解Python网格交易策略,利用ccxt获取加密货币数据及backtrader回测,通过设定网格节点,低买高卖获利,适合震荡行情,下面跟我一起看看我们的第一... 网格交易是一种经典的量化交易策略,其核心思想是在价格上下预设多个“网格”,当价格触发特定网格时执行买

python设置环境变量路径实现过程

《python设置环境变量路径实现过程》本文介绍设置Python路径的多种方法:临时设置(Windows用`set`,Linux/macOS用`export`)、永久设置(系统属性或shell配置文件... 目录设置python路径的方法临时设置环境变量(适用于当前会话)永久设置环境变量(Windows系统

Mysql中设计数据表的过程解析

《Mysql中设计数据表的过程解析》数据库约束通过NOTNULL、UNIQUE、DEFAULT、主键和外键等规则保障数据完整性,自动校验数据,减少人工错误,提升数据一致性和业务逻辑严谨性,本文介绍My... 目录1.引言2.NOT NULL——制定某列不可以存储NULL值2.UNIQUE——保证某一列的每一

Python对接支付宝支付之使用AliPay实现的详细操作指南

《Python对接支付宝支付之使用AliPay实现的详细操作指南》支付宝没有提供PythonSDK,但是强大的github就有提供python-alipay-sdk,封装里很多复杂操作,使用这个我们就... 目录一、引言二、准备工作2.1 支付宝开放平台入驻与应用创建2.2 密钥生成与配置2.3 安装ali

Spring Security 单点登录与自动登录机制的实现原理

《SpringSecurity单点登录与自动登录机制的实现原理》本文探讨SpringSecurity实现单点登录(SSO)与自动登录机制,涵盖JWT跨系统认证、RememberMe持久化Token... 目录一、核心概念解析1.1 单点登录(SSO)1.2 自动登录(Remember Me)二、代码分析三、

PyCharm中配置PyQt的实现步骤

《PyCharm中配置PyQt的实现步骤》PyCharm是JetBrains推出的一款强大的PythonIDE,结合PyQt可以进行pythion高效开发桌面GUI应用程序,本文就来介绍一下PyCha... 目录1. 安装China编程PyQt1.PyQt 核心组件2. 基础 PyQt 应用程序结构3. 使用 Q

Python实现批量提取BLF文件时间戳

《Python实现批量提取BLF文件时间戳》BLF(BinaryLoggingFormat)作为Vector公司推出的CAN总线数据记录格式,被广泛用于存储车辆通信数据,本文将使用Python轻松提取... 目录一、为什么需要批量处理 BLF 文件二、核心代码解析:从文件遍历到数据导出1. 环境准备与依赖库

linux下shell脚本启动jar包实现过程

《linux下shell脚本启动jar包实现过程》确保APP_NAME和LOG_FILE位于目录内,首次启动前需手动创建log文件夹,否则报错,此为个人经验,供参考,欢迎支持脚本之家... 目录linux下shell脚本启动jar包样例1样例2总结linux下shell脚本启动jar包样例1#!/bin