Введение в стандарт IEEE. Справочное руководство по языку VHDL (Пересмотр стандарта IEEE. 1076-1987), страница 14

port(

r1, r2, r3 : in std_logic;

ck, reset : in std_logic;

a1, a2, a3 : out std_logic ); 

end arbiter;

architecture behavior of arbiter is

type state_type is (waiting, ack1, ack2, ack3);

signal current_state, next_state : state_type;

begin

-- блок регистра

process (ck, reset)

begin

if reset = '1' then

current_state <= waiting;

elsif ck = '1' and ck'event then

current_state <= next_state;

end if;

end process;

-- процесс конечного автомата

process (current_state, r1, r2, r3) begin

- выходы заданные по умолчанию

a1 <= '0';

a2 <= '0';

a3 <= '0';

case current_state is

when waiting =>

-- условия перехода

if    r1 = '1' then next_state <= ack1;

elsif r2 = '1' then next_state <= ack2;

elsif r3 = '1' then next_state <= ack3;

else                next_state <= waiting;

end if;

when ack1 =>

-- выходы

a1 <= '1';

-- условия перехода

if    r1 = '1' then next_state <= ack1;

else                next_state <= waiting;

end if;

when ack2 =>

-- выходы

a2 <= '1';

-- условия перехода

if    r2 = '1' then next_state <= ack2;

else                next_state <= waiting;

end if;

when ack3 =>

-- выходы

a3 <= '1';

-- условия перехода

          if      r3 = '1' then next_state <= ack3;

else       next_state <= waiting;

end if;

when others =>

next_state <= waiting;

end case;

end process;

end behavior;


VHDL модель для автомата конечных состояний использует комбинационный логический блок смоделированный как процесс, с оператором case, разветвляющемся в текущем состоянии. В состав каждой ветки оператора case должно входить простое назначение следующего состояния, и выходные сигналы. Ветки на диаграмме состояний моделируются оператором if в пределах ветки оператора case.

Неизвестные или неиспользуемые состояния.

     Предложенный код для конечного автомата имеет важное свойство - защита от других запросов. Эта инструкция - обычно заключительная проверка, осуществляемая оператором выбора. Если машина вводит неизвестное или несуществующее состояние, запрос сбрасывает конечный автомат к известному состоянию.

when ack3 =>

a3 <= '1';

  if r3 = '1'    then next_state <= ack3;

else        next_state <= waiting;

end if;

when others =>

next_state <= waiting;

end case;

Кодирование состояний.

Элементы памяти на триггерах в конечном автомате следят за текущим состоянием. Каждому возможному состоянию автомата, логическим синтезатором назначен уникальный двоичный код; это известно также как кодирование состояний. Данным n триггерам, доступны максимум 2 из n состояний. Имеются архитектуры, которые имеют огромное количество состояний подобно CPLD и ППЗУ, которые являются идеальным для конечных автоматов, закодированных 2-мя состояниями.

     Альтернативный подход состоит в том, чтобы максимизировать число триггеров, используемых для кодирования конечного автомата. Один триггер выделен для каждого состояния; поэтому, n триггеров описывают n состояний. Эта методика известна как метод кодирования с единицей переноса. Первичное преимущество кодирования c единицей переноса состоит в том, что для декодирования текущего значения состояния никакая комбинационная логика не требуется, поэтому это будет работать быстрее в архитектуре содержащей большое количество логических устройств типа FPGAs.

     Первая выборка кода конечного автомата использует перечисляемые типы VHDL, чтобы нумеровать каждое уникальное состояние (Waiting, Ack1-Ack3). Если вы предпочитаете кодировать ваши собственные состояния, используйте VHDL константы. В выборке ниже, перечисляемые типы были заменены на константы, чтобы явно определить кодирование.

Типовой код кодирования состояний:

entity priority_arbiter is

port(R1, R2, R3 : in std_logic;

ck : in std_logic;

A1, A2, A3 : out std_logic);

end;

architecture behavior of priority_arbiter is