|
Прояснить ситуацию, синхронная загрузка регистров по enable |
|
|
|
Mar 17 2008, 06:06
|
Знающий
   
Группа: Свой
Сообщений: 921
Регистрация: 6-04-07
Из: Israel
Пользователь №: 26 822

|
Вопрос в следующем: есть код который конвертирует последовательность из 8-битного серийного потока (т.е. байтный поток, один байт за другим) в параллельные слова каждые 3 последовательных байта. Т.е. первые 2 байта загружаются в промеж. регистры, затем по третьему байту - все 3 считываются параллельно на выходе в соотв. раскладе. В принципе, все работает в симуляции как надо, но начало работы конвертора динхронизировано с определенным сигналом. Фронт данного enable синхронизирован с фронтом первого релевантного клока. Первый байт данных в потоке синхронизирован тоже по фронту того-же клока, т.е. должен загружаться в первый промеж. регистр по спаду первого клока. Т.е. по фронту первого клока получаем enable, по его спаду должны загрузить первое данное в регистр. Далее все продолжается синхронно, по каждому спаду идет загрузка в цепочку из 2х регистров, по каждому 3ему спаду - считывает параллельное данное. Проблема в следующем: при симуляции вижу получив enable на первом клоке (по его фронту), загрузка не начинается по спаду того-же клока, а только по спаду следующего (второго) клока, т.е. пропускается первый байт потока. Пока не пойму почему. Клок достаточно медленный (примерно 20-25 MHz), 50% duty cycle, симуляция: post-route functional. Вот релевантный кусок кода: Код process(nRST, IN_CLK, DV) --Input FIFO - buffering input RGB sequence begin if nRST = RST_pol or DV = not DV_active then r0 <= x"00"; r1 <= x"00"; RGB_OUT <= x"0000"; elsif IN_CLK'event and IN_CLK = '0' then --FIFO is chain-loaded upon falling edge r0 <= RGB_IN; --G sample (8 bits), 6 MSB bits will be picked r1 <= r0; --R sample (8 bits), 5 MSB bits will be picked if out_load_en = '1' then --loading the output RGB buffer (parallel RGB) RGB_OUT <= r1(7 downto 3) & r0(7 downto 2) & RGB_IN(7 downto 3); end if; end if; end process; Пока не пойму что мешает по получении enable по фронту клока начать загруску по спаду того-же клока...? Спасибо
|
|
|
|
|
Mar 17 2008, 08:35
|
Знающий
   
Группа: Свой
Сообщений: 921
Регистрация: 6-04-07
Из: Israel
Пользователь №: 26 822

|
Цитата(dvladim @ Mar 17 2008, 11:58)  Поведение post-route отличается от функционального? Если да, меняйте схему.
Из того кода, что у вас, видно, что сброс асинхронный, а это не есть хорошо.
Приведите вейвформы. Спасибо за ответ. Я видимо не точно выразился: симуляция идет post-route functional, т.е. она после route но функциональная, т.е. без тайминга. Сброс там действительно асинхронный. Он может влиять таким образом ? Дал кусок симуляции, рележантные сигналы вверху окна. nrst - асинхронный reset clk - входной клок dv - enable загрузки (синхронизирован с фронтом клока) rgb_out_debug - данные на выходе (16 бит параллельные) oled_video_in - даннтые на входе (8-битный поток)
Эскизы прикрепленных изображений
|
|
|
|
|
Mar 17 2008, 11:25
|
Знающий
   
Группа: Свой
Сообщений: 921
Регистрация: 6-04-07
Из: Israel
Пользователь №: 26 822

