简易CPU设计入门:控制总线的剩余信号(四)

news2025/1/30 12:34:04

项目代码下载

请大家首先准备好本项目所用的源代码。如果已经下载了,那就不用重复下载了。如果还没有下载,那么,请大家点击下方链接,来了解下载本项目的CPU源代码的方法。

CSDN文章:下载本项目代码

上述链接为本项目所依据的版本。

在讲解过程中,我还时不时地发现自己在讲解与注释上的一些个错误。有时,我还会添加一点新的资料。在这里,我将动态更新的代码版本发在下面的链接中。

Gitee项目:简易CPU设计入门项目代码:

讲课的时候,我主要依据的是CSDN文章链接。然后呢,如果你为了获得我的最近更新的版本,那就请在Gitee项目链接里下载代码。

准备好了项目源代码以后,我们接着去讲解。

本节前言

经过前面的讲解,控制总线的各路控制信号,我已经是讲得差不多了。

本节的代码,位于【......\cpu_me01\code\Ctrl_Center\】路径里面。主要讲解的代码,是【ctrl_center.v】。

我们来看一下控制总线的信号列表。

如果【ctrl_bus】的取值范围是【0 <= ctrl_bus < 4】,表示本次操作为寄存器写操作。
如果【ctrl_bus】的取值范围是【4 <= ctrl_bus < 8】,表示本次操作为寄存器读操作。
如果【ctrl_bus】的取值范围是【8 <= ctrl_bus < 12】,表示本次操作为内存写操作。
如果【ctrl_bus】的取值范围是【12 <= ctrl_bus < 16】,表示本次操作为内存读操作。
如果【ctrl_bus】的取值范围是【16 <= ctrl_bus < 20】,表示本次操作为立即数读操作。
如果【ctrl_bus】的取值范围是【20 <= ctrl_bus < 24】,表示本次操作为算术逻辑运算。
如果【ctrl_bus】的取值范围是【24 <= ctrl_bus < 28】,表示本次操作为更新指令指针寄存器【ip】。
如果【ctrl_bus】的取值范围是【28 <= ctrl_bus < 32】,表示本次操作为停机操作。

以上的块引用部分的内容,是控制总线的全部控制信号。我们之前讲了一部分,它们是【0 <= ctrl_bus < 28】的范围的信号。

这样一来,我们所剩下的,就只有指示停机的控制信号了。

本节,我们要去讲解的,便是用来指示停机的控制信号。

一.    系统总线与内部寄存器

本节所要讲解的东西,主要是跟停机信号有关。我们来看一看系统总线。

图1

图1中所示的代码,位于控制中心模块的端口声明部分。它们分别是我们的仿真CPU项目中的控制总线,地址总线,数据总线,它们都属于是系统总线。

图2

在图2中,65行到67行,分别是用来对控制总线、地址总线和数据总线进行缓存的变量。为啥要进行缓存呢?因为,三大系统总线中的信号的有效期,仅有一个时钟周期,稍纵即逝。而我们又需要在不同于总线数据有效期的时间里使用它们,所以呢,我们就声明了三个变量,用来将三大总线的数据给缓存下来,以便长久使用。

在图2的 64 行,我们声明了一个 reg 类型的数组,如下面的代码块所示。

reg [15:0] inner_reg[3:0];

它的含义是,声明四个 reg 类型的向量,每一个向量都是16位的,其中最高有效位是位15,最低有效位是位0。四个向量,用数组索引来引用。四个向量的引用方法为:inner_reg[0],inner_reg[1], inner_reg[2],inner_reg[3]。

这四个向量,是我们的系统中的四个内部寄存器。注意,它们是内部寄存器,而非通用寄存器。

图2的68行申请的变量,它在代码中,用来作为访问内部寄存器的索引变量。由于,每当新指令任务到来之时,要访问的内部寄存器的索引位于控制总线【ctrl_bus】中,所以,我将这个用来访问内部寄存器的索引变量命名为【ctrl_bus_index】。

