状态机;为什么只有最后一个状态有效?

2024-01-03

我有一个有 6 个状态(3 个主要状态)的状态机。只有最后一个状态有效,但前 2 个状态无效(共 3 个)。只有最后一个状态有效。我发现了问题,当我移除去抖电路时它可以工作,但我需要去抖电路。我从网上得到了去抖电路。如果有人可以提供帮助,我会很高兴。

 type SM_STATES is (state_column_1, scan_col_1, state_column_2, scan_col_2,
                          state_column_3, scan_col_3);
 signal my_state     : SM_STATES                   := state_column_1;

下面是状态机:

scanner_sm : process (clk)
begin  -- process key_scanner
  if clk'event and clk = '1' then

  if state_inc = '1' then -- clock divider finished counting down 100000

    -- reset scan_complete
    scan_complete <= '0';

case my_state is

  when state_column_1 =>
    scanned_val  <= (others => '0');
    original_col   <= "110";
    my_state <= scan_col_1;

  when scan_col_1 =>
    case bcd_val is
      when "1110" => scanned_val <= "1100100";  -- 1 wrong
      when "1101" => scanned_val <= "1100010";  -- 2 wrong
      when others => scanned_val <= "0010000";
    end case;
    my_state <= state_column_2;

  when state_column_2 =>
    original_col   <= "011";
    my_state <= scan_col_2;

  when scan_col_2 =>
    case bcd_val is
      when "1110" => scanned_val <= "1011011";  -- 5 wrong
      when "1101" => scanned_val <= "1011111";  -- 6 wrong
      when others => scanned_val <= "0000000";
    end case;
    my_state <= state_column_3;

  when state_column_3 =>
    original_col   <= "101";
    my_state <= scan_col_3;

  when scan_col_3 => -- Reading S1 // The only working state
    case bcd_val is
      when "1110" => scanned_val <= "1100000";  -- 9/ 1
      when "1101" => scanned_val <= "0111110";  -- X/ 2
      when others => scanned_val <= "0000000";
    end case;
    my_state <= state_column_1; -- ************ Error might be here
    scan_complete <= '1'; -- ********** Error might be here

  when others => scanned_val <= "0000000";
end case;

      end if;
  end if;
end process scanner_sm;

