简易CPU设计入门:验证取指令模块【未完成】

项目代码下载

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

下载本项目代码

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

本节前言

想要学习本节,前提是,你得是学习过我讲解取指令模块的有关章节。最好呢,你是从本系列专栏的开头,连续地,学习到这里的。否则,知识不完整,你也不知道哪里落下了,即使你来问我,我可能也不知道,你究竟是差在哪里未理解。

下面的四个链接,是我讲解取指令模块的四篇文章。

取指令(一)

取指令(二)

取指令(三)

取指令(四)

以上的四个讲解取指令模块的文章,建议没有学习的同学,还是先去学习一下。如果你学完完了上述的内容,那么,我们可以继续本文的学习。

取指令模块,它指的是【cpu_me01\code\get_instruct.v】代码文件中的模块。取指令模块的代码,我就不贴了。

验证取指令模块的代码,我这里已经是写好了,我来将其内容给贴在下面的代码块中。

`timescale 1ns/1ns
module tb_get_instruct();
reg sys_clk;
reg sys_rst_n;
reg get_inst_en;
reg [15:0] ip;	
wire decode_en;
wire [15:0] instruct_code;wire [15:0] ip_buf;
wire [15:0] instruct_code_wire;
wire rd_en;
wire rd_en_d1;
wire rd_en_d2;reg [9:0] cnt;assign ip_buf = get_instruct_inst.ip_buf;
assign instruct_code_wire = get_instruct_inst.instruct_code_wire;
assign rd_en = get_instruct_inst.rd_en;
assign rd_en_d1 = get_instruct_inst.rd_en_d1;
assign rd_en_d2 = get_instruct_inst.rd_en_d2;initial
beginsys_clk = 1'b1;sys_rst_n <= 1'b0;
#60sys_rst_n <= 1'b1;
endalways #10 sys_clk = ~sys_clk;always @(posedge sys_clk or negedge sys_rst_n)if (sys_rst_n == 1'b0)cnt <= 10'd0;else if (cnt < 10'd20)cnt <= cnt + 10'd1;elsecnt <= cnt;always @(posedge sys_clk or negedge sys_rst_n)if (sys_rst_n == 1'b0)beginget_inst_en <= 1'b0;ip <= 16'h0000;endelse if (cnt == 10'd3)beginget_inst_en <= 1'b1;ip <= 16'h0002;endelsebeginget_inst_en <= 1'b0;ip <= 16'h0000;endget_instruct get_instruct_inst(.sys_clk(sys_clk),.sys_rst_n(sys_rst_n),.get_inst_en(get_inst_en),.ip(ip),.decode_en(decode_en),.instruct_code(instruct_code)
);endmodule

以上,是验证取指令模块的代码内容了。接下来,我就来讲解代码。

代码讲解

图1

图1中的代码,是验证模块的前14行的内容。其中,第1行,这个是规定了本仿真验证模块使用的时间尺度。在【1ns/1ns】这部分语句中,左边的【1ns】代表着,本模块的1个时间单位,是1ns。右边的【1ns】用于指定仿真过程中进位取整的精度为1ns。

需要注意的是,如下的写法是错误的。

`timescale 60ns/3ns

这是因为,无论是左边的指定时间单位的数值,还是右边的指定时间精度的数值,只能采用1、10或者100,两边的数值可以相同,也可以不同。

第2行,是规定了本模块的模块名。我们的取指令模块的模块名是【get_instruct】,那么,对该模块的验证,就是在它的前面,加上【tb_】前缀,变为【tb_get_instruct】。

一般地,我们想要验证的模块是什么名字,验证该模块的模块名,都是在被验证模块的前面加上【tb_】前缀。

第3行到第8行,它们对应着取指令模块的输入输出端口。其实我在写仿真验证代码的时候,就是将取指令模块的输入输出端口给复制过来的。复制过来以后,将端口类型【input wire】或者【input】修改为【reg】,将【output wire】或者【output】修改为【wire】,就可以了。

我们可以来看一看取指令模块的端口声明部分。

图2,取指令模块的端口声明部分

我们将图2的3到9行,与图1的3到8行做一个对比,就会明白【tb_get_instruct】模块的3到8行的写法了。

