简易CPU设计入门:算术逻辑单元(四)

项目代码下载

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

CSDN文章:下载本项目代码

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

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

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

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

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

本节前言

上一节的文章,我主要是采用【复制 + 修改】的方法来完成的。本节,依然会采用这种方法。因为,整个的算术逻辑操作的代码思路,其实是一样的。

在本节,我们要来讲解乘法运算。

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

一.    端口声明

我们来看一下端口声明部分的代码。

图1

【multi_cell.v】里面的端口声明,和相同路径里面的【ALU.v】里面的端口声明是一样的。

第3行和第4行是系统时钟与系统复位信号。系统时钟信号,其频率为50MHz。系统复位信号为低电平有效。

第6行到第8行,它们对应着控制中心里面的3个内部寄存器。其中呢,【oprand0】对应着控制中心里面的0号内部寄存器,【oprand1】对应着控制中心里面的1号内部寄存器,【oprand2】对应着控制中心里面的2号内部寄存器。

我们可以看一下控制中心里面的代码。

图2,控制中心里面的代码

图2里面的代码,是控制中心模块里面的代码。它显示了三个操作数变量与三个内部寄存器的绑定代码。在这里,三个操作数变量【oprand0-2】是如何声明的,以及它们是如何与本节的图1中的三个操作数变量【oprand0-2】相联系的,我就不去展示了。有兴趣的话,你可以自己去查看。

第10行到第12行,是本系统中的三大内部总线。第14行,是用于发送【成功完成】信号的总线。

二.    变量声明与总线绑定

图3

第17行和第18行,是用来计时的两个变量。其中呢,【cal_time_d1】延后【cal_time】一个时钟周期。

第20行,它是用来保存计算结果的。本节的模块名称为【multi_cell】,所以呢,这里的 res,保存的是乘法法运算的运算结果。

第21行和第22行,分别是端口声明中的【work_ok_inner】和【data_sig_inner】总线变量的代理变量。

我们来看一下两个总线代理与对应的总线变量的绑定代码。

图4

图4显示了这种总线变量与它的代理变量的绑定代码。

三.    计算