|
Цитата(Михаил_K @ Mar 17 2008, 14:32)  Асинхронный сброс еще как может на это влиять. Вообще-то делается примерно так
signal p : std_logic_vector (2 downto 0);
process (CLK) begin if (CLK'Event and CLK = '1') then if (Dv = '0') then p<="001"; else p<=p(1 downto 0) & p(2); -- маркер на 3 байта r0<= RGB_In; r1<=R0; if (p(2) = '1') then RGB_Out<=r1(7 downto 3) & r0(7 downto 2) & RGB_IN(7 downto 3); end if; end if; end if;
end process;
И не нужно мудрить с фронтами клока, если уж схема работает по фронтам, то лучше чтобы она вся так и работала. Переходить на работу по спаду, нужно только когда нет другого выхода. Данный случай к этому не отностится. OK, сделал синхронный Reset - ситуация не улучшилась. Честно гворя не понял у вас в коде как продвигается p, кроме того вы видимо имели ввиду (но забыли) включить в sens list процесса сигналы кроме DV (клок и т.д.). Но не существенно. Мой код работает нормально, out_load_en дает enable на чтение выходных данных (по каждому третьему клоку), его контроль описан в другом процессе, кстати - у себя обнаружил что забыл вставить out_load_en в sense list процесса.... Работа по фронту конечно желательно, согласен, но проблема в том что первый байт потока на входе согласован прямо по первому фронту клока по которому-же и синхронизирован DV, посему ежели брать дату по фронту - первая valid дата будет упускаться, но ежели по спаду - она должна по идее фиксироваться...
|
|
|
|
|
Mar 17 2008, 12:03
|
Частый гость
 
Группа: Свой
Сообщений: 183
Регистрация: 10-02-06
Из: Киев, Украина
Пользователь №: 14 188

|
Цитата кстати - у себя обнаружил что забыл вставить out_load_en в sense list процесса.... Он там не нужен. Если описывается синхронная часть(if clk'event...), то достаточно только clk в списке чувствительности. ...Если входные данные синхронизированы по фронту - работайте с ними по фронту, если это один и тот же клок. Ничего не будет упускаться.  Это нормальная работа любого синхронного проекта. Работа с входными данными будет начинаться по следующему фронту после того, на котором выставляется DV и завершаться, соответственно, на следующем фронте после установки DV в ноль(в том смысле, что на этом фронте работа уже не будет совершаться)... ... считайте, что данные или DV изменяются ПОСЛЕ фронта CLK, а не во время него, т.е. вполне можно одновременно выставлять по фронту сигнал(например, DV) и по тому же фронту пользоваться его прежним значением(например, в качестве разрешения записи). То же самое касается и данных.
|
|
|
|
|
Mar 17 2008, 12:26
|
Знающий
   
Группа: Свой
Сообщений: 921
Регистрация: 6-04-07
Из: Israel
Пользователь №: 26 822

|
Цитата(Very_hard @ Mar 17 2008, 16:03)  Он там не нужен. Если описывается синхронная часть(if clk'event...), то достаточно только clk в списке чувствительности. ...Если входные данные синхронизированы по фронту - работайте с ними по фронту, если это один и тот же клок. Ничего не будет упускаться.  Это нормальная работа любого синхронного проекта. Работа с входными данными будет начинаться по следующему фронту после того, на котором выставляется DV и завершаться, соответственно, на следующем фронте после установки DV в ноль... ... считайте, что данные или DV изменяются ПОСЛЕ фронта CLK, а не во время него, т.е. вполне можно одновременно выставлять по фронту сигнал(например, DV) и по тому же фронту пользоваться его прежним значением(например, в качестве разрешения записи). То же самое касается и данных. Возможно, на практике наверно не проблема как вы и говорите, я-же просто стараюсь придерживаться "книги", посему стараюсь все сигналы участвущие в процессе как входа заность в список чуствительности..  , меньше потом вохможной головной боли... С фронтами проблема как и упоминал в том что на входе фронт клока совпадает с фронтом DV значит как вы правильно упомянули работа с входными данными сможет начаться только по след. фронту, а значит первое данное упущено. Здесь привел кусок симуляции где работаем только по фронту - как раз видимо это и происходит - первое данное с которым работаем получается вторым в потоке (00h) после DV = 1, тогда как должно быть первое (FFh). P.S. сорри, забыл присобачить кусок симуляции..обратите внимание на обведенный участок.
Эскизы прикрепленных изображений
|
|
|
|
|
Mar 17 2008, 12:40
|
Знающий
   
Группа: Свой
Сообщений: 552
Регистрация: 29-02-08
Пользователь №: 35 481

|
Цитата(Саша Z @ Mar 17 2008, 14:25)  Работа по фронту конечно желательно, согласен, но проблема в том что первый байт потока на входе согласован прямо по первому фронту клока по которому-же и синхронизирован DV, посему ежели брать дату по фронту - первая valid дата будет упускаться, но ежели по спаду - она должна по идее фиксироваться... Выражайтесь более точно. DV и данные выходят с триггера, который работает по клоку? Или как? Если так, как я говорю, то замечание Very_hard - правильное. Ничего упускаться не будет. Цитата(Саша Z @ Mar 17 2008, 14:25)  Честно гворя не понял у вас в коде как продвигается p p - двигается циклично, и синхронизируется с первым значимым данным. Раз в три такта, когда на входе 3е данное, в старшем разряде p появляется 1, что и является признаком выдачи данных в параллельный регистр.
|
|
|
|
|
Mar 17 2008, 12:56
|
Знающий
   
Группа: Свой
Сообщений: 921
Регистрация: 6-04-07
Из: Israel
Пользователь №: 26 822

|
Цитата(Михаил_K @ Mar 17 2008, 16:40)  Выражайтесь более точно. DV и данные выходят с триггера, который работает по клоку? Или как? Если так, как я говорю, то замечание Very_hard - правильное. Ничего упускаться не будет. p - двигается циклично, и синхронизируется с первым значимым данным. Раз в три такта, когда на входе 3е данное, в старшем разряде p появляется 1, что и является признаком выдачи данных в параллельный регистр. Насчет p - понял, спасибо. В моем случае - счетчик до 3х...делает в результате тоже-самое. DV, данные, клок приходят извне, т.е. в системе но от внешнего устройства, в test benchе я их сгенерировал согласно их ожидаемому таймингу (по specу того устройства). DV и дата по идее синхронизированы по входному клоку (в внешнем устройстве), значит в реальности видимо будет задержка между фронтом соотв. клока и фронтом DV и первого данного. Я пока симулирую функционально (хотя и после route), посему этих задержек не видно (хотя можно наверно их проимитировать)... Цитата(andrew_b @ Mar 17 2008, 16:33)  Мне кажется, я начинаю догадываться... Будьте добры, приведите код генерации dv и oled_video_in. код DV (в test benchе): Код OLED_DV: PROCESS BEGIN DV <= '0'; wait for start_time; for fdv in frames_to_simulate downto 1 loop for ldv in TV_tot_lines downto 1 loop if ldv > (TV_tot_lines - TVs) or ldv <= (TV_tot_lines - TVd - TVs) then DV <= '0'; wait for line_time; else wait for HSYNC_time; DV <= '1'; wait for DV_time; --activate DV for 960 PCLKs DV <= '0'; wait for (line_time - DV_time - HSYNC_time); end if; end loop; end loop; wait; END PROCESS; все параметры - нужные задержки для имитации циклов синхронизации DV в строках. код данных: Код OLED_DATA: PROCESS BEGIN OLED_VIDEO_IN <= x"00"; wait for start_time; OLED_VIDEO_IN <= x"00"; wait for start_frame_blank_time; --wait for first 7 blank lines for ldat in TVd downto 1 loop wait for HSYNC_time; --wait for HSYNC pulse duration for clkdat in 960 downto 1 loop OLED_VIDEO_IN <= x"FF"; wait for Tclock; OLED_VIDEO_IN <= x"00"; wait for Tclock; end loop; end loop; END PROCESS; опять-же все константы задержек нужны для синхронизации видео sync сигналов и т.д.
|
|
|
|
|
Mar 17 2008, 13:01
|
Знающий
   
Группа: Свой
Сообщений: 552
Регистрация: 29-02-08
Пользователь №: 35 481

|
Цитата(Саша Z @ Mar 17 2008, 15:56)  Насчет p - понял, спасибо. В моем случае - счетчик до 3х...делает в результате тоже-самое. DV, данные, клок приходят извне, т.е. в системе но от внешнего устройства, в test benchе я их сгенерировал согласно их ожидаемому таймингу (по specу того устройства). DV и дата по идее синхронизированы по входному клоку (в внешнем устройстве), значит в реальности видимо будет задержка между фронтом соотв. клока и фронтом DV и первого данного. Я пока симулирую функционально (хотя и после route), посему этих задержек не видно (хотя можно наверно их проимитировать)...
опять-же все константы задержек нужны для синхронизации видео sync сигналов и т.д. ИМХО если данные приходят из вне вместе с клоком, то в первую очередь их нужно принять на входной триггер, тактируемый этим клоком. И сигнал DV также. После этого все становится нормально.
Сообщение отредактировал Михаил_K - Mar 17 2008, 13:03
|
|
|
|
|
Mar 17 2008, 13:23
|
Профессионал
    
Группа: Свой
Сообщений: 1 975
Регистрация: 30-12-04
Из: Воронеж
Пользователь №: 1 757

|
Цитата(Саша Z @ Mar 17 2008, 15:56)  DV, данные, клок приходят извне, т.е. в системе но от внешнего устройства, в test benchе я их сгенерировал согласно их ожидаемому таймингу (по specу того устройства). DV и дата по идее синхронизированы по входному клоку (в внешнем устройстве), Во внешнем -- да, но у вас в тестбенче нет. "Данные, меняющиеся вместе с клоком" и " данные, меняющиеся по клоку" -- две большие разницы. В первом случае это, к примеру, Код Clk <= not Clk after 10 ns; Data <= not Data after 20 ns; вроде бы всё нормально, но Clk и D асинхронны друг по отношению к другу. Что у вас и получается. Второй случай -- это синхронная схема Код Clk <= not Clk after 10 ns;
process(Clk) begin if (rising_edge(Clk)) then Data <= not Data; end if; end process; Цитата значит в реальности видимо будет задержка между фронтом соотв. клока и фронтом DV и первого данного. Я пока симулирую функционально (хотя и после route), посему этих задержек не видно (хотя можно наверно их проимитировать)... Не можно, а нужно. Проще всего сдвинуть клок, чтобы изменение данных не совпадало по времени с изменением клока. Это будет асинхронщина, но результат у вас будет другой.
|
|
|
|
|
Mar 17 2008, 14:21
|
Знающий
   
Группа: Свой
Сообщений: 921
Регистрация: 6-04-07
Из: Israel
Пользователь №: 26 822

|
Цитата(andrew_b @ Mar 17 2008, 17:23)  Во внешнем -- да, но у вас в тестбенче нет. "Данные, меняющиеся вместе с клоком" и " данные, меняющиеся по клоку" -- две большие разницы. В первом случае это, к примеру, Код Clk <= not Clk after 10 ns; Data <= not Data after 20 ns; вроде бы всё нормально, но Clk и D асинхронны друг по отношению к другу. Что у вас и получается. Второй случай -- это синхронная схема Код Clk <= not Clk after 10 ns;
process(Clk) begin if (rising_edge(Clk)) then Data <= not Data; end if; end process; Не можно, а нужно. Проще всего сдвинуть клок, чтобы изменение данных не совпадало по времени с изменением клока. Это будет асинхронщина, но результат у вас будет другой. ОК, спасибо. Хмм, нужно ли синхронизировать входные контроли и данные (syncs + data) в коде по входному клоку перед процессингом как советует Михаил_К или в приципе достаточно довольстоваться тем фактом что они синхронизированны друг с другом во внешнем устройстве ? Мне кажется предложение Михаила логичным... Будем думать как сдвинуть клок в test benchе (создать скажем 5-10 ns tpd входных сигналов относительно входного клока)...
|
|
|
|
|
Mar 17 2008, 15:03
|
Знающий
   
Группа: Свой
Сообщений: 552
Регистрация: 29-02-08
Пользователь №: 35 481

|
Цитата(Саша Z @ Mar 17 2008, 17:21)  ОК, спасибо. Хмм, нужно ли синхронизировать входные контроли и данные (syncs + data) в коде по входному клоку перед процессингом как советует Михаил_К или в приципе достаточно довольстоваться тем фактом что они синхронизированны друг с другом во внешнем устройстве ? Мне кажется предложение Михаила логичным... Будем думать как сдвинуть клок в test benchе (создать скажем 5-10 ns tpd входных сигналов относительно входного клока)... Дело в том, что система параметров плиса (я работаю с xilinx) построена так, что временные параметры, относящиеся к вводу-выводу даны для условий, что сигналы принимаются (выдаются) на триггеры, расположенные в IOB. Только руководствуясь этими параметрами можно расчитать правильную передачу данных с внешнего девайса на ПЛИС. В противном случае никто не гарантирует вам правильную работу устройсвта, и убедившись в том, что одно устройство работает, вы можете нарваться на то, что другой экземпляр работать не будет.
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|