二.    stop_flag 组节拍变量

图3

图3所示的几个变量,便是 ALU_flag 组节拍变量。从名字上可以大致猜到,【stop_flag】是主要的变量,【stop_flag_d1】比【stop_flag】延后一个时钟周期,【stop_flag_d2】比【stop_flag_d1】延后一个时钟周期。

是否如此呢?我们来看看下图所示的代码。

图4

从图4来看,的确是说,【stop_flag】是主要的变量,【stop_flag_d1】比【stop_flag】延后一个时钟周期,【stop_flag_d2】比【stop_flag_d1】延后一个时钟周期。

三.    new_task 变量与缓存系统总线的有效数据

这个变量是我在控制中心模块里申请的一个 wire 型变量,如下图所示。

图5

关于这个变量的含义,本节,我们依然是先不去深究。我们需要了解它的基本含义。如果它为1,就代表了一个新的微指令的开始,或者是代表了一个新的微操作的开始。

当 new_task 为1的时候,三大系统总线均含有有效数据。三大总线中的数据与 new_task 一样,有效数据的存在时间只有一个时钟周期。

对于 new_task 变量,它的值我们不需要保存。而对于三大系统总线的有效数据,我们是需要将其保存下来的,因为,它们正好处于有效期的时候,我们可能暂时用不到,但是 后面会有用,所以,我们需要将其缓存下来。

图6

在图6里面,我们可以看到三大系统总线缓存变量与内部寄存器索引变量【ctrl_bus_index】的逻辑。

在系统复位时,三大系统总线缓存变量与内部寄存器索引变量【ctrl_bus_index】均被非阻塞赋值为高阻态值。在平时,先来无事时,也就是在【else】分支里面,它们都保存着各自的现有值不变。

每当 new_task 为1时,也就是,每当开启了一个新的微指令的时候,三大系统总线缓存变量会缓存各自对应的系统总线的有效数据。同时呢,内部寄存器索引变量【ctrl_bus_index】会将控制总线【ctrl_bus】的位1与位0给缓存下来。对于停机指令而言,这个索引号,是为了在将来作为一个扩展,以指定停机方式。不过,目前,在代码逻辑方面,我并未针对停机指令的停机方式,作出任何规定,而只是将这个索引号给缓存了下来。

四.    stop_flag 组节拍变量的逻辑

 首先呢,我们来看 stop_flag 的逻辑。

