2016-05-19 133 views
1

我在使用这段代码时遇到了一些麻烦。看起来状态S0总是有效的,即使它不应该是。看起来这个状态的输出是反转的(当它被禁止时是有效的)。有任何想法吗?底部的模拟打印。由于VHDL为什么当状态S0不应该是活动状态?

library IEEE; 
use IEEE.STD_LOGIC_1164.all; 

entity ControlUnit is 
    port(clk   : in std_logic; 
      reset   : in std_logic; 
      validTime  : in std_logic; 
      timeData  : in std_logic_vector(3 downto 0); 
      writeEnable : out std_logic; 
      writeAddress : out std_logic_vector(3 downto 0); 
      averageReady : out std_logic); 
end ControlUnit; 

architecture Behavioral of ControlUnit is 
    type TState is (S0, S1, S2, S3, S4, S5); 
    signal PState, NState: TState; 
begin 

    sync_proc: process(clk, reset) 
    begin 
     if(reset = '1') then 
      PState <= S0; 
     elsif(rising_edge(clk)) then 
      PState <= NState; 
     end if; 
    end process; 

    comb_proc: process(PState, validTime, timeData) 
    begin 
     averageReady <= '0'; 
     writeEnable <= '0'; 
     case PState is 
      when S0 => 
       if(validTime = '1') then 
        writeEnable <= '1'; 
        NState <= S1; 
       else 
        NState <= S0; 
       end if; 
      when S1 => 
       if(validTime = '1') then 
        writeEnable <= '1'; 
        NState <= S2; 
       else 
        NState <= S1; 
       end if; 
      when S2 => 
       if(validTime = '1') then 
        writeEnable <= '1'; 
        NState <= S3; 
       else 
        NState <= S2; 
       end if; 
      when S3 => 
       if(validTime = '1') then 
        writeEnable <= '1'; 
        NState <= S4; 
       else 
        NState <= S3; 
       end if; 
      when S4 => 
       if(validTime = '1') then 
        writeEnable <= '1'; 
        NState <= S5; 
       else 
        NState <= S4; 
       end if; 
      when S5 => 
       averageReady <= '1'; 
       NState <= S0; 
      when others => 
       NState <= S0; 
     end case; 
    end process; 

    with PState select 
     writeAddress <= "0000" when S0, 
          "0001" When S1, 
          "0010" when S2, 
          "0011" when S3, 
          "0100" when S4, 
          "XXXX" when others; 
end Behavioral; 

这里是模拟的打印:

(点击)

+2

这似乎是一个热门编码(暗示这是后合成模拟)。 PState.S0的极性看起来是倒置的,而其余的看起来是正确的。合成的硬件需要保持极性直线,但PState不是输出,它是否正确模拟?您尚未提供允许预综合模拟的[最小,完整和可验证示例](http://stackoverflow.com/help/mcve)。 *任何想法?*对于一个问题有点宽泛。如果你想要在内部进行同步,也许你可以以不同的方式限制合成。 – user1155120

回答

0

一切都确定了你的代码。为什么你认为S0状态总是激活?你不能从波形中说出来,因为你不知道编码方案。另一方面,你不断地写地址信号变化,这意味着你的状态机改变它的状态。

+0

如果你看一下S0状态并想它倒置,是不是应该看起来像这样倒置?我的意思是,S0状态是“默认”......如果没有其他状态是活动的,那么只有一个活动应该是S0,对吧?如果你看一下〜100ns的差距,那就没有活跃的状态......这对我来说听起来有点奇怪 –

+0

首先。如果您想确切地确定自己所处的状态,请不要使用该类型的枚举定义。对于状态信号,请使用简单的std_logic_vector类型,并自行定义状态的常量。我们这里的自动枚举类型为std_logic_vector convertion,可能导致S0状态被编码为“000000”,这是我们在复位信号之后的波形处看到的。 –

+0

另外我还需要指出代码中的另一个错误 - 在复位期间,writeEnable处于活动状态。这是因为当复位处于活动状态时,您处于S0状态,并且如果在此状态下validTime = 1,则writeEn也为1.这不是我想要的。我会建议有一个叫做RST_ST的状态。复位信号有效时保持在此位置,否则移到S0。因此,在复位期间,您的writeEn信号不会有效 –