VHDL 2进程状态机和输出初始化

时间:2017-06-19 17:20:28

标签: vhdl state-machine

因此,Altera提供了一个2进程状态机this link的示例。

我有点喜欢这种风格,但我不明白的是,如果'input'保持为'0',则第二个进程永远不会被触发,因为状态永远不会改变,因此'output'从未被分配或初始化......或者是吗?

我的理解是,需要在灵敏度列表信号(本例中为“状态”)之一上进行转换,这在此处永远不会发生。

有人可以澄清这里有什么交易吗?

以下是代码:

ENTITY state_machine IS
   PORT(
      clk      : IN   STD_LOGIC;
      input    : IN   STD_LOGIC;
      reset    : IN   STD_LOGIC;
      output   : OUT  STD_LOGIC_VECTOR(1 downto 0));
END state_machine;
ARCHITECTURE a OF state_machine IS
   TYPE STATE_TYPE IS (s0, s1, s2);
   SIGNAL state   : STATE_TYPE;
BEGIN
   PROCESS (clk, reset)
   BEGIN
      IF reset = '1' THEN
         state <= s0;
      ELSIF (clk'EVENT AND clk = '1') THEN
         CASE state IS
            WHEN s0=>
               IF input = '1' THEN
                  state <= s1;
               ELSE
                  state <= s0;
               END IF;
            WHEN s1=>
               IF input = '1' THEN
                  state <= s2;
               ELSE
                  state <= s1;
               END IF;
            WHEN s2=>
               IF input = '1' THEN
                  state <= s0;
               ELSE
                  state <= s2;
               END IF;
         END CASE;
      END IF;
   END PROCESS;

   PROCESS (state)
   BEGIN
      CASE state IS
         WHEN s0 =>
            output <= "00";
         WHEN s1 =>
            output <= "01";
         WHEN s2 =>
            output <= "10";
      END CASE;
   END PROCESS;

END a;

修改 为了澄清,我的问题是:在我看来'输出'将处于未定义状态,直到'输入'转换为'1'。考虑到这是Altera的官方示例,这不是那么糟糕的做法吗? 顺便说一下,在这里初始化'输出'的正确方法是什么?使用异步重置?

1 个答案:

答案 0 :(得分:2)

  

......它在我看来“输出&#39;将处于未定义状态,直到   &#39;输入&#39;过渡到&#39; 1&#39;。

否(见下文)。在模拟开始时,output将立即取值"00",即使未设置重置并且input上没有转换。

  

不是那种不好的做法,考虑到这是一个官方的例子   Altera?

不,这段代码很好。由于重置,状态寄存器(state)可以正确初始化,output组合依赖于state。无论是在模拟中还是在硬件中,该模型都将按预期运行。

  

顺便说一下,初始化&#39;输出的正确方法是什么?   这里 ?使用异步重置?

您没有通过重置初始化组合输出。重置(异步或同步)用于初始化寄存器(在您的示例中为state)。

敏感性列表只是语法糖。具有敏感性列表的流程等同于相同的流程,没有敏感性列表,并且wait on <sensitivity-list>;作为最后语句。例如:

PROCESS (state)
BEGIN
  CASE state IS
     WHEN s0 =>
        output <= "00";
     WHEN s1 =>
        output <= "01";
     WHEN s2 =>
        output <= "10";
  END CASE;
END PROCESS;

相当于:

PROCESS
BEGIN
  CASE state IS
     WHEN s0 =>
        output <= "00";
     WHEN s1 =>
        output <= "01";
     WHEN s2 =>
        output <= "10";
  END CASE;
  WAIT ON state;
END PROCESS;

因此,此过程在模拟开始时被触发(作为所有过程),并为output分配值。在您的特定情况下,此值将为"00",因为state的初始值是其枚举类型的最左侧值,即s0。总而言之,output已初始化为"UU"U是枚举类型std_logic的最左侧值),并且在第一个模拟步骤(T = 0)之后,它取值"00"

注意:这段代码很好,很好地代表了Moore状态机的编码(不是Mealy,因为其他答案说明:输出仅取决于当前状态)。但它(至少)有两个小问题:

  1. 它使用std_logic已解析类型用于单驱动器信号,这不是一个好主意。 <{1}}和std_ulogic会更好更安全。
  2. 它使用名称std_ulogic_vectorinput,而不应保留语言的保留字:它们是output中定义的标准输入和输出流。