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

на вход CLK0 подана частота с кварцевого генератора 50мгц

требуется получить частоту 150 мгц и использовать внутри фпга. на внешнюю ножку не надо.

гуру, помогите vhdl-фрагментом как юзать PLL
Kuzmi4
MegaWizard Plug-In Manager спасёт отца русской демократии wink.gif
Methane
Цитата(%-) @ Dec 6 2009, 16:01) *
нужно задействовать pll в циклон-2 фпга.

на вход CLK0 подана частота с кварцевого генератора 50мгц

требуется получить частоту 150 мгц и использовать внутри фпга. на внешнюю ножку не надо.

гуру, помогите vhdl-фрагментом как юзать PLL

В мегавизарде конфигурируется, потом готовый файл с настройками подключается к проекту, расписываются выводы. Все.
%-)
Подключил PLL следующим образом. В мегавизарде сформировал ALTPLL.
Далее перенёс компонент в основной текст:

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

entity test is port
(
Clk:in std_logic;    --входной сигнал синхронизации 50 МГц
ClkOut:out std_logic; --выходной умноженный сигнал
CounterOut:out std_logic_vector(7 downto 0)
);
end test;

architecture test_arch of test is

signal c:std_logic; --сигнал на выходе умножителя

signal counter:std_logic_vector(7 downto 0):=(others => '0'); --счётчик

component pll port
(
inclk0:in std_logic:='0';
c0:out std_logic
);

end component;

begin

pll_inst:pll port map(Clk,c);

process(c)
begin
if rising_edge(c) then
  counter<=counter+1;
end if;
end process;

ClkOut<=counter(0); --ошибка

Counterout(0)<=counter(0); --нет ошибки

end test_arch;


1) Правильно ли сделал?

Также интересуют следующие вопросы:

2) Есть 4 режима PLL: normal mode, source-syncronous mode, in zero-delay buffer mode, with no compensation

какой из этих режимов позволяет выводить сигнал с PLL, чтоб он начинался с той же фазы что и входной сигнал? (тобишь синхронно менялся - в 1 такт входного сигнала вписывалось целое число тактов выходного сигнала с PLL) ?

3) что вообще даёт эта компенсация? Теорию ФАПЧ знаю (ГУН, ФНЧ, делитель, опорный генератор, ...)

4) В мега-визарде указываются входная частота и градация по скорости. Зачем? Не для параметров ФНЧ случайно ли? Заметил что если "обмануть" мегавизард - сказать ему входную частоту в 2 раза меньше, то стабильность частоты на выходе PLL улучшается (даже при самой безалаберной разводке цепей питания/земли PLL)

5) выбрал режим zero delay buffer. Почему-то в этом режиме из-за присвоения бита счётчика на выходной сигнал - ошибка(см. текст программы ыше - "ClkOut<=counter(0); --ошибка").

Тескт ошибки:

Цитата
Error: PLL "pll:pll_inst|altpll:altpll_component|pll" COMPENSATE_CLOCK port CLK0 must feed an output pin when OPERATION_MODE is set to ZERO_DELAY_BUFFER
Error: Quartus II Analysis & Synthesis was unsuccessful. 1 error, 16 warnings
Error: Peak virtual memory: 188 megabytes
Error: Processing ended: Wed Dec 09 10:47:14 2009
Error: Elapsed time: 00:00:02
Error: Total CPU time (on all processors): 00:00:02
Error: Quartus II Full Compilation was unsuccessful. 3 errors, 16 warnings


А конструкция типа: Counterout(0)<=counter(0); - не даёт ошибки.

6) можно ли более тонко осуществить настройку PLL? Например увеличить время установления, поставив более низкочастотный ФНЧ, и увеличить стабильность (без улучшения разводки питания/земли)?

7) каков процент отклонения частоты PLL на 150 МГц при отсутствии феритовой бусины и аналоговых полигонов? (входная кварцевый генератор 50мгц) - только 10нф +0.1мкф + 10мкф всё керамика
des00
Цитата(%-) @ Dec 8 2009, 19:01) *
1) Правильно ли сделал?


Собрать, проверить.

Цитата
2) Есть 4 режима PLL: normal mode, source-syncronous mode, in zero-delay buffer mode, with no compensation
какой из этих режимов позволяет выводить сигнал с PLL, чтоб он начинался с той же фазы что и входной сигнал? (тобишь синхронно менялся - в 1 такт входного сигнала вписывалось целое число тактов выходного сигнала с PLL) ?
3) что вообще даёт эта компенсация? Теорию ФАПЧ знаю (ГУН, ФНЧ, делитель, опорный генератор, ...)


в даташите на целевую фпга все разрисовано и объяснено. изучайте, там все есть.

Цитата
5) выбрал режим zero delay buffer. Почему-то в этом режиме из-за присвоения бита счётчика на выходной сигнал - ошибка(см. текст программы ыше - "ClkOut<=counter(0); --ошибка").


телепаты в отпуске

Цитата
6) можно ли более тонко осуществить настройку PLL? Например увеличить время установления, поставив более низкочастотный ФНЧ, и увеличить стабильность (без улучшения разводки питания/земли)?


можно но не во всех фпга.
%-)
Цитата(des00 @ Dec 9 2009, 07:58) *
телепаты в отпуске


тут вы погорячились. лог ошибки привёл в предыдущем сообщении. смотрите внимательнее smile.gif


на счёт мегавизарда.
чой-то он бред лепит - прошу из входной частоты 50 мгц сделать 100 мгц, выбираю умножитель 2 делитель 1

он автоматом делает частоту VCO 800 МГц cranky.gif

альтера требует чтобы 10 – 400 MHz без вывода на внешнюю ногу.

