Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Как правильно сформировать сигнал DATA READY?
Форум разработчиков электроники ELECTRONIX.ru > Программируемая логика ПЛИС (FPGA,CPLD, PLD) > Языки проектирования на ПЛИС (FPGA)
eteP
Привет.

Посмотрите плз. код.
Хотелось бы сделать так как показыно на картинке ну и с наименьшими затратами ресурсов в FPGA.
Сигнал DRY не зависел от длинны ND.
Ну и передний фрот DRY на 180 сдвинут от CLK.

Спасибо.

Код
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.std_logic_arith.all;
use IEEE.std_logic_unsigned.all;

entity a2b is
    port(
 CLK:    in std_logic;
 RSTl:    in std_logic;
 ND:  in std_logic;
 DIN:    in std_logic_vector(15 downto 0);
 DRY:    out std_logic;
 DOUT:    out std_logic_vector(15 downto 0)
    );
end a2b;


architecture a2b_arch of a2b is

signal DRY1: std_logic;
signal R: std_logic;

begin

P1:    process (CLK, RSTl)
begin
    
    if RSTl = '0' then

 DRY1 <= '0';
 DOUT <= (others => '0');
    
    elsif CLK'event and CLK = '1' then
 
 if ND = '1' then
     DOUT <= DIN;
     DRY1 <= '1';
 else
     DRY1 <= '0';
 end if;
 
    end if;
    
end process P1;

P2: process (CLK, RSTl, R)
begin

    if RSTl = '0' then
    
 DRY <= '0';
 R <= '0';
 
    elsif CLK'event and CLK = '0' then
    
 if R = '1' then
     DRY <= '0';
 elsif DRY1 = '1' then
     DRY <= '1';
     R <= '1';
 else
     R <= '0';
 end if;
 
 end if;
end process P2;

end a2b_arch;
Нажмите для просмотра прикрепленного файла
tocha
Если надо сформировать по фронту короткий импульс длительностью в один такт частоты, ставишь двухбитный сдвиговый регистр, и компаратор, который при комбинации в нём "01" выдаёт единицу. Получается например "01" - положительный фронт, "10" - отрицателльный, или наоборот, смотря в какую сторону сдвигать.
oval
Обычно я поступаю следующим образом:
Код
signal DRY_int : std_logic_vector(1 downto 0);

BEGIN
 p_Main : process(RST1, CLK)

 begin
   if RST1 = '0' then
     DRY_int <= (others => '0'); --Async reset
   elsif Falling_Edge(CLK) then -- Clocked by falling edge of CLK
     DRY_int <= ND & DRY_int(1); --Two bit shift register
   end if;
 end process p_Main;

 DRY <= DRY_int(1) and not DRY_int(0); -- Set output DRY

END arch;
eteP
А основной процесс работает по фронту?

Эта схема будет не правильно работать если сигнал ND будет выставлен чуть раньше заднего фронта.
По этому ND нельзя использовать. Нужен еще один регистер для ND. Тогда все работает коректно.

Код
signal DRY_int : std_logic_vector(1 downto 0);
signal DRY1: std_logic;

begin

P1:    process (CLK, RSTl)
begin
    
    if RSTl = '0' then

 DOUT <= (others => '0');
    
    elsif CLK'event and CLK = '1' then
 
 if ND = '1' then
     DOUT <= DIN;
     DRY1 <= '1';
 else
     DRY1 <= '0';
 end if;
 
    end if;
    
    
end process P1;


P2 : process(RSTl, CLK)

begin
  if RSTl = '0' then
    DRY_int <= (others => '0'); --Async reset
  elsif CLK'event and CLK = '0' then -- Clocked by falling edge of CLK
    DRY_int <= DRY1 & DRY_int(1); --Two bit shift register
  end if;
end process P2;

DRY <= DRY_int(1) and not DRY_int(0); -- Set output DRY

end a2b_arch;


Спасибо.
Это лучшее схема чем было у меня до этого. Спасибо еще раз.
makc
Если я не ошибаюсь, то в вышеприведенных схемах не учтен вопрос метастабильности. Я предпочитаю использовать несколько иную схему, которая учитывает метастабильность триггеров.

