简易CPU设计入门:本系统中的通用寄存器(三)

项目代码下载

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

下载本项目代码

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

本节前言

在上一节,我是讲解了寄存器元素模块的两行注释与一行参数声明代码。本节,我们要来讲解着变量声明的部分。

在讲解代码之前,还是请大家在下载了项目压缩包和解压缩以后,打开本节对应的代码文件。

本节代码文件,主要是指位于【......cpu_me01\code\Ctrl_Center\】路径里面的【register_element.v】。

一. 与寄存器ID相关的线网变量

图1

图1,为本节所讲解的变量声明部分。在这里,我还将上一节讲过了的参数声明代码也给包含了进来。之所以要包含参数声明部分,是因为,在第27行声明的 reg_id 变量与参数有着密切的关系。

图1中的27行,声明的变量,与参数 REG_ID 仅仅是大小写不同。我们再来看第29行的代码。

第29行代码,将 REG_ID 的值赋给线网变量 reg_id。这种赋值,似乎是没有必要的。因为,在代码中,使用 reg_id 的地方,其实都可以用 REG_ID 来代替。这么写,算是我个人的一种习惯。你也可以不采取我的写法。

二. 带有代理性质的reg型变量

我们来看第19行代码,它是声明了一个reg类型的变量,【data_sig_represent】。它和模块开头的信号声明部分的【data_sig_inner】一样,都是16位的。那么,请问,两者是什么关系?

回答是,【data_sig_represent】是【data_sig_inner】的代理。

我们请看下图所示的代码。
图2

在图2所示的95行代码中,我们看到,我们用连续赋值语句,将reg型变量【data_sig_represent】的值赋给了线网变量【data_sig_inner】。由于是连续赋值语句,所以呢,每当【data_sig_represent】变化时,【data_sig_inner】的值会立即变化并且与【data_sig_represent】的新值相等。

既然两个变量的值相等,那么,我们干脆只用【data_sig_inner】就好了,为啥还要多此一举,设置【data_sig_represent】这个代理变量呢?

这是因为,在寄存器元素模块中,我们需要让【data_sig_inner】参与时序逻辑的运算,要求它在非阻塞赋值中参与运算。

然而,在Verilog HDL中,wire型变量,不可以用于过程赋值语句的左侧变量,不可以用于时序逻辑运算中的左侧变量。
图3

在图3里面。我们暂且不关注 reg 型变量【data_sig_represent】的逻辑。在图3中,reg型变量,可以放在【data_sig_represent】的位置上,而线网类型的变量是不可以放在【data_sig_represent】的位置的。

在一个过程赋值语句中,或者是连续赋值语句中,赋值符号【=】或者【<=】左侧的变量,可以叫做左值。

wire型变量,不可以用于过程赋值语句的左值。过程赋值语句,它包括非阻塞赋值语句和阻塞赋值语句两种类型。wire型变量,在这两种类型的过程赋值语句中,都是不可以使用的。然而,reg型变量,它是可以用于过程赋值语句的左值的。

wire型变量【data_sig_inner】,不可以用于非阻塞赋值语句的左值,而我们又需要让它参与时序逻辑运算,让它成为非阻塞赋值语句的左值,在这种情况下,我们可以采取的一种做法,那就是申请一个reg型变量,让它作为wire型变量【data_sig_inner】的分身,来参与时序逻辑运算,并作为非阻塞赋值语句的左值。

在代码中,我们给wire型变量【data_sig_inner】设置的分身,便是 reg 型变量【data_sig_represent】。【data_sig_represent】的逻辑代码,正是图3中所示的代码。在这里,我们暂且不讲关于【data_sig_represent】的逻辑。我们本节也不会讲。在以后的分节里面,我们会去讲解的。

设置了 reg 型变量【data_sig_represent】以后,它还仅仅是一个单纯的 reg 型变量,它还不是【data_sig_inner】的分身。如何让【data_sig_inner】与【data_sig_represent】建立绑定关系呢?

通过图2中的95行代码所示的连续赋值语句,就可以建立【data_sig_inner】与【data_sig_represent】的绑定关系了。

我们还是回到图1,。
图1副本

在图1里面,在20行,我们建立了另一个代理性质的变量,reg 型的【work_ok_represent】变量。