на вход допускается 11 – 311 MHz

какая польза тогда от мегавизарда, если потом файл компонента вручную править прийдётся? (исправлять множители)

и вообще он как-то странно подбирает частоту ГУН зависимо от коэффициентов mul, div

скриншот ниже
des00
Цитата(%-) @ Dec 8 2009, 22:44) *
тут вы погорячились. лог ошибки привёл в предыдущем сообщении. смотрите внимательнее smile.gif


Да не заметил. За это научу вас пользоваться RTFM smile.gif Ответ лежит там : Cyclone II Device Handbook, Volume 1 -> Section II. Clock Management -> Chapter 7. PLLs in Cyclone II Devices -> Clock Feedback Modes -> Zero Delay Buffer Mode -> In zero delay buffer mode, the clock signal on the PLL external clock output pin (FLL<#>_OUT), fed by the c2 counter, is phase-aligned with the PLL input clock for zero delay. И т.д. ответ лежи на поверхности

Кстати был не прав, для Source synchronus систем режим PLL называется по другому. Для асинхронной нарезки вам достаточно режима Normal

Цитата
на счёт мегавизарда.
чой-то он бред лепит - прошу из входной частоты 50 мгц сделать 100 мгц, выбираю умножитель 2 делитель 1
он автоматом делает частоту VCO 800 МГц cranky.gif


читаем Cyclone II Device Handbook, Volume 1 -> Section II. Clock Management -> Chapter 7. PLLs in Cyclone II Devices -> Hardware Features. Ответ лежит там

Цитата
какая польза тогда от мегавизарда, если потом файл компонента вручную править прийдётся? (исправлять множители)
и вообще он как-то странно подбирает частоту ГУН зависимо от коэффициентов mul, div


Думаю что проблема не в мегавизарде, а в вашем не понимании что происходит. Или вы думаете что разработчики альтеры настолько глупы что сделали не рабочий генератор PLL, который там со времен первых сборок квартуса. И это никто за 10-15 лет не заметил ? %)
%-)
Цитата(des00 @ Dec 9 2009, 09:37) *
Кстати был не прав, для Source synchronus систем режим PLL называется по другому. Для асинхронной нарезки вам достаточно режима Normal


спасибо за разъяснения и RTFM beer.gif

но всё-таки частоты VCO=800..1000 МГц вызывают у меня недоумение по поводу возможности их реализации в ПЛИС smile.gif

наверняка - чем больше частоты, тем более качественно нужно разводить цепи питания PLL



На счёт асинхронной нарезки. Согласно теореме Котельникова - нам нужен сигнал с периодом как минимум в 2 раза выше, чем исходный период.

Значит при частоте шины 133 МГц для того чтобы нарезать сигнал с точностью до 1 CLK , нам нужно частоту PLL выбрать не менее 266 МГц.

Я прав или нет?
Builder
Цитата(%-) @ Dec 9 2009, 07:44) *
на счёт мегавизарда.
чой-то он бред лепит - прошу из входной частоты 50 мгц сделать 100 мгц, выбираю умножитель 2 делитель 1

он автоматом делает частоту VCO 800 МГц cranky.gif

альтера требует чтобы 10 – 400 MHz без вывода на внешнюю ногу.
какая польза тогда от мегавизарда, если потом файл компонента вручную править прийдётся? (исправлять множители)

А чем Вас смущает VCO 800 МГц ? Это не та частота, что идёт на тригеры.
Эта частота базовая для PLL.
Учитывая что вы с этим первый раз сталкиваетесь, лучше руками в настройки пока не лезть,
а то вообще не разберётесь почему не работает.
Остальное ответили.
des00
Цитата(%-) @ Dec 9 2009, 00:11) *
спасибо за разъяснения и RTFM beer.gif

но всё-таки частоты VCO=800..1000 МГц вызывают у меня недоумение по поводу возможности их реализации в ПЛИС smile.gif

наверняка - чем больше частоты, тем более качественно нужно разводить цепи питания PLL


не путайте частоту ГУНа PLL и выходную частоту PLL.

Cyclone II PLL Hardware Overview -> The VCO frequency is a critical param eter that must be between 300 and 1,000 MHz to ensure proper operation of the PLL. The Quartus II software automatically sets the VCO frequency within the recommended range based on the clock output and phase-shift requirements in your design.

потому то цепи PLL и требуют особого внимания.

Цитата
На счёт асинхронной нарезки. Согласно теореме Котельникова - нам нужен сигнал с периодом как минимум в 2 раза выше, чем исходный период.

Значит при частоте шины 133 МГц для того чтобы нарезать сигнал с точностью до 1 CLK , нам нужно частоту PLL выбрать не менее 266 МГц.


но у вас же tsu/twr/th 2 такта. Если вы связывайтесь с асинхронной нарезкой надо рассматривать сигналы шины как асинхронные и учитывать из длительности. ИМХО резать нужно такой частотой, что бы умещалось хотя бы 2.5-3 отсчета на сигнал. Котельников тут не совсем к месту %)
Builder
Цитата(%-) @ Dec 9 2009, 09:11) *
но всё-таки частоты VCO=800..1000 МГц вызывают у меня недоумение по поводу возможности их реализации в ПЛИС smile.gif
На счёт асинхронной нарезки. Согласно теореме Котельникова - нам нужен сигнал с периодом как минимум в 2 раза выше, чем исходный период.
Значит при частоте шины 133 МГц для того чтобы нарезать сигнал с точностью до 1 CLK , нам нужно частоту PLL выбрать не менее 266 МГц.

