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

Как правильно сформировать сигнал DATA READY?

Привет.

 

Посмотрите плз. код.

Хотелось бы сделать так как показыно на картинке ну и с наименьшими затратами ресурсов в 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;

post-166-1116340219.jpg

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


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

Если надо сформировать по фронту короткий импульс длительностью в один такт частоты, ставишь двухбитный сдвиговый регистр, и компаратор, который при комбинации в нём "01" выдаёт единицу. Получается например "01" - положительный фронт, "10" - отрицателльный, или наоборот, смотря в какую сторону сдвигать.

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


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

Обычно я поступаю следующим образом:

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;

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


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

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

 

Эта схема будет не правильно работать если сигнал 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;

 

Спасибо.

Это лучшее схема чем было у меня до этого. Спасибо еще раз.

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


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

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

 

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. :)

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


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

А не должно ли быть здесь

 

 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

 

 

забавно.

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


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

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

 

Всего три триггера и один инвертор и элемент xor. :)

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

 

Хотя может я ошибаюсь :glare:

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


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

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

 

Всего три триггера и один инвертор и элемент xor. :)

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

 

Хотя может я ошибаюсь :glare:

 

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

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


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

А не должно ли быть здесь

 

 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. Но по большому счету это не принципиально. :)

 

Если использовать 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

 

 

забавно.

 

Да... Разница видна невооруженным взглядом. :)

Даже не думал, что может быть такой разрыв.

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


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

Действительно, если сигнал ND асинхронен по отношению к CLK, то в общем

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

частот самого CLK и частоты переключения ND. Для малых частот достаточно

одного уровня (триггера) подтактирования. Для больших частот может потребоваться два или даже три уровня подтактирования. Можно играть с фронтами CLK для схемы подтактирования (синхронизации). Можно подтактировать и непосредственно выход, т. е. DRY. Современная элементная

база имеет очень высокую степень защиты от метастабильных состояний и

очень быстро выходит из этого состояния. Но все же принебрегать этим я бы

не рекомендовал. Я обычно использую не более двух уровней подтактирования, чаще даже один. Для сокращения времени передачи сигнала из одного тактового домена в другой обычно использую оба фронта тактового сигнала. Пока с проблемами метастабильности не сталкивался, хотя работал даже с технологиями ASIC.

 

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

 

А для какой технологии синтезируете?

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


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

Я использую среду альдек. Ситезатор XST 6.3 мапирование и разводу тоже сфот от ксалинкса. Все параметры по умолчанию, кроме как выходные буфера добавить.

Все делаю для Virtex2 2000 -4

Ограничение только одно period для клока ставлю 20 ns. (что бы увидить на сколько развидется)

Вот и все вроде.

Меня настораживает только одно, что есть большие различия между функциональной симуляции и временной симуляции.

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

 

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

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


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

Я использую среду альдек. Ситезатор  XST 6.3 мапирование и разводу тоже сфот от ксалинкса. Все параметры по умолчанию, кроме как выходные буфера добавить.

Все делаю для Virtex2 2000 -4

Ограничение только одно period для клока ставлю 20 ns. (что бы увидить на сколько развидется)

Вот и все вроде.

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

Меня настораживает только одно, что есть большие различия между функциональной симуляции и временной симуляции.

А что за различия? Логика работы не должна меняться в любом случае.

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

 

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

Ничего, все приходит с опытом. Главное точно понимать, что делаешь и как работает.

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


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

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

 

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. :)

Я разрисовал Ваш вариант схемы и у меня возникло несколько вопросов:

1. Куда на нее подается входной асинхронный сигнал (сигнал ND)?

2. Для чего используется триггер Q0?

Если вход триггера Q1 (т. е. выход Q0) является асинхронным (может переключаться в произвольный момент времени) по отношению к clk, то очевидно, что это все равно что подавать асинхронный входной сигнал (ND) непосредственно на вход Q1, т. е. степень стабильности схемы по сравнению с моим вариантом ничем не отличается. Так в чем же идея?

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


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

Когда я говорил что есть различия в моделирование, я использовал схему от makc.

При функциональном моделирование все работает корректно при любой частоте клока. А вот при временном симулирование, даже с учетом задержек на выходных буферах, она работает правильно (так как мне нужно), только в определенном диапазоне частот.

 

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

 

 

Как я понял, что схема от makc, для передачи данных из одного частотного домена в другой. Но ее можно пользовать и для задачи которую я описал.

Для этого миняем RUN -> ND, EN выкидываем.

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


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

Когда я говорил что есть различия в моделирование, я использовал схему от makc. 

При функциональном моделирование все работает корректно при любой частоте клока. А вот при временном симулирование, даже с учетом задержек на выходных буферах, она работает правильно (так как мне нужно), только в определенном диапазоне частот.

 

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

Насчет схемы от makc, я не совсем понял идею, поэтому никаких выводов делать не буду. По поводу своей, как только период тактового сигнала станет меньше, чем минимальный допустимый период (т. е. то, что было 113МГц), то логика работы схемы нарушиться, и это правильно. Речь идет о временном моделировании естественно. Для логического все равно.

Как я понял, что схема от makc, для передачи данных из одного частотного домена в другой. Но ее можно пользовать и для задачи которую я описал.

Для этого миняем RUN -> ND, EN выкидываем.

Все равно, я не понял идею. Мне не понятна функция триггера Q0. Насчет включения, я так и предполагал. Элементов больше, доменов два, толку ноль, но может я чего-то не понимаю.

PS: Если длительность импульса на ND меньше одного периода clk, то схема может его и не заметить.

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


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

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

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

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

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

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

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

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

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

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