在图2中,在96行,我们看到了【work_ok_represent】与【work_ok_inner】的绑定关系、在本代码文件中,【work_ok_represent】是【work_ok_inner】的时序逻辑代理。

三. 节拍变量

在这里,我们来讲解图1中的第21行到第25行的代码。

这几行代码里面,它是分为两组。

【get_time】,【get_time_d1】和【get_time_d2】是一组,而【write_time】与【write_time_d1】是另一组。

我先来将get_time组变量。

【get_time】变量用来标识一个基准的时刻。【get_time_d1】是比【get_time】延迟一个时钟周期的信号,而【get_time_d2】是比【get_time】延迟两个时钟周期的变量。

假定,初始条件里面,三个变量的值,均为0。

然后呢,get_time的值,在后续的几个时钟的上升沿,依次变化为1,0,1,1。再往后,get_time的值就都是0了。在这种情况下,我们来看get_time,get_time_d1与get_time_d2的变化情况

初始条件:get_time == 0, get_time_d1 == 0, get_time_d2 == 0.

1号上升沿:get_time == 1, get_time_d1 == 0, get_time_d2 == 0.

2号上升沿:get_time == 0, get_time_d1 == 1, get_time_d2 == 0.

3号上升沿:get_time == 1, get_time_d1 == 0, get_time_d2 == 1.

4号上升沿:get_time == 1, get_time_d1 == 1, get_time_d2 == 0.

5号上升沿:get_time == 0, get_time_d1 == 1, get_time_d2 == 1.

6号上升沿:get_time == 0, get_time_d1 == 0, get_time_d2 == 1.

7号上升沿:get_time == 0, get_time_d1 == 0, get_time_d2 == 0.

从上面的变化列表可以看出,get_time一组的值的变化是相同的,只不过,存在着节拍延迟的情况。

get_time一组是这样的延迟情况,write_time与之类似,只是这一组里面只有两个变量而已。

那么,设置这种节拍变量有什么意义吗?

有的。无论是做广播体操,还是排练舞蹈,都需要有节拍。舞蹈有了节拍,跳舞的人,都按照节拍来演练动作,那么,大家的动作就都可以整齐划一了。广播体操有了节拍,学生们也可以大致保持动作的整齐,而不至于乱成一锅粥。

当然了,实际在做广播体操的人,好多人是不去认真做的。但是呢,有了节拍以后,即使部分人只是慵懒得伸伸胳膊,伸伸腿,大体上的动作,也是整齐划一的,而非你做你的我做我的,你打排球我练太极拳,你躺着我趴着。

我们这几节,要讲解的东西,是寄存器元素模块,以及寄存器的读写操作。那么,我们设置节拍,就是想要确定,对于寄存器的读操作或者写操作,何时进行特定的操作,何时完成。有了这种节拍变量,可以使寄存器的读写操作有序进行,不至于混乱。

关于节拍变量,我们就先讲到这里吧。在后续的几节,我们还是会具体地来讲解着节拍变量的内容的。

在本节,我们可以对节拍变量有一个大致的印象。

结束语

本节的内容,应该是不难理解吧。既然不是很难,那么,希望大家能够学好本节知识。

大家再见。

相关推荐
即将头秃的程序媛1 小时前
centos 7.9安装tomcat,并实现开机自启
linux·运维·centos
fangeqin1 小时前
ubuntu源码安装python3.13遇到Could not build the ssl module!解决方法
linux·python·ubuntu·openssl
国科安芯2 小时前
【AS32系列MCU调试教程】SPI调试的常见问题解析
单片机·嵌入式硬件·性能优化·硬件架构·硬件工程
爱奥尼欧3 小时前
【Linux 系统】基础IO——Linux中对文件的理解
linux·服务器·microsoft
超喜欢下雨天3 小时前
服务器安装 ros2时遇到底层库依赖冲突的问题
linux·运维·服务器·ros2
search73 小时前
Verilog 语法介绍 1-1结构
fpga开发
tan77º4 小时前
【Linux网络编程】网络基础
linux·服务器·网络
笑衬人心。4 小时前
Ubuntu 22.04 + MySQL 8 无密码登录问题与 root 密码重置指南
linux·mysql·ubuntu
chanalbert6 小时前
CentOS系统新手指导手册
linux·运维·centos
星宸追风6 小时前
Ubuntu更换Home目录所在硬盘的过程
linux·运维·ubuntu