1. насчёт VCO я уже написал, что это за частота.
2. Кательников это хорошо, но применительно к ПЛИС, это имеет косвенное отношение, т.к. вариаций времянки много.
Учитывая что Вы топчетесь с этой шиной уже долго. Я давно, когда начинал этим заниматься, смотрел как делает асинронную шину альтера в своих IP модулях. Проанализируйте. Может на опенкорес что найдёте. На уартах, совместимых со стандартными должны ставить асинхронную шину, их и посмотрите.
Я уже не помню как там у Вас задача ставилась исходно, если 133 - это просто шина, это одно. Если это темп записи, это уже совсем другое. Первое можно и без высокой частоты сделать.
Смысл тут уже Вам писали много, повторяться не вижу смысла. Попробуйте сделать ещё заход с этой стороны-проанализируйте
доступные дизайны. Что не поймёте - спросите. Только вопросы поконкретнее, после того как сами подумаете...
%-)
Цитата(des00 @ Dec 9 2009, 10:23) *
но у вас же tsu/twr/th 2 такта. Если вы связывайтесь с асинхронной нарезкой надо рассматривать сигналы шины как асинхронные и учитывать из длительности.


рассматривал много вариантов. в том числе tsu=1,twr=1,th=1

Цитата(des00 @ Dec 9 2009, 10:23) *
ИМХО резать нужно такой частотой, что бы умещалось хотя бы 2.5-3 отсчета на сигнал


исходя из чего вы брали 2,5 - 3 отсчёта?

пробовал работать на 1.5 отсчётах - оно работает!!!
на одном отсчёте не заработало (наверное из-за 6нс-задержки перед спадом сигналов WE,CE в BF533)

времянка такая: tsu=4, tw=4, th=0, Fbus=133.3 МГц, Ffpga=50 Мгц (правда OSC, а не PLL)


Цитата(Builder @ Dec 9 2009, 10:36) *
Учитывая что Вы топчетесь с этой шиной уже долго. Я давно, когда начинал этим заниматься, смотрел как делает асинронную шину альтера в своих IP модулях. Проанализируйте. Может на опенкорес что найдёте. На уартах, совместимых со стандартными должны ставить асинхронную шину, их и посмотрите.


смотрел, но похожее на своё там не нашёл...
может плохо и не то искал? smile.gif

Цитата(Builder @ Dec 9 2009, 10:36) *
Я уже не помню как там у Вас задача ставилась исходно, если 133 - это просто шина, это одно. Если это темп записи, это уже совсем другое. Первое можно и без высокой частоты сделать.
Смысл тут уже Вам писали много, повторяться не вижу смысла. Попробуйте сделать ещё заход с этой стороны-проанализируйте
доступные дизайны. Что не поймёте - спросите. Только вопросы поконкретнее, после того как сами подумаете...


задча что не есть на первый взгляд простая - нужно писать в управляющие регистры и манипулировать адресом для памяти.

пока сделал так:

1) по фронту тактовой(или PLL) нарезаю : CE,WE,A,D

2) по фронту тактовой проверяю если WE=0 и CE=0, то это первое состояние - пишим в регистр если A=0, или увеличиваем адрес SRAM (внешняя,болтается на ПЛИС) если A=1. Состояние<=2

3) по фронту тактовой проверяю если WE=1 и CE=0 - то перейти в первое состояние.

Замечено, что если из проверок выкинуть CE, то обмен идёт иногда нестабильно. Хотя устройство на асинхронке одно.

работает на ts=4, tw=4, th=0 1clk=133 мгц, режу частотой 50 мгц.

может быть и глупо сделал.
возможен ли лучше вариант, чем тот что описал?
des00
Цитата(%-) @ Dec 9 2009, 01:21) *
исходя из чего вы брали 2,5 - 3 отсчёта?
пробовал работать на 1.5 отсчётах - оно работает!!!


личный опыт, стробы это асинхронные сигналы на них надо давить метастабильность на что уйдет 2 триггера .

Цитата
1) по фронту тактовой(или PLL) нарезаю : CE,WE,A,D

2) по фронту тактовой проверяю если WE=0 и CE=0, то это первое состояние - пишим в регистр если A=0, или увеличиваем адрес SRAM (внешняя,болтается на ПЛИС) если A=1. Состояние<=2

3) по фронту тактовой проверяю если WE=1 и CE=0 - то перейти в первое состояние.

Замечено, что если из проверок выкинуть CE, то обмен идёт иногда нестабильно. Хотя устройство на асинхронке одно.

работает на ts=4, tw=4, th=0 1clk=133 мгц, режу частотой 50 мгц.


ИМХО я бы привязывался к переднему фронту сигнала WE, в этот момент tsu по адресу, данным, CE уже будет выполнен и есть еще twr времени на то что бы все операции закончить.
Builder
Цитата(des00 @ Dec 9 2009, 09:50) *
ИМХО я бы привязывался к переднему фронту сигнала WE, в этот момент tsu по адресу, данным, CE уже будет выполнен и есть еще twr времени на то что бы все операции закончить.

Во-во, я -бы тоже, сделал запись в регистры фронтом врайта, само сбой с контролем сетапов холдов.
А внутри уже 2 варианта определения факта записи (если нужно):
нарезка селекта высокой частотой, или сброс флагового тригера асинхронно, а потом уже синхронно возведение обратно и анализ что была запись и куда была запись. Но со фторым вариантом нужно поосторожнее, т.к. влупите асинхронный сброс, у которого есть иголки из=за гонок, будете потом долго искать откуда глюки. Хотят он не требует высокой частоты для нарезки.

Цитата
смотрел, но похожее на своё там не нашёл...
может плохо и не то искал?

