Sv37 0 24 сентября, 2019 Опубликовано 24 сентября, 2019 · Жалоба Здравствуйте! Проблема такая: есть код, смысл которого - поднять в единицу выходной сигнал и удерживать его в течение заданного времени(0.1, 1, 10 и 85 секунд, в зависимости от входящего сигнала). Всё запускается и правильно работает в симуляторе, но в железе выходной сигнал сбрасывается до того, как достигается заданное время(0.1с = 0.1с, 1с = 0.77с, 10с = 9.9с, 45с = 32с, 85с = 65.5с). Тестировалась на Cyclone IV и II - результат одинаков. Я новичок в этом деле, подскажите, что я упускаю из виду? --**Модуль обеспечивает заданное время исследования. --С компьютера приходит команда, задающая необходимую продолжительность --исследования, данный модуль обеспечивает это время.** library ieee; use ieee.std_logic_1164.all; entity Int_former is port (clk_1kHz : in std_logic; res_enable : in std_logic; --запуск отсчёта времени измерения time_set : in std_logic_vector(1 downto 0); --заданное время измерения cnt_enable : out std_logic); --сигнал разрешения исследования end Int_former; architecture Count of Int_former is begin Counting: process (clk_1kHz, res_enable, time_set) is variable res_time : integer range 0 to 100000 := 0; --время исследования variable msec : integer range 0 to 100001 := 0; --отсчёт времени исследования в милисекундах variable r_enable : integer range 0 to 1 := 0; --дублирование res_enable, которым можно управлять variable sync : integer range 0 to 1 := 0; --синхронизация счёта с clk begin --установка времени исследования в секундах if time_set = "01" then res_time := 100; end if; --0.1 секунды if time_set = "10" then res_time := 1000; end if; --1 секунда if time_set = "00" then res_time := 10000; end if; --10 секунд if time_set = "11" then res_time := 85000; end if; --85 секунд if rising_edge(res_enable) then r_enable := 1; end if; if rising_edge(clk_1kHz) then if r_enable = 1 then msec := msec + 1; sync := 1; end if; --счёт времени исследования по фронту тактовой частоты end if; if (msec < (res_time + 1) and sync = 1) then cnt_enable <= '1'; else cnt_enable <= '0';end if; --если время меньше заданного, то выходной сигнал в высоком уровне if msec > res_time then msec := 0; sync := 0; r_enable := 0; end if; --сброс всего по достижении заданного времени end process Counting; end Count; Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Nick_K 0 24 сентября, 2019 Опубликовано 24 сентября, 2019 · Жалоба 1. Использовать только variable в VHDL плохой тон и оно может привести к неожиданным синтезам. Пользуйтесь сигналами 2. Такая конструкция без понимания что оно делает if rising_edge(res_enable) then r_enable := 1; end if; грубая ошибка. Это нужно правильно констрейнить, понимать разводку и убедится, что синтезатор нормально это обработает. В Вашем случае она применена неправильно впринципе. 3. Зачем куча дублирующих сигналов - непонятно. Пользуйтесь теми что завели, не плодите лишние сущности. 4. Счётчик msec описан как синхронный регистр и псевдо сбрасывается по асинхронному значению. Это может быть засинтезировано как мультиплексор на выходе, соответственно когда сработал компаратор "msec > res_time" это не значит, что счёт прекратился "msec := msec + 1", а просто значит что на выходе ноль, при этом если подавать быстро значения на выход time_set то будет идти счёт, до неправильного значения. Основное: Не пишите условия в строку - это не читаемо! Хотя и получше чем у Вашего одногруппника из соседней темы. (Не могу понять, сессия чтоль?) Второе: перепишите все конструкции в одно условие для каждого отдельного сигнала, то бышь присвоение каждой переменной находилось в одном общем if-else. И третье: читайте соседнюю тему. Ошибки повторяются. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Sv37 0 30 сентября, 2021 Опубликовано 30 сентября, 2021 · Жалоба 24.09.2019 в 15:35, Nick_K сказал: 1. Использовать только variable в VHDL плохой тон и оно может привести к неожиданным синтезам. Пользуйтесь сигналами 2. Такая конструкция без понимания что оно делает if rising_edge(res_enable) then r_enable := 1; end if; грубая ошибка. Это нужно правильно констрейнить, понимать разводку и убедится, что синтезатор нормально это обработает. В Вашем случае она применена неправильно впринципе. 3. Зачем куча дублирующих сигналов - непонятно. Пользуйтесь теми что завели, не плодите лишние сущности. 4. Счётчик msec описан как синхронный регистр и псевдо сбрасывается по асинхронному значению. Это может быть засинтезировано как мультиплексор на выходе, соответственно когда сработал компаратор "msec > res_time" это не значит, что счёт прекратился "msec := msec + 1", а просто значит что на выходе ноль, при этом если подавать быстро значения на выход time_set то будет идти счёт, до неправильного значения. Основное: Не пишите условия в строку - это не читаемо! Хотя и получше чем у Вашего одногруппника из соседней темы. (Не могу понять, сессия чтоль?) Второе: перепишите все конструкции в одно условие для каждого отдельного сигнала, то бышь присвоение каждой переменной находилось в одном общем if-else. И третье: читайте соседнюю тему. Ошибки повторяются. Спасибо за ответ! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
gosha 0 6 октября, 2021 Опубликовано 6 октября, 2021 · Жалоба On 9/24/2019 at 3:14 PM, Sv37 said: Здравствуйте! Проблема такая: есть код, смысл которого - поднять в единицу выходной сигнал и удерживать его в течение заданного времени(0.1, 1, 10 и 85 секунд, в зависимости от входящего сигнала). Всё запускается и правильно работает в симуляторе, но в железе выходной сигнал сбрасывается до того, как достигается заданное время(0.1с = 0.1с, 1с = 0.77с, 10с = 9.9с, 45с = 32с, 85с = 65.5с). Тестировалась на Cyclone IV и II - результат одинаков. Я новичок в этом деле, подскажите, что я упускаю из виду? --**Модуль обеспечивает заданное время исследования. --С компьютера приходит команда, задающая необходимую продолжительность --исследования, данный модуль обеспечивает это время.** library ieee; use ieee.std_logic_1164.all; entity Int_former is port (clk_1kHz : in std_logic; res_enable : in std_logic; --запуск отсчёта времени измерения time_set : in std_logic_vector(1 downto 0); --заданное время измерения cnt_enable : out std_logic); --сигнал разрешения исследования end Int_former; architecture Count of Int_former is begin Counting: process (clk_1kHz, res_enable, time_set) is variable res_time : integer range 0 to 100000 := 0; --время исследования variable msec : integer range 0 to 100001 := 0; --отсчёт времени исследования в милисекундах variable r_enable : integer range 0 to 1 := 0; --дублирование res_enable, которым можно управлять variable sync : integer range 0 to 1 := 0; --синхронизация счёта с clk begin --установка времени исследования в секундах if time_set = "01" then res_time := 100; end if; --0.1 секунды if time_set = "10" then res_time := 1000; end if; --1 секунда if time_set = "00" then res_time := 10000; end if; --10 секунд if time_set = "11" then res_time := 85000; end if; --85 секунд if rising_edge(res_enable) then r_enable := 1; end if; if rising_edge(clk_1kHz) then if r_enable = 1 then msec := msec + 1; sync := 1; end if; --счёт времени исследования по фронту тактовой частоты end if; if (msec < (res_time + 1) and sync = 1) then cnt_enable <= '1'; else cnt_enable <= '0';end if; --если время меньше заданного, то выходной сигнал в высоком уровне if msec > res_time then msec := 0; sync := 0; r_enable := 0; end if; --сброс всего по достижении заданного времени end process Counting; end Count; Где сбрасываются msec и r_enable ? В симуляторе моделировали неоднократную подачу res_enable ? Не совсем хорошо rising_edge(res_enable) - лучше автомат с синхронной логикой, где все по максимуму вся логика работает от одного синхросигнала. В противном случае вероятна метастабильность: https://habr.com/ru/post/317514/ https://kit-e.ru/elcomp/neizvestnoe-ob-izvestnom-ili-chto-takoe-metastabilnost-triggerov/ Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться