Verilog基础:层次化标识符的使用

相关阅读

Verilog基础icon-default.png?t=O83Ahttps://blog.csdn.net/weixin_45791458/category_12263729.html?spm=1001.2014.3001.5482


一、前言

        Verilog HDL中的标识符(identifier)是一个为了引用而给一个Verilog对象起的名字,分为两大类:普通标识符大类和层次化标识符大类。普通标识符大类又可以分为简单标识符和转义标识符,详情见下面的博客。

Verilog基础:简单标识符和转义标识符-CSDN博客文章浏览阅读647次,点赞25次,收藏20次。标识符(identifier)是一个为了引用而给一个对象起的名字。一个标识符可以是一个简单标识符,也可以是一个转义标识符。本文将对两者进行详细阐述。_转义标识符veriloghttps://blog.csdn.net/weixin_45791458/article/details/140436528?ops_request_misc=%257B%2522request%255Fid%2522%253A%25226813B559-9D37-4969-810B-88F9A143E446%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fblog.%2522%257D&request_id=6813B559-9D37-4969-810B-88F9A143E446&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~blog~first_rank_ecpm_v1~rank_v31_ecpm-1-140436528-null-null.nonecase&utm_term=%E6%A0%87%E8%AF%86%E7%AC%A6&spm=1018.2226.3001.4450        一般情况下我们只会接触到简单标识符,但是有些时候(如验证设计时),层次化标识符也会被使用,本文目的是为需要使用层次化标识符的设计人员提供一定参考。

二、层次化标识符的起源

        模块、任务、函数、命名块和生成块的定义引入了命名空间(模块命名空间、块命名空间和生成块命名空间),详情见下面的博客。

Verilog基础:八种命名空间(定义命名空间、文本宏命名空间、模块命名空间,块命名空间、生成块命名空间、端口命名空间、specify块命名空间、属性命名空间)详解(上)-CSDN博客文章浏览阅读1k次,点赞44次,收藏24次。Verilog有八个标识符命名空间:其中两个是全局的(定义命名空间和文本宏命名空间),六个是局部的(模块命名空间,块命名空间、生成块命名空间、端口命名空间、specify块命名空间、属性命名空间)。_verilog 过程块命名https://blog.csdn.net/weixin_45791458/article/details/142132358?spm=1001.2014.3001.5501        命名空间的层次化结构可以被视为树结构,其中每个模块(实例)、任务、函数、命名块和生成块在树的特定分支中定义了新的层次,而一个普通标识符在一个层次中最多只能声明一次(需要特别注意的是,层次化标识符不能用来声明)。任何非匿名的对象都可以通过若干直接或间接包含它的模块(实例)名、任务名、函数名、命名块名和生成块名进行引用(在本文中,“**名”和“名字”这种表述指的是普通标识符)

三、层次化标识符的语法

        图1是层次化标识符的BNF范式(语法),有关BNF范式相关内容,可以参考下面的文章。

Verilog基础:巴科斯范式(BNF)-CSDN博客文章浏览阅读556次,点赞14次,收藏40次。最后一个范式定义了variable_lvalue可以是hierarchical_variable_identifier加上可选的[]包围的多个数组表达式索引,以及可选的最后的[]包围的位选或域选表达式,variable_lvalue还可以是使用拼接运算符{}连接起来的多个variable_lvalue(递归定义自己)。第三个范式定义了第一个范式中的delay_or_event_control,为delay_control或event_control或使用repeat语句的event_control。_bnf veriloghttps://blog.csdn.net/weixin_45791458/article/details/132567389?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522F7990A6B-6C1B-4DA7-98FC-0BEFAC7FAAA8%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fblog.%2522%257D&request_id=F7990A6B-6C1B-4DA7-98FC-0BEFAC7FAAA8&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~blog~first_rank_ecpm_v1~rank_v31_ecpm-1-132567389-null-null.nonecase&utm_term=BNF&spm=1018.2226.3001.4450 

图1 层次化标识符的语法

        层次化标识符由若干由句点.分隔的普通标识符组成,其中只有最左边的普通标识符可以是一个模块名,如果层次化标识符中包含实例数组名或循环生成块名,则该名后要有内含常量表达式的方括号组成,这表示选择实例数组或循环生成块的一个特定实例,一个完整的层次化标识符应该从顶层(根)模块名开始写起,因此它对于每个对象而言唯一的。

        例1给出了一个层次化设计的Verilog代码,其中包括三个模块:mod、cct和wave,图2给出了这个层次化设计的树形结构。 