Поищу, г-дето была функция уарта альтеровского, котрый совместим со стандартным 550.
Если найду - сброшу, куда бросать?
%-)
Цитата(Builder @ Dec 9 2009, 12:09) *
Поищу, г-дето была функция уарта альтеровского, котрый совместим со стандартным 550.
Если найду - сброшу, куда бросать?


electronshik85<гаф>mail.ru
только на vhdl, с верилогом туговато будет smile.gif

Цитата(des00 @ Dec 9 2009, 11:50) *
ИМХО я бы привязывался к переднему фронту сигнала WE, в этот момент tsu по адресу, данным, CE уже будет выполнен и есть еще twr времени на то что бы все операции закончить.


передний фронт - понятие разное - для разных сигналов. это который rising(0-1) или falling(1-0) при активном уровне=0 ?
Builder
Цитата(%-) @ Dec 9 2009, 10:52) *
только на vhdl, с верилогом туговато будет smile.gif

Ха, там помнится AHDL был, осилите? Искать? Это давно было, может сейчас что и на vhdl есть, но у меня с ходу нету.
Так а Вы на опен корес всё перерыли?
С ходу вот это нашёл, смотрели: http://opencores.org/project,a_vhd_16550_uart ?
Я его не анализировал, но по идее там кусок синхронизации какой-то должен быть.

Цитата(%-) @ Dec 9 2009, 10:52) *
передний фронт - понятие разное - для разных сигналов. это который rising(0-1) или falling(1-0) при активном уровне=0 ?

Насколько я понял, имеется ввиду то, что обычно врайт идёт инверсный, соответственно передний фронт - это тот,
который идёт в конце записи, которым можно защёлкивать данные с шины.


Цитата(%-) @ Dec 6 2009, 16:01) *
нужно задействовать pll в циклон-2 фпга.
на вход CLK0 подана частота с кварцевого генератора 50мгц
требуется получить частоту 150 мгц и использовать внутри фпга. на внешнюю ножку не надо.
гуру, помогите vhdl-фрагментом как юзать PLL

В Вашем случае Вам уже всё пересоветовали, т.к. мегавизард всегда чётко отрабатывал. В доках примеры есть.
Следующий этам - вкладывайте проект, где Вы вставили pll, который типа не работает.
будет у кого время - посмотрит. Скорее всего Вы просто невнимательно что-то сделали, обычно это минутное дело,
вставить визардом PLL...

Да, ещё добавлю. Близок к варианту с синхронным сбросом способ SM, когда синхронизируются два домена.
Вообще, перечитайте полностью посты по ссылке и доки, которые там есть.
Вам это думаю будет очень полезно, без иронии и обид. Т.к. Вам базовых понятий что и как работает не хватает.
http://electronix.ru/forum/index.php?showtopic=64795
И посторожнее с асинхронным сбросом! В том примере гонок нету, т.к. сброс идёт с выхода тригера.
В вашем случае, как вариант, сделайте сброс от врайта (гонок не будет, не делайте никакой логики между врайтом
и асинхронными сбросами/установками), а уже что и куда писалось - синхронно анализируйте.

Да, вот ещё не плохая ссылка smile.gif:
http://ln.com.ua/~openxs/articles/smart-qu...-ru.html#before
%-)
1) с PLL разобрался. работает

2) с памятью разобрался - адрес увеличивается исправно

3) запись в регистры глючит

обращение к регистрам когда A=0, WE=0, CE=0

пересылка данных для памяти когда A=1, WE=0, CE=0

ГЛЮК: регистры отрабатывают независимо от того A=1 или 0 - срабатывают по-любому

делал нарезку:
WE,CE,A,D

по фронту Clk проверял A, WE, CE, исходя из результатов сравнения - присваивал регистрам значения.

Обращения к регистрам сделано через порт:

*(short*)(BaseAddr+0x000) = Data

Обращение к памяти через порт:

*(short*)(BaseAddr+0x100) = Data

Нетрудно догадаться , что смещение 0x000 и 0x100 - порождается адресным битом A

Но при записи в память иногда происходит запись в регистры с какого-то перепугу.

как побороть проблему?
Builder
Может проблема в этом?
Цитата(%-) @ Dec 9 2009, 13:13) *
делал нарезку:
WE,CE,A,D

Рискну предположить что нарезаете эти сигналы независимо, что может быть не корректно.
Рекомендуется нарезать уже функцию от этих сигналов, и её анализировать.
Иначе можно ловить ситуации, когда один сигнал раньше на такт, а друго позже проходит, и из-за этого что-то не срастается.
Где-то встречал описание таких ошибок, не помню только где. Там документ был тоже по синхронизации клоковых доменов.
А вообще - код показывайте.
%-)
Цитата(Builder @ Dec 9 2009, 15:21) *
Рекомендуется нарезать уже функцию от этих сигналов, и её анализировать.
Иначе можно ловить ситуации, когда один сигнал раньше на такт, а друго позже проходит, и из-за этого что-то не срастается.
Где-то встречал описание таких ошибок, не помню только где. Там документ был тоже по синхронизации клоковых доменов.
А вообще - код показывайте.


Привожу фрагмент записи в регистры и увеличение адреса памяти:

Код
process(Clk)
begin
if rising_edge(Clk) then
  if R_M(0)='0' then
   WriteAddress:=("101000000"*Y)+X;
  else
   WriteAddress:=("010100000"*Y)+X;
  end if;
end if;
end process;

process(Clk)
begin
if rising_edge(Clk) then
  CE<=Port_CE;
  WE<=Port_WE;
  A<=Port_A;
  D<=Port_D;
end if;
end process;

