Как сбросить переменные в автомате распознавания последовательности в VHDL? - PullRequest
0 голосов
/ 18 мая 2018

Я новичок с VHDL.Я создал автомат распознавания (Мур) последовательности 000010 для доступа к лифту.После распознавания всей последовательности в состоянии X1 двери лифта открываются и загораются два светодиода, двери закрываются через 5 секунд в X2 и в X3, а через 10 секунд лифт достигает нужного этажа.Имитируя все с помощью Modelsim, ошибок нет.

Моя проблема в том, что я хочу сбросить все переменные (а затем вернуться в исходное состояние X0) в случае, например, если вы находитесь в каком-либо состоянии.Например, в X1 переменные «esito», led1 и led2 должны возвращаться к 0.

Так как невозможно сбросить эти переменные в первом процессе (где есть условие сброса = 1), потому чтоУ меня будет ошибка «Не удается разрешить несколько постоянных драйверов для сети» (в обоих процессах используются одни и те же переменные), я хотел бы спросить вас, было ли правильное решение, принятое мной в следующем коде (сбросьте переменные в X0 раньшеконтроль выполняется на вставленной последовательности).

Надеюсь, я был ясен, и вы можете мне помочь.

Это код:

library IEEE;
use IEEE.std_logic_1164.all;

entity riconoscitore is
port(   
    simbolo:inout  std_logic_vector(5 downto 0);
    clock,esito,reset:inout std_logic;
    led1,led2:out std_logic
    );
end riconoscitore;

architecture myriconosc of riconoscitore is
type state_values is 
(X0,X1,X2,X3);
signal current_st,next_st:state_values;
signal timer:std_logic;
begin

process(clock,reset) 
begin
if(reset='1') then
  current_st<=X0;
elsif(rising_edge(clock))then
current_st<=next_st;
end if;
end process;

process(current_st,simbolo,timer,reset)
begin
next_st<=X0;

case current_st is

when X0 =>
esito<='0';
led1<='0';
led2<='0';
reset<='0';
timer<='0';
simbolo<=('U','U','U','U','U','U');
if(simbolo="000010")then
  next_st<=X1; 
else
  next_st<=X0;
end if;

when X1 =>
esito<='1';
led1<='1';
led2<='1';
timer<= transport '1' after 5 sec;
next_st<=X2;

when X2=>
led1<='0';
if(timer='1') then
  next_st<=X3;
  reset<= transport '1' after 10 sec;
else next_st<=X2;
end if;

when X3=>
if (reset='1') then
  next_st<=X0;
  esito<='U';
  reset<='U';
  timer<='U';
  simbolo<=('U','U','U','U','U','U');
  led2<='0';
else 
  next_st<=X3;
end if;

end case;
end process;

end myriconosc;

Ответы [ 2 ]

0 голосов
/ 18 мая 2018

Один
Причина, по которой у вас возникли проблемы, заключается в том, что вы не следовали правилам кодирования для HDL.

У вас есть две секции: секция регистров / тактовая частота и комбинаторная секция.

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

Есть два решения:

  1. Назначьте значение каждому сигналу и переменной в каждом состоянии.
  2. Использовать по умолчанию

Два
Существует вторая ошибка, которую я раньше не видел:
Ваш process(clock,reset) зависит от сброса.В этом процессе вы устанавливаете состояние.

Затем в следующем процессе вы используете состояние для установки сброса.Вы только что создали самый неприятный круговой конечный автомат!Уберите ВСЕ использование сброса из второго процесса.Сброс должен контролировать только ваш первый процесс!

0 голосов
/ 18 мая 2018

Ваш последовательный процесс сброса асинхронный :

process(clock,reset) 
begin
if(reset='1') then
  current_st<=X0;
elsif(rising_edge(clock))then
current_st<=next_st;
end if;
end process;

Асинхронный сброс используется только для перевода триггеров в известное состояние, когда возникает какое-то исключение, наиболее частоДальнейшее включение.Никогда не используйте асинхронный сброс для каких-либо других целей.Никогда не используйте асинхронный сброс как часть нормальной работы вашей схемы.

Так, например, предположим, что у вас был секундомер с двумя кнопками: START / STOP и RESET .Таким образом, в начале гонки хронометрист нажимает START / STOP , чтобы начать отсчет часов, а в конце гонки хронометрист снова нажимает START / STOP , чтобы остановитьчасы считают.Как только время будет записано, хронометрист будет нажимать RESET , чтобы установить часы на ноль, готовые к следующей гонке.Предположим, через некоторое время батарея разрядится.Хронометрист вставит новые батарейки и обнаружит, что секундомер уже сброшен и готов к следующей гонке.Вы можете использовать асинхронный сброс для сброса часов во втором (новых батарей) случае;Вы никогда не должны использовать его в первом случае, потому что это не исключение - сброс к нулю, готовый к следующей гонке, - это то, что секундомеры делают как часть их нормальной работы.

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

Итак, в вашем проекте вы должны использовать асинхронный сброс, чтобы перевести ваши триггеры в известное состояние - X0 (как вы это сделали) - и выходные данные состояния FSM, когда они находятся в этом состоянии.это состояние, которое они имеют при сбросе.Вот и все.Если вам не нравится состояние выходов в состоянии X0, вам нужно изменить его или сбросить триггеры в другое состояние.

...