绝大多数 VHDL 设计使用时钟逻辑 ,也称为同步逻辑 或顺序逻辑 .时钟进程仅由主时钟信号触发,而不是在任何其他输入信号发生变化时触发。 时钟逻辑的基本构建块是一个称为触发器的组件 .它有不同的变体,在本教程中,我们将重点介绍带负复位的正沿触发触发器: 触发器是一个采样保持电路,这意味着它会在时钟信号的上升沿到达时将值从输入复制到输出。然后输出保持稳定在采样值,直到时钟的下一个上升沿,或直到产生复位信号。 这篇博文是基本 VHDL 教程系列的一部分。 所有时钟进程同时触发,并将立即读取它们的输入。同时,他们将输出上一次迭代的结果。时钟信号有效地在数据流中创建时间步长。这使得设
完成基本 VHDL 教程系列中的教程 12-17 后,通过此 VHDL 测验测试您的进度! 关于签名类型,哪项陈述是正确的? 他们可以表示比无符号类型更高的值 如果最左边的位是 1 值必须是负数 溢出是运行时错误 正确的!错误的! - 哪个相当于这个并发进程? 正确的!错误的! - 运行此代码后,Output 将具有什么值? 0000 0001 UUUU XXXX 正确的!错误的! - 哪个是关于港口申报的? 端口仅用于验证目的 端口可以同时包含信号和变量 端口
在之前的教程中,我们使用了 wait for 在模拟中延迟时间的声明。但是生产模块呢? wait for 声明不能用于此。这仅在模拟中有效,因为我们不能只告诉电路中的电子暂停给定时间。那么我们如何在设计模块中跟踪时间呢? 答案只是简单地计算时钟周期。每个数字设计都可以访问以固定的已知频率振荡的时钟信号。因此,如果我们知道时钟频率为 100 MHz,我们可以通过计算一亿个时钟周期来测量一秒。 这篇博文是基本 VHDL 教程系列的一部分。 要在 VHDL 中计算秒数,我们可以实现一个计数器来计算经过的时钟周期数。当这个计数器达到时钟频率的值时,例如 1 亿,我们知道已经过了一秒钟,是时候增
程序是 VHDL 中的一种子程序,可以帮助我们避免重复代码。有时需要在整个设计中的多个位置执行相同的操作。虽然创建一个模块对于小操作来说可能是多余的,但过程通常是你想要的。 可以在任何声明区域内声明过程。该过程的范围将仅限于它被声明的地方、架构、包或流程。每当您调用该过程时,它的行为就像该过程的代码插入到调用它的位置一样。 过程不像函数那样返回值,但您可以通过声明 out 来返回值 或 inout 参数列表中的信号。 这篇博文是基本 VHDL 教程系列的一部分。 创建过程的基本语法是:procedure <procedure_name> (signal|variable|
有限状态机(FSM)是一种机制,其输出不仅取决于输入的当前状态,还取决于过去的输入和输出值。 每当你需要在 VHDL 中创建某种时间相关的算法,或者遇到在 FPGA 中实现计算机程序的问题时,通常可以使用 FSM 来解决。 VHDL 中的状态机是时钟进程,其输出由状态信号的值控制。状态信号用作上一次迭代中发生的事情的内部记忆。 这篇博文是基本 VHDL 教程系列的一部分。 考虑这个路口的红绿灯状态: 交通信号灯有有限数量的状态,我们已经给了可识别的名称。我们的示例状态机没有控制输入,输出是北/南和西/东方向的灯光状态。推进这个状态机的是经过的时间和输出的先前状态。 我们可以
函数是 VHDL 中的子程序,可用于实现常用算法。一个函数接受零个或多个输入值,它总是返回一个值。除了返回值之外,函数与过程的不同之处在于它不能包含等待语句。这意味着函数总是消耗零仿真时间。 如果你熟悉其他编程语言的函数或方法,VHDL函数应该很容易掌握。在VHDL中,我们不能省略返回值或返回void,函数总是要返回一些东西,返回值必须分配给一些东西。 这篇博文是基本 VHDL 教程系列的一部分。 在 VHDL 中,有两种类型的函数,纯 和不纯 功能。一个函数是纯的意味着它不会被允许修改或读取任何外部信号。我们可以肯定,当我们调用带有特定参数的纯函数时,它总是会返回相同的值。我们说这个
不纯函数可以读取或写入其范围内的任何信号,包括那些不在参数列表中的信号。我们说这个函数有副作用 . 我们所说的副作用的意思是,不能保证每次使用相同的参数调用函数时都会返回相同的值。如果函数可以读取不在参数列表中的信号,则返回值也可能取决于这些影子参数。此外,该函数可能正在更改未从其返回值分配的外部信号。 这篇博文是基本 VHDL 教程系列的一部分。 尽管我们可以在任何可以声明普通纯函数的地方声明不纯函数,但只有在进程中使用它们才有意义。当在我们通常声明信号的架构中声明时,在编译时没有任何信号在其范围内。因此,在架构或包中声明时,不纯函数只能做纯函数所能做的事情。 使用不纯函数的动机主
可以从程序驱动外部信号。只要信号在过程范围内,就可以对其进行读写访问,即使它没有在参数列表中列出。 在体系结构的声明区域中声明的过程不能驱动任何外部信号。这仅仅是因为在编译时其范围内没有信号。另一方面,在进程中声明的过程将可以访问该进程可以看到的所有信号。 这篇博文是基本 VHDL 教程系列的一部分。 此类程序可用于在多次发生相同操作的过程中对算法进行整理。我们可以使用一个正常的过程,当你调用它时,所有的输入和输出都分配给本地信号,但这不是重点。通过在过程调用中省略输入和输出信号,我们必须减少输入,更重要的是,我们使代码更具可读性。 想象一个实现复杂通信协议的进程。如果把一些操作换成
完成基本 VHDL 教程系列的第 4 部分后,通过此 VHDL 测验测试您的进度! 我们如何在 VHDL 中测量实时? 通过使用“等待 1 ns”语句 通过计数时钟周期 通过利用传播延迟 正确的!错误的! - 哪种说法正确 过程不能包含等待语句 程序参数总是输入 使用时在过程中,return 关键字必须没有值 正确的!错误的! - 哪项陈述描述了该火控系统的根本缺陷? 缺少重置状态信号的 缺少其他-case 语句中的子句 状态信号一旦进入 Armed 状态就会卡住 初始state 将是随机的,因为没有为 State 信号分配默
链表是一种动态数据结构。当事先不知道元素的总数时,可以使用链表。它在内存中的增长和收缩,相对于它包含的项目数。 使用面向对象编程语言中的类最方便地实现链表。 VHDL 具有一些面向对象的特性,可用于从用户那里抽象出实现的复杂性。 在本文中,我们将使用访问类型、记录和受保护类型在 VHDL 中实现链表。我们将创建一个新的 VHDL 包,我们将在其中编写所有链表代码。 包 我们要做的第一件事是声明一个包含我们代码的包。 VHDL 包是可以导入另一个 VHDL 文件的类型、对象或子程序的集合。大多数 VHDL 模块从 IEEE 库中导入 std_logic_1164 包。我们正在创建自己的包,
自检测试台是一个 VHDL 程序,它可以验证被测设备 (DUT) 的正确性,而无需操作员手动检查输出。自检测试台完全独立运行,最后打印“OK”或“Failed”消息。 每个 VHDL 模块都应该有一个相关的自检测试平台。能够随时验证所有模块是否具有预期行为非常重要。例如,当您对 DUT、子模块或接口模块进行更改时。我们都知道东西会坏掉,而解决这些问题的最佳工具就是自检测试台。 被测设备 让我们直接进入并创建一个自检测试平台的示例。首先,我们需要测试的东西,一个 DUT。为此,我在下面的代码中创建了模块。这是一个二进制到格雷码的转换器。 library ieee;use ieee.std_l
交互式测试台是一种模拟器设置,其中在测试台运行时由操作员提供对被测设备 (DUT) 的输入。大多数情况下,这意味着您在模拟器控制台中输入命令来为 DUT 提供激励。 虽然您应该始终创建一个自检测试平台,但交互式测试平台可能是一个很好的补充。使用手头的交互式测试台进行临时测试比更改自检测试台的代码更容易。 很多时候,您会在实验室中发现您想在测试平台中尝试的问题。使用交互式测试平台,只需键入已观察到的输入序列即可复制模拟器中的不良行为。 Tcl 与 VHDL 交互 大多数 VHDL 模拟器使用 Tcl 作为它们的控制台语言。模拟器有一堆特定于供应商的命令,但好消息是它们可以被视为任何其他 T
循环缓冲区是用于在顺序编程语言中创建队列的流行结构,但它们也可以在硬件中实现。在本文中,我们将在 VHDL 中创建一个环形缓冲区,以在 Block RAM 中实现一个 FIFO。 在实现 FIFO 时,您必须做出许多设计决策。你需要什么样的接口?你受资源限制吗?它应该能够适应过度读取和覆盖吗?延迟可以接受吗?这些是我在被要求创建 FIFO 时出现的一些问题。 在线存在许多免费的 FIFO 实现,以及 Xilinx LogiCORE 等 FIFO 生成器。但是,许多工程师仍然喜欢实现自己的 FIFO。因为即使它们都执行相同的基本队列和出队任务,但考虑到细节时它们可能会有很大的不同。 环形缓冲
约束随机验证是一种测试平台策略,它依赖于为被测设备 (DUT) 生成伪随机事务。目标是通过与 DUT 的随机交互来实现对许多预定义事件的功能覆盖。 开源 VHDL 验证方法 (OSVVM) 是一个免费的 VHDL 库,其中包括许多用于创建受限随机测试平台的便捷包。我们对 RandomPkg 和 CoveragePck 特别感兴趣,我们将在本文中使用它们。我建议访问 OSVVM GitHub 页面以了解有关此库的更多功能。 被测设备 我将深入研究一个示例,以更好地解释受约束的随机测试平台与使用定向测试的经典测试平台有何不同。我们在本博客上一篇文章中创建了环形缓冲区 FIFO,但我们没有创建自
我很高兴地宣布,我过去六个月一直在学习的 VHDL 和 FPGA 课程开始完成。该课程目前处于测试阶段,我计划在今年秋季首次推出。 FPGA 课程适合谁? FPGA 课程面向具有其他编程语言知识但不熟悉 VHDL 和 FPGA 的开发人员。本课程将带您从初级或中级到能够理解和使用高级 VHDL 编码结构。 该课程非常适合负责 FPGA 开发的专业软件工程师。它也适合对硬件设计感兴趣的学生或自由职业者,或许正在考虑转行到 FPGA 开发。 任何具有基本编程技能的人都可以从本课程教给您的实践方法中受益。我们正在从头开始开发一个真实的实体产品。我正在向您展示如果我作为 FPGA 工程师提出要求
当我第一次必须创建逻辑来连接 AXI 模块时,我对 AXI 接口的特殊性有点恼火。代替常规的忙/有效、满/有效或空/有效控制信号,AXI 接口使用名为“就绪”和“有效”的两个控制信号。我的沮丧很快变成了敬畏。 AXI 接口具有内置流量控制,无需使用额外的控制信号。这些规则很容易理解,但在 FPGA 上实现 AXI 接口时必须考虑一些陷阱。本文将向您展示如何在 VHDL 中创建 AXI FIFO。 AXI 解决了延迟一个周期的问题 防止过度读取和覆盖是创建数据流接口时的常见问题。问题是当两个时钟逻辑模块进行通信时,每个模块只能以一个时钟周期延迟读取其对应模块的输出。 上图显示了顺序
使用初始值填充块 RAM 的一种方便方法是从 ASCII 文件中读取二进制或十六进制文字。这也是在 VHDL 中创建 ROM(只读存储器)的好方法。毕竟在 FPGA 中 RAM 和 ROM 是一回事,ROM 是你只能读取的 RAM。 本文中的示例将假定以下常量和 RAM 类型已在 VHDL 文件的声明区域的开头声明。 constant ram_depth : natural := 256;constant ram_width : natural := 32;type ram_type is array (0 to ram_depth - 1) of std_logic_vector(ram
从文件中读取信号值是为被测设备 (DUT) 生成刺激的另一种方法。测试台序列和时序硬编码在 VHDL 测试台逐行读取的激励文件中。这使您可以轻松更改要馈送到测试对象的波形模式。 有时,您有一个非常具体的测试模式或事件序列,您希望您的 DUT 通过。您可以通过在 ASCII 文件中指定每个信号应具有的信号值以及它们应更改的相对仿真时间来实现此目的。 VHDL 测试平台在这种策略中的作用是从激励文件中读取数据,并在正确的时间将这些值应用于 DUT 输入。 本文是 VHDL 文件访问系列文章的第二篇。我们在上一篇博文中了解了如何从文件中读取十六进制、八进制和二进制值,如果您想了解有关使用 TEX
将图像文件转换为位图格式是使用 VHDL 读取图片的最简单方法。 Microsoft Windows 操作系统中内置了对 BMP 光栅图形图像文件格式的支持。这使得 BMP 成为一种合适的图像格式,用于存储用于 VHDL 测试平台的照片。 在本文中,您将学习如何读取像 BMP 这样的二进制图像文件并将数据存储在模拟器的动态内存中。我们将使用一个示例图像处理模块将图像转换为灰度,这将是我们的被测设备 (DUT)。最后,我们将 DUT 的输出写入一个新图像,我们可以在视觉上与原始图像进行比较。 这篇博文是关于在 VHDL 中使用 TEXTIO 库的系列文章的一部分。在此处阅读其他文章: 如何
该视频是关于 FPGA 和可编程逻辑技术的介绍性演示。我于 2019 年 11 月 19 日在泰国曼谷由 7 Peaks Software 主办的一次活动中发表了这个 45 分钟的演讲。 演讲的亮点包括: 05:07 谁在使用 FPGA? 09:06 什么是 FPGA? 12:13 如何使用静态 RAM 模拟逻辑门 17:47 通用 FPGA 原语 19:51 最便宜和最昂贵的 FPGA 20:53 FPGA 平面图 24:30 VHDL 28:05 综合和布局布线 30:50 软核 33:15 混合 FPGA/CPU (Zynq-7000) 36:44 FPGA 的优缺点 40:28
VHDL