当前位置: 首页 > article >正文

简易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与之类似,只是这一组里面只有两个变量而已。

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

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

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

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

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

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

结束语

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

大家再见。


http://www.kler.cn/a/459307.html

相关文章:

  • 自从学会Git,感觉打开了一扇新大门
  • 2024国城杯 Web
  • SQL 实战:分页查询的多种方式对比与优化
  • 自动化办公 | 根据成绩进行自动评级
  • JavaScript中的JSON是什么
  • C语言优化技巧--达夫设备(Duff‘s Device)解析
  • 实景三维点云处理专业软件ArcGIS根据DSM生成地表点云集
  • IS-2T2R存储器:AWS精度下降问题的解决方案
  • js单例模式
  • Java网络编程之UDP协议介绍及示例代码
  • qingzhou
  • 【Ubuntu】Ubuntu server 18.04 搭建Slurm并行计算环境(包含NFS)
  • WinForm事件遇到异步方法的处理方式
  • 5_SparkGraphX讲解
  • 职场中哪些话中话,弦外之音
  • word中插入zotero引用
  • QT写的动态正弦曲线图显示并打印
  • 多模态机器人
  • 24.小R的随机播放顺序<字节青训营-中等题>
  • 实战指南:Shiro、CAS打造完美单点登录体验
  • 运行python程序报错 undefined symbol: ffi_type_uint32 的参考解决方法
  • 马原复习笔记
  • AWS K8s 部署架构
  • 在云服务器中编译IDF(ESP32库)
  • 2024年个人总结
  • 使用 PyInstaller 和 hdiutil 打包 Tkinter 应用为 macOS 可安装的 DMG 文件