// 例1
module mod(in);input in;always @(posedge in) begin: keepreg hold;hold = in;end
endmodule//***********************************module cct(stim1, stim2);input stim1, stim2;mod amod(stim1), bmod(stim2);
endmodule//***********************************module wave;reg stim1, stim2;cct a(stim1, stim2);initial begin: wave1#100 fork: innerwavereg hold;joinend
endmodule

图2 例1的树形结构

        例2给出了这个层次设计中所有对象的完整层次化标识符。

// 例2
wave                       // 模块的完整层次化标识符
wave.stim1                 // reg信号的完整层次化标识符
wave.stim2                 // reg信号的完整层次化标识符
wave.a                     // 模块实例的完整层次化标识符
wave.a.stim1               // reg信号的完整层次化标识符
wave.a.stim2               // reg信号的完整层次化标识符
wave.a.amod                // 模块实例的完整层次化标识符
wave.a.amod.in             // wire信号的完整层次化标识符
wave.a.amod.keep           // 命名块的完整层次化标识符
wave.a.amod.keep.hold      // reg信号的完整层次化标识符
wave.a.bmod                // 模块实例的完整层次化标识符
wave.a.bmod.in             // wire信号的完整层次化标识符
wave.a.bmod.keep           // 命名块的完整层次化标识符
wave.a.bmod.keep.hold      // reg信号的完整层次化标识符
wave.wave1                 // 命名块的完整层次化标识符
wave.wave1.innerwave       // 命名块的完整层次化标识符
wave.wave1.innerwave.hold  // reg信号的完整层次化标识符

四、层次化标识符的引用位置

        普通标识符(除任务、函数外)要求引用位置在定义位置后,例3给出了一个错误的引用方式。

// 例3
module example;initial beginstim1 = 1'b0; // 编译错误,引用位置在定义位置前stim2 = 1'b1; // 编译错误,引用位置在定义位置前endreg stim1, stim2;
endmodule

        任务名和函数名则没有这个要求,如例4所示。

// 例4
module example;initial begin$display("Sum is: %d", add(2, 3)); endfunction integer add;input integer a, b;beginadd = a + b;endendfunction
endmodule

        如果使用层次化标识符,则所有对象都没有这个要求,如例5所示,因为层次名解析是在elaboration阶段进行而不是在编译阶段进行。 

// 例5
module example;initial beginexample.stim1 = 1'b0; // 没有问题example.stim2 = 1'b1; // 没有问题endreg stim1, stim2;
endmodule

五、不完整的层次化标识符

        使用完整的层次化标识符简单直观,但当层次结构复杂起来时,完整的层次化标识符便显得十分臃肿,此时可以使用不完整的层次化标识符,即层次化标识符不从顶层(根)模块名开始写起。

        不完整的层次化标识符的语法和图1所示的一样,但是此时不要求最左边的普通标识符是顶层(根)模块名,它可以是模块(实例)名、任务名、函数名、命名块名和生成块名。

        不完整的层次化标识符解析遵循一定的规则,如下所示:

        1、首先在层次化标识符引用位置的命名空间中尝试匹配层次化标识符,匹配指的是从层次化标识符最左边的普通标识符开始依次匹配后续的所有普通标识符,如果匹配失败且当前命名空间不是模块命名空间,则在上层命名空间中尝试匹配层次化标识符,以此类推直到匹配成功或到达模块命名空间。例6展示展示了不完整的层次化标识符的使用方式。

// 例6
module example;initial begin: block1reg x, y;x = 1;y = 0;begin: block1reg x;x = 0;$display("x = %b", block1.x);  // 输出:x = 0$display("y = %b", block1.y);  // 输出:y = 0endend
endmodule

        2、在规则1中在到达模块命名空间后,如果匹配仍然失败,则会在父模块的模块命名空间(最外层)尝试匹配层次化标识符。

        在父模块的模块命名空间内匹配时会有一个例外,那就是首先将层次化标识符最左边的普通标识符与模块名匹配,如果成功则将其视为子模块实例名(指直接或间接包含的子模块实例);如果匹配失败再尝试匹配其他名字(用于实例化的模块名可以与模块命名空间中的名字重名),如例7所示。