我们再回到图1里面。图1的10到14行,声明了几个wire型变量,这几个变量,其实在取指令模块里面都有。我们在图1里面,也就是在【tb_get_instruct】模块里面声明这几个变量,其实是为了将验证模块与取指令模块的对应变量连接起来,以观测取指令模块中相应变量的波形变化情况。

我们来看一看取指令模块声明的几个变量。

图3,取指令模块声明的几个变量

在图3中,可以看到,在取指令模块中声明的几个变量,有reg型的,也有wire型的。而在图1的10到14行,我们声明的同名变量,均为wire型的。这是因为,我们在验证模块中声明的变量,是为了与取指令模块中的相应变脸连接起来,实时地观察取指令模块中对应变量的值。想要实现实时观测的效果,而没有仿真的延迟,那么,在仿真验证模块中,我们就需要用wire型变量,来连接取指令模块中的对应变量。

一般来讲,我们若是想要在test bench文件中观测被验证模块中的某一个变量,我们就需要再test bench中声明一个wire型变量,并且用连续赋值语句将验证模块与被验证模块中的相应的变量连接起来。wire型变量,它具备着实时性,可以用来实时观测。

既然提到了连续赋值语句,而且,我们在图1中的10到14行声明几个wire型变量,正是为了与取指令模块中的对应同名变量相连接,那么,我们肯定是在test bench中,用到了连续赋值语句。那么,我们就来看一看我们的连续赋值语句。如下面的代码块所示。

assign ip_buf = get_instruct_inst.ip_buf;
assign instruct_code_wire = get_instruct_inst.instruct_code_wire;
assign rd_en = get_instruct_inst.rd_en;
assign rd_en_d1 = get_instruct_inst.rd_en_d1;
assign rd_en_d2 = get_instruct_inst.rd_en_d2;

上面的代码块,都用到了【tb_get_instruct】模块中所实例化的取指令模块的模块名,【get_instruct_inst】。实例化取指令模块的代码,我们一会儿再看。

从上面的代码块,我们看到,我们的确是通过连续赋值语句,将本验证模块【tb_get_instruct】中的几个变量与取指令模块中的同名变量给连接起来了。

接下来呢,我们再来看一看验证模块中,实例化取指令模块的代码。如下图所示。

图4

图4的写法,其实,也就是一种套路写法。第59行,是模块与实例名。第60行到65行,是【get_instruct】模块与本验证模块【tb_get_instruct】的变量连接情况。写这个变量连接的代码的时候,我是将取指令模块的端口声明部分,给复制过来,然后呢,将端口类型给去掉,把【[15:0]】等等的向量类型也给去掉,仅仅留下端口名。然后呢,在每一个端口名前面加上英文的句点符号。然后呢,每一行的端口右边加上括号,括号内写上本模块的要连接的变量名。

一般地,我去写验证模块的时候,我都将验证模块与被验证模块的连接变量设置为相同的名称。当然了,随着代码复杂度的增加,免不了地,以后,会有被验证模块的端口名与验证模块的连接变量名不一致的情况。

在写实例化代码的时候,在初学阶段,究竟是否要将验证模块的连接变量与被验证模块的端口名设置为相同,这个你自己来决定。我的建议是,你在跟着哪本书或者哪个教程来学习,你就先学习哪种写法。

在我们的专栏里面,在写实例化代码的时候,我倾向于,将被验证模块的端口名与验证模块的连接变量设置为相同的名称。

在图4里面,写完了实例化代码以后,在68行,是【endmodule】字样。也就是,实例化代码,位于【tb_get_instruct】的最后面的位置。

一般地,书写 test bench 代码文件的时候,实例化代码,都是写在最后的位置。至少我这里是这样子来写的。你当然可以自由地设置其书写位置,不过,我确实是这么来写的。貌似,我在学习FPGA开发版的配套教程的时候,里面也是这么写的。

某些个一般的通行的惯例,大家跟着照做就可以了。

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

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

相关文章

MySQL详细学习攻略 MySQL基础非常全面教程 MySQL安装教程