process(Clk)
variable W2:std_logic_vector(8 downto 0);
variable X0:std_logic_vector(8 downto 0);
variable X1:std_logic_vector(8 downto 0);
variable H2:std_logic_vector(7 downto 0);
variable Y0:std_logic_vector(7 downto 0);
variable Y1:std_logic_vector(7 downto 0);
begin
if rising_edge(Clk) then
  if State=0 then
   if (CE='0' and WE='1') then
    State:=1;
   end if;
  else
   if (CE='0' and WE='0') then
    State:=0;
    if A='0' then
     case D(15 downto 12) is
      when "1001" =>
       R_P:=D(0);
      when "1010" =>
       R_W:=D(8 downto 0);
       W2:='0'&R_W(8 downto 1);
       X0:="010100000"-W2;
       X1:="010011111"+W2;
       X:=X0;
      when "1011" =>
       R_H:=D(7 downto 0);
       H2:='0'&R_H(7 downto 1);
       Y0:="01111000"-H2;
       Y1:="01110111"+H2;
       Y:=Y0;
      when others =>null;
     end case;
    else
     if X=X1 then
      X:=X0;
      if Y=Y1 then
       Y:=Y0;
      else
       Y:=Y+1;
      end if;
     else
      X:=X+1;
     end if;
    end if;
   end if;
  end if;
end if;
end process;

VRAM0_CE<='0';
VRAM1_CE<='0';

VRAM0_OE<=H(0) when (R_P='0' and Blank='1') else '1';
VRAM1_OE<=H(0) when (R_P='1' and Blank='1') else '1';

process(Clk)
begin
if rising_edge(Clk) then
  if A='1' then
   if R_P='0' then
    VRAM0_WE<='1';
    VRAM1_WE<=WE;
   else
    VRAM0_WE<=WE;
    VRAM1_WE<='1';
   end if;
  else
   VRAM0_WE<='1';
   VRAM1_WE<='1';
  end if;
end if;
end process;

process(Clk)
begin
if rising_edge(Clk) then
  if R_P='0' then
   VRAM0_A<=ReadAddress;
   VRAM1_A<=WriteAddress;
   VRAM0_D<=(others => 'Z');
   VRAM1_D<=D;
  else
   VRAM0_A<=WriteAddress;
   VRAM1_A<=ReadAddress;
   VRAM0_D<=D;
   VRAM1_D<=(others => 'Z');
  end if;
end if;
end process;


полный текст вложил.
des00
Цитата(%-) @ Dec 9 2009, 05:13) *
обращение к регистрам когда A=0, WE=0, CE=0

пересылка данных для памяти когда A=1, WE=0, CE=0

Обращения к регистрам сделано через порт:

*(short*)(BaseAddr+0x000) = Data

Обращение к памяти через порт:

*(short*)(BaseAddr+0x100) = Data


1. как то смещение +0x100 не вяжется с +1
2. signal tap вам в помощь
%-)
Цитата(des00 @ Dec 9 2009, 16:01) *
1. как то смещение +0x100 не вяжется с +1


данные пишим в этот порт - очень много... адрес увеличивается сам - ПЛИС выставляет после поднятия строба записи

Цитата(des00 @ Dec 9 2009, 16:01) *
2. signal tap вам в помощь


дорого обойдется
%-)
Цитата(Builder @ Dec 9 2009, 15:21) *
Рискну предположить что нарезаете эти сигналы независимо, что может быть не корректно.
Рекомендуется нарезать уже функцию от этих сигналов, и её анализировать.
Иначе можно ловить ситуации, когда один сигнал раньше на такт, а друго позже проходит, и из-за этого что-то не срастается.
Где-то встречал описание таких ошибок, не помню только где. Там документ был тоже по синхронизации клоковых доменов.


объединил в функцию WE,CE и A и результат порезал

глюкота исчезла почти совсем, но иногда проявляется одиночно...
des00
Цитата(%-) @ Dec 9 2009, 06:04) *
дорого обойдется


дорого в смысле ресурса ? ~500-800 плиток логики + пара блочков памяти в сыклонах точно найдется. я использую его даже на первых самых маленьких сыклонах при 99% забитости кристалла. Если уж вы не умеете моделировать, рекомендую хотя бы использовать сигнал тап (осваивается за 10минут).

дорого в смысле денег? собрать усб бластер можно на коленке, спаяв макетку с FTDI + максом 3000/авркой/51/и т.д. и т.п.
%-)
Цитата(des00 @ Dec 9 2009, 20:29) *
дорого в смысле ресурса ?


Google выдал что сигнал тап - это цифровой осциллограф lol.gif

Решил проблему пока так:

перед записью в регистр в командный порт засылаю 0xFFFF - так как данные значат только 15 бит, то старший бит не несёт информации. И он послужил дополнительным признаком защёлкивания.

тоесть:

*(short*)(BaseAddr+0x000)=0xFFFF; //сообщаем что будем писать в регистр A=0
*(short*)(BaseAddr+0x000)=(RegNum<<12)|(RegData); //пишем в регистр данные, RegNum=0..15 - номер регистра, Reg_Data=0..4095 - данные регистра

далее мы можем сколь угодно заливать в порт данные (пересылаем кадр) A=1:

for(i=0;i<320*240;i++) *(short*)(BaseAddr+0x100)=VideoBuffer[i];
des00
Цитата(%-) @ Dec 9 2009, 17:28) *
Google выдал что сигнал тап - это цифровой осциллограф lol.gif


ИМХО проблема в том, что вы ищете ответы не на www.altera.com, что правильно и логично, а гугле или на форуме. Не самый лучший способ.
%-)
Итак...

После осознанного перепрочтения всех своих тредов в форуме, посвященных несчастной шине обмена CPU=>FPGA, внял тому что сказал Shivers, в этой теме.