Код
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity synchronizer is
    Port (
 clk: in std_logic;
 en:    in std_logic;
 run: in std_logic;
 ce: out std_logic
    );
end synchronizer;

architecture Behavioral of synchronizer is
    signal Q0, Q1, Q2: std_logic := '0';
begin
    process(run,en)
    begin
 if rising_edge(run) and en='1' then
     Q0 <= not Q1;
 end if;
    end process;

    process(clk)
    begin
 if rising_edge(clk) then
     Q1 <= Q0;
     Q2 <= Q1;
 end if;  
    end process;

    ce <= Q2 xor Q1;

end Behavioral;


Всего три триггера и один инвертор и элемент xor. smile.gif
eteP
А не должно ли быть здесь

Код
process(clk)
begin
if rising_edge(clk) then
 Q1 <= Q0;
 Q2 <= Q1;
end if;  
end process;

ce <= Q2 xor Q1;


в место rising_edge -> falling_edge?

Если использовать rising_edge то в функциональной симуляции показывает не верно, вернее не то что я хочу, но после роутинга все замечательно. А если использовать falling_edge и RUN завести на тригер, то везде показывает правильно.

А где вы видите метастабильность трегеров в схеме от oval?

Сравнил две схемы после размещения и роутинга

Oval:
SLICEs - 2
Max. freq. - 113 MHz

Makc с rising_edge:
SLICEs - 4
Max. freq. - 454 MHz

Makc с falling_edge:
SLICEs - 4
Max. freq. - 607 MHz


забавно.
des00
Цитата(makc @ May 17 2005, 12:48)
Если я не ошибаюсь, то в вышеприведенных схемах не учтен вопрос метастабильности. Я предпочитаю использовать несколько иную схему, которая учитывает метастабильность триггеров.

Всего три триггера и один инвертор и элемент xor. smile.gif
*

Можно глупый вопрос ? а почему здесь вы считает будет подавление метастабильности ? Имхо подавать информационные сигналы на тактовые выходы тригера не есть лучшее решение, лучше пропустить их через еще один Д тригер ?

Хотя может я ошибаюсь glare.gif
makc
Цитата(des00 @ May 18 2005, 07:12)
Цитата(makc @ May 17 2005, 12:48)
Если я не ошибаюсь, то в вышеприведенных схемах не учтен вопрос метастабильности. Я предпочитаю использовать несколько иную схему, которая учитывает метастабильность триггеров.

Всего три триггера и один инвертор и элемент xor. smile.gif
*

Можно глупый вопрос ? а почему здесь вы считает будет подавление метастабильности ? Имхо подавать информационные сигналы на тактовые выходы тригера не есть лучшее решение, лучше пропустить их через еще один Д тригер ?

Хотя может я ошибаюсь glare.gif
*



А что есть метастабильность? smile.gif Она возникает в случае, когда нарушается время предварительной установки на входе данных или время удержания. В приведенном мною примере первый триггер (Q0) не будет метастабильным, если сигналы на его синхровход будут подаваться реже, чем период синхронизации CLK. В метастабильное состояние может перейти триггер Q1, т.к. переключение Q0 может произойти в произвольный момент. Но Q1 будет в этом состоянии не более периода, поскольку следующий же фронт CLK защелкнет в нем правильное значение. А далее оно будет правильно записано в Q2. Таким образом, Q1 выступает в роли синхронизатора (буфера) для входного сигнала и помогает избавиться от проблемы метастабильности.
makc
Цитата(eteP @ May 17 2005, 21:35)
А не должно ли быть здесь

Код
process(clk)
begin
if rising_edge(clk) then
 Q1 <= Q0;
 Q2 <= Q1;
end if;  
end process;

ce <= Q2 xor Q1;


в место rising_edge -> falling_edge?
*


Да, для реализации приведенной Вами временной диаграммы нужно falling_edge. Но по большому счету это не принципиально. smile.gif

Цитата
Если использовать rising_edge то в функциональной симуляции показывает не верно, вернее не то что я хочу, но после роутинга все замечательно. А если использовать falling_edge и RUN завести на тригер, то везде показывает правильно.


Странно, оно должно быть везде неправильно.