MySQL安装教程 章节目录 一、MySQL简介与安装前准备 二、Windows系统下MySQL的安装 三、Linux系统下MySQL的安装 四、MySQL安装后的基本配置 五、MySQL服务的启动与停止 六、MySQL客户端工具的使用 七、MySQL安装常见问题与解决方案 一、MySQL简介与安装前准备 重点内容知识…

Flythings学习(四)串口通信

文章目录 1 串口编程基本步骤1.1 打开串口1.2 配置串口 1.3 读串口1.4 发送串口1.5 关闭串口 2 综合使用3 如何在软件上保证串口稳定通信4 flythings中的串口通讯5 协议接收部分使用和修改方法6 通讯协议数据怎么和UI控件对接 1 串口编程基本步骤 串口通信有5个步骤 1.打开串口…

YOLOv11模型改进-注意力机制-引入自适应稀疏自注意力ASSA

随着目标检测领域的快速发展&#xff0c;YOLO系列模型凭借其端到端、高效的检测性能逐渐成为工业界和学术界的标杆。然而&#xff0c;如何进一步优化YOLOv11的特征提取能力&#xff0c;减少冗余信息并提升模型对复杂场景的适应性&#xff0c;仍是一个值得深入探讨的问题。为此&…

Android:记录一个打包发布版的release包以后闪退的问题

个人感觉其实release闪退的问题挺难排查的&#xff0c;因为release包运行起来as捕获不到相应的应用程序进程&#xff0c;从而不易查看到日志&#xff0c;也是我玩得不溜&#xff0c;大家有不同的方法可以评论区探讨&#xff0c;我也定期回复一些评论一起讨论。以下是我遇到的情…

【数据结构】宜宾大学-计院-实验三

线性表的应用——实现两多项式的相加 课前准备&#xff1a;实验学时&#xff1a;2实验目的&#xff1a;实验内容&#xff1a;实验结果&#xff1a;实验报告:&#xff08;及时撰写实验报告&#xff09;实验测试结果&#xff1a;代码实现&#xff1a;&#xff08;C/C&#xff09;…

安宝特方案 | AR技术在轨交行业的应用优势

随着轨道交通行业不断向智能化和数字化转型&#xff0c;传统巡检方式的局限性日益凸显。而安宝特AR眼镜以其独特的佩戴方式和轻便设计&#xff0c;为轨道交通巡检领域注入了创新活力&#xff0c;提供了全新的解决方案。 01 多样化佩戴方法&#xff0c;完美适应户外环境 安宝特…

访问控制列表(课内实验)

实验2&#xff1a;访问控制列表 实验目的及要求&#xff1a; 通过实验&#xff0c;进一步的理解标准ACL与扩展ACL的工作原理及执行过程。理解通配符的概念&#xff0c;熟练掌握标准ACL与扩展ACL的配置指令&#xff0c;掌握将访问控制列表应用VTY线路上&#xff0c;并且能够判断…

鸿蒙开发 四十五 鸿蒙状态管理(嵌套对象界面更新)

当运行时的状态变量变化&#xff0c;UI重新渲染&#xff0c;在ArkUI中称为状态管理机制&#xff0c;前提是变量必须被装饰器修饰。不是状态变量的所有更改都会引起刷新&#xff0c;只有可以被框架观测到的更改才会引起UI刷新。其中boolen、string、number类型&#xff0c;可观察…

Oracle漏洞修复 19.3 补丁包 升级为19.22

