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

VHDL счёт сбрасывается раньше времени

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

Проблема такая: есть код, смысл которого - поднять в единицу выходной сигнал и удерживать его в течение заданного времени(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;

 

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


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

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.

И третье: читайте соседнюю тему. Ошибки повторяются.

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


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

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.

И третье: читайте соседнюю тему. Ошибки повторяются.

Спасибо за ответ!

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


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

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/

 

 

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


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

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

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

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

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

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

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

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

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

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