Цитата
А где вы видите метастабильность трегеров в схеме от oval?


Там в сдвиговый регистр вдвигается значение входного сигнала, которое может нарушить время предварительной установки первого триггера -> перевести его в метастабильное состояние. Хотя, если верить производителям ПЛИС, вероятность этого очень мала.

Цитата
Сравнил две схемы после размещения и роутинга

Oval:
SLICEs - 2
Max. freq. - 113 MHz

Makc с rising_edge:
SLICEs - 4
Max. freq. - 454 MHz

Makc с falling_edge:
SLICEs - 4
Max. freq. - 607 MHz


забавно.


Да... Разница видна невооруженным взглядом. smile.gif
Даже не думал, что может быть такой разрыв.
oval
Действительно, если сигнал ND асинхронен по отношению к CLK, то в общем
случае требуется его подтактирование. При этом все зависит от отношения
частот самого CLK и частоты переключения ND. Для малых частот достаточно
одного уровня (триггера) подтактирования. Для больших частот может потребоваться два или даже три уровня подтактирования. Можно играть с фронтами CLK для схемы подтактирования (синхронизации). Можно подтактировать и непосредственно выход, т. е. DRY. Современная элементная
база имеет очень высокую степень защиты от метастабильных состояний и
очень быстро выходит из этого состояния. Но все же принебрегать этим я бы
не рекомендовал. Я обычно использую не более двух уровней подтактирования, чаще даже один. Для сокращения времени передачи сигнала из одного тактового домена в другой обычно использую оба фронта тактового сигнала. Пока с проблемами метастабильности не сталкивался, хотя работал даже с технологиями ASIC.

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

А для какой технологии синтезируете?
eteP
Я использую среду альдек. Ситезатор XST 6.3 мапирование и разводу тоже сфот от ксалинкса. Все параметры по умолчанию, кроме как выходные буфера добавить.
Все делаю для Virtex2 2000 -4
Ограничение только одно period для клока ставлю 20 ns. (что бы увидить на сколько развидется)
Вот и все вроде.
Меня настораживает только одно, что есть большие различия между функциональной симуляции и временной симуляции.
К сожалению у меня нет сейчас JTAG кабеля и не могу посмотреть что реально происходит. Попробую сейчас вывести сигнал на ружу и посмотреть скопом, хоть примерно оценить как все работает.

Вот еще нашел опцию у мапера -timing интрестные результаты получаются с ней и без. То что работало без нее (имеется ввиду временная симуляция) не работает с этой опцией и наоборт. Я только пол года занимаюсь этим и для меня много чего является откравениемsmile.gif)
oval
Цитата(eteP @ May 18 2005, 15:33)
Я использую среду альдек. Ситезатор  XST 6.3 мапирование и разводу тоже сфот от ксалинкса. Все параметры по умолчанию, кроме как выходные буфера добавить.
Все делаю для Virtex2 2000 -4
Ограничение только одно period для клока ставлю 20 ns. (что бы увидить на сколько развидется)
Вот и все вроде.

Понятно. Для этой технологии (Virtex-II) полученные результаты временного анализа - явный бред. Особенно 454 и 607МГц, если учитывать к тому же добавление буферов ввода/вывода. Кстати, 113МГц для моего варианта схемы - это возможно реально.
Цитата
Меня настораживает только одно, что есть большие различия между функциональной симуляции и временной симуляции.

А что за различия? Логика работы не должна меняться в любом случае.
Цитата
К сожалению у меня нет сейчас JTAG кабеля и не могу посмотреть что реально происходит. Попробую сейчас вывести сигнал на ружу и посмотреть скопом, хоть примерно оценить как все работает.

Вот еще нашел опцию у мапера -timing интрестные результаты получаются с ней и без. То что работало без нее (имеется ввиду временная симуляция) не работает с этой опцией и наоборт. Я только пол года занимаюсь этим и для меня много чего является откравениемsmile.gif)
*

Ничего, все приходит с опытом. Главное точно понимать, что делаешь и как работает.
oval
Цитата(makc @ May 17 2005, 20:48)
Если я не ошибаюсь, то в вышеприведенных схемах не учтен вопрос метастабильности. Я предпочитаю использовать несколько иную схему, которая учитывает метастабильность триггеров.

