VHDL:进程块内的多个上升沿检测

2023-12-29

我对 VHDL(以及一般的数字电路)还很陌生,我正在尝试使用 BCD 样式块实现两位数的计数器。该电路的外部有一些按钮,按下这些按钮时,会将感兴趣的数字加一(很像闹钟)。这是一个异步操作,会在某种形式的编辑模式下发生(外部强制)。我编写的代码在没有“elsifrising_edge(digitUp1)then”和“elsifrising_edge(digitUp1)then”块的情况下工作正常,但包含它们时会失败。我真的不知道为什么它不起作用或如何修复它。不断出现错误,例如“无法在此时钟边缘实现分配的寄存器”、“无法推断 count2[3] 的寄存器,因为其行为取决于多个不同时钟的边缘”和“无法推断寄存器” count2[3]”位于 MinuteCounter.vhd(21),因为它在时钟边沿之外不保存其值”。任何帮助将不胜感激。

library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_signed.all;

-- ToDo: ENFORCE ON ALL COUNTERS (externally) LOGIC TO PAUSE AT MAX/MIN

entity MinuteCounter is
port( clockIn, digitUp1, digitUp2, reset, counting, countUp : in std_logic;
      clockOut : out std_logic;
      BCD1, BCD2 : out std_logic_vector(3 downto 0));
end MinuteCounter;

architecture structure of MinuteCounter is
signal count1, count2 : std_logic_vector(3 downto 0);
signal carryOut : std_logic;
begin

process( clockIn, digitUp1, digitUp2, countUp, reset, counting)
begin 

    -- Asynchronous reset
    if reset = '1' then
        count1 <= "0000";
        count2 <= "0000";

    -- What to run when there's an active edge of the clock
    elsif rising_edge(clockIn) then

        -- Code to run when timer is running
        if counting = '1' then

            -- What to do when counting up
            if countUp = '1' then
                if ((count1 = "1001") and (count2 = "0101")) then
                    count1 <= "0000";
                    count2 <= "0000";
                    if carryOut = '0' then
                        carryOut <= '1';
                    else
                        carryOut <= '0';
                    end if;
                elsif count1 = "1001" then
                    count1 <= "0000";
                    count2 <= count2 + 1;
                else
                    count1 <= count1 + 1;
                end if;

            -- What to do when counting down (This logic is hard to understand)
            else
                if ((count1 = "0000") and (count2 = "0000")) then
                    count1 <= "1001";
                    count2 <= "0101";
                    if carryOut = '0' then
                        carryOut <= '1';
                    else
                        carryOut <= '0';
                    end if;
                elsif count1 = "0000" then
                    count1 <= "1001";
                    count2 <= count2 - 1;
                else
                    count1 <= count1 - 1;
                end if;
            end if;

        -- When counting is disabled, but there is an active edge (do nothing)
        else
            count1 <= count1;
            count2 <= count2;
        end if;

    -- Code to run when entering values (will not be run if counting = '1') << Externally enforced
    elsif rising_edge(digitUp1) then
        if count1 = "1001" then
            count1 <= "0000";
            count1 <= count1 + 1;
        else
            count1 <= count1 + 1;
        end if;

    -- Code to run when entering values (will not be run if counting = '1') << Externally enforced
    elsif rising_edge(digitUp2) then
        if count2 = "0101" then
            count2 <= "0000";
            count2 <= count2 + 1;
        else
            count2 <= count2 + 1;
        end if;

    -- What to do when there is no active edge or other events (nothing)
    else
        count1 <= count1;
        count2 <= count2;
    end if;

end process;

-- Assign outputs
BCD1 <= count1;
BCD2 <= count2;
clockOut <= carryOut;

end structure;

问题标题中解释了“为什么它不起作用”:进程块内的多个上升沿检测.

VHDL旨在描述硬件,没有响应多个时钟信号的基本电路元件。所以你不能那样描述电路。

