|
Автомат состояний из StateCad отлично проверяется в StateBench но практически не работает в реальности. |
|
|
|
Jul 9 2007, 14:03
|
Профессионал
    
Группа: Свой
Сообщений: 1 817
Регистрация: 14-02-07
Из: наших, которые работают за бугром
Пользователь №: 25 368

|
Привет. Подскажите плиз, что может быть за глюк: есть простенькая диаграмма, нарисованная в StateCad на картинке. Смысл в том, чтобы проверять длину входящего импульса ERR_IN и если она больше 18 циклов, то устанавливать флаг ERROR_OUT. Для подсчета используется счетчик COUNT_ERR. Скорость всего этого 3 МГц на Спартане 3 с 75Мгц кристалом. Сигнал ERR_IN - асинхронный STATE_CAD сгенерировал очень понятный VHDL код с CASE и IFами, который я на основании знаний основных язаков программирования, но не VHDL, оцениванию как правильный. Прикол в том, что при проверке CHIPSCOPEом в реальности часто происходят такие сбои, хотя в большинстве случаев работает правильно: 1. При подаче импульса счетчик считает до 2-4, а потом устанавливается флаг ERROR_OUT 2. При подаче импульса ERR_IN счетчик считает до 1-2 а потом устанавливается в 0. Когда через несколько циклов ERR_IN исчезает , то в этот момент устанавливется ERROR_OUT. 3. Если ERR_IN устанавливается в 0 во время счета то иногда в COUNT_ERR все равно хранится предыдущее состояние, а не 0. Если чесно, то это абсолютно ново для меня - но выглядет, как будто синтезатор что - то левое генерирует. Подскажите, может, надо регистр ставить на ERR_IN, или я в FPGA что-то не понимаю? Спасибо.
|
|
|
|
2 страниц
1 2 >
|
 |
Ответов
(1 - 14)
|
Jul 10 2007, 10:29
|
Профессионал
    
Группа: Свой
Сообщений: 1 817
Регистрация: 14-02-07
Из: наших, которые работают за бугром
Пользователь №: 25 368