Код
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity synchronizer is
    Port (
 clk: in std_logic;
 en:    in std_logic;
 run: in std_logic;
 ce: out std_logic
    );
end synchronizer;

architecture Behavioral of synchronizer is
    signal Q0, Q1, Q2: std_logic := '0';
begin
    process(run,en)
    begin
 if rising_edge(run) and en='1' then
     Q0 <= not Q1;
 end if;
    end process;

    process(clk)
    begin
 if rising_edge(clk) then
     Q1 <= Q0;
     Q2 <= Q1;
 end if;  
    end process;

    ce <= Q2 xor Q1;

end Behavioral;


Всего три триггера и один инвертор и элемент xor. smile.gif
*

Я разрисовал Ваш вариант схемы и у меня возникло несколько вопросов:
1. Куда на нее подается входной асинхронный сигнал (сигнал ND)?
2. Для чего используется триггер Q0?
Если вход триггера Q1 (т. е. выход Q0) является асинхронным (может переключаться в произвольный момент времени) по отношению к clk, то очевидно, что это все равно что подавать асинхронный входной сигнал (ND) непосредственно на вход Q1, т. е. степень стабильности схемы по сравнению с моим вариантом ничем не отличается. Так в чем же идея?
eteP
Когда я говорил что есть различия в моделирование, я использовал схему от makc.
При функциональном моделирование все работает корректно при любой частоте клока. А вот при временном симулирование, даже с учетом задержек на выходных буферах, она работает правильно (так как мне нужно), только в определенном диапазоне частот.

Ваша схема работает правильно при всех видах симуляции и для частот от 10 до 100 МГц (больше я не пробывал) без проблем.


Как я понял, что схема от makc, для передачи данных из одного частотного домена в другой. Но ее можно пользовать и для задачи которую я описал.
Для этого миняем RUN -> ND, EN выкидываем.
oval
Цитата(eteP @ May 18 2005, 17:00)
Когда я говорил что есть различия в моделирование, я использовал схему от makc. 
При функциональном моделирование все работает корректно при любой частоте клока. А вот при временном симулирование, даже с учетом задержек на выходных буферах, она работает правильно (так как мне нужно), только в определенном диапазоне частот.

Ваша схема работает правильно при всех видах симуляции и для частот от 10 до 100 МГц (больше я не пробывал) без проблем.

Насчет схемы от makc, я не совсем понял идею, поэтому никаких выводов делать не буду. По поводу своей, как только период тактового сигнала станет меньше, чем минимальный допустимый период (т. е. то, что было 113МГц), то логика работы схемы нарушиться, и это правильно. Речь идет о временном моделировании естественно. Для логического все равно.
Цитата
Как я понял, что схема от makc, для передачи данных из одного частотного домена в другой. Но ее можно пользовать и для задачи которую я описал.
Для этого миняем RUN -> ND, EN выкидываем.
*

Все равно, я не понял идею. Мне не понятна функция триггера Q0. Насчет включения, я так и предполагал. Элементов больше, доменов два, толку ноль, но может я чего-то не понимаю.
PS: Если длительность импульса на ND меньше одного периода clk, то схема может его и не заметить.
eteP
Тригер Q0 клокируется сигналом ND и не зависит от сигнала CLK. А это значит, что на выходе его будет стоять или 0 или 1 стабильно. Но должно быть выполнино одно условие: частота сигнала ND < CLK. Не зависимо когда придет передний фронт сигнала CLK, тригер Q1 перейдет или в 0 или в 1 когда все идет нормально или выходя из метастабильного состояния. Допустим что на входе Q1 устанавливается 1 и в этот момент пришел CLK. Q1 перешел не в правильное состояние и на выходе у него 0. Тогда на следующем клоке он захватит все равно 1. (вот почему должно выполняться условие ND < CLK). Единственное что, сигнал DRY будет черт знает что вытворять. Но и тут можно поставить еще один тригер, тогда вероятность метостабильности уменьшается. Где-то я даже формулу видел как это вычисляется.

