Перейти к содержанию
    

Непонятное поведение структур case и if-then-elsif (VHDL)...

Здравствуйте.

Я никак не могу понять, в чем же тут дело...

Дано: получить данные(1 байт) из UARTа, выделить командные биты и, в зависимости от кода команды, выполнить некие действия.

Что я сделал (минимум кода который уже работает неправильно):

...
process (RS232_READY) -- запуск процесса по стробу наличия данных в UARTе

variable command: std_logic_vector (2 downto 0);

begin
    if rising_edge(RS232_READY) then
        in_data_rs232<=RS232_IN; получение в переменную in_data_rs232 байта из UARTа
                command := in_data_rs232(7 downto 5); -- три бита - код команды
       
        case command is
            when "000" => NO_BLCK_A <= '0';       --простейший вариант - выставить 0 или 1 на ножке NO_BLCK_A                            
            when "001"  => NO_BLCK_A <= '1'; 
            when others => null; -- остальное не важно
            end case;    
        end if;
     
TEST_COMM_BUS <= command; -- проверка получения команды,  вывод на вспомогательную шину
end process;    

...

Так вот, при функциональном моделировании все работало нормально (а исходный код был гораздо объемней), но при переносе проекта в железо получилось следующее:

- реакция системы запаздывает на одну команду. То есть мы послали команду 001, на NO_BLCK_A = 0, потом еще раз - любую команду, тогда на NO_BLCK_A=1. После команды 000 - аналогично, задержка на одну команду. Причем на шине TEST_COMM_BUS - команда правильная, то есть та, которая была тоько что подана.

Менял case на if-then-elsif - то же самое.

UART работает стабильно, он проверен.

Код писался в Active HDL 7.2, компиляция - в Xilinx ISE 9.2, ПЛИС - Spartan XC2S200.

Подскажите, пожалуйста, в чем дело.

Может, тут какие-то тонкости кодирования конечных автоматов...

... или у меня просто лыжи не едут?...

( не едут, точно, не в тот раздел повесил...)

Изменено пользователем nya

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Здравствуйте.

Я никак не могу понять, в чем же тут дело...

Ну дак всё правильно, получился параллельный сдвиговый регистр.

 

Заменить

 

command := in_data_rs232(7 downto 5)

на

command := RS232_IN

 

и станет как нада.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Ну дак всё правильно, получился параллельный сдвиговый регистр.

 

Заменить

 

command := in_data_rs232(7 downto 5)

на

command := RS232_IN

 

и станет как нада.

 

ДА!!!!!!!

И даже проще можно:

case RS232_IN(7 downto 5) is
... -- и тэ дэ

 

Спасибо огромное, второй день пытался понять, в чем засада!

:yeah:

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

2 tocha -

Ну делаю я

command := RS232_IN

Но всё равно потом вычленять надо

7 downto 5

 

Может я что-то недопонял , можете объяснить ход ваших мыслей далее ?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

2 tocha -

Ну делаю я

 

Но всё равно потом вычленять надо

7 downto 5

 

Может я что-то недопонял , можете объяснить ход ваших мыслей далее ?

 

 

Так

command := RS232_IN (7 downto 5);

не будет синтезирован сдвиговый регистр, соответственно не будет задержки на такт.

 

Какие там биты из шины RS232_IN анализировать - решайте сами.

 

Я просто недокопировал "(7 downto 5)", теперь исправился.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Так

command := RS232_IN (7 downto 5);

не будет синтезирован сдвиговый регистр, соответственно не будет задержки на такт.

 

Какие там биты из шины RS232_IN анализировать - решайте сами.

 

Я просто недокопировал "(7 downto 5)", теперь исправился.

А разве это читаемо. У Вас процесс по фронту клока. Почему нет задержки на такт?

Наверно потому что в процессе используются одновременно два оператора :=, и <=

Что заставляет хорошо подумать, во что такую конструкцию синтезатор реализует.

Наверно нагляднне в процессе <=, А все не регистровое из процесса вынести.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А разве это читаемо. У Вас процесс по фронту клока. Почему нет задержки на такт?

Наверно потому что в процессе используются одновременно два оператора :=, и <=

Что заставляет хорошо подумать, во что такую конструкцию синтезатор реализует.

Наверно нагляднне в процессе <=, А все не регистровое из процесса вынести.

 

Это не у меня.

А задержки нет, потому что присваивание значения переменной в процессе происходит сразу, и дальше по процессу переменная уже имееет новое значение, в отличии от сигнала.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Что заставляет хорошо подумать, во что такую конструкцию синтезатор реализует.
Всё давно известно. У меня никогда проблем с этим не было.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

...

Наверно потому что в процессе используются одновременно два оператора :=, и <=

Что заставляет хорошо подумать, во что такую конструкцию синтезатор реализует.

Наверно нагляднне в процессе <=, А все не регистровое из процесса вынести.

А ведь получается, что лучше вообще не использовать variabl'ы в процессах? Только сигналы? И свести к минимуму операции присвоения? правильно?

И, кстати, можно как-то этот топик перенести в другой раздел, здесь он не совсем уместен?...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А ведь получается, что лучше вообще не использовать variabl'ы в процессах? Только сигналы? И свести к минимуму операции присвоения? правильно?

 

Так ведь я вопрос сам задавал. (Фактически с одной переменной два разных по реализации в железе оператора). Мне ответили - на любителя.

Посмотрите в книге Полякова (со стр. 34). Там показаны различия.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Так ведь я вопрос сам задавал. (Фактически с одной переменной два разных по реализации в железе оператора). Мне ответили - на любителя.

Посмотрите в книге Полякова (со стр. 34). Там показаны различия.

 

Каких два оператора? Всё однозначно.

Переменная отличается от сигнала тем, что апдэйтится новой величиной сразу после оператора присваивания и может использоваться в этом же процессе ниже по тексту.

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

 

Тут сделано лишнее присваивание:

in_data_rs232<=RS232_IN; получение в переменную in_data_rs232 байта из UARTа

получился сдвиговый регистр и задержка на такт.

 

Строка с переменной

command := in_data_rs232(7 downto 5);

здесь вводит ещё одно имя "command" для "in_data_rs232(7 downto 5)".

Всё. Больше она на ни на что не влияет.

 

П.С. Переменные юзать можна, иногда помогают.

Присваиваний делать столько, сколько нужно. В данном случае можна ниодного. Как в последнем варианте

case RS232_IN(7 downto 5) is

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...