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

Конечный автомат, интерпритации средой

блин... вот теперь еще сложнее, только я вздохнул спокойно насчет дефалта, теперь еще одна напасть... Вроде бы у меня на входе спартана стоят триггера шмидта, вроде бы там стоят фильтры, и вроде бы я не использую сигналы не защелкнутые на регистр. Внутренний же регистр ПЛИС не будет дрибезжать... С этим вроде как все ок!

Очень это хорошо на I2C происходит. Там тоже можно поставить триггер шмидта и он на пологом фронте сигнала с частотой пусть даже 1 МГц наловит дребезга, а поскольку внутри ПЛИС 100 Мгц и более, то автомату этого вполне хватит...

 

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


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

блин... вот теперь еще сложнее, только я вздохнул спокойно насчет дефалта, теперь еще одна напасть... Вроде бы у меня на входе спартана стоят триггера шмидта, вроде бы там стоят фильтры, и вроде бы я не использую сигналы не защелкнутые на регистр. Внутренний же регистр ПЛИС не будет дрибезжать... С этим вроде как все ок!

 

Можно лишь уменьшить вероятность появления метастабильного состояния, поэтому лучше всё же делать выход из неопределённого состояния, чтобы устройство не зависало намертво до передёргивания питания.

 

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


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

И я прочту дальше Пушкина - аж до Маяковского

я домотал до конца, и читал про Маяковского, но это только утвердило меня в своем решении...

 

Можно лишь уменьшить вероятность появления метастабильного состояния, поэтому лучше всё же делать выход из неопределённого состояния, чтобы устройство не зависало намертво до передёргивания питания.

у меня можно сбросить конкретный автомат. И для меня лучше чтобы он завис и все остановилось. Я уже больше суток об этом думаю, пока что противоречий не нашел так что пока у меня будет так. Повисание - остановка, диагностика через статусы, ресет конкретного повисшего автомата. Но вроде там все сигналы внутренние...

 

Очень это хорошо на I2C происходит. Там тоже можно поставить триггер шмидта и он на пологом фронте сигнала с частотой пусть даже 1 МГц наловит дребезга, а поскольку внутри ПЛИС 100 Мгц и более, то автомату этого вполне хватит...

правильно я понимаю что если взять автомат который работает на клоке 100 МГц, и входной сигнал пропустить через триггер (а лучше 2) с клоком те же 100 МГц, то проблема дребезга пропадает, в каждый момент времени на вход автомата будет приходить заданное триггером и стабилизированное на время клока состояние?

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


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

у меня можно сбросить конкретный автомат. И для меня лучше чтобы он завис и все остановилось. Я уже больше суток об этом думаю, пока что противоречий не нашел так что пока у меня будет так. Повисание - остановка, диагностика через статусы, ресет конкретного повисшего автомата. Но вроде там все сигналы внутренние...

 

Надеюсь что ресет синхронный.

 

 

правильно я понимаю что если взять автомат который работает на клоке 100 МГц, и входной сигнал пропустить через триггер (а лучше 2) с клоком те же 100 МГц, то проблема дребезга пропадает, в каждый момент времени на вход автомата будет приходить заданное триггером и стабилизированное на время клока состояние?

 

Дребезг это про другое наверное? Вероятность метастабильного состояния уменьшается, но не пропадает.

Лучше через 3))), и синтезатору указать, чтобы триггеры располагались рядом физически, ну и учитывать, что появляется неопределённость прихода фронтов сигнала на выходах таких сдвиговых регистров.

 

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


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

Надеюсь что ресет синхронный.

понятно дело...

 

Дребезг это про другое наверное?

тут я понимаю дребезг автомату может помешать только мета-стабильностью, при условии что автомат синхронный?

 

 

 

кстати давно хотел узнать, в такой конструкции