// 例7
module top;example example_1(1);     // 对于实例example_1中的$display,它输出1example example_2(0);     // 对于实例example_2中的$display,它输出0initial begin: examplereg x;x = 1'bx;               // 优先搜索模块名,因此这个x没有被引用end
endmodulemodule example(input a);reg x;initial begin#1;x = a;$display("x = %b", example.x);  // 对于实例example_1中example相当于example_1;对于实例example_2中的example相当于example_2。end
endmodule

        3、如果在父模块的模块命名空间中的匹配全部失败了,则重复规则2直到顶层(根)模块,如果顶层(根)模块的模块命名空间也是失败的,则它会被视为一个完整的层次化标识符

        没错,其实完整的层次化标识符的解析也可以认为是遵守这个规则的,可以视为一层一层向上匹配但全部匹配失败,直到最后在假象的顶层(根)模块的父模块中匹配成功。

        善于思考的你可能会提出问题,那岂不是会出现拦截问题,比如顶层(根)模块的模块命名空间中的一个名字可能会因为在向上匹配的过程中被提前匹配而无法被引用到,这是对的!如例8所示。

// 例8
module top;reg x = 0;example example_0();initial begin: topreg x;x = 1;end
endmodulemodule example();initial begin#1 $display("x = %b", top.x);  // 输出:x = 1,这种情况下,此处无法引用到顶层(根)模块命名空间中的xend
endmodule

        为了克服这个问题,后面的SystemVerilog标准提出了$root,本文就不对此进行详述了。

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

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

相关文章

监控易监测对象及指标之:Kafka中间件JMX监控指标解读

监控易作为一款功能强大的监控软件,旨在为企业提供全方位的IT系统监控服务。其中,针对Kafka中间件的JMX监控是监控易的重要功能之一。本文将详细解读监控易中Kafka的JMX监控指标,帮助企业更好地理解并运用这些数据进行系统性能调优和故障排查…

算法笔记day07

1.最长回文子串 最长回文子串_牛客题霸_牛客网 算法思路: 使用中心扩散算法,枚举所有的中点,向两边扩散,一个中点需要枚举两次,一次当回文串是奇数另一次回文串是偶数的情况。 class Solution { public:int getLong…

mysql--基本查询

目录 搞定mysql--CURD操作,细节比较多,不难,贵在多多练 1、Create--创建 (1)单行插入 / 全列插入 (2)插入否则替换 (3)替换 2、Retuieve--select 1)全…

git rebase的常用场景: 交互式变基, 变基和本地分支基于远端分支的变基

文章目录 作用应用场景场景一:交互式变基(合并同一条线上的提交记录) —— git rebase -i HEAD~2场景二:变基(合并分支) —— git rebase [其他分支名称]场景三:本地分支与远端分支的变基 作用 使git的提交记录变得更加简洁 应用场景 场景…

Unity之如何使用Unity Cloud Build云构建

文章目录 前言什么是 UnityCloudBuild?如何使用Unity云构建Unity 团队中的人员不属于 Unity Team 的人员UnityCloudBuild2.0价格表如何使用Unity云构建配置CloudBuild前言 Unity Cloud Build作为Unity平台的一项强大工具,它允许开发团队通过云端自动构建项目,节省了繁琐的手…

基于Springboot在线视频网站的设计与实现

基于Springboot视频网站的设计与实现 开发语言:Java 框架:springboot JDK版本:JDK1.8 服务器:tomcat7 数据库:mysql 5.7 数据库工具:Navicat11 开发软件:idea 源码获取:https://do…

JSON 注入攻击 API

文章目录 JSON 注入攻击 API"注入所有东西"是"聪明的"发生了什么? 什么是 JSON 注入?为什么解析器是问题所在解析不一致 JSON 解析器互操作性中的安全问题处理重复密钥的方式不一致按键碰撞响应不一致JSON 序列化(反序列化)中的不一致 好的。JSON 解析器…

Java | Leetcode Java题解之第497题非重叠矩形中的随机点

题目&#xff1a; 题解&#xff1a; class Solution {Random rand;List<Integer> arr;int[][] rects;public Solution(int[][] rects) {rand new Random();arr new ArrayList<Integer>();arr.add(0);this.rects rects;for (int[] rect : rects) {int a rect[0…

PPT自动化:Python如何将PPT转换为图片(ppt2img源码)

文章目录 📖 介绍 📖🏡 演示环境 🏡📒 PPT转换图片 📒📝 Windows环境下PPT转为图片(源码)📝 Linux环境下PPT转为图片(源码)📝 注意事项⚓️ 相关链接 ⚓️📖 介绍 📖 在日常工作中,我们常常需要将大量的幻灯片转换为图片,这样不仅方便分享,还能提…

