|
|
  |
pll в цык-2, как сделать |
|
|
|
Dec 9 2009, 09:16
|
iBuilder©
   
Группа: Свой
Сообщений: 519
Регистрация: 14-07-04
Из: Минск
Пользователь №: 322

|
Цитата(%-) @ Dec 9 2009, 10:52)  только на vhdl, с верилогом туговато будет  Ха, там помнится 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И посторожнее с асинхронным сбросом! В том примере гонок нету, т.к. сброс идёт с выхода тригера. В вашем случае, как вариант, сделайте сброс от врайта (гонок не будет, не делайте никакой логики между врайтом и асинхронными сбросами/установками), а уже что и куда писалось - синхронно анализируйте. Да, вот ещё не плохая ссылка  : http://ln.com.ua/~openxs/articles/smart-qu...-ru.html#before
Сообщение отредактировал Builder - Dec 9 2009, 09:29
|
|
|
|
|
Dec 9 2009, 11:13
|
Частый гость
 
Группа: Участник
Сообщений: 118
Регистрация: 13-09-09
Пользователь №: 52 331

|
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
Но при записи в память иногда происходит запись в регистры с какого-то перепугу.
как побороть проблему?
|
|
|
|
|
Dec 9 2009, 11:21
|
iBuilder©
   
Группа: Свой
Сообщений: 519
Регистрация: 14-07-04
Из: Минск
Пользователь №: 322

|
Может проблема в этом? Цитата(%-) @ Dec 9 2009, 13:13)  делал нарезку: WE,CE,A,D Рискну предположить что нарезаете эти сигналы независимо, что может быть не корректно. Рекомендуется нарезать уже функцию от этих сигналов, и её анализировать. Иначе можно ловить ситуации, когда один сигнал раньше на такт, а друго позже проходит, и из-за этого что-то не срастается. Где-то встречал описание таких ошибок, не помню только где. Там документ был тоже по синхронизации клоковых доменов. А вообще - код показывайте.
|
|
|
|
|
Dec 9 2009, 11:47
|
Частый гость
 
Группа: Участник
Сообщений: 118
Регистрация: 13-09-09
Пользователь №: 52 331

|
Цитата(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; полный текст вложил.
|
|
|
|
|
Dec 9 2009, 12:04
|
Частый гость
 
Группа: Участник
Сообщений: 118
Регистрация: 13-09-09
Пользователь №: 52 331

|
Цитата(des00 @ Dec 9 2009, 16:01)  1. как то смещение +0x100 не вяжется с +1 данные пишим в этот порт - очень много... адрес увеличивается сам - ПЛИС выставляет после поднятия строба записи Цитата(des00 @ Dec 9 2009, 16:01)  2. signal tap вам в помощь дорого обойдется
|
|
|
|
|
Dec 9 2009, 13:25
|
Частый гость
 
Группа: Участник
Сообщений: 118
Регистрация: 13-09-09
Пользователь №: 52 331

|
Цитата(Builder @ Dec 9 2009, 15:21)  Рискну предположить что нарезаете эти сигналы независимо, что может быть не корректно. Рекомендуется нарезать уже функцию от этих сигналов, и её анализировать. Иначе можно ловить ситуации, когда один сигнал раньше на такт, а друго позже проходит, и из-за этого что-то не срастается. Где-то встречал описание таких ошибок, не помню только где. Там документ был тоже по синхронизации клоковых доменов. объединил в функцию WE,CE и A и результат порезал глюкота исчезла почти совсем, но иногда проявляется одиночно...
|
|
|
|
|
Dec 9 2009, 23:28
|
Частый гость
 
Группа: Участник
Сообщений: 118
Регистрация: 13-09-09
Пользователь №: 52 331

|
Цитата(des00 @ Dec 9 2009, 20:29)  дорого в смысле ресурса ? Google выдал что сигнал тап - это цифровой осциллограф Решил проблему пока так: перед записью в регистр в командный порт засылаю 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];
|
|
|
|
|
Dec 10 2009, 13:38
|
Частый гость
 
Группа: Участник
Сообщений: 118
Регистрация: 13-09-09
Пользователь №: 52 331

|
Итак... После осознанного перепрочтения всех своих тредов в форуме, посвященных несчастной шине обмена 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; И что вы думаете? Фрагмент работает исправно как часы - глюков с путаницей "регистр-память" не возникло ни разу! 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. а адрес с данными тоже надо нарезать - а то пиксель пишится в память размазанно влево-вправо
Сообщение отредактировал %-) - Dec 10 2009, 13:40
|
|
|
|
|
Dec 10 2009, 16:47
|
iBuilder©
   
Группа: Свой
Сообщений: 519
Регистрация: 14-07-04
Из: Минск
Пользователь №: 322

|
Цитата(%-) @ Dec 10 2009, 15:38)  И что вы думаете? Фрагмент работает исправно как часы - глюков с путаницей "регистр-память" не возникло ни разу! 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. а адрес с данными тоже надо нарезать - а то пиксель пишится в память размазанно влево-вправо Вы хоть поняли почему не работало и почему заработало? Если до конца поймёте - вопросы сами отпадут. Нет с собой архива, так и быть, раз сами не нащли, кину вечером Вам на почту ещё одну доку по синхронизации доменов. Как-то проскакивал документик на форуме, а ранее я его находил в инете, ссылку не помню. Там описывается что Вы сейчас сделали. Почитаете, разберётесь. Хотя мне этот способ меньше нравится, чем тот что я предлагал первым, хотят и это тоже рабочий, если всё правильно сделать.
|
|
|
|
|
Dec 10 2009, 22:43
|
Частый гость
 
Группа: Участник
Сообщений: 118
Регистрация: 13-09-09
Пользователь №: 52 331

|
Цитата(Builder @ Dec 10 2009, 19:47)  Вы хоть поняли почему не работало и почему заработало? Если до конца поймёте - вопросы сами отпадут. Метастабильность, мать её! Где-то по вашим ссылкам видел тему в который был прикреплён PDF-ник про метастабильность. Там про шарик на вершине холма и о цепочке двух последовательных триггеров, тактируемых одним клоком. Насколько я понимаю, кода WE1=0 и WE2=1 - анализируется фронт сигнала и вопрос о метастабильности вообще отпадает. Так ? Цитата(Builder @ Dec 10 2009, 19:47)  Нет с собой архива, так и быть, раз сами не нащли, кину вечером Вам на почту ещё одну доку по синхронизации доменов. Как-то проскакивал документик на форуме, а ранее я его находил в инете, ссылку не помню. Это случайно не то, о чём только что написал выше? Цитата(Builder @ Dec 10 2009, 19:47)  Хотя мне этот способ меньше нравится, чем тот что я предлагал первым, хотят и это тоже рабочий, если всё правильно сделать. Хочется осознать и ваш способ. Можете в терминах моих переменных-сигналов объяснить свой метод? А то по ранее высказанным вами предложениями не могу сделать пример.
|
|
|
|
|
Dec 11 2009, 00:43
|
iBuilder©
   
Группа: Свой
Сообщений: 519
Регистрация: 14-07-04
Из: Минск
Пользователь №: 322

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

|
Цитата(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)  ЗЫ. не ленитесь копаться в чужиз доступных исходниках. Но сегодня в инете куча всего есть... у меня уже все ссылки красные в поисковике
|
|
|
|
|
  |
2 чел. читают эту тему (гостей: 2, скрытых пользователей: 0)
Пользователей: 0
|
|
|