活动介绍

VHDL中共享变量、受保护类型与属性的深入解析

立即解锁
发布时间: 2025-08-16 01:28:55 阅读量: 7 订阅数: 11
PDF

VHDL设计指南:从入门到精通

# VHDL中共享变量、受保护类型与属性的深入解析 ## 1. VHDL - 93中的共享变量 在VHDL - 93里,共享变量不必是受保护类型,它们类似于普通的非共享变量。共享变量可以声明为除文件类型之外的任何类型,并且声明时可以包含初始值表达式。共享变量的值能在表达式中使用,也可以通过普通的变量赋值语句进行更新。不过,在给定的仿真周期内,不同进程对共享变量的访问没有互斥机制,这意味着不同进程的读写操作可能会相互干扰。所以,在VHDL - 93中使用共享变量时,必须格外小心,确保每个仿真周期内只有一个进程能访问每个共享变量。如果一个模型依赖于在任何仿真周期内被多个进程访问的共享变量的值,那么该模型会被视为错误。 ## 2. 受保护类型中的未实例化方法 ### 2.1 未实例化子程序与受保护类型的关系 存在两种情况需要考虑: - **将未实例化子程序的实例声明为受保护类型的方法**:若在受保护类型外部声明了一个未实例化子程序,并在受保护类型声明内声明该子程序的一个实例,那么这个实例就成为了受保护类型的一个方法。示例代码如下: ```vhdl procedure uninstantiated_name generic ( ... ) parameter ( ... ); type PT is protected ... procedure instance_name is new uninstantiated_name generic map ( ... ); ... end protected PT; shared variable SV : PT; ... SV.instance_name ( ... ); ``` 乍一看,这种方案似乎没有什么意义,因为未实例化子程序在受保护类型外部,无法引用受保护类型封装的项。但我们可以通过将受保护类型的一个方法作为实际的通用子程序提供给实例,从而实现对封装项的受控访问。改进后的方案如下: ```vhdl procedure uninstantiated_name generic ( ...; formal_generic_subprogram; ... ) parameter ( ... ); type PT is protected method_declaration; procedure instance_name is new uninstantiated_name generic map ( ..., method_name, ... ); ... end protected PT; ``` 在这个方案中,该方法可以访问受保护类型内的封装项。当实例调用实际的通用子程序时,就会调用该方法。 ### 2.2 示例:带跟踪功能的测试向量集 假设有一个未实例化子程序,它能获取与指定时间对应的测试向量值,并将该向量值写入标准输出文件。该过程有一个形式通用子程序,代表获取测试向量的操作。代码如下: ```vhdl procedure trace_test_vector is generic ( impure function get_test_vector ( vector_time : time ) return test_vector ) parameter ( vector_time : time ) is variable vector : test_vector; use std.textio.all; variable L : line; begin write(L, now); write(L, string'(": ")); vector := get_test_vector(vector_time); ... -- write test vector writeline(output, L); end procedure trace; ``` 我们可以声明一个受保护类型,代表要在不同时间应用的一组测试向量。该受保护类型有一个方法,用于获取特定时间的测试向量。我们将`trace_test_vector`过程的一个实例作为方法,用于跟踪受保护类型的共享变量所代表的特定测试向量集。受保护类型声明如下: ```vhdl type test_set is protected ... impure function get_vector_for_time ( vector_time : time ) return test_vector; procedure trace_for_time is new trace_test_vector generic map ( get_test_vector => get_vector_for_time ); end protected test_set; ``` 我们可以声明该受保护类型的两个共享变量,代表两组不同的测试向量: ```vhdl shared variable main_test_set, extra_test_set : test_set; ``` 如果调用其中一个共享变量的`trace_for_time`方法: ```vhdl main_test_set.trace_for_time(100 ns); ``` `trace_test_vector`过程的实例会调用为受保护类型实例提供的实际子程序,即调用与共享变量`main_test_set`关联的`get_vector_for_time`方法。同理,调用另一个共享变量的`trace_for_time`方法时,也会调用相应的`get_vector_for_time`方法。这表明受保护类型的每个共享变量将其`get_vector_for_time`方法(该方法可以访问共享变量的状态)绑定为`trace_test_vector`过程实例中的实际通用过程,因此该实例可以间接访问共享变量的状态。 ### 2.3 在受保护类型内声明未实例化子程序 受保护类型内声明的未实例化过程本身不是一个方法,因为它不能被调用。但是,它可以在受保护类型内实例化以提供一个方法。而且,受保护类型的每个共享变量在逻辑上都包含该未实例化子程序的单独声明。这个子程序可以被实例化,从而得到一个可以访问共享变量中封装项的子程序。 #### 示例:带访问者遍历的激励列表 对于需要有符号激励值的设计,我们可以声明一个用于将有符号值显示到标准输出文件的过程: ```vhdl procedure output_signed ( value : in signed ) is use std.textio.all; variable L : line; begin write(L, value); writeline(output, L); end procedure output_signed; ``` 我们还声明一个用于有符号激励值列表的受保护类型: ```vhdl type signed_stimulus_list is protected ... procedure traverse_with_in_parameter generic ( procedure visit ( param : in signed ) ); procedure output_all is new traverse_with_in_parameter generic map ( visit => output_signed ); end protected signed_stimulus_list; ``` 该受保护类型包含一个未实例化过程`traverse_with_in_parameter`,用于将一个访问者过程应用于有符号值列表中的每个元素。它实例化该遍历过程以提供一个显示每个元素的方法。我们可以使用这个受保护类型声明一个共享变量,然后调用该方法来显示其元素值: ```vhdl shared variable list1 : signed_stimulus_list; ... list1.output_all; ``` 如果我们想使用遍历过程来累积列表中元素的总和,以便计算平均值,可以提供另一个操作过程,并在遍历过程的进一步实例化中使用它: ```vhdl variable sum, average : signed(31 downto 0); variable count : natural := 0; procedure accumulate_signed ( value : in signed ) is begin sum := sum + value; count := count + 1; end procedure accumulate_signed; procedure accumulate_all_list1 is new list1.traverse_with_in_parameter generic map ( visit => accumulate_signed ); ... accumulate_all_list1; average := sum / count; ``` 在这种情况下,实例是在受保护类型外部声明的一个过程。但由于它是在共享变量`list1`内定义的子程序的一个实例,所以该实例可以访问`list1`中封装的项。实例`accumulate_all_list1`会将`accumulate_signed`访问者过程应用于`list1`中的每个元素。 如果我们想计算任何元素列表的平均值,需要将这些声明封装在一个以共享变量为参数的过程中,包括在外部过程内声明遍历过程的实例。完整的过程如下: ```vhdl procedure calculate_average ( variable list : inout signed_stimulus_list variable average : out signed ) is variable sum : signed(average'range); variable count : natural := 0; procedure accumulate_signed ( value : in signed ) is begin sum := sum + value; count := count + 1; end procedure accumulate_signed; procedure accumulate_all is new list.traverse_with_in_parameter generic map ( visit => accumulate_signed ); begin accumulate_all; average := sum / count; end procedure calculate_average; ``` ### 2.4 练习 以下是一些相关练习: 1. 假设在VHDL - 93中,在一个包`instrumentation`中声明了一个共享变量: ```vhdl shared variable multiply_counter : natural := 0; ``` 有一个行为乘法器模型的两个实例`m1`和`m2`,其中包含语句: ```vhdl instrumentation.multiply_counter := instrumentation.multiply_counter + 1; ``` 请说明在VHDL - 93中,如果允许这两个实例在同一仿真周期内访问该变量,变量可能会被错误更新的情况。 2. 编写一个受保护类型声明和主体,为一个整数共享变量提供互斥机制。该受保护类型应包含一个名为`set`的方法来更新变量值,以及一个名为`get`的方法来检索变量值。 3. 第12.3.2节中的有界缓冲区抽象数据类型(ADT)可用于将字节流从一个进程发送到另一个进程。但是,如果发送者和接收者同时调用写和读过程,可能会干扰并导致缓冲区状态损坏。开发一个包,定义一个受保护的有界缓冲区的受保护类型。受保护类型主体应封装第12.3.2节中有界缓冲区ADT的一个变量。受保护类型应包含测试缓冲区是否已满、是否为空以及读写字节的方法。在一个架构主体中使用生产者和消费者进程,通过该受保护有界缓冲区类型的共享变量进行通信,测试你的包。 4. 我们可以使用受保护类型来封装抽象数据类型的私有数据,从而对类型的用户隐藏这些数据。例如,我们可以声明一个随机数流类型: ```vhdl type random_generator is protected impure function next_random return real; impure function next_random ( min, max : real ) return real; impure function next_random ( min, max : integer ) return integer; ... end protected random_generator; ``` 受保护类型主体包括用于存储随机种子的变量声明。这些方法结合`math_real.uniform`过程使用种子来生成连续的随机数,每个方法会对结果进行缩放和类型转换。开发一个包,完成该受保护类型的定义,包括返回`bit_vector`和`std_ulogic_vector`类型值的方法。在一个模型中使用你的包,为一个32位加法器生成随机激励值进行测试。 ## 3. VHDL中的预定义属性 ### 3.1 属性概述 VHDL提供了全面的机制来表达设计的行为和结构,同时还提供了属性机制,用于为模型添加额外的信息。以下是对预定义属性的总结: ### 3.2 不同类型的预定义属性 #### 3.2.1 标量类型的属性 这些属性提供有关标量类型中值的信息,具体如下表所示: | 属性 | T的类型 | 结果类型 | 结果 | | ---- | ---- | ---- | ---- | | T'left | 任何标量类型或子类型 | 与T相同 | T中的最左值 | | T'right | 任何标量类型或子类型 | 与T相同 | T中的最右值 | | T'low | 任何标量类型或子类型 | 与T相同 | T中的最小值 | | T'high | 任何标量类型或子类型 | 与T相同 | T中的最大值 | | T'ascending | 任何标量类型或子类型 | boolean | 如果T是升序范围,则为true,否则为false | | T'image(x) | 任何标量类型或子类型 | string | 类型T的值x的文本表示 | | T'value(s) | 任何标量类型或子类型 | T的基类型 | 由字符串s表示的T中的值 | | T'pos(s) | 任何离散或物理类型或子类型 | 通用整数 | x在T中的位置编号
corwn 最低0.47元/天 解锁专栏
赠100次下载
继续阅读 点击查看下一篇
profit 400次 会员资源下载次数
profit 300万+ 优质博客文章
profit 1000万+ 优质下载资源
profit 1000万+ 优质文库回答
复制全文

