Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/asp.net/33.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
VHDL-FSMs中的状态管理_Vhdl_Fsm - Fatal编程技术网

VHDL-FSMs中的状态管理

VHDL-FSMs中的状态管理,vhdl,fsm,Vhdl,Fsm,我在VHDL中看到的许多FSM都是通过在FSM逻辑中设置变量“next\u state”来工作的,然后将其分别分配给进程外部的状态变量 如果简单地写“状态”有什么问题,那么简单地写状态或者甚至使用变量有什么问题吗: state := state_five 使用一个变量来存储状态意味着它仍然完全位于进程的本地,并且不会污染整个体系结构的命名空间 这还意味着,如果您习惯于在调试时使用printf(抱歉report)跟踪状态机的进度(这有时比波形查看器更可取),那么您可以在状态机进程结束时报告预期的

我在VHDL中看到的许多FSM都是通过在FSM逻辑中设置变量“
next\u state
”来工作的,然后将其分别分配给进程外部的状态变量


如果简单地写“
状态”有什么问题,那么简单地写
状态或者甚至使用变量有什么问题吗:

state := state_five
使用一个变量来存储状态意味着它仍然完全位于进程的本地,并且不会污染整个
体系结构的命名空间

这还意味着,如果您习惯于在调试时使用printf(抱歉
report
)跟踪状态机的进度(这有时比波形查看器更可取),那么您可以在状态机进程结束时报告预期的下一个状态,这很方便

增加: 如注释中所述,变量赋值是“立即”发生的(要清楚,这不会导致
case
语句立即切换到下一个状态!)


如果您需要提前一个周期的输出,可以(偶尔)利用这种效果,方法是根据过程结束时的下一个状态分配给所述信号。如果我最终需要这样做,我倾向于使用一个显式的
next_state
变量,除了
case
语句和
state:=next_state(正好在计时进程的末尾)。它向代码审阅者演示了您打算这样做

一些人总是编写两个进程状态机(即一个同步进程和一个并发进程)的原因可能主要是因为他们在学校里学会了这样做,就像其他人所说的那样

然而,在某些情况下,这种编码方式实际上比使用单个同步进程要好。简而言之,它允许您在同一上下文中混合同步和并发分配。考虑下面两段代码,都实现同样的事情:

两进程状态机:

process (clk)
begin
  if rising_edge(clk) then
    state <= state_next;
  end if;
end process;  

process (all)
begin 
  state_next <= state;
  case state is 
    when s_idle => 
      if req_i = '1' then 
        fifo_read <= '1'; -- Concurrent assignment
        state_next <= s_check_data; -- "Synchronous" assignment 
      end if; 
    when s_check_data =>
      if fifo_out = x"1234" then
        (...)
      end if;
    (...) 
  end case; 
end process;
process (clk)
begin 
  if rising_edge(clk) then
    case state is 
      when s_idle => 
        if req_i = '1' then 
          fifo_read <= '1';
          state <= s_wait_for_data;
        end if;
      when s_wait_for_data =>
        state <= s_check_data;
      when s_check_data =>
        -- Data word from FIFO now available.
        if fifo_out = x"1234" then
          (...)
        end if;
      (...) 
    end case;
  end if;
end process;
过程(clk)
开始
如果上升沿(clk),则

我的理解是变量的赋值发生在它们被写的地方,而信号的变化发生在过程的末尾。我想在实践中,除了在switch语句中,你不会看到状态,所以它没有什么区别;这是一个有趣的想法,但在代码中的不同位置,每个状态都会发生一些事情。(虽然在您的例子中,这两个位置在同一个进程中。)具有下一个信号的两进程状态机的优点是,您有一个case语句,每个状态(同步和并发)的所有赋值都在同一个位置。这可能更容易阅读。(并不是说我非常喜欢这种风格,只是想让讨论更加平衡。)@pc3-如果你使用next_state变量,它与两进程系统没有太大区别。但它仍然具有单个进程的特性(例如,从来没有锁存器,所有输出上都有一个DFF,所有东西都保持在一起,状态是单个进程的局部状态,更少的信号混乱)。正如你在回答中所说的,如果你必须减少延迟,那么仍然有一些事情是你用两个过程的方法无法实现的。我同意所有这些。总而言之,我尽量不要对此有太强烈的意见,因为所有不同的编码风格都有利弊。有些人喜欢编写两个进程状态机,我不鼓励他们停止。@pc3-我想我们达成了激烈的一致:)我也不想鼓励人们停止。只是停下来想想相对的优点,而不是盲目地耕耘。这些年来,相对的优点已经发生了变化,但我看到的很多建议(并不意味着你的!)似乎都是基于“旧知识”。(这让我想知道——我想知道我应该重新思考我的传统做法:)