Сделал цепочку из двойных триггеров:

Код
process(C)
begin
if rising_edge(C) then
  CE1<=Port_CE;
  WE1<=Port_WE;
  A1<=Port_A;
  D1<=Port_D;
  CE2<=CE1;
  WE2<=WE1;
  A2<=A1;
  D2<=D1;
  if R_M(0)='0' then
   WriteAddress1<=("101000000"*Y)+X;
  else
   WriteAddress1<=("010100000"*Y)+X;
  end if;
  WriteAddress2<=WriteAddress1;
end if;
end process;

process(C)
variable W2:std_logic_vector(8 downto 0);
variable X0:std_logic_vector(8 downto 0);
variable X1:std_logic_vector(8 downto 0);
variable H2:std_logic_vector(7 downto 0);
variable Y0:std_logic_vector(7 downto 0);
variable Y1:std_logic_vector(7 downto 0);
begin
if rising_edge(C) then
  if(WE1='0' and WE2='1') then
   if CE2='0' then
    if A2='0' then
     case D2(15 downto 12) is
      when "1001" =>
       R_P:=D2(0);
      when "1010" =>
       R_W:=D2(8 downto 0);
       W2:='0'&R_W(8 downto 1);
       X0:="010100000"-W2;
       X1:="010011111"+W2;
       X:=X0;
      when "1011" =>
       R_H:=D2(7 downto 0);
       H2:='0'&R_H(7 downto 1);
       Y0:="01111000"-H2;
       Y1:="01110111"+H2;
       Y:=Y0;
      when others =>null;
     end case;
    else
     if X=X1 then
      X:=X0;
      if Y=Y1 then
       Y:=Y0;
      else
       Y:=Y+1;
      end if;
     else
      X:=X+1;
     end if;
    end if;
   end if;
  end if;
end if;
end process;

VRAM0_CE<='0';
VRAM1_CE<='0';

VRAM0_OE<=H(0) when (R_P='0' and Blank='1') else '1';
VRAM1_OE<=H(0) when (R_P='1' and Blank='1') else '1';

VRAM0_WE<=WE2 when (A2='1' and R_P='1') else '1';
VRAM1_WE<=WE2 when (A2='1' and R_P='0') else '1';

VRAM0_D<=D2 when R_P='1' else (others => 'Z');
VRAM1_D<=D2 when R_P='0' else (others => 'Z');

VRAM0_A<=WriteAddress2 when R_P='1' else ReadAddress;
VRAM1_A<=WriteAddress2 when R_P='0' else ReadAddress;

end VideoFlipper_Architecture;


И что вы думаете?

Фрагмент работает исправно как часы - глюков с путаницей "регистр-память" не возникло ни разу! rolleyes.gif

C - это клок с PLL = 200 МГц

С Блекфина биру только CE,WE,A,D. CLKOUT=133.3 МГц (не биру)

Устройство работает устойчиво при Tsu>=2, Tw>=1

При Tsu<2 адрес не успевает вычисляться - изобразение начинает скролиться по горизонтали и потихоньку съезжать по вертикали, что логично. Для регистров хватает.

При любом режиме с Thold>0, адрес вычисляется также некорректно.

В целом Tsu=2, Tw=1 я доволен, но интересует возможность получить более быструю времянку , например Tsu=1, Tw=1 -
возможно ли как-нибудь изменить вышеприведенный код?

С какой оптимальной (компромисс надёжность(!главное)/потребление) частотой можно нарезать данные для такого метода?

Понимаю, что des00, говорил что в 2.5 - 3 больше чем отдельный минимальный отсчёт нуля или единицы, но интересует данный случай.

P.S. а адрес с данными тоже надо нарезать - а то пиксель пишится в память размазанно влево-вправо
Builder
Цитата(%-) @ Dec 10 2009, 15:38) *
И что вы думаете?
Фрагмент работает исправно как часы - глюков с путаницей "регистр-память" не возникло ни разу! rolleyes.gif
C - это клок с PLL = 200 МГц
С Блекфина биру только CE,WE,A,D. CLKOUT=133.3 МГц (не биру)
Устройство работает устойчиво при Tsu>=2, Tw>=1
При Tsu<2 адрес не успевает вычисляться - изобразение начинает скролиться по горизонтали и потихоньку съезжать по вертикали, что логично. Для регистров хватает.
При любом режиме с Thold>0, адрес вычисляется также некорректно.
В целом Tsu=2, Tw=1 я доволен, но интересует возможность получить более быструю времянку , например Tsu=1, Tw=1 -
возможно ли как-нибудь изменить вышеприведенный код?
С какой оптимальной (компромисс надёжность(!главное)/потребление) частотой можно нарезать данные для такого метода?
Понимаю, что des00, говорил что в 2.5 - 3 больше чем отдельный минимальный отсчёт нуля или единицы, но интересует данный случай.
P.S. а адрес с данными тоже надо нарезать - а то пиксель пишится в память размазанно влево-вправо

Вы хоть поняли почему не работало и почему заработало?
Если до конца поймёте - вопросы сами отпадут.
Нет с собой архива, так и быть, раз сами не нащли, кину вечером Вам на почту ещё одну доку по синхронизации доменов.
Как-то проскакивал документик на форуме, а ранее я его находил в инете, ссылку не помню.
Там описывается что Вы сейчас сделали.
Почитаете, разберётесь. Хотя мне этот способ меньше нравится, чем тот что я предлагал первым, хотят и это тоже рабочий, если всё правильно сделать.
%-)
Цитата(Builder @ Dec 10 2009, 19:47) *
Вы хоть поняли почему не работало и почему заработало?
Если до конца поймёте - вопросы сами отпадут.