相关推荐

Big黄勇

硬件工程师
广州大学计算机硕士,硬件开发资深技术专家,拥有超过10多年的工作经验。曾就职于全球知名的大型科技公司,担任硬件工程师一职。任职期间负责产品的整体架构设计、电路设计、原型制作和测试验证工作。对硬件开发领域有着深入的理解和独到的见解。
最低0.47元/天 解锁专栏
赠100次下载
百万级 高质量VIP文章无限畅学
千万级 优质资源任意下载
千万级 优质文库回答免费看
立即解锁

专栏目录

最新推荐

【仿真模型数字化转换】:从模拟到数字的精准与效率提升

![【仿真模型数字化转换】:从模拟到数字的精准与效率提升](https://img-blog.csdnimg.cn/42826d38e43b44bc906b69e92fa19d1b.png) # 摘要 本文全面介绍了仿真模型数字化转换的关键概念、理论基础、技术框架及其在实践中的应用流程。通过对数字化转换过程中的基本理论、关键技术、工具和平台的深入探讨,文章进一步阐述了在工程和科学研究领域中仿真模型的应用案例。此外,文中还提出了数字化转换过程中的性能优化策略,包括性能评估方法和优化策略与方法,并讨论了数字化转换面临的挑战、未来发展趋势和对行业的长远意义。本文旨在为专业人士提供一份关于仿真模型数

【C#数据绑定高级教程】:深入ListView数据源绑定,解锁数据处理新技能

![技术专有名词:ListView](https://androidknowledge.com/wp-content/uploads/2023/01/customlistthumb-1024x576.png) # 摘要 随着应用程序开发的复杂性增加,数据绑定技术在C#开发中扮演了关键角色,尤其在UI组件如ListView控件中。本文从基础到高级技巧,全面介绍了C#数据绑定的概念、原理及应用。首先概述了C#中数据绑定的基本概念和ListView控件的基础结构,然后深入探讨了数据源绑定的实战技巧,包括绑定简单和复杂数据源、数据源更新同步等。此外,文章还涉及了高级技巧,如数据模板自定义渲染、选中项

手机Modem协议在网络环境下的表现:分析与优化之道

![手机Modem协议开发快速上手.docx](https://img-blog.csdnimg.cn/0b64ecd8ef6b4f50a190aadb6e17f838.JPG?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBATlVBQeiInOWTpQ==,size_20,color_FFFFFF,t_70,g_se,x_16) # 摘要 Modem协议在网络通信中扮演着至关重要的角色,它不仅定义了数据传输的基础结构,还涉及到信号调制、通信流程及错误检测与纠正机制。本文首先介

零信任架构的IoT应用:端到端安全认证技术详解

![零信任架构的IoT应用:端到端安全认证技术详解](https://img-blog.csdnimg.cn/20210321210025683.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQyMzI4MjI4,size_16,color_FFFFFF,t_70) # 摘要 随着物联网(IoT)设备的广泛应用,其安全问题逐渐成为研究的焦点。本文旨在探讨零信任架构下的IoT安全认证问题,首先概述零信任架构的基本概念及其对Io

虚拟助理引领智能服务:酒店行业的未来篇章

![虚拟助理引领智能服务:酒店行业的未来篇章](https://images.squarespace-cdn.com/content/v1/5936700d59cc68f898564990/1497444125228-M6OT9CELKKA9TKV7SU1H/image-asset.png) # 摘要 随着人工智能技术的发展,智能服务在酒店行业迅速崛起,其中虚拟助理技术在改善客户体验、优化运营效率等方面起到了关键作用。本文系统地阐述了虚拟助理的定义、功能、工作原理及其对酒店行业的影响。通过分析实践案例,探讨了虚拟助理在酒店行业的应用,包括智能客服、客房服务智能化和后勤管理自动化等方面。同时,

FPGA高精度波形生成:DDS技术的顶尖实践指南

![FPGA高精度波形生成:DDS技术的顶尖实践指南](https://d3i71xaburhd42.cloudfront.net/22eb917a14c76085a5ffb29fbc263dd49109b6e2/2-Figure1-1.png) # 摘要 本文深入探讨了现场可编程门阵列(FPGA)与直接数字合成(DDS)技术的集成与应用。首先,本文介绍了DDS的技术基础和理论框架,包括其核心组件及优化策略。随后,详细阐述了FPGA中DDS的设计实践,包括硬件架构、参数编程与控制以及性能测试与验证。文章进一步分析了实现高精度波形生成的技术挑战,并讨论了高频率分辨率与高动态范围波形的生成方法。

【多源数据整合王】:DayDreamInGIS_Geometry在不同GIS格式中的转换技巧,轻松转换

![【多源数据整合王】:DayDreamInGIS_Geometry在不同GIS格式中的转换技巧,轻松转换](https://community.esri.com/t5/image/serverpage/image-id/26124i748BE03C6A81111E?v=v2) # 摘要 本论文详细介绍了DayDreamInGIS_Geometry这一GIS数据处理工具,阐述了其核心功能以及与GIS数据格式转换相关的理论基础。通过分析不同的GIS数据格式,并提供详尽的转换技巧和实践应用案例,本文旨在指导用户高效地进行数据格式转换,并解决转换过程中遇到的问题。文中还探讨了转换过程中的高级技巧、

物联网技术:共享电动车连接与控制的未来趋势

![物联网技术:共享电动车连接与控制的未来趋势](https://read.nxtbook.com/ieee/potentials/january_february_2020/assets/4cf66356268e356a72e7e1d0d1ae0d88.jpg) # 摘要 本文综述了物联网技术在共享电动车领域的应用,探讨了核心的物联网连接技术、控制技术、安全机制、网络架构设计以及实践案例。文章首先介绍了物联网技术及其在共享电动车中的应用概况,接着深入分析了物联网通信协议的选择、安全机制、网络架构设计。第三章围绕共享电动车的控制技术,讨论了智能控制系统原理、远程控制技术以及自动调度与充电管理

【提升心电信号情绪识别准确性】:算法优化策略大公开

![【提升心电信号情绪识别准确性】:算法优化策略大公开](https://pub.mdpi-res.com/entropy/entropy-23-00321/article_deploy/html/images/entropy-23-00321-ag.png?1616397756) # 摘要 本文综述了心电信号情绪识别技术的发展历程、理论基础、分析方法及深度学习的应用,并展望了未来发展趋势。首先,介绍了心电信号情绪识别的理论基础及其必要性。随后,详细分析了传统心电信号分析方法,包括预处理技术、特征提取和情绪分类算法。重点阐述了深度学习在心电信号识别中的基础算法、模型构建与训练、以及模型优化与