always @(posedge clk or posedge reset)
begin
if(reset == 1'b1) 
   ...
end

if срабатывает и по фронту reset и по идее должен срабатывать на каждый следующий клок? Получается что для сигналов ресет длинной больше клока синхронный ресет и асинхронный неразличимы. Или я не прав? Как на железном уровне работает вход сброса триггера?

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


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

тут я понимаю дребезг автомату может помешать только мета-стабильностью, при условии что автомат синхронный?

Дребезг и метастабильность - это вообще разные песни!

Дребезг - это когда вместо одного фронта ловится 2 или 3... Если триггера тактируются на 100 Мгц, то дребезг от кнопки они пропустят без сомнения.

 

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


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

что такое дребезг сам по себе понятно.

Что он с точки зрения синхронного автомата, да в целом просто сигнал, и если правильно описана реакция на сигнал с учетом его особенностей, то есть автомат правильный, то он не улетит никуда, куда автор не хочет... Потому я думаю для правильного автомата дребезг не страшен как таковой, только как нечто что увеличивает число переходов на триггере, и повышает вероятность поймать "середину" сигнала, то есть мета-стабильностью.

 

Я где-то не прав в своих рассуждениях?

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


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

кстати давно хотел узнать, в такой конструкции

always @(posedge clk or posedge reset)
begin
if(reset == 1'b1) 
   ...
end

if срабатывает и по фронту reset и по идее должен срабатывать на каждый следующий клок? Получается что для сигналов ресет длинной больше клока синхронный ресет и асинхронный неразличимы. Или я не прав? Как на железном уровне работает вход сброса триггера?

система проектирования заведёт reset на асинхронный сброс(установка) и будет права. Ибо первичная проверка идёт по reset == 1'b1, всё остальное (изменение clk) не важно - тактовый вход ни на что не влияет. Классический D триггер с асинхронным сбросом.

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

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


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

кстати давно хотел узнать, в такой конструкции

always @(posedge clk or posedge reset)
begin
if(reset == 1'b1) 
   ...
end

if срабатывает и по фронту reset и по идее должен срабатывать на каждый следующий клок? Получается что для сигналов ресет длинной больше клока синхронный ресет и асинхронный неразличимы. Или я не прав? Как на железном уровне работает вход сброса триггера?

 

 

У iosifk есть отличная статья

http://iosifk.narod.ru/hdl_coding/hdl_coding_11_kit_1_09.pdf

 

Для логики работы региста вашего автомата используйте синхронный сброс(вход D), а не вход R асинхронного сброса.

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


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

что такое дребезг сам по себе понятно.

Что он с точки зрения синхронного автомата, да в целом просто сигнал, и если правильно описана реакция на сигнал с учетом его особенностей, то есть автомат правильный, то он не улетит никуда, куда автор не хочет... Потому я думаю для правильного автомата дребезг не страшен как таковой, только как нечто что увеличивает число переходов на триггере, и повышает вероятность поймать "середину" сигнала, то есть мета-стабильностью.

 

Я где-то не прав в своих рассуждениях?

Нет, абсолютно НЕ ПРАВ!

Например, есть медленный процесс. Пусть тот же I2C. На пологом фронте наловим импульсов. Если у автомата нет таймера на выдержку времени, как в UARTе, то лишние фронты будут трактоваться как импульсы данных. и по концу их приема автомат будет ждать какой-нибудь сигнал завершения операции. А он не сформируется, потому как чего-нибудь где-нибудь не хватит... Так словами расписать трудно, нужно приводить более конкретный пример, а я пока сходу ничего не придумал...

 

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


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

Для логики работы региста вашего автомата используйте синхронный сброс(вход D), а не вход R асинхронного сброса.

Это понятно...

 

я мыслил о то что можно и так написать

 

reg [3 : 0] Count=0;
always @(posedge clk or posedge reset)
begin
  if(reset == 1'b1)
    Count <= Count + 1'b1;
end

И в этом случае получается что нельзя ресет просто на сброс подать, но понял что Сount в этом случае должен уметь считать по 2 фронтам, и эта конструкция не синтезируемая... Затупил маленько)...

 

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

 

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

 

Поковырялся в схемах триггеров на уровне логики. Что-то у меня получается что асинхронный сброс работает по уровню а не по фронту. Я не прав?

 

А если оно работает по уровню, то фронт не важен, важно просто какая-то длительность верхнего уровня, схема не сможет пропустить фронт...

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


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

Нет, абсолютно НЕ ПРАВ!

Например, есть медленный процесс. Пусть тот же I2C. На пологом фронте наловим импульсов. Если у автомата нет таймера на выдержку времени, как в UARTе, то лишние фронты будут трактоваться как импульсы данных. и по концу их приема автомат будет ждать какой-нибудь сигнал завершения операции. А он не сформируется, потому как чего-нибудь где-нибудь не хватит... Так словами расписать трудно, нужно приводить более конкретный пример, а я пока сходу ничего не придумал...

Если автомат будет находиться в состоянии 6 и ждать "какой-нибудь сигнал завершения операции" для перехода в состояние 0, то описаны сигнал 7 или автор забыл это сделать не имеет никакого значения. iosifk, не понимаю вашей точки зрения. В случае не бог весть какой помехи слетит вся fpga, и бороться с этим нужно не на уровне недописанного автомата. А переход автомата в неописанное состояние, если компилятор правильно понял автора, невозможен. Вы конечно опытней меня, но вот никак не могу уловить вашу мысль.

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


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

Уважаемые форумчане, прошу хотябы бегло просмотреть мой код на предмет корректного написания и дать свои комментарии.

 

Этот конечный автомат моделируется идельно, но когда загружую в ПЛИС - иногда влетает не в те состояния, которые были задуманы по поряюку работы. Анализатор максимальной частоты говорит что автомат может работать на частотах даже выше 300 МГц, но реально хоть на 80 хоть на 40 МГц работает со сбоями, и для примера, может из состояния S22 перепрыгнуть в состояние S2, а не в S3. Все это безобразие котролирую на осциллографе по выходным сигналам автомата.

Меняю стратегию компилятора, меняется немного стабильность работы, но лиш меняется комбинации неправильных переходов. Констрейнты на клоки выполняются. Пробовал и в Ква и ИСЕ, поведение примерно одинаково - есть неожиданные переходы.

Автомат простой как 2 рубля, понимаю, писал и на много более сложные, но сейчас какая-то чертовщина. Может это производители ПЛИС спец баг влепили - чтобы пользовались их ИП ядрами!

 

----------------------------------------------------------------------------------
--
--
-- Машина состояний для работы с модулем FTDI
--
--
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;


entity sm_ft1248_to_modem_f is
generic (
			CMD_WR			: std_logic_vector(7 downto 0)  := "01101001"; 
			CMD_RD			: std_logic_vector(7 downto 0)  := "01101011";
			CMD_RD_MOD_ST	: std_logic_vector(7 downto 0)  := "01101101";
			CMD_WR_MOD_ST	: std_logic_vector(7 downto 0)  := "01101111";
			CMD_RD_USB_ST	: std_logic_vector(7 downto 0)  := "11101001"
		);
Port ( 
		-- INPUTS
			clk			: in  STD_LOGIC := '0';	-- 
			ce			: in  STD_LOGIC := '0';	-- 
			sclr		: in  std_logic := '0';		-- 
			clk_en		: in  STD_LOGIC := '0';	--
			rdy			: in  STD_LOGIC := '0';	-- 
			miosio		: in  STD_LOGIC := '0';	-- 
			miso		: in  STD_LOGIC := '0';	-- 
	   -- OUTPUTS
			cmd				: out  STD_LOGIC_VECTOR (7 downto 0);	-- команда для передачи модулю FTDI
			wr_rd			: out  STD_LOGIC;	-- чтения или записи 0 записи 1 чтерия
			valid			: out  STD_LOGIC;	-- начала транзакции

		-- TESTES
		-- OUTPUT
			test		: out STD_LOGIC_VECTOR (7 downto 0)			-- составной (композитный) сигнал для тестов
	);
end sm_ft1248_to_modem_f;

architecture Behavioral of sm_ft1248_to_modem_f is



type state_type is (s1, s2, s21, s22, s3, s31); -- , s4, s5, s6, s7, s8, s9, s10, s11, s12, s13, s14, s15, s16);
signal cur_state			: state_type; -- текущие состояния
signal next_state			: state_type; -- следующие состояния

signal N_wr_rd				: std_logic; -- следующее состояние сигнала 1 записи 0 чтерия
signal rg_wr_rd				: std_logic; -- текущее состояние сигнала

signal N_valid				: std_logic; -- следующее состояние сигнала
signal rg_valid				: std_logic; -- текущее состояние сигнала

signal N_cmd				: STD_LOGIC_VECTOR (7 downto 0); -- следующее состояние сигнала
signal rg_cmd				: STD_LOGIC_VECTOR (7 downto 0); -- текущее состояние сигнала
signal EN_cmd				: std_logic; -- сигнал разрешения изменения значение команды

signal N_test				: STD_LOGIC_VECTOR (7 downto 0); -- следующее состояние порта
signal rg_test				: STD_LOGIC_VECTOR (7 downto 0); -- текущее состояние порта

attribute syn_encoding				  : string;
attribute syn_encoding of state_type : type is "SEQUENTIAL"; -- SEQUENTIAL ONE-HOT JOHNSON GRAY COMPACT
begin


--------------------------------------------------------------
---======= 	смена текущего состояния с.машины
--------------------------------------------------------------
process(clk, sclr, next_state, N_valid, N_test, cur_state, rg_valid, rg_test)
begin
	if rising_edge(clk) then
		if sclr = '1' then
		----------
			cur_state <= s1;
			rg_valid <= '0';
			rg_wr_rd <= '0';
			rg_test <= (others => '0');
			rg_cmd <= (others => '0');
		----------
		elsif ce = '1' then
		----------
			cur_state <= next_state;
			---------------
			rg_valid <= N_valid;
			---------------
			---------------	
			rg_test <= N_test;
			---------------	
			if EN_cmd = '1' then
				rg_cmd <= N_cmd;
				rg_wr_rd <= N_wr_rd;
			else
				rg_cmd <= rg_cmd;
				rg_wr_rd <= rg_wr_rd;
			end if;					
		----------
		else
		----------
			cur_state <= cur_state;
			---------------
			rg_valid <= rg_valid;
			---------------	
			rg_wr_rd <= rg_wr_rd;
			---------------	
			rg_test <= rg_test;
			---------------	
			rg_cmd <= rg_cmd;
		----------
		end if;
	end if;
end process;
--============================================================
--============================================================


--------------------------------------------------------------
---======= 	выбор нового состояния
--------------------------------------------------------------
process(cur_state, rdy, miso, miosio)
begin

	next_state <= cur_state;

	case cur_state is
		when s1 => 					-- 

			if (rdy = '1') then
				next_state <= s2;
			end if;
		when s2 =>

			if (miso = '0') then		-- 
				-------------------
				next_state <= s21;		-- 
			end if;

		when s21 => 					-- 

			if (rdy = '0') then
				next_state <= s22;
			end if;

		when s22 => 					-- 

			if (rdy = '1') then
				next_state <= s3;
			end if;

		when s3 =>

			if (miosio = '0') then  --
				---------------------
				next_state <= s31;
			end if;

		when others => 					--

			if (rdy = '0') then
				next_state <= s1;
			end if;
	end case;
end process;

--============================================================
--============================================================


--------------------------------------------------------------
---======= 	формирование выходных сигналов
--------------------------------------------------------------
process(cur_state, rdy, miso, miosio, rg_cmd, rg_test)
begin

	if cur_state = s2 and (miso = '0') then		-- 
		-------------------
		EN_cmd <= '1';
		N_cmd <= CMD_RD;
		N_wr_rd <= '1';
		N_valid <= '1';

	elsif cur_state = s3 and miosio = '0' then

		EN_cmd <= '1';
		N_cmd <= CMD_WR;
		N_wr_rd <= '0';
		N_valid <= '1';

	else

		N_valid <= '0';
		N_wr_rd <= rg_wr_rd;
		EN_cmd <= '0';
		N_cmd <= rg_cmd; --

	end if;

end process;

--============================================================
--============================================================


--------------------------------------------------------------
---======= 	выходы
--------------------------------------------------------------


wr_rd <= rg_wr_rd;

valid <= rg_valid;

cmd <= rg_cmd;

test <= rg_test;

--============================================================
--============================================================


end Behavioral;

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


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

я чего-то не понимаю, у вас смена состояний автомат асинхронная что ли, по изменению входных сигналов?

 

 

 

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


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

Я бы все же состояние s31 явно бы описал.

А входные rdy, miosio, miso у Вас асинхронные относительно clk?

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


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

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

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

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

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

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

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

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

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

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