那么如何解决呢?

您可以将电路转换为任何单个进程仅具有一个时钟信号的电路(如果您正确使用,还可以选择一个异步复位信号)。这可以使用真实的寄存器和触发器来实现。

两种方法是:

  1. 多个进程,使用信号在它们之间进行通信
  2. 单个进程使用单个时钟,在主时钟边沿采样其他信号。

在这些之间做出正确的决定需要对设计有一定的整体了解。

这里听起来好像所有三个时钟信号实际上都是按钮按下,而不是一个快速时钟。因此,您不能保证按下另一个按钮时会有时钟沿。

因此,这是前进的多种方法之一:make一个时钟信号(进程外部),它将涵盖所有三个输入事件。

my_clock <= clockIn or digitUp1 or digitUp2;

现在您可以使用此时钟重写该过程:

process(my_clock, reset) is
begin
   if reset = '1' then
      -- reset actions
   elsif rising_edge(my_clock) then
      -- what caused this event?
      if digitUp1 = '1' then      -- bump digit 1
      elsif digitup2 = '1' then   -- bump digit 2
      else                        -- count normally
      endif;
   end if;
end process;

Notes:

  1. 由于这是一个正确的同步过程,因此只有时钟和复位属于敏感列表。
  2. 尽管这在某种意义上可行,但这可能不是客户想要的:例如,如果他按住所有三个按钮会发生什么?您可能想探索其他设计方法。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

VHDL:进程块内的多个上升沿检测 的相关文章

