VHDL Почему состояние S0 активно, хотя этого быть не должно?

У меня возникли проблемы с этим фрагментом кода. Кажется, что состояние 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;

Вот распечатка симуляции:

(кликабельно)


person Paulo Gil    schedule 19.05.2016    source источник
comment
Похоже, это горячее кодирование (подразумевается, что это симуляция постсинтеза). Полярность PState.S0 кажется инвертированной, в то время как остальные кажутся положительными. Синтезированное оборудование должно поддерживать прямую полярность, но PState не является выходом, правильно ли он имитирует? Вы не предоставили минимальный, полный и проверяемый пример, позволяющий проводить моделирование перед синтезом. Есть идеи? — слишком широкое слово для вопроса. Возможно, вы могли бы ограничить синтез по-другому, если бы хотели заглянуть внутрь.   -  person    schedule 20.05.2016


Ответы (1)


С вашим кодом все в порядке. Как вы думаете, почему состояние S0 всегда активно? Вы не можете сказать это по форме волны, потому что вы не знаете схему кодирования. С другой стороны, вы пишете, что сигнал Address постоянно меняется, что означает, что ваш конечный автомат меняет свое состояние.

person ya_urock    schedule 21.05.2016
comment
Если вы посмотрите на состояние S0 и представите его перевернутым, разве оно не должно было выглядеть именно так, перевернуто? Я имею в виду, что состояние S0 используется по умолчанию... Если ни одно из других состояний не активно, то единственным активным должно быть состояние S0, верно? Если вы посмотрите на разрыв ~100 нс, активного состояния нет... Это звучит немного странно для меня. - person Paulo Gil; 23.05.2016
comment
Прежде всего. если вы хотите быть точно уверены, в каком состоянии вы находитесь, не используйте определение перечисления этого типа. Для сигнала состояния используйте простой тип std_logic_vector и определите константы для состояний самостоятельно. Здесь мы имеем дело с автоматическим преобразованием типа enum в std_logic_vector, что может привести к кодированию состояния S0 как 000000, что мы видим на осциллограмме сразу после сигнала сброса. - person ya_urock; 23.05.2016
comment
Также я хочу указать на еще одну ошибку в вашем коде - во время сброса активен writeEnable. Это потому, что когда сброс активен, вы находитесь в состоянии S0, и если в этом состоянии validTime = 1, то writeEn также равно 1. Я полагаю, это не то, что вы хотите. Я бы предложил иметь еще одно состояние с именем RST_ST. Оставайтесь в нем, когда активен сигнал сброса, затем переходите к S0, когда он не активен. Таким образом, вы пишете, что сигнал En не будет активен в течение периода сброса. - person ya_urock; 23.05.2016