图7
always @(posedge sys_clk or negedge sys_rst_n)
	if (sys_rst_n == 1'b0)
		stop_flag <= 1'b0;
	else if ((new_task == 1'b1) && (ctrl_bus >= 16'd28) && (ctrl_bus < 16'd32))
		stop_flag <= 1'b1;
	else
		stop_flag <= 1'b0;

图7中所示,是关于 stop_flag 的逻辑。它的逻辑是,系统复位与处于【else】分支时,它都是0值。每当系统检测到【(new_task == 1'b1) && (ctrl_bus >= 16'd28) && (ctrl_bus < 16'd32)】条件满足时,则 stop_flag 会被非阻塞赋值为 1。

 new_task 变量我们讲过了,它为1,表示开启了一个新的微指令操作,标志着新任务的开始。而当 new_task 为1时,控制总线【ctrl_bus】的值,则是表示了本次微指令的功能。

根据本节的前言部分的控制总线信号的列表信息,如果【ctrl_bus】的取值范围是【28 <= ctrl_bus < 32】,且 new_task 为 1 时,表示开启了一个新任务,这个新任务的内容,为算术逻辑操作。

想要执行停机操作,我们还需要指出,停机的方式是什么。那么,这个用来表示停机方式的数据在哪里呢?这个数据,目前是保存在地址总线变量的位1和位0,保存在【ctrl_bus[1:0]】之中,相当于内部寄存器的有效索引号。我们将【ctrl_bus[1:0]】赋给【ctrl_bus_index】,正是为了方便地引用这个索引号,引用这个停机方式。

五.    指示停机

图8

根据图8,我们可以了解到【exe_running】变量的逻辑。

根据165行与166行的代码,当系统复位时,【exe_running】变量被赋予 0 值。而根据171和172行代码,在【else】分支里面,也就是闲来无事之时,【exe_running】保持现有值不变。

根据167和168行代码,当【init_done】为1,也就是完成了系统初始化工作的时候,exe_running

会变为1。此时,【exe_running】从系统复位时候的 0 值第一次变为 1 值。

然后呢,根据169到170行的代码,当【stop_flag】为 1 时,【exe_running】会变为 0 值。

【exe_running】变为 0 值,表示CPU停止运行,结束运行状态。那么,当【exe_running】变为 0 时,CPU 的运行会发生什么变化呢?

图9

对于图9,我们看到,在406到407行里面,当【exe_running】变为0时,指令指针寄存器 ip 会被清零。我们再看。

图10

在图10之中,我们看一看【get_inst_en】的逻辑。

根据175和176行的代码,在系统复位时,取指令使能信号【get_inst_en】被清零。根据181行和182行代码,在【else】分支里面,也就是在闲来无事之时,取指令使能信号【get_inst_en】也是被清零了。

何时变为1呢?第1种情况,根据177和178行代码,当检测到【init_done】为1时,也就是,系统初始化工作完成了的时候,取指令使能信号【get_inst_en】会变为1。初始化完成是在系统复位以后。系统复位时,取指令使能信号【get_inst_en】被赋予 0 值。而在完成了系统初始化工作以后,取指令使能信号【get_inst_en】又被赋予1值,且是第1次被赋予1值。接下来,很快地,系统会处于【else】分支,也就是,取指令使能信号【get_inst_en】很快地又会变为0值。取指令使能信号【get_inst_en】为1的时间,仅仅是一个时钟周期而已。

第2种情况,根据179和180行代码,当【job_ok_d1 == 1 && exe_running == 1】条件满足之时,取指令使能信号【get_inst_en】才会被赋予1值。那么,如果我们破坏了第2种情况的成立条件,让【exe_running】为0,结果会如何?结果就是,179行的条件得不到满足,系统会一直处于181行的【else】分支的情况,因此,取指令使能信号【get_inst_en】会一直为0,不会再变为1值。

综上所述,当我们执行了停机指令,致使【exe_running】变为0值,这会导致两个结果。第1,指令指针寄存器 ip 被清零。第2,取指令使能信号【get_inst_en】会一直为0,也就是,系统不会再去取指令了。不去取指令,当然也就不会有译码与执行了,此时,CPU就真的是停止了。

结束语

到了这里,我想,我们又算是完成了一个不错的任务了。

对控制总线的控制信号的讲解,我认为是一件比较麻烦的事情。

好在,我这里,可以通过复制加修改的方法,来开展着写作。但是呢,在你那里,学习效果如何,我就不知道了。希望你能够学习好这一块的知识。

CPU的设计,是一个有趣的事情。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2284908.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

基础IO(2)

基础IO&#xff08;2&#xff09; 理解“⼀切皆⽂件” ⾸先&#xff0c;在windows中是⽂件的东西&#xff0c;它们在linux中也是⽂件&#xff1b;其次⼀些在windows中不是⽂件的东西&#xff0c;⽐如进程、磁盘、显⽰器、键盘这样硬件设备也被抽象成了⽂件&#xff0c;你可以使…

IDM-VTON本地部署教程:双重编码 + 文字提示,解锁真实野外试穿

一、介绍 IDM-VTON&#xff1a;改进扩散模型&#xff0c;实现真实的野外虚拟试穿。 技术原理&#xff1a;改进扩散模型&#xff0c;利用视觉编码器提取服装高级语义信息并与交叉注意力层融合&#xff0c;通过并行 UNet 结构的 GarmentNet 捕捉服装低级特征并与自注意力层结合&…

【2024年华为OD机试】 (C卷,200分)- 矩阵匹配(JavaScriptJava PythonC/C++)

一、问题描述 问题描述 给定一个大小为 ( N \times M )&#xff08;( N \leq M )&#xff09;的矩阵&#xff0c;从中选出 ( N ) 个数&#xff0c;要求任意两个数字不能在同一行或同一列。求选出来的 ( N ) 个数中第 ( K ) 大的数字的最小值。 输入描述 输入矩阵要求&#…

AI 浪潮席卷中国年,开启科技新春新纪元

在这博主提前祝大家蛇年快乐呀&#xff01;&#xff01;&#xff01; 随着人工智能&#xff08;AI&#xff09;技术的飞速发展&#xff0c;其影响力已经渗透到社会生活的方方面面。在中国传统节日 —— 春节期间&#xff0c;AI 技术也展现出了巨大的潜力&#xff0c;为中国年带…

Python 数据分析 - Matplotlib 绘图

Python 数据分析 - Matplotlib 绘图 简介绘图折线图单线多线子图 散点图直方图条形图纵置横置多条 饼图 简介 Matplotlib 是 Python 提供的一个绘图库&#xff0c;通过该库我们可以很容易的绘制出折线图、直方图、散点图、饼图等丰富的统计图&#xff0c;安装使用 pip install…

搭建Spark分布式集群

1&#xff0c;下载 下载 spark-3.5.4-bin-without-hadoop.tgz 地址&#xff1a; https://downloads.apache.org/spark/spark-3.5.4/ 2&#xff0c;安装 通过虚拟机设置共享文件夹将需要的安装包复制到linux虚拟机中 localhost1。虚拟机的共享盘在 /mnt/hgfs/。 将共享盘安装…

新年祝词(原创)

新年将至&#xff0c;福进万户。 家家团圆&#xff0c;事事顺心。 喜迎财神&#xff0c;多寿添金。 瑞兽迎春&#xff0c;炮竹声起。 趋吉避凶&#xff0c;蛇年大吉。 中华崛起&#xff0c;人人自强。 天下大同&#xff0c;百姓富足。 有情有义&#xff0c;平易近人。 …

线上突发:MySQL 自增 ID 用完,怎么办?

线上突发&#xff1a;MySQL 自增 ID 用完&#xff0c;怎么办&#xff1f; 1. 问题背景2. 场景复现3. 自增id用完怎么办&#xff1f;4. 总结 1. 问题背景 最近&#xff0c;我们在数据库巡检的时候发现了一个问题&#xff1a;线上的地址表自增主键用的是int类型。随着业务越做越…

ESP32 I2S音频总线学习笔记(二):I2S读取INMP441音频数据

简介 在这个系列的上一篇文章中&#xff0c;我们介绍了ESP32 I2S音频总线的相关知识&#xff0c;简要了解了什么是I2S总线、它的通信格式&#xff0c;以及相关的底层API函数。没有看过上篇文章的可以点击文章进行回顾&#xff1a; ESP32 I2S音频总线学习笔记&#xff08;一&a…

一文简单回顾Java中的String、StringBuilder、StringBuffer

简单说下String、StringBuilder、StringBuffer的区别 String、StringBuffer、StringBuilder在Java中都是用于处理字符串的&#xff0c;它们之间的区别是String是不可变的&#xff0c;平常开发用的最多&#xff0c;当遇到大量字符串连接的时候&#xff0c;就用StringBuilder&am…

matlab中,fill命令用法

在 MATLAB 中&#xff0c;fill 命令用于创建填充多边形的图形对象。使用 fill 可以在二维坐标系中绘制填充的区域&#xff0c;通常用于绘制图形的背景或显示数据分布。 基本语法 fill(X, Y, C)X 和 Y 是同样长度的向量&#xff0c;定义了多边形的顶点坐标。C 是颜色&#xff0…

计算机网络之链路层

本文章目录结构出自于《王道计算机考研 计算机网络_哔哩哔哩_bilibili》 02 数据链路层 在网上看到其他人做了详细的笔记&#xff0c;就不再多余写了&#xff0c;直接参考着学习吧。 1 详解数据链路层-数据链路层的功能【王道计算机网络笔记】_wx63088f6683f8f的技术博客_51C…

lib.exe正确用法winhv.lib生成方法

lib.exe /def:winhv.def /OUT:winhv.lib /machine:x64 winhv.def注意是 winhv.sys要不然会变成dll LIBRARY winhv.sys EXPORTSWinHvAllocateOverlayPagesWinHvDisablePartitionVtlWinHvDisableVpVtlWinHvEnablePartitionVtlWinHvEnableVpVtlWinHvFreeOverlayPagesWinHvGetCurr…

react-bn-面试

1.主要内容 工作台待办 实现思路&#xff1a; 1&#xff0c;待办list由后端返回&#xff0c;固定需要的字段有id(查详细)、type(本条待办的类型)&#xff0c;还可能需要时间&#xff0c;状态等 2&#xff0c;一个集中处理待办中转路由页&#xff0c;所有待办都跳转到这个页面…

Linux:一切皆文件

**文件描述符**&#xff1a;它是一种特殊的索引&#xff0c;本质上是进程中file_struct结构体成员fd_array数组的下标。在Linux等系统中&#xff0c;文件描述符是一个非负整数&#xff0c;用于标识打开的文件&#xff0c;是内核为了高效管理已被打开的文件所创建的索引。通过文…

【物联网】ARM核常用指令(详解):数据传送、计算、位运算、比较、跳转、内存访问、CPSR/SPSR、流水线及伪指令

文章目录 指令格式&#xff08;重点&#xff09;1. 立即数2. 寄存器位移 一、数据传送指令1. MOV指令2. MVN指令3. LDR指令 二、数据计算指令1. ADD指令1. SUB指令1. MUL指令 三、位运算指令1. AND指令2. ORR指令3. EOR指令4. BIC指令 四、比较指令五、跳转指令1. B/BL指令2. l…

项目集成Nacos

文章目录 1.环境搭建1.创建模块 sunrays-common-cloud-nacos-starter2.目录结构3.pom.xml4.自动配置1.NacosAutoConfiguration.java2.spring.factories 5.引入cloud模块通用依赖 2.测试1.创建模块 sunrays-common-cloud-nacos-starter-demo2.目录结构3.pom.xml4.application.ym…

QT交叉编译环境搭建(Cmake和qmake)

介绍一共有两种方法&#xff08;基于qmake和cmake&#xff09;&#xff1a; 1.直接调用虚拟机中的交叉编译工具编译 2.在QT中新建编译套件kits camke和qmake的区别&#xff1a;CMake 和 qmake 都是自动化构建工具&#xff0c;用于简化构建过程&#xff0c;管理编译设置&…

[cg] 使用snapgragon 对UE5.3抓帧

最近想要抓opengl 的api&#xff0c;renderdoc在起应用时会闪退&#xff08;具体原因还不知道&#xff09;&#xff0c;试了下snapgraon, 还是可以的 官网需要注册登录后下载&#xff0c;官网路径&#xff1a;Developer | Qualcomm 为了方便贴上已经下载好的exe安装包&#x…

物业巡更系统在现代社区管理中的优势与应用探讨

内容概要 在现代社区管理中&#xff0c;物业巡更系统正逐渐成为一种不可或缺的工具。结合先进的智能技术&#xff0c;这些系统能够有效地提升社区管理的各个方面&#xff0c;尤其是在巡检效率和信息透明度方面。通过实时记录巡检数据&#xff0c;物业管理人员能够确保工作人员…