随机推荐

  • AWS EC2 Autoscaling:定义一个永不终止的主实例

    我使用具有自动缩放和负载平衡功能的 EC2 来托管我的 Web 应用程序 为了保证EC2实例之间的一致性 我只想允许从一个实例访问管理界面 因此所有写操作都在该实例上执行 然后其他实例定期下载已更改文件的副本 所以这是我的问题 我可以在我的
  • 如果参数等于这个字符串,定义一个像这个字符串的变量

    我正在做一些 bash 脚本 现在我得到了一个变量调用source和一个名为samples 像这样 source country samples US Canada Mexico 因为我想扩大源的数量 并且每个源都有自己的样本 所以我尝试添
  • 在 PHP 中使用 google image API 获取图像搜索结果的第一个 URL

    你知道一个 php 脚本 一个类就很好 可以获取 google api 图像搜索的第一个图像结果的 url 吗 谢谢 Example 正如 Sarfraz 所说 我找到了一种使用简单 HTML DOM 从 Google Image 结果中获
  • X11:通过命令行移动现有窗口?

    给定一个 X 客户端窗口 ID 有没有办法从命令行移动该窗口或更改其几何形状 xlsclients a Window 0x3000001 Machine ohm Name Terminal Icon Name foo Command foo
  • 将 DataGridView 值复制到 TextBox

    我试图得到这个问题的答案 但到目前为止没有任何帮助能够做到我想要的 我有这段代码 它的目的是查看所选行并将其列输出到相应的文本框中 private void DataGridView01 SelectionChanged object se
  • 为 REST-ful API 编写单元测试 [关闭]

    Closed 这个问题需要细节或清晰度 help closed questions 目前不接受答案 我正计划为 RESTful API 编写单元测试 我想知道我应该采取的方法 我最关心的方面与数据库状态有关 我的理解是 每次测试的测试目标的
  • 关于垃圾回收。为什么我们需要调用System.gc();?

    当引用的对象不再可供任何变量使用时 会自动调用垃圾收集 但我想知道为什么当自动调用垃圾回收时我们要显式调用 System gc 我们什么时候调用 System gc 你不知道 正如你所说 垃圾收集是自动的 System gc 甚至不强制进行
  • Ajax - 500 内部服务器错误

    我正在尝试在工作中为这个项目学习AJAX 我有一个加载患者正在服用的药物的网站 我递归地调用此 AJAX 函数 以便它将附加一个包含单一药物和 7 天历史记录的新表 我在 FF 和 IE 中执行代码时遇到问题 在镀铬中工作得非常好 我收到了
  • Python3并行处理opencv视频帧

    我有一个视频文件 需要逐帧处理 然后需要在帧中显示结果 目前我正在按顺序进行处理并一一显示帧 现在我想并行处理帧而不是顺序处理 一旦处理了 X 个帧 则 cv2 imshow 必须出现 并且必须以正确的顺序显示已处理的帧 目前我的顺序代码如
  • 有没有办法在禁用按钮时防止文本变灰?

    当我将按钮设置为禁用时 文本变为灰色 之前为黑色 在我的窗口中 结果是当按钮被禁用时文本不可读 我翻遍了 NSButton NSButtonCell NSCell NSControl 的文档 但没有找到任何方法使文本保持黑色 你知道我该怎么
  • Kotlin编译器会编译java文件吗?

    我有一个包含 java 和 kt 文件的项目 Kotlin 编译器会同时编译 java 和 kt 文件 还是只编译我的 kt 文件 No kotlinc仅编译 Kotlin 文件 kt 混合语言项目需要将两者结合起来kotlinc and
  • Angular + VB.NET - 路由不起作用

    所以我正在开发一个使用 AngularJS 和用 VB NET 编写的 Web API 的项目 所有这些工作都很好 直到我们必须维护路由为止 以下代码来自我的 angularApp 它定义了路由 var angularApp angular
  • 如何在 Cloud Run 上使用 Stackdriver 日志记录

    我正在尝试让 stackdriver 日志记录在 Google Cloud Run 完全托管 中运行的简单 Go 应用程序正常工作 但在 CloudRun 日志中看不到 stackdriver 条目 我已经创建了最简单的演示应用程序 htt
  • 使用 minimax 进行 tic-tac-toe 游戏可以使用多少个线程?

    我们以 5x5 井字游戏为例 假设轮到我的人工智能了 然后 我做了 25 步 基本上每个单元格 当然 如果它是合法的 移动 为每次移动创建一个线程 总共 25 个线程 最多 在每次移动时调用 minimax 函数 然后当所有结果都来自每个线
  • Visual C++ 2008 Express 下载链接失效了? [关闭]

    Closed 这个问题是无关 help closed questions 目前不接受答案 我目前正在学习的编程课程使用 Visual C 2008 为了在家工作 我们可以选择获取 Express 版本 我在网站上找不到下载链接 微软的支持也
  • Android 地图 - 限制在 180 度

    我可以将 Google 地图 V2 Android 限制在 180 180 经度 如 iOS MapKit 吗 我不希望它环绕 因为我正在尝试实现 clusterin 算法 而 180 180 度分割会让它变得困难 我希望平移限制在红线处
  • AngularJS - 如何访问指令中 templateUrl 内定义的表单?

    我正在尝试访问指令内的表单以进行验证 因此我想访问 setPristine 但是 我似乎无法弄清楚如何获取使用 templateUrl 创建的表单 我有一个 plunker 在这里详细说明了这个问题 http plnkr co edit S
  • Java用奇怪的字符创建Redis键和内容

    我正在使用以下代码创建一个新的 Redis 密钥 和内容 private static final String KEY ESTADOS estados private HashOperations
  • 在没有管理员权限的 Windows 上安装 python 模块

    我的工作笔记本电脑没有管理员权限 我的机器上已经安装了python和pip 版本号如下 C Users banand AppData Local Programs Python Python36 Scripts gt python vers
  • VHDL:进程块内的多个上升沿检测

    我对 VHDL 以及一般的数字电路 还很陌生 我正在尝试使用 BCD 样式块实现两位数的计数器 该电路的外部有一些按钮 按下这些按钮时 会将感兴趣的数字加一 很像闹钟 这是一个异步操作 会在某种形式的编辑模式下发生 外部强制 我编写的代码在