Jump to content

    

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;

 

Share this post


Link to post
Share on other sites

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.

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

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now