Метастабильность, мать её! smile3046.gif

Где-то по вашим ссылкам видел тему в который был прикреплён PDF-ник про метастабильность. Там про шарик на вершине холма и о цепочке двух последовательных триггеров, тактируемых одним клоком.

Насколько я понимаю, кода WE1=0 и WE2=1 - анализируется фронт сигнала и вопрос о метастабильности вообще отпадает.

Так ?

Цитата(Builder @ Dec 10 2009, 19:47) *
Нет с собой архива, так и быть, раз сами не нащли, кину вечером Вам на почту ещё одну доку по синхронизации доменов.
Как-то проскакивал документик на форуме, а ранее я его находил в инете, ссылку не помню.


Это случайно не то, о чём только что написал выше?

Цитата(Builder @ Dec 10 2009, 19:47) *
Хотя мне этот способ меньше нравится, чем тот что я предлагал первым, хотят и это тоже рабочий, если всё правильно сделать.


Хочется осознать и ваш способ. Можете в терминах моих переменных-сигналов объяснить свой метод?
А то по ранее высказанным вами предложениями не могу сделать пример.
Builder
Цитата(%-) @ Dec 11 2009, 00:43) *
Метастабильность, мать её! smile3046.gif
В том числе и она.
Цитата(%-) @ Dec 11 2009, 00:43) *
Где-то по вашим ссылкам видел тему в который был прикреплён PDF-ник про метастабильность. Там про шарик на вершине холма и о цепочке двух последовательных триггеров, тактируемых одним клоком.
Насколько я понимаю, кода WE1=0 и WE2=1 - анализируется фронт сигнала и вопрос о метастабильности вообще отпадает.
Так ?
Это случайно не то, о чём только что написал выше?
Вот файл, собственно мне добавить к тому что написаному ранее и тому что в файлах уже нечего.
Читайте темы, файлы, осознавайте.
Цитата(%-) @ Dec 11 2009, 00:43) *
Хочется осознать и ваш способ. Можете в терминах моих переменных-сигналов объяснить свой метод?
А то по ранее высказанным вами предложениями не могу сделать пример.
Перечитайте всё по ссылке, что я давал ранее, в частности пример синхронизатора от SM.
Представьте что тригер там будет асинхронно сбрасываться сигналом от проца, например WR.
Только нкакой дополнительной комбинаторики. По моему для осзания идее того примера достаточно.
С примером из UART от альтеры облом, потерял, не могу у себя найти. Но там идея та-же была,
асинхронный сброс и синхроннй анализ. Главное при реализации всё правильно сделать.

ЗЫ. не ленитесь копаться в чужиз доступных исходниках. Но сегодня в инете куча всего есть...
%-)
Цитата(Builder @ Dec 11 2009, 03:43) *
Вот файл, собственно мне добавить к тому что написаному ранее и тому что в файлах уже нечего.
Читайте темы, файлы, осознавайте


Почитал. Спасибо. Там также рассмотрен случай, когда используется комбинационная логика управляющих сигналов, что их надо объединять в функцию ДО синхронизации.
Вопрос - какие из сигналов: CE,WE,A,D являются управляющими?
Я склонен считать что CE и WE - обязательно, а вот на счёт A - не совсем уверен, потому что это - адресный бит от которого зависит распознавание "регистр-память"
И уж совсем менее склонен считать управляющим сигнал D - так как это данные, НО в старших битах - номер регистра.

Какие из них нужно объединить в функцию перед подачей на синхронизацию?

Цитата(Builder @ Dec 11 2009, 03:43) *
Перечитайте всё по ссылке, что я давал ранее, в частности пример синхронизатора от SM.



Вот его модуль:
Код
module interck2 ( in, out, clka, clkb, reset, completed);
input in, clka,clkb,reset;
output out, completed;

reg in_at_clka;
reg [1:0] out_at_clkb;

wire clra = reset | out_at_clkb[1];

always @(posedge clka or posedge clra)
  if (clra) in_at_clka <= 1'b0;
  else if (in) in_at_clka <= 1'b1;

always @(posedge clkb or posedge reset)
  if (reset) out_at_clkb <= 2'b00;
  else out_at_clkb <= {out_at_clkb[0] & !out_at_clkb[1], in_at_clka};

assign out = out_at_clkb[1];

reg [1:0] cmpl_at_clka;
reg cmpl_at_clkb;
wire clrb = reset | cmpl_at_clka[1];

always @(posedge clkb or posedge clrb)
  if (clrb) cmpl_at_clkb <= 1'b0;
  else if (out_at_clkb[1]) cmpl_at_clkb <= 1'b1;

always @(posedge clka or posedge reset)
  if (reset) cmpl_at_clka <= 2'h0; else
  cmpl_at_clka <= {cmpl_at_clka[0] & !cmpl_at_clka[1], cmpl_at_clkb};

assign completed = cmpl_at_clka[1];

endmodule


Честно говоря мало чего понял, потому что:

1) verilog
2) непонятны назначения сигналов
3) и как это примениить в моём случае?

Цитата(Builder @ Dec 11 2009, 03:43) *
Представьте что тригер там будет асинхронно сбрасываться сигналом от проца, например WR.
Только нкакой дополнительной комбинаторики. По моему для осзания идее того примера достаточно.


а вы можете куском кода, а то на словах как-то не сильно улавливаю суть явлений...

Цитата(Builder @ Dec 11 2009, 03:43) *
ЗЫ. не ленитесь копаться в чужиз доступных исходниках. Но сегодня в инете куча всего есть...