图5
always @(posedge sys_clk or negedge sys_rst_n)if (sys_rst_n == 1'b0)res <= 1'b0;else if ((ctrl_sig_inner[4] == 1'b1) && (addr_sig_inner == 6'd2))res <= oprand1 * oprand0;elseres <= res;

图5中的代码,就是执行计算的代码,它也是关于 res 的逻辑的代码。

res的逻辑是,在系统复位时,它是被赋值为0值。在【else】分支里面,也就是闲来无事时,它是保持现有值不变。而每当满足【(ctrl_sig_inner[4] == 1'b1) && (addr_sig_inner == 6'd2)】条件之时,它就执行计算,将【oprand1 * oprand0】的运算结果赋给 res 变量。

在这里,【ctrl_sig_inner[4] == 1'b1】是什么意思?

我们还是来复习一下内部控制总线的知识。

图6
/*********************************************
ctrl_sig_inner[0]:register write enable:寄存器写使能
ctrl_sig_inner[1]:register read enable:寄存器读使能
ctrl_sig_inner[2]:random memory write ebable:内存写使能
ctrl_sig_inner[3]:random memory read enable:内存读使能
ctrl_sig_inner[4]:Arithmetic and Logic calculate:算术逻辑运算
ctrl_sig_inner[5]:reserve:保留
ctrl_sig_inner[6]:reserve:保留
ctrl_sig_inner[7]:reserve:保留
ctrl_sig_inner[8]:reserve:保留
ctrl_sig_inner[9]:reserve:保留
ctrl_sig_inner[10]:reserve:保留
ctrl_sig_inner[11]:reserve:保留
ctrl_sig_inner[12]:reserve:保留
ctrl_sig_inner[13]:reserve:保留
ctrl_sig_inner[14]:reserve:保留
ctrl_sig_inner[15]:reserve:保留
还有一种运算叫做读取立即数,将立即数放入内部寄存器。
此运算不需要通过内部信号的参与。
************************************************/

根据图6,当内部控制总线的位4为1,而其余位都是0值时,表示控制中心向算术逻辑单元发布了算术逻辑运算使能信号。

算术逻辑运算,可以包含着多种运算类型。加法算一个,减法也算是一个。那么,如何来区分不同的运算类型呢?这个时候,我们就通过内部地址总线【addr_sig_inner】来表示不同的运算种类。

当本模块收到的【addr_sig_inner】总线信号的值是2时,就表示执行乘法运算。

所以呢,图5所示代码的意思是,当【multi_cell】模块收到了算术逻辑运算使能信号,并且根据内部地址信号值,确定本次的运算类型为乘法运算时,则在非阻塞赋值阶段,将端口中的操作数1乘以操作数0,结果放在 res 变量里面。

四.    计时变量

图7
always @(posedge sys_clk or negedge sys_rst_n)if (sys_rst_n == 1'b0)cal_time <= 1'b0;else if ((ctrl_sig_inner[4] == 1'b1) && (addr_sig_inner == 6'd2))cal_time <= 1'b1;elsecal_time <= 1'b0;

在图7里面,显示了【cal_time】的逻辑。在系统复位与【else】分支里面,它都是被赋予0值。而在满足了【(ctrl_sig_inner[4] == 1'b1) && (addr_sig_inner == 6'd2)】条件之时,它就被赋予 1 值。

这个条件,它其实和第三分节中的 res 被重新计算的条件一样的。它是说,在收到了算术逻辑运算使能信号,且根据内部地址总线的值,判断出,本次执行的运算类型为乘法运算时,则将【cal_time】变量赋值为 1 值。

然后呢,我们再来看【cal_time_d1】的逻辑。

图8

图8显示了【cal_time_d1】的逻辑。它是将【cal_time】延后一个时钟周期,所形成的信号。

五.    总线逻辑

图9

图9显示了本模块的两个总线变量【data_sig_inner】和【work_ok_inner】的对应代理变量【data_sig_represent】和【work_ok_represent】的逻辑。

当检测到【cal_tijme == 1】条件满足之时,在此后的非阻塞赋值阶段,【data_sig_represent】和【work_ok_represent】被赋予 0 值。

当检测到【cal_tijme_d1 == 1】条件满足之时,在此后的非阻塞赋值阶段,【data_sig_represent】和【work_ok_represent】分别被赋予各自的有效值。其中,【data_sig_represent】被赋予 res 的值,也就是,将本模块的算术逻辑运算结果,保存下来。而【work_ok_represent】被赋予 1 值。

在这里,两大代理变量分别与本模块的两大总线变量相绑定。而本模块的两大总线变量,又与各自的同名的内部总线相连接。所以呢,向代理写入了什么值,就相当于,向对应的内部总线传递了什么值。

六.    总体逻辑

本模块的总体逻辑是,当检测到了算术逻辑使能信号,且运算类型为乘法运算时,则执行操作数1乘以操作数0的乘法运算,并将运算结果暂时保存在 res 变量里面。同时,将【cal_time】设置为 1 值。

然后呢,在检测到【cal_time == 1】条件满足之时,对两大内部总线【data_sig_inner】和【work_ok_inner】分别写入 0 值。同时,将【cal_time_d1】设置为 1 值。

在检测到【cal_time_d1 == 1】条件满足之时,对两大内部总线【data_sig_inner】和【work_ok_inner】分别传递有效值。其中呢,【data_sig_inner】被传入运算结果 res 的值,【work_ok_inner】被传递 1 值。

【work_ok_inner】被写入 1 值,表示本次操作成功完成。在【work_ok_inner】被写入 1 值的同时,运算结果也同时被传到【data_sig_inner】总线里面了。所以呢,成功完成信号【work_ok_inner】与运算结果【data_sig_inner】同时有效。控制中心,会从这两个内部总线接收到消息,并且会进行相应的处理的。

结束语

本节内容,应该不难。如果你理解了我之前所讲解的加法与减法操作的逻辑,本节,其实并不难。

在你熟悉了之前的加法与减法的讲解内容以后,有可能你会觉得,本节的内容,有点废话练习的意思。

其实,在学习中,有些时候,这种重复性的东西,对于学习是有好处的。重复几次,可以令你对有关知识更为熟练,印象也更为深刻。

在我的讲解中,基本上,我是喜欢采用比较详细的讲解方式。详细,也就意味着,好多的讲解,有可能,你已经是很熟悉了。

学习,是一种在旧知识的基础上,积累新知识的过程。如果,我们在学习的时候,旧知识有着足够的比例,因而在学习新知识的时候,并不觉得累,我觉得是好的。

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

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

相关文章

Spring Boot 和微服务:快速入门指南

&#x1f496; 欢迎来到我的博客&#xff01; 非常高兴能在这里与您相遇。在这里&#xff0c;您不仅能获得有趣的技术分享&#xff0c;还能感受到轻松愉快的氛围。无论您是编程新手&#xff0c;还是资深开发者&#xff0c;都能在这里找到属于您的知识宝藏&#xff0c;学习和成长…

VSCode 使用鼠标滚轮控制字体

一、 文件 | 首选项 | 设置 二、单击在 settings.json中编辑 "editor.mouseWheelZoom": true 注注注意&#xff1a;保存哦&#xff01;ctrlS 三、测试 按住ctrl鼠标滚轮&#xff0c;控制字体大小

rabbitmq的三个交换机及简单使用

提前说一下&#xff0c;创建队列&#xff0c;交换机&#xff0c;绑定交换机和队列都是在生产者。消费者只负责监听就行了&#xff0c;不用配其他的。 完成这个场景需要两个服务哦。 1直连交换机-生产者的代码。 在配置类中创建队列&#xff0c;交换机&#xff0c;绑定交换机…

代码随想录算法训练营第3天(链表1)| 203.移除链表元素 707.设计链表 206.反转链表

一、203.移除链表元素 题目&#xff1a;203. 移除链表元素 - 力扣&#xff08;LeetCode&#xff09; 视频&#xff1a;手把手带你学会操作链表 | LeetCode&#xff1a;203.移除链表元素_哔哩哔哩_bilibili 讲解&#xff1a;代码随想录 注意&#xff1a; 针对头结点和非头结点的…

CES Asia 2025科技盛宴,AI智能体成焦点

2025第七届亚洲消费电子技术展&#xff08;CES Asia赛逸展&#xff09;将在北京拉开帷幕&#xff0c;AI智能体有望成为展会的核心亮点。 深圳市人工智能行业协会发文表示全力支持CES Asia 2025&#xff08;赛逸展&#xff09;&#xff0c;称其为人工智能领域的创新发展提供了强…

matlab编写分段Hermite插值多项式

文章目录 原理使用分段Hermite插值多项式原因公式第一类的两个插值积函数第二类的两个插值积函数 例题法一法二 代码分段 Hermite 插值的思路&#xff1a;分段 Hermite 插值多项式的构造&#xff1a;MATLAB 实现代码&#xff1a;结果如图&#xff1a;注归一化变量的作用&#x…

Cline(原Claude Dev)开源的IDE AI插件,如何搭配OpenRouter实现cursor功能,Cline怎么使用

Cline&#xff08;原Claude Dev&#xff09;是一个开源的IDE AI插件&#xff0c;可以使用你的命令行界面和编辑器的人工智能助手。 你可以直接在VS Code编辑器进行安装。如果你使用过Cursor AI IDE的话&#xff0c;可以尝试最新发布的Cline3.1版本。 在OpenRouter上&#xff0…

计科高可用服务器架构实训(防火墙、双机热备,VRRP、MSTP、DHCP、OSPF)

一、项目介绍 需求分析&#xff1a; &#xff08;1&#xff09;总部和分部要求网络拓扑简单&#xff0c;方便维护&#xff0c;网络有扩展和冗余性&#xff1b; &#xff08;2&#xff09;总部分财务部&#xff0c;人事部&#xff0c;工程部&#xff0c;技术部&#xff0c;提供…

企业级PHP异步RabbitMQ协程版客户端 2.0 正式发布

概述 workerman/rabbitmq 是一个异步RabbitMQ客户端&#xff0c;使用AMQP协议。 RabbitMQ是一个基于AMQP&#xff08;高级消息队列协议&#xff09;实现的开源消息组件&#xff0c;它主要用于在分布式系统中存储和转发消息。RabbitMQ由高性能、高可用以及高扩展性出名的Erlan…

AsyncOperation.allowSceneActivation导致异步加载卡死

先看这段代码&#xff0c;有个诡异的问题&#xff0c;不确定是不是bug public class Test : MonoBehaviour {void Start(){StartCoroutine(LoadScene(Ego.LoadingLevel));}IEnumerator LoadScene(string sceneName){LoadingUI.UpdateProgress(0.9f);yield return new WaitForS…

C#使用MVC框架创建WebApi服务接口

第一步,使用VS2019新建MVC-Web API应用程序 创建BridgeApi 第二步,运行将生成默认的示例网页,网页Url为 https://localhost:44361/home/index 右键 项目 添加 WebAPI控制器类 添加 我们可以看到App_Start目录下 有三个文件: BundleConfig.cs代表 捆绑文件的引用 有脚本文件…

hive迁移后修复分区慢,怎么办?

我有1个30TB的分区表&#xff0c;客户给的带宽只有600MB&#xff0c;按照150%的耗时来算&#xff0c;大概要迁移17小时。 使用hive自带的修复分区命令&#xff08;一般修复分区比迁移时间长一点&#xff09;&#xff0c;可能要花24小时。于是打算用前面黄大佬的牛B方案。 Hive增…

慧集通(DataLinkX)iPaaS集成平台-业务建模之业务对象(一)

通过左侧导航菜单〖业务建模〗→〖业务对象〗&#xff0c;进入该界面&#xff1b;在该界面可以查看到系统中已存在的业务对象&#xff1b; 1.新建业务对象 在DatalinkX中进入【业务建模】的【业务对象】页面&#xff0c;点击【新建】按钮进入新建页面&#xff1b; 新建页面左侧…

Linux系统之hostname相关命令基本使用

Linux系统之hostname相关命令基本使用 一、检查本地系统版本二、hostname命令的帮助说明中文帮助说明 三、hostname命令的基本使用1. 查看计算机名2. 查看本机上所有IP地址3. 查看主机FQDN4. 查看短主机名 四、hostnamectl命令的使用1. 查看主机详细信息2. 设置主机名3. hostna…

DC系列靶场渗透--DC-3

目录 环境搭建 开始渗透 扫存活 扫端口 扫服务 查看80端口 尝试在80端口中的登陆页面寻找sql注入失败 扫目录 进入/htaccess.txt目录看一下 我们尝试找一下Joomla3.7.0版本的漏洞 我们尝试利用该漏洞 查数据库名 查表名 查列名 查数据 找到密码的可能的编码方式…

js代理模式

允许在不改变原始对象的情况下&#xff0c;通过代理对象来访问原始对象。代理对象可以在访问原始对象之前或之后&#xff0c;添加一些额外的逻辑或功能。 科学上网过程 一般情况下,在访问国外的网站,会显示无法访问 因为在dns解析过程,这些ip被禁止解析,所以显示无法访问 引…

uniapp 之 uni-forms校验提示【提交的字段[‘xxx‘]在数据库中并不存在】解决方案

目录 场景问题代码结果问题剖析解决方案 场景 uni-forms官方组件地址 使用uniapp官方提供的组件&#xff0c;某个表单需求&#xff0c;单位性质字段如果是高校&#xff0c;那么工作单位则是高校的下拉选择格式&#xff0c;单位性质如果是其他的类型&#xff0c;工作单位则是手动…

深度学习知识点:RNN

文章目录 1.简单介绍2.网络结构3.应对梯度消失 1.简单介绍 循环神经网络&#xff08;RNN&#xff0c;Recurrent Neural Network&#xff09;是一类用于处理序列数据的神经网络。与传统网络相比&#xff0c;变化不是特别大&#xff0c;不如CNN的变化那么大。 为什么要有循环神经…

(leetcode算法题)287. 寻找重复数(经典题目,二分解法)

如果一个题目限定了数据范围是[1, n]内的整数&#xff0c;那么这个题目可以思考的就是 nums[i]和 i 的关系&#xff0c;769. 最多能完成排序的块 这个题就使用到了子数组中最大值和 连续[0, n - 1]的关系 而对于本题来说&#xff0c;也可以思考[1, n] 和 nums[i] 的关系&…

4.1、二纤单向、二纤双向、四纤双向,网络级保护

1、线性复用段保护&#xff08;LMSP&#xff09; 就像是给网络业务传输准备的一个 “保险”。在 SDH 和 MSTP 网络里&#xff0c;业务信号要通过一段一段的路&#xff08;复用段&#xff09;来传输&#xff0c;LMSP 就是为了保证这些路出问题的时候&#xff0c;业务还能正常走。…