|
Цитата в данном случае необходимо пропустить указанный сигнал через D-триггер, тактируемый рабочим тактовым сигналом автомата. Синтезатор в такой ситуации просто не в состоянии адекватно оценить задержки. А эту неадекватность как-то можно проверить? Синтезатор генерит процесс: PROCESS (sreg3,COUNT_ERR0,COUNT_ERR1,COUNT_ERR2,COUNT_ERR3,COUNT_ERR4, COUNT_ERR5,COUNT_ERR6,COUNT_ERR7,ERR_IN,RESET,COUNT_ERR) который не тактируется CLK. То есть такое все же может быть? А можете на основании дальнейшего кода, привести пример, когда сигнал, асинхронно изменившийся, может привести к неправильному переходу. У меня чего-то не получается Цитата CASE sreg3 IS WHEN ERR_COUNT => IF ( COUNT_ERR1='1' AND COUNT_ERR4='1' ) OR ( COUNT_ERR2='1' AND COUNT_ERR4='1' ) OR ( COUNT_ERR3='1' AND COUNT_ERR4='1' ) OR ( COUNT_ERR5='1' ) OR ( COUNT_ERR6='1' ) OR ( COUNT_ERR7='1' ) THEN next_sreg3<=ERROR; next_ERROR_OUT<='1';
COUNT_ERR <= (std_logic_vector'("00000000")); ELSIF ( ERR_IN='1' ) THEN next_sreg3<=ERR_COUNT; next_ERROR_OUT<='0';
COUNT_ERR <= (( std_logic_vector'(COUNT_ERR7, COUNT_ERR6, COUNT_ERR5, COUNT_ERR4, COUNT_ERR3, COUNT_ERR2, COUNT_ERR1, COUNT_ERR0)) + std_logic_vector'("00000001")); ELSE next_sreg3<=NO_ERROR; next_ERROR_OUT<='0';
COUNT_ERR <= (std_logic_vector'("00000000")); END IF; WHEN ERROR => IF ( ERR_IN='0' ) THEN next_sreg3<=NO_ERROR; next_ERROR_OUT<='0';
COUNT_ERR <= (( std_logic_vector'(COUNT_ERR7, COUNT_ERR6, COUNT_ERR5, COUNT_ERR4, COUNT_ERR3, COUNT_ERR2, COUNT_ERR1, COUNT_ERR0))); ELSE next_sreg3<=ERROR; next_ERROR_OUT<='1';
COUNT_ERR <= (( std_logic_vector'(COUNT_ERR7, COUNT_ERR6, COUNT_ERR5, COUNT_ERR4, COUNT_ERR3, COUNT_ERR2, COUNT_ERR1, COUNT_ERR0))); END IF; WHEN NO_ERROR => IF ( ERR_IN='1' ) THEN next_sreg3<=ERR_COUNT; next_ERROR_OUT<='0';
COUNT_ERR <= (( std_logic_vector'(COUNT_ERR7, COUNT_ERR6, COUNT_ERR5, COUNT_ERR4, COUNT_ERR3, COUNT_ERR2, COUNT_ERR1, COUNT_ERR0)) + std_logic_vector'("00000001")); ELSE next_sreg3<=NO_ERROR; next_ERROR_OUT<='0';
COUNT_ERR <= (( std_logic_vector'(COUNT_ERR7, COUNT_ERR6, COUNT_ERR5, COUNT_ERR4, COUNT_ERR3, COUNT_ERR2, COUNT_ERR1, COUNT_ERR0))); END IF; WHEN OTHERS => END CASE;
|
|
|
|
|
Jul 10 2007, 10:49
|

Знающий
   
Группа: Свой
Сообщений: 541
Регистрация: 11-04-05
Из: Москва
Пользователь №: 4 045

|
Фокус в том, что приведенный Вами кусок описывает лишь функцию переходов автомата - комбинаторная логика формирование следующего состояния next_sreg3 на основании входов ERR_IN и COUNT_ERR (про него я забыл в первом своем посте - он также асинхронен по отношению к автомату?) и текущего состояния sreg3. Где-то еще должен быть синхронный процесс чем-то тактируемый, осуществляющий "переход следующего состояния в текущее". А ошибки возникают вот почему. Представьте себе, что у Вас имеется 2 триггера, описывающие состояния автомата. Всего у этого автомата может быть 4 состояния 00, 01, 10, 11, но Вы используете только 3. На входе каждого триггера висит логическая функция от обоих этих триггеров и пусть одного асинхронного по отношению к автомату сигнала. Предположим, что фронт тактового сигнала на эти два триггера приходит не одновременно (а по жизни так оно и есть). Тогда если изменение входа произойдет после переключения первого и до переключения второго, то Вы как раз и получите неверный переход или запрещенное состояние (при проектировании автоматов предполагается, что все триггеры его составляющие работают с одними и теми же значениями входов, а в данном случае это условие нарушается).
Кстати, вариант со счетчиком, предложенный выше, также будет работать неправильно по изложенной мной причине - там триггеров не 2, а целых 5 и взаимное расположение ERR_IN и фронтов тактового сигнала будет для каждого триггера индивидуально.
--------------------
Дурак, занимающий высокий пост, подобен человеку на вершине горы - все ему кажется маленьким, а всем остальным кажется маленьким он сам. /Законы Мерфи/
|
|
|
|
|
Jul 10 2007, 11:42
|
Профессионал
    
Группа: Свой
Сообщений: 1 817
Регистрация: 14-02-07
Из: наших, которые работают за бугром
Пользователь №: 25 368

|
После предыдущего кода есть кусок:
next_COUNT_ERR7 <= COUNT_ERR(7); next_COUNT_ERR6 <= COUNT_ERR(6); next_COUNT_ERR5 <= COUNT_ERR(5); next_COUNT_ERR4 <= COUNT_ERR(4); next_COUNT_ERR3 <= COUNT_ERR(3); next_COUNT_ERR2 <= COUNT_ERR(2); next_COUNT_ERR1 <= COUNT_ERR(1); next_COUNT_ERR0 <= COUNT_ERR(0);
А синхронный процесс, перехода выглядет так: PROCESS (CLK, next_sreg3, next_ERROR_OUT, next_COUNT_ERR7, next_COUNT_ERR6, next_COUNT_ERR5, next_COUNT_ERR4, next_COUNT_ERR3, next_COUNT_ERR2, next_COUNT_ERR1, next_COUNT_ERR0) BEGIN IF CLK='1' AND CLK'event THEN sreg3 <= next_sreg3; ERROR_OUT <= next_ERROR_OUT; COUNT_ERR7 <= next_COUNT_ERR7; COUNT_ERR6 <= next_COUNT_ERR6; COUNT_ERR5 <= next_COUNT_ERR5; COUNT_ERR4 <= next_COUNT_ERR4; COUNT_ERR3 <= next_COUNT_ERR3; COUNT_ERR2 <= next_COUNT_ERR2; COUNT_ERR1 <= next_COUNT_ERR1; COUNT_ERR0 <= next_COUNT_ERR0; END IF; END PROCESS;
Но я уже прикидываю, что между CLK переменная next_sreg3 может получить черт-знает какое значение, потому что процесс автомата может кучу раз выполнится между клоками. Или я неправ?
|
|
|
|
|
Jul 10 2007, 12:25
|

Знающий
   
Группа: Свой
Сообщений: 541
Регистрация: 11-04-05
Из: Москва
Пользователь №: 4 045

|
Цитата(sazh @ Jul 10 2007, 15:40)  Впрочем никто не мешает простробировать клоком ERR_IN. Это же набросок и не более того. Только так и нужно делать, иначе никакие констрейны не помогут. Цитата(syoma @ Jul 10 2007, 15:42)  Но я уже прикидываю, что между CLK переменная next_sreg3 может получить черт-знает какое значение, потому что процесс автомата может кучу раз выполнится между клоками. Или я неправ? Процесс выполняется при изменении любого сигнала в списке чувствительности, поэтому через некоторое время после фронта тактового сигнала (определяемое задержками распространения и логики) если все сигналы на входе тактируются одним клоком, значения на выходе комбинаторных элементов будут вполне определенные. Я же уже приводил рецепт: Код process (CLK) begin if (CLK'event and CLK = '1') then ERR_IN_CLK <= ERR_IN; end if; end process; А ERR_IN_CLK используйте как вход автомата.
--------------------
Дурак, занимающий высокий пост, подобен человеку на вершине горы - все ему кажется маленьким, а всем остальным кажется маленьким он сам. /Законы Мерфи/
|
|
|
|
|
Jul 10 2007, 14:57
|
Профессионал
    
Группа: Свой
Сообщений: 1 817
Регистрация: 14-02-07
Из: наших, которые работают за бугром
Пользователь №: 25 368

|
Цитата(BSV @ Jul 10 2007, 14:25)  Код process (CLK) begin if (CLK'event and CLK = '1') then ERR_IN_CLK <= ERR_IN; end if; end process; А ERR_IN_CLK используйте как вход автомата. В принципе такой код и получается, если пропустить вход через регистр с CLK. Сегодня вечером попробую. Всем спасибо.
|
|
|
|
|
Jul 10 2007, 23:16
|

Знающий
   
Группа: Свой
Сообщений: 541
Регистрация: 11-04-05
Из: Москва
Пользователь №: 4 045

|
Цитата(sazh @ Jul 10 2007, 19:54)  Вобще то переводом с английского это называется - бог в помощь. Считаете, что это излишняя перестраховка? Net Skew для глобальных клоков хоть и небольшие, но ненулевые, поэтому нельзя исключать возможность, что асинхронный сигнал отработается триггерами по разному ИМХО. По поводу использования автомата - согласен с предыдущими ораторами, что применение его в данном контексте излишне.
--------------------
Дурак, занимающий высокий пост, подобен человеку на вершине горы - все ему кажется маленьким, а всем остальным кажется маленьким он сам. /Законы Мерфи/
|
|
|
|
|
Jul 11 2007, 06:03
|
Гуру
     
Группа: Свой
Сообщений: 2 435
Регистрация: 6-10-04
Из: Петербург
Пользователь №: 804

|
Считаете, что это излишняя перестраховка? Net Skew для глобальных клоков хоть и небольшие, но ненулевые, поэтому нельзя исключать возможность, что асинхронный сигнал отработается триггерами по разному ИМХО. /////////////////////////////////////// Все Вы правильно говорите. У нормального макроса и входы и выходы должны быть регистровые. В моем функциональном примере естественно не хватает триггера. А может и двух. если входной сигнал внешний для системы, можно ведь и о метастабильности вспомнить. Я хотел сказать , что на функциональном уровне этот автомат не работает. (не из за времени установки и удержания данных относительно фронта клока на триггерах state). Наверно, потому, что не верно описан. В том числе и с точки зрения рекомендаций по созданию автоматов. (one hot и т.д.). Поэтому триггер на входе такого автомата, как мертвому припарки. Ну кому охота разбираться в автомате на десятки строк, когда это оисывается тремя. Причем без асинхронного ресета для перевода автомата в состояние IDLE, который по идее тоже нужно пропускать через триггер.
|
|
|
|
|
Jul 11 2007, 19:43
|

Знающий
   
Группа: Свой
Сообщений: 541
Регистрация: 11-04-05
Из: Москва
Пользователь №: 4 045

|
Мое мнение такое - пусть с логикой работы схемы автор разбирается сам, поскольку только так можно научиться грамотному проектированию. После определенного количества мучений упрощения и оптимизации находятся сами собой, а уж потом появляется интуиция, подсказывающая как нужно делать ту или иную вещь. Однако, кодирование схем ПЛИС на HDL языках порождает у мигрантов из программирования некоторые иллюзии, которые на первых порах сбивают их с толку и приводят к ошибкам, о существовании которых они и не подозревают. Одно из таких темных мест мы тут и рассмотрели, хотя на каком-нибудь более злобном форуме народ сразу начинает вопить, что это мульен раз уже говорилось, писалось и есть в любой книжке по цифровой схемотехнике. А автор замолчал что-то. Интересно, чем закончились его изыскания?
--------------------
Дурак, занимающий высокий пост, подобен человеку на вершине горы - все ему кажется маленьким, а всем остальным кажется маленьким он сам. /Законы Мерфи/
|
|
|
|
2 чел. читают эту тему (гостей: 2, скрытых пользователей: 0)
Пользователей: 0
|
|
|