debounce: process (CLK) is 
begin 
 if (CLK'event and CLK = '1') then  
  Q0 <= scannel_val; 

  Q1 <= Q0; 

  Q2 <= Q1; 

 end if; 

end process; 

Final_val <= Q0 and Q1 and (not Q2);

end Behavioral; 

到目前为止,您的代码还不完整 - 您直接在 case 语句中分配给信号my_state由状态机评估。要理解这个问题,我们需要知道模拟器是如何工作的:

与实际硬件相比,模拟器必须使用顺序 CPU 按顺序处理代码。这是通过在无限小的时间距离内一遍又一遍地运行代码来实现的 - 所谓的达美延迟 http://en.wikipedia.org/wiki/Delta_delay- 直到所有依赖关系都解决了,即不再发生任何变化。

请注意,在此迭代期间没有实际时间过去。在正确编写的设计中,模拟器现在会等待直到下一个事件发生——通常是由时钟的滴答声引起的,该时钟滴答声再次重新启动顺序迭代。

你的例子基本上类似于一个无限循环:改变my_state总是会导致 my_state 的下一次更改,因此模拟器永远不会稳定在某个值 - 直到它达到硬编码的迭代限制,在您的情况下碰巧是第三种状态。

那么,如何解决这个问题呢?我们需要引入一个时钟,并需要根据实际的模拟时间进行状态转换,通常是通过等待时钟事件来实现。最佳实践是将组合部分和顺序部分分成两个不同的进程,如状态机的这个最小示例所示:

library ieee;
use ieee.std_logic_1164.all;

entity foo is

end entity foo;

architecture bar of foo is
  type SM_STATES is (state_column_1, scan_col_1, state_column_2, scan_col_2, state_column_3, scan_col_3);
  signal my_state, my_state_next : SM_STATES;
  signal bcd_val                 : std_logic_vector(3 downto 0) := "1110";
  signal clk                     : std_logic                    := '1';
  signal nRST                    : std_logic                    := '0';
  signal scanned_val             : std_logic_vector(6 downto 0);
  signal original_col            : std_logic_vector(2 downto 0);
  signal scan_complete           : std_logic;
begin  -- architecture bar

  comb : process (my_state, bcd_val) is
  begin  -- process baz
    case my_state is

      when state_column_1 =>
        scanned_val   <= (others => '0');
        original_col  <= "110";
        my_state_next <= scan_col_1;

      when scan_col_1 =>
        case bcd_val is
          when "1110" => scanned_val <= "1100100";  -- 1 wrong
          when "1101" => scanned_val <= "1100010";  -- 2 wrong
          when others => scanned_val <= "0010000";
        end case;
        my_state_next <= state_column_2;

      when state_column_2 =>
        original_col  <= "011";
        my_state_next <= scan_col_2;

      when scan_col_2 =>
        case bcd_val is
          when "1110" => scanned_val <= "1011011";  -- 5 wrong
          when "1101" => scanned_val <= "1011111";  -- 6 wrong
          when others => scanned_val <= "0000000";
        end case;
        my_state_next <= state_column_3;

      when state_column_3 =>
        original_col  <= "101";
        my_state_next <= scan_col_3;

      when scan_col_3 =>                -- Reading S1 // The only working state
        case bcd_val is
          when "1110" => scanned_val <= "1100000";  -- 9/ 1
          when "1101" => scanned_val <= "0111110";  -- X/ 2
          when others => scanned_val <= "0000000";
        end case;
        my_state_next <= state_column_1;  -- ************ Error might be here
        scan_complete <= '1';           -- ********** Error might be here

      when others => scanned_val <= "0000000";
    end case;
  end process comb;

  process (clk, nRST) is
  begin  -- process
    if nRST = '0' then                  -- asynchronous reset (active low)
      my_state <= state_column_1;
    elsif clk'event and clk = '1' then  -- rising clock edge
      my_state <= my_state_next;
    end if;
  end process;

  -- this clock and reset signal would usually be supplied from the outside
  clk  <= not clk after 10 ns;
  nRST <= '1'     after 101 ns;
end architecture bar;

如果我们现在在模拟器中运行此文件,我们可以看到每个时钟周期的状态切换:

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

状态机;为什么只有最后一个状态有效? 的相关文章

  • “警告 C0007:架构具有未绑定的实例”问题!

    我从 数字设计基础 一书随附的 CD 中获取了以下源代码 当我尝试运行该程序时 出现以下错误 Compiling Fig17 13 vhd C Users SPIDER Desktop EE460 The Final Project Fig
  • 状态机;为什么只有最后一个状态有效?

    我有一个有 6 个状态 3 个主要状态 的状态机 只有最后一个状态有效 但前 2 个状态无效 共 3 个 只有最后一个状态有效 我发现了问题 当我移除去抖电路时它可以工作 但我需要去抖电路 我从网上得到了去抖电路 如果有人可以提供帮助 我会
  • VHDL - PhysDesignRules:367

    当我尝试从 VHDL 代码合成 实现和生成程序文件时 我收到警告 当我尝试合成时出现此错误 WARNING Xst 647 Input
  • R 在使用 case_when 时提供参数(R 向量化)

    这是我之前提出的问题的后续问题 当存在大量类别 类型时 R 使用 case when R 向量化 应用多个函数 https stackoverflow com questions 62377561 r apply multiple func
  • Lex VHDL '(勾号)令牌

    在 VHDL 中 字符可用于封装字符标记ie 或者它可以作为属性分隔符 类似于 CPP 的 token ie string hello 解析包含字符的属性名称时出现问题ie string a b c 在这种情况下 天真的词法分析器将错误地标
  • rspec:未找到属性(存在)错误

    我在指定模型验证时遇到一些问题 该模型充当状态机 gem state machine 0 9 4 通过 stat machine 我定义了对交付状态下的自行车的验证 state delivered do validates presence
  • Quartus初始化RAM

    我制作了一个实体 其中 quartus 成功识别 RAM 并为其实例化 RAM 宏功能 如果我可以从文件初始化 RAM 那就太好了 我找到了制作此类文件 mif 文件 的教程 现在我已经创建了该文件 我不知道如何让 quartus 初始化该
  • 触发器在两个信号的边沿触发

    我需要一个对两个不同信号的边缘做出反应的触发器 像这样的东西 if rising edge sig1 then bit lt 0 elsif rising edge sig2 then bit lt 1 end if 这样的触发器是否存在或
  • 将工作流(状态机)存储在数据库中。最好的办法是什么?

    我在用工作流程宝石 https rubygems org gems workflow 在 FoR 模型 用户 内部对一个简单的状态机进行建模 实际上是许多具有相同根的工作流程 状态机是硬编码在模型中 但我需要一种方法来允许管理员自定义工作流
  • 将库添加到 Vivado 2014.4

    我对 Vivado 和 VHDL 还很陌生 我想要一些关于基本问题的指导 我猜我可以创建自己的库并在我的项目中使用它们 就像使用默认库和基本库一样 eg library IEEE use IEEE std logic 1164 ALL us
  • VHDL 中的 BRAM_INIT

    我正在模拟基于处理器的设计 其中程序存储器内容保存在 BRAM 中 我正在使用 VHDL 推断 BRAM 实现程序存储器 我试图避免使用 CoreGen 因为我想保持设计的可移植性 最终该设计将进入 FPGA 我想看看是否有一种方法可以使用
  • 使用 C# 中的静态类通过事件通知其他订阅者的简单状态机

    我一直在尝试为我的应用程序编写一个简单的静态类状态机 以便在系统状态更改时通知其他控件和代码 我想我几乎已经解决了 但我遇到了一个小问题 我不知道如何解决 这是代码 An enum denoting the 3 States public
  • .NET 的状态机框架

    我工作中的系统基本上是一个消息驱动的状态机 它接收各种类型的消息 根据消息查找某些上下文 状态 然后根据消息和当前状态决定要做什么 通常结果是一条消息被发送到系统之外 有没有好的开源框架可以在 NET 中实现状态机 我研究了最新版本的 Wi
  • 将 *.vhdl 编译到库中时出现编译器错误 - Altera Quartus II

    我已经从以下位置下载了浮点包http www vhdl org fphdl http www vhdl org fphdl 并做了以下事情 我在项目中包含了 math utility pkg vhd fixed pkg c vhd 和 fl
  • 在 VHDL 中使用 SB_RGBA_DRV 原语

    我在使用为 Lattice ICE40UP fpga 提供的 SB RGBA DRV 原语时遇到问题 技术库提供了一个 verilog 示例 我可以使用它 但是当我尝试在 VHDL 中使用它时 P R 失败 输出以下消息 错误 非法连接 S
  • VHDL - 为什么直接在函数上使用长度属性会产生警告?

    我有一个 VHDL 函数 它返回记录的 std logic vector 表示形式 并且我想要该 std logic vector 的长度 我可以直接在函数上使用长度属性 为什么这会在 ModelSim 中产生警告 我是否会引发一些微妙的问
  • VHDL 计数器错误 (vcom-1576)

    伙计们 我试图用 VHDL 编写一个简单的计数器 但我总是收到此错误 Error C Users usrname dir1 dir2 dir3 counter vhd 22 near rising edge vcom 1576 expect
  • 仅使用 std_logic_vector 包将 std_logic_vector 与常量进行比较

    我仅在 VHDL 文件中使用以下包 library IEEE use IEEE STD LOGIC 1164 ALL 在代码中 我将 std logic vector 信号 A 与常量值进行比较 例如 if A lt 00001011 th
  • 32x8 寄存器文件 VHDL 测试台

    我已经用 vhdl 编写了该电路的汇编代码 我想用测试台来模拟它 RegWrite 1 位输入 时钟 写寄存器个数 3位输入 写地址 写入数据 32 位输入 数据输入 读取 寄存器编号 A 3 位输入 读取地址 读取寄存器编号 B 3 位输
  • VHDL:如何声明可变宽度通用[重复]

    这个问题在这里已经有答案了 我想创建一个 VHDL 实体 其中一个泛型可以更改另一个泛型的宽度 entity lfsr n is generic WIDTH integer 32 counter width POLYNOMIAL std l

随机推荐

  • 在 JavaScript 中将字符串转换为 base64。 btoa 和 atob 已弃用

    我最近一直在 VS Code 中处理一些项目 突然开始在我的代码中收到 btoa 和 atob 现已弃用的通知 除了 VS Code 之外 我找不到任何相关资源 如果这是真的 还有什么替代方案呢 Node btoa 和 atob 函数是唯一
  • 通过滚动窗口分区计算不同客户的数量

    我的问题类似于redshift 通过窗口分区计算不同客户的数量 https stackoverflow com questions 47736584 redshift count distinct customers over window
  • 我不知道 Postgresql 如何在我的 mac 上创建用户

    前两天开始学习postgresql 我在网上遵循的大多数教程要么是旧的 要么是代码不能在我的 Mac 上运行 我遵循了很多教程 做了很多完全不同的事情 当我今天打开系统时 我注意到 Postgresql 在我的 mac 上创建了一个用户 我
  • @Input() 在 Angular 中的用途是什么?

    我正在学习创建功能组件 https angular io tutorial toh pt3 add the input hero propertyangular io 上的教程然后我注意到 Input装饰器属性 src app hero d
  • wtforms 表单类子类化和字段排序

    我有一个用户窗体类 class UserForm Form first name TextField u First name validators Required last name TextField u Last name vali
  • 确定事件处理程序的优先级

    我有以下代码 我处理一个事件两次 但我总是想确保mynewclass始终首先处理事件 然后触发本地事件处理程序代码 我知道 MyClass 事件应该首先触发 因为这是第一个创建的事件 但由于线程和排队正在发生 我认为它花费了太长时间并且它在
  • 在 Python 程序中嵌入 Python shell

    我正在用 Python 创建一个科学实验室 用户可以在其中创建 修改和分析各种对象 我想在程序中放置一个Python shell 以便用户可以通过shell操作对象 注 他还可以通过常用的 GUI 来操纵对象 一个模型可以说明这一点 htt
  • jQuery load() 在 IE 中抛出“权限被拒绝”错误

    我正在通过 AJAX 使用 jQuery 加载页面load 功能 它在 IE8 中不起作用 给出 权限被拒绝 错误 使用 IE 调试器 似乎当 jQuery 尝试打开 xhr 时 ie 会阻止它 问题是 我的页面有一个 javascript
  • jars 似乎不再被签名。 JARSigningException:找到未签名的条目

    NB 7 4RC2 Win 7 在 Java 控制面板中 选中 保留临时 Internet 文件 复选框 我正在使用受信任的证书签署我的 Web Start 应用程序 然而 dist lib 中的第 3 方 jar 似乎未签名 C Prog
  • 更改代码后,PowerShell ISE 有时会出现不可预测的行为

    我正在使用 PowerShell ISE PS 版本 5 0 如果我运行这段代码 Write Host This 它输出 This 如果我像这样修改脚本 Write Host That 它输出 That 伟大的 正如预期的那样 现在 如果我
  • 无法在第二轮中将项目添加到集合中

    基本上我的 Windows 服务应用程序中有一个阻塞集合 每次我想向集合中添加 4 个项目然后对其进行处理 第一轮还好 第二轮就失败了 错误是 BlockingCollection 已被标记为已完成添加 My code public sta
  • Python - 以毫秒为单位的时间差对我不起作用

    我读过一些关于此的文章 并认为我有一些有效的代码 如果两个值之间的差异小于 1 秒 则显示的毫秒是正确的 如果差异超过一秒 它仍然只显示毫秒的差异 如下 Correct now wind 2013 08 25 08 43 04 776209
  • 在自己的数据集上训练 Tensorflow 对象检测

    在花了几天时间尝试完成这项任务之后 我想分享一下我如何回答这个问题的经验 我该如何使用TS 物体检测 https github com tensorflow models tree master research object detect
  • if (true) 的目的

    我见过一些这样写的代码 if true do something 你为什么要做这样的事情 这个结构有什么特别的地方吗 THanks 几乎任何现代编译器都会对此进行优化 我的猜测是 有人在开发过程中把它放在那里 让他们轻松删除代码块 通过更改
  • 如何防止argv中丢失双引号?

    好吧 我知道我可以这样循环 for int i 1 i lt argc 1 i cout lt lt argv i lt lt endl 但是这样双引号就丢失了 那就是一个字符串 something here 被视为 args 数组的一个元
  • 在绘图表达式中使用变量

    我试图将回归结果 即 R2 放入图表中 但似乎无法弄清楚如何从表达式中调用变量 它粘贴变量名称 这是我的代码 R2Val lt signif summary sMod pre90 r squared 1 2 text 92 4 expres
  • zsh compinit:安装 Homebrew 后,Mac 上出现不安全目录错误消息

    在我的 Mac 上安装 Homebrew 和 Homebrew Cask 后 以管理员身份 用户 ID 为 admin 运行 MacOS 10 12 6 我收到错误消息 zsh compinit insecure directories r
  • 发生整数溢出时无符号和有符号整数的行为差异[关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • 从 iOS 7.1 到 iOS 8 发送数据时 BLE 花费太多时间

    我有一个奇怪的问题 我正在开发一个应用程序 我在其中发送20 20 字节的块 一切正常 当我发送字节数据时从 iOS 8 到 iOS 8设备从一个设备传输到另一个设备大约需要 4 5 秒 但我的问题是当我从iOS 7 1 至 iOS 8或者
  • 状态机;为什么只有最后一个状态有效?

    我有一个有 6 个状态 3 个主要状态 的状态机 只有最后一个状态有效 但前 2 个状态无效 共 3 个 只有最后一个状态有效 我发现了问题 当我移除去抖电路时它可以工作 但我需要去抖电路 我从网上得到了去抖电路 如果有人可以提供帮助 我会