【数据库系统概论】第3章 关系数据库标准语言SQL(一)数据定义(超详细)

教材&#xff1a; 数据库系统概论&#xff08;第6版&#xff09;王珊,杜小勇,陈红编著 目录 一、SQL概述 1.1 SQL 的产生与发展 1.2 SQL的特点 1.3 SQL的基本概念 二、数据定义 2.1 数据库的定义 2.2 数据表的定义 2.3 模式的定义 一、SQL概述 1974年IBM为关系DBMS设…

Docker 搭建mysql

拉取mysql镜像 docker pull mysql # 拉取镜像 [rooteason ~]# docker pull mysql Using default tag: latest latest: Pulling from library/mysql 72a69066d2fe: Pull complete 93619dbc5b36: Pull complete 99da31dd6142: Pull complete 626033c43d70: Pull complete 37d…

用HTML构建酷炫的文件上传下载界面

1. 基础HTML结构 首先&#xff0c;我们构建一个基本的HTML结构&#xff0c;包括一个表单用于文件上传&#xff0c;以及一个列表用于展示已上传文件&#xff1a; HTML <!DOCTYPE html> <html> <head><title>酷炫文件上传下载</title><link …

分布式ID生成策略

文章目录 分布式ID必要性1.UUID2.基于DB的自增主键方案3.数据库多主模式4.号段模式5.Redis6.Zookeeper7.ETCD8.雪花算法9.百度(Uidgenerator)10.美团(Leaf)11.滴滴(TinyID) 分布式ID必要性 业务量小于500W的时候单独一个mysql即可提供服务&#xff0c;再大点的时候就进行读写分…

浏览器播放rtsp视频流解决方案

方案一: html5 websocket_rtsp_proxy 实现视频流直播 实现原理 实现步骤 服务器安装streamedian服务器 客户端通过video标签播放 <video id"test_video" controls autoplay></video><script src"free.player.1.8.4.js"></script&g…

openresty通过header_filter_by_lua记录特定的请求头和特定的响应头到日志文件

有时我们希望记录特定的请求头信息和特定的响应头信息,以便能够通过关联请求信息和响应头信息,来实现记录请求和响应的对应关系。这里通过逐步尝试和优化的方式进行尝试。具体包括将需要的请求头和响应头组织到一条日志记录,输出到单独的错误日志文件记录等的配置尝试。 1.…

HAL+M4学习记录_8

一、TIM的HAL库用法 这里记录学习HAL库开发TIM 1.1 定时中断基本结构 这里给出定时中断的基本结构 基本步骤如下 开启时钟选择时基单元时钟源配置时基单元配置输出中断控制&#xff0c;允许更新中断输出到NVIC配置NVIC&#xff0c;打开定时器中断通道运行控制编写中断服务函…

为什么九齐单片机中不能使用bit?

如果开发环境不支持bit 定义static unsigned char task_720ms_flag 0;还可以用什么方式替代bit定义标志&#xff0c;使其占用内存空间小。 如果开发环境不支持位定义&#xff0c;可以使用 unsigned char 的多个状态位来替代。可以将多个标志合并到一个 unsigned char 中&…

Vue - Element 选择器 el-select 既可以选择下拉又可以手动输入文本功能(手动输入的值只能是数字 并且支持4位小数)

Vue - Element 选择器 el-select 既可以选择下拉又可以手动输入文本功能&#xff08;手动输入的值只能是数字 并且支持4位小数&#xff09; 备注 filterable 下拉框开启快速搜索功能 no-match-text 当输入的内容在下拉框中找不到时&#xff1b;下拉框提示的文字 handFocus 触发…

软件测试快速入门:测试对象、过程模型、生命周期与测试用例

✨✨ 欢迎大家来访Srlua的博文&#xff08;づ&#xffe3;3&#xffe3;&#xff09;づ╭❤&#xff5e;✨✨ &#x1f31f;&#x1f31f; 欢迎各位亲爱的读者&#xff0c;感谢你们抽出宝贵的时间来阅读我的文章。 我是Srlua小谢&#xff0c;在这里我会分享我的知识和经验。&am…

redis集群介绍

Redis集群是一种分布式存储系统&#xff0c;它通过将数据分散存储在多个Redis节点上来实现可扩展性和高可用性。每个节点都是一个独立的Redis服务器实例&#xff0c;它们通过网络相互连接&#xff0c;共同协作以提供数据服务。 在Redis集群中&#xff0c;数据被划分为多个槽&am…