1.场景描述 上周末2024-10-12日,服务器扫出漏洞,希望及时修复。其中,oracle的漏洞清单如下,总结了下,基本都是 Oracle Database Server 的 19.3 版本到 19.20 版本和 21.3 版本到 21.11 版本存在安全漏洞,即版本问题。如: Oracle Database Server 安全漏洞(CVE-2023-22…

Spring AI Java程序员的AI之Spring AI(一)

SpringAI 基础使用 前言Spring AIChatClientImageClientOpenAiAudioTranscriptionClientEmbeddingClient 总结 前言 Spring AI&#xff0c;听着名字就感觉很好使用&#xff0c;快速上手&#xff0c;虽然功能没有太完善&#xff0c;但是社区活跃度很高&#xff0c;可以看看源码…

低代码框架参考

企业管理信息系统作为一类重要的应用软件系统&#xff0c;具有自己的特点&#xff0c;主要有两个方面&#xff1a; 1. 系统规模大&#xff0c;目前市场上常见的ERP系统一般都有几千个页面。 2. 页面逻辑相似性强。经过比较可以发现&#xff0c;大部分页面具有类似的功能&…

Docker新手必看:快速安装和配置BookStack在线文档系统

文章目录 前言1. 安装Docker2. Docker镜像源添加方法3. 创建并启动BookStack容器4. 登录与简单使用5. 公网远程访问本地BookStack5.1 内网穿透工具安装5.2 创建远程连接公网地址5.3 使用固定公网地址远程访问 前言 本文主要介绍如何在Linux系统使用Docker本地部署在线文档管理…

【c++篇】:初识c++--编程新手的快速入门之道(二)

文章目录 前言一.引用1.引用的概念2.引用的特性3.引用的使用场景4.常引用5.引用和指针的区别 二.内联函数1.C语言的宏函数2.内联函数的概念3.内联函数的特性 三.auto关键字1.auto的定义2.auto的使用规则3.auto不能推导的场景 四.基于范围的for循环1.范围for的语法2.范围for的使…

时间序列预测(七)——梯度消失(Vanishing Gradient)与梯度爆炸(Exploding Gradient)

目录 一、定义 二、产生原因 三、解决方法&#xff1a; 梯度消失与梯度爆炸是深度学习中常见的训练问题&#xff0c;它们主要发生在神经网络的反向传播过程中&#xff0c;使得模型难以有效学习。 一、定义 1、梯度消失&#xff08;Vanishing Gradient&#xff09;&#xf…

PCL 点云配准-改进的RANSAC算法(粗配准)

目录 一、概述 1.1原理 1.2实现步骤 1.3应用场景 二、代码实现 2.1关键函数 2.1.1 计算FPFH特征 2.1.2 RANSAC配准 2.1.3 可视化点云 2.2完整代码 三、实现效果 PCL点云算法汇总及实战案例汇总的目录地址链接&#xff1a; PCL点云算法与项目实战案例汇总&#xff0…

FlinkCDC 实现 MySQL 数据变更实时同步

文章目录 1、基本介绍2、代码实战2.1、数据源准备2.2、代码实战2.3、数据格式 1、基本介绍 Flink CDC 是 Apache Flink 提供的一个功能强大的组件&#xff0c;用于实时捕获和处理数据库中的数据变更。可以实时地从各种数据库&#xff08;如MySQL、PostgreSQL、Oracle、MongoDB…

【图论】(一)图论理论基础与岛屿问题

图论理论基础与岛屿问题 图论理论基础深度搜索&#xff08;dfs&#xff09;广度搜索&#xff08;bfs&#xff09;岛屿问题概述 岛屿数量岛屿数量-深搜版岛屿数量-广搜版 岛屿的最大面积孤岛的总面积沉没孤岛建造最大人工岛水流问题岛屿的周长 图论理论基础 这里仅对图论相关核…

java学习--集合(大写五.5)

5.collection子接口&#xff1a;Set 5.1Set及其实现类特点 java.util.Collection:存储一个一个的数据 子接口&#xff1a;Set:存储无序的、不可重复的数据(高中学习的集合) 1&#xff09;HashsSet主要实现类 底层使用的是HashMap&#xff0c;即使用数组单向链表红黑树结构进行…

netron安装(windows linux)

目录 netron简介 不同操作系统的安装方式 linux windows mac系统 netron简介 netron可视化工具&#xff0c;是一个可以清晰的看到神经网络模型的每一层的输入输出&#xff0c;网络总体的架构&#xff0c;而且支持各种不同网络框架&#xff0c;简单好用。 效果如下所示 不…

【视频笔记】408新增知识点信号——里昂视频

文章目录 **2.信号****3.信号的实现**4.信号的处理**①忽略信号****②执行信号的默认操作****③捕获井处理信号**几个Linux支持的典型信号&#xff1a; **5.信号的产生**① **通过终端按键(键盘)产生信号**例如&#xff0c;CtrlC发送2号信号SIGINT、Ctrl\发送3号信号SIGQUIT② …