Кодирование конечных автоматов в VHDL - PullRequest
3 голосов
/ 11 мая 2011

Я смотрю на создание системы на VHDL, которая фильтрует изображение после получения его через USB-устройство FTDI. Как часть этого, я считаю, что я определил состояния, в которых должен находиться мой CPLD, но я никогда раньше не создавал сложный конечный автомат в VHDL, поэтому я сомневаюсь, что мои методы являются надежными. В настоящее время основной план для моего конечного автомата таков:

begin
    process(clk, reset, USB_RXFN, USB_TXEN)
    begin
        case state is
            when IDLE =>
            when NEGOTIATING =>
            when RECEIVING =>
            when FILTERING =>
            when TRANSMITTING =>
            when OTHERS  => -- this should never happen but go to IDLE
    end process;

Моя проблема здесь в том, что в каждом руководстве по конечному автомату мне удалось найти состояние изменений на каждом переднем фронте (или аналогичном, но один раз за такт), и это устройство должно много раз находиться в режиме ожидания и переходить в режим NEGOTIATING только при USB_RXFN снижается, оставайтесь в ПЕРЕГОВОРЕ, пока это не будет сделано, оставайтесь в ПОЛУЧЕНИИ, пока не будет передано все изображение и т. д. *

Есть ли в моем подходе что-то принципиальное? CPLD просто не подходят для этой цели? Или можно оставаться в состоянии более одного часа, а учебники просто написаны таким образом для простоты?

Ответы [ 2 ]

3 голосов
/ 11 мая 2011

Да, вы можете подождать любое количество времени и / или комбинаций ввода, которые вам нравятся, прежде чем переходить в другое состояние.Вот один пример процесса.Я предпочитаю один процесс (TomiJ показал классический двухпроцессный конечный автомат, я использовал его повторно - спасибо TomiJ), так как он немного короче и позволяет избежать непреднамеренных выводов защелок, если вы пропустите сигнал из списка чувствительности«не синхронизированный» процесс.

architecture foo of bar is
begin
    FSM: process(clk, reset)
        type StateType is (IDLE, NEGOTIATING, RECEIVING, FILTERING, TRANSMITTING);
        variable state, next_state : StateType;
    begin
        if reset='1' then
            state := IDLE;
            next_state := IDLE;
        elsif rising_edge(clk) then
            case state is
                when IDLE =>
                    if USB_RXFN='0' then
                        next_state := NEGOTIATING;
                    end if;
                -- etc
            end case;
            -- Perform other logic based on state or next_state here

            -- finally update state for next time
            state := next_state;
        end if;
    end process FSM;
end foo;
3 голосов
/ 11 мая 2011

Короче говоря, уроки, которые вы прочитали, были написаны таким образом для простоты.

Вполне нормально подождать какое-то событие в состоянии, прежде чем перейти к другому. Это может быть выражено многими способами в VHDL, один общий способ состоит в том, чтобы иметь и сигналы State, и NextState, что-то вроде:

architecture foo of bar is
    type StateType is (IDLE, NEGOTIATING, RECEIVING, FILTERING, TRANSMITTING);
    signal State : StateType;
    signal NextState : StateType;
begin
    FSM: process(clk, reset)
    begin
        if reset='1' then
            State <= IDLE;
        elsif clk'event and clk='1' then
            State <= NextState;
        end if;
    end process FSM;

    STATES: process(State, USB_RXFN, USB_TXEN) -- ...
    begin
        NextState <= State; -- by default, stay in the same state (avoid a latch while you're at it)
        case State is
            when IDLE =>
                if USB_RXFN='0' then
                    NextState <= NEGOTIATING;
                end if;
            -- etc
        end case;
    end process STATES;
end foo;
...