у меня уже все ссылки красные в поисковике laughing.gif
des00
Цитата(%-) @ Dec 10 2009, 07:38) *
При любом режиме с Thold>0, адрес вычисляется также некорректно.

если верить времянкам что вы привели, вот это очень странно. Th со стороны проца влиять не должен, т.к. в это время он не изменяет состояние линий CS/A/D/WE.

Цитата
P.S. а адрес с данными тоже надо нарезать - а то пиксель пишится в память размазанно влево-вправо

на одном триггере можно и хлопнуть, а вот 2 триггера ИМХО излишне.

Цитата
Там также рассмотрен случай, когда используется комбинационная логика управляющих сигналов, что их надо объединять в функцию ДО синхронизации.
Вопрос - какие из сигналов: CE,WE,A,D являются управляющими?
Я склонен считать что CE и WE - обязательно, а вот на счёт A - не совсем уверен, потому что это - адресный бит от которого зависит распознавание "регистр-память"
И уж совсем менее склонен считать управляющим сигнал D - так как это данные, НО в старших битах - номер регистра.

Если верить времянкам что вы привели и вы используете только запись то ИМХО управляющий сигнал здесь один WE. И обрабатывал я бы его по первому (спадающему фронту) Т.е. в начале фазы записи twr. CE/A/D к этому моменту должны быть уже установлены и удерживаться в фиксированном положении (tsu). WE нарезал бы на 3-х триггерах, последние 2 использовал для детектора фронта. Если на длительности сигнала не менее 2 отсчетов тактовой нарезки, то все должно работать с полпинка при времянках Tsu >= 1, Twr = 1, Th >= 0.

Цитата
у меня уже все ссылки красные в поисковике laughing.gif

еще раз : нужно не гугл читать, а www.altera.com там всё есть. кроме того надо не просто читать, нужно еще и понимать что читаешь.

PS. владеть обоими языками ХДЛ не обязательно, но уметь читать надо оба.
PPS. и ваш VHDL код я бы переписал, на начальном этапе увлечение VHDL variable до добра не доведет. Да и читать ваш код из-за этого сложно.
%-)
Цитата(des00 @ Dec 11 2009, 08:01) *
если верить времянкам что вы привели, вот это очень странно. Th со стороны проца влиять не должен, т.к. в это время он не изменяет состояние линий CS/A/D/WE.


зато есть разница, когда вычислять адрес.
ИМХО не совсем корректно считать адрес по опусканию строба записи - так как можно ещё нитуда записать

Об этом (уже не помню кто) говорил - что лучше по фронту хватать данные, а не по спаду

Кстати, много подключал асиков к шине блекфина - так ни одно из них не работало корректно с Thold>0. Почему - не знаю smile.gif

Цитата(des00 @ Dec 11 2009, 08:01) *
на одном триггере можно и хлопнуть, а вот 2 триггера ИМХО излишне.


попробуем

Цитата(des00 @ Dec 11 2009, 08:01) *
Если верить времянкам что вы привели и вы используете только запись то ИМХО управляющий сигнал здесь один WE. И обрабатывал я бы его по первому (спадающему фронту) Т.е. в начале фазы записи twr. CE/A/D к этому моменту должны быть уже установлены и удерживаться в фиксированном положении (tsu). WE нарезал бы на 3-х триггерах, последние 2 использовал для детектора фронта. Если на длительности сигнала не менее 2 отсчетов тактовой нарезки, то все должно работать с полпинка при времянках Tsu >= 1, Twr = 1, Th >= 0.


осмыслю сказанное вами, попробую. результат напишу. Не забывайте также что у меня SRAM 10ns - как она поведёт на Twr=1 (7.5ns) - ещё не известно smile.gif

Цитата(des00 @ Dec 11 2009, 08:01) *
PPS. и ваш VHDL код я бы переписал, на начальном этапе увлечение VHDL variable до добра не доведет. Да и читать ваш код из-за этого сложно.


переменные хранят значения только управляющих регистров. и всё.

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

в чём опасность использования переменных - конкретно в моём коде - где и каких?
des00
Цитата(%-) @ Dec 10 2009, 23:35) *
зато есть разница, когда вычислять адрес.
ИМХО не совсем корректно считать адрес по опусканию строба записи - так как можно ещё нитуда записать
осмыслю сказанное вами, попробую. результат напишу. Не забывайте также что у меня SRAM 10ns - как она поведёт на Twr=1 (7.5ns) - ещё не известно smile.gif

уже советовал вам разделить фазы обращения проца к фпга и обращения фпга к памяти, а не делать их одновременно.

Цитата
Об этом (уже не помню кто) говорил - что лучше по фронту хватать данные, а не по спаду

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

Цитата
Кстати, много подключал асиков к шине блекфина - так ни одно из них не работало корректно с Thold>0. Почему - не знаю smile.gif

осцил в руки и смотреть, ад не выполняет собственных спецификаций?

Цитата
различия между сигналами и переменными представляю - сигнал апдейтится только при следующем клоке, а переменная мгновено. Это если синхронная логика и процесс последовательный. При параллельном они одинаковы.


далеко не факт. например ваш код

Код
      
when "1011" =>
       R_H:=D(7 downto 0);
       H2:='0'&R_H(7 downto 1);
       Y0:="01111000"-H2;
       Y1:="01110111"+H2;
       Y:=Y0;


исходя из описания (считаем что другого кода, который обращается к этим переменным нет) Y/Y1 будут регистрами, остальное выродиться в комбинационную логику. Т.е. этот код аналог вот этого

Код
when "1011" =>
       Y <="01111000"-(0'&D(7 downto 1));
       Y1 <="01110111"+(0'&D(7 downto 1));
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.