Так вот это я все вижу.
makc
Цитата(eteP @ May 18 2005, 18:06)
Тригер Q0 клокируется сигналом ND и не зависит от сигнала CLK. А это значит, что на выходе его будет стоять или 0 или 1 стабильно. Но должно быть выполнино одно условие: частота сигнала ND < CLK. Не зависимо когда придет передний фронт сигнала CLK, тригер Q1 перейдет или в 0 или в 1 когда все идет нормально или выходя из метастабильного состояния. Допустим что на входе Q1 устанавливается 1 и в этот момент пришел CLK. Q1 перешел не в правильное состояние и на выходе у него 0. Тогда на следующем клоке он захватит все равно 1. (вот почему должно выполняться условие ND < CLK). Единственное что, сигнал DRY будет черт знает что вытворять. Но и тут можно поставить еще один тригер, тогда вероятность метостабильности уменьшается. Где-то я даже формулу видел как это вычисляется.

Так вот это я все вижу.
*


Все правильно. И если принять, что DRY обрабатывается в схеме по тому же фронту CLK, по которому вырабатывается - все будет в полном порядке, т.к. к моменту его обработки триггер Q1 уже выйдет из метастабильного состояния. cheers.gif
sazh
Признаюсь, такую реализацию увидел в первый раз. Если первый триггер пишет, то 0, то 1. Разве это не эквивалентно записи в этот триггер всегда 1 с последующим сбросом. А если период сигнала run в N раз больше периода клока, разве это не эквивалентно
sdvig_rg_q[2:0] <= {sdvig_rg_q[1:0], run};
assign ce = sdvig_rg_q[1] & ~sdvig_rg_q[2];
Кстати, Ваша схема сходу вводит в заблужение,
потому что во всех учебниках реализация q1 ^ q2 приводит к формированию одиночного импульса по переднему и заднему фронту сигнала run.
К чему изощренность, все должно быть прозрачно.
oval
Цитата(eteP @ May 18 2005, 18:06)
Тригер Q0 клокируется сигналом ND и не зависит от сигнала CLK. А это значит, что на выходе его будет стоять или 0 или 1 стабильно. Но должно быть выполнино одно условие: частота сигнала ND < CLK. Не зависимо когда придет передний фронт сигнала CLK, тригер Q1 перейдет или в 0 или в 1 когда все идет нормально или выходя из метастабильного состояния. Допустим что на входе Q1 устанавливается 1 и в этот момент пришел CLK. Q1 перешел не в правильное состояние и на выходе у него 0. Тогда на следующем клоке он захватит все равно 1. (вот почему должно выполняться условие ND < CLK). Единственное что, сигнал DRY будет черт знает что вытворять. Но и тут можно поставить еще один тригер, тогда вероятность метостабильности уменьшается. Где-то я даже формулу видел как это вычисляется.

Так вот это я все вижу.
*

Идею понял, но каким образом она увеличивает стабильность схемы (т. е. параметр MTBF (Mean Time Between Failures)) так и не понял. Переключение то выхода триггера Q0 попрежнему остается асинхронным по отношению к clk. Следовательно, Q1 может оказаться в метастабильном состоянии с не меньшей вероятностью, чем если просто подать сигнал ND на вход Q1. Вообщем, такое решение встречаю впервые. Думаю триггер Q0 здесь не несет никакой полезной функции, поскольку его выход попрежнему остается асинхронным по отношению к clk. Допустим, сигнал ND формируется где-то в другом тактовом домене, через сколько бы последовательных триггеров того тактового домена он не проходил (хоть даже через несколько разных асинхронных по отношению к clk) "синхроннее" к clk он не станет. Заменяем тактирование триггера Q0 на clk и подаем ND на его вход, вот стандартная (правда одноуровневая) схема синхронизации, которая приводится во всех документах, которые я видел по данной теме. Таким образом, Q0 синхронизирует появление метастабильного состояния по отношению к clk. Для относительно малых частот одного уровня синхронизации (т. е. триггера Q0)достаточно, для больших частот может потребоваться еще один уровень синхронизации. Все зависит от характеристик технологии (от параментра времени нахождения триггера в метастабильном состоянии). Вот что на этот счет когда-то писала Altera:
Нажмите для просмотра прикрепленного файла
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.