|
Магический пин P143 на spartan 6, Крайне странное поведение схемы, или я сделал что-то очень глупое... |
|
|
|
Oct 17 2013, 14:41
|

Местный
  
Группа: Свой
Сообщений: 323
Регистрация: 14-12-10
Из: Королёв
Пользователь №: 61 599

|
Цитата(Golikov A. @ Oct 17 2013, 17:02)  Нет не правильно! Читаете плохо видать. Вывод сигнала ресет через другой пин не вызывает варнинга и все работает. Вывод константы 1 0 любого сигнала через 143 пин вызывает варнинг и все падает.
ничего этим не сказано... Это варнинг появляется от 143 пина... Внимание не на варнинг а на то что он появляется
Да вот уже все даташиты проглядел. Реально магия какая то. Ща до проекта добирусь проверю не подбрасывается ли глобальный ресет. Это последние что хоть как то рационально объясняет происходящее 1. Попробуйте вместо always @(posedge CLK) использовать CLK как разрешение счета always @(posedge main_clk) if(reset) .. else if(CLK) .. 2. Попробуйте Ваш выход на ножку подтактировать main_clk
|
|
|
|
|
Oct 17 2013, 15:08
|
Знающий
   
Группа: Свой
Сообщений: 702
Регистрация: 8-06-06
Пользователь №: 17 871

|
Цитата(Golikov A. @ Oct 17 2013, 11:06)  всей схемы просто подтянут к земле
NET "glb_reset" PULLDOWN;
не нашлось ему как то сначала ноги, а потом про него забыли... Может так нельзя? Так нельзя! Это лишь означает, что ограничений на этот порт нет и его можно развести на любую ножку. Посмотрите pad report, там будет видно, куда плейсер пихнул этот пин. Возможно, как раз на ваш магический P143. А может, ваши проблемы с этим и не связаны. НО в любом случае, оставлять порт без LOC нельзя. Цитата(Golikov A. @ Oct 16 2013, 21:54)  в куске кода Код output port143;
assign port143 = ~reset;
if (reset) CLK<=1'b0; else begin if(clk_dev < DEVIDER) clk_dev <= clk_dev + 1; else begin clk_dev <=0; CLK<=~CLK; end end Интересно, и какая же частота ожидается на CLK? Пока этот абсолютно не корректный асинхронный код не исправлен, двигаться дальше нельзя.
|
|
|
|
|
Oct 17 2013, 15:53
|
Гуру
     
Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454

|
Цитата(Sergey_Bekrenyov @ Oct 17 2013, 18:41)  1. Попробуйте вместо always @(posedge CLK) использовать CLK как разрешение счета
always @(posedge main_clk) if(reset) .. else if(CLK) ..
2. Попробуйте Ваш выход на ножку подтактировать main_clk выход на ножку тактировать пробовал, теже... только в профиль CLK я не использую в конструкциях типа always внутри проекта, он используется в клок форвардинге через выходной DDR. Цитата(Flood @ Oct 17 2013, 19:08)  Так нельзя! Это лишь означает, что ограничений на этот порт нет и его можно развести на любую ножку. Посмотрите pad report, там будет видно, куда плейсер пихнул этот пин. Возможно, как раз на ваш магический P143. А может, ваши проблемы с этим и не связаны. НО в любом случае, оставлять порт без LOC нельзя.
Интересно, и какая же частота ожидается на CLK? Пока этот абсолютно не корректный асинхронный код не исправлен, двигаться дальше нельзя. Забыл я про эту ножку, какой - то из ответов навел меня на мысль о ней. Есть вариант что 143 пин это последний оставшийся не занятый пин, и когда я его подключаю ресету не находится места. А можно как то LOC на землю сделать? понятно что можно внутри проекта ее занулить, но вот в констраине нет такого инструмента? (это я для общего развития) Насчет куска кода - он выдран из контекста, но не приведя полного кода я так понял меня будут клевать Код reg CLK = 1; reg INV_CLK = 0; reg [3:0] Devider = 0; localparam DIV_CONST = 2;
always @(posedge main_clk) begin if(reset == 1'b1) begin CLK <= 1'b1; INV_CLK <= 1'b0; Divider <= 0; end else begin if(Divider < DIV_CONST) Divider <= Divider + 1; else begin CLK <= ~CLK; INV_CLK <= ~INV_CLK; Divider <= 0; end end end я еще и ошибку в написании делителя исправил  круто да? теперь то точно заработает как надо... ну я надеюсь понятно что ресет это сигнал, Далее CLK и INV_CLK идут как клок и инверсный клок на выходной DDR, в качестве данных на который поданы 1 и 0, и в результате на ножке получается клоковый сигнал. Эта схема клок форвардинга предложенная xilinx, позволяет не задействовав глобальных клоковых буферов выводить наружу клок. Причем прелесть схемы такова что может работать не только posedge main_clk а по обоим фронтам always @(posedge main_clk or negedge main_clk) и получать делитель клока не только на четные значения, но и на нечетные. так вот что еще интересно в этой ситуации варнинга на CLK нет, есть только на INV_CLK. Я допускаю что синтезатор рюхнул что один сигнал инверсия другого, потому сигнал в варнинге остался один. Но все равно странно, почему вывод наружу ресета, сделал этот сигнал непойми чем... П.С. кусок кода я не копировал из проекта, написал просто еще раз, так что заметив опечатки не начинайте кричать что нашли из-за чего все не работает....
|
|
|
|
|
Oct 17 2013, 16:53
|
Знающий
   
Группа: Свой
Сообщений: 702
Регистрация: 8-06-06
Пользователь №: 17 871

|
Цитата(Golikov A. @ Oct 17 2013, 19:53)  Забыл я про эту ножку, какой - то из ответов навел меня на мысль о ней. Есть вариант что 143 пин это последний оставшийся не занятый пин, и когда я его подключаю ресету не находится места. Смысл гадать? Посмотрите pad report (файл .pad). Там будет видно, куда оказался посажен ресет. Если такой внешний пин не нужен, правильнее всего убрать его из портов топ-левела.
|
|
|
|
|
Oct 17 2013, 18:17
|
Гуру
     
Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454

|
Ура! ну вообщем победа. Как собственно и думал, любая магия - это следствие какой - то большой глупости. Оставленный без присмотра пин глобального ресета всего и вся (этож надо было именно этот пин без присмотра оставить) изначально как раз выходил на 143 порт, а на нем держится ноль, плюс подтяжка и все работало. с выводом другого сигнала на 143 пин, глобальный ресет перевесился на ножку входную от внешнего устройства, которая на данный момент никуда не назначена. Внешнее устройство решили не использовать в этом проекте. Там какая - то оптическая развязка, наверняка в свободном положении она дает 1 и держит схему в ресете (Я не очень хочу сейчас лазить с тестером по плате, это немного не удобно). Ну и со всеми вытекающими схема в вечном ресете. Спасибо всем кто вник в тему и привел меня к нахождению этого косячка. Люблю устранять все странности, потому что изначально любая странность - это потенциальная ошибка... На сладкое осталось понять почему после вывода ресета наружу пин стал комбинаторной логикой, и как это победить. Цитата(ASN @ Oct 17 2013, 20:59)  Golikov A Дайте, пожалуйста, ссылочку на где есть схема клок форвардинга предложенная xilinx. IMHO, У Spartan 6 достаточно выходов PLL, чтобы не задействовать для формирования частот ещё и логику. Как тогда контролировать сдвиг частот при трассировке ? дело было так: написал я делитель клока по обоим фронтам входного клока работающий и вывел его на ножку. После чего получил то ли варнинг, то ли еррор что так нельзя и не есть правильно, и предложение прям в этом же сообщении использовать DDR для клок форвардинга. После чего было написано в яндексе и гугле clock forward DDR, и получены ссылки типа http://forums.xilinx.com/t5/Spartan-Family...-IO/td-p/212825я не помню точно какую их них тыкал, но сути не меняет. там я нашел рецеп Verilog > Synthesis Constructs > Coding Examples > Misc > Output Clock Forwarding Using DDR вот... Как я понимаю проблему: даже сделав клок на ПЛЛ чтобы выдать его на ружу будет задействован глобальный клоковый буфер, которых не так много. А вот ДДР на выходе стоит на каждой ножке, так чего не использовать его?.... В моем случае я делаю клок ручками потому что мне надо синхронизовать с ним поведение еще нескольких сигналов, может я ошибаюсь, но мне показалась такая схема более простой, и я пошел по этому решению. Тем более что в примерах был клок форвардинг, и он же обсуждался на форуме. Ну вот и с последним разобрался. Это мне синтезатор помог он увидел что INV_MCLK инверсия MCLK, (как догадался...) и устранил его при оптимизации, а когда дошло до размещения INV_MCLK стал комбинаторным ну и так далее, варнинг выпрыгнул... оставил MCLK регистром INV_MCLK сделал Код wire INV_MCLK assign INV_MCLK = ~ MCLK. теперь все счастливы....
|
|
|
|
|
Oct 18 2013, 06:54
|

Знающий
   
Группа: Свой
Сообщений: 680
Регистрация: 11-02-08
Из: Msk
Пользователь №: 34 950

|
Код не слишком корректный, может поэтому синтезатор/мэппер и корежит. Я бы разделил конструкции для облегчения работы синтезатора как то так: Код always @(posedge main_clk) begin if(reset == 1'b1) begin CLK <= 1'b1; INV_CLK <= 1'b0; end else begin if(Divider[3:0] != DIV_CONST) begin CLK <= ~CLK; INV_CLK <= ~INV_CLK; end end
always @(posedge main_clk) if( reset | Divider[3:0] == DIV_CONST) Divider[3:0] <= 4'h0; else Divider[3:0] <= Divider[3:0] + 4'h1; По хорошему сброс желательно еще и асинхронным сделать, но это уже надо смотреть мануал на ПЛИС, как LUT устроен. С асинхронным сбросом будет так: Код assign resetn = ~reset;
always @(posedge main_clk or negedge resetn) begin if(~resetn) begin CLK <= 1'b1; INV_CLK <= 1'b0; end else if(Divider[3:0] != DIV_CONST) begin CLK <= ~CLK; INV_CLK <= ~INV_CLK; end
always @(posedge main_clk or negedge resetn) if( ~resetn) Divider[3:0] <= 4'h0; else if(Divider[3:0] != DIV_CONST) Divider[3:0] <= Divider[3:0] + 4'h1; else Divider[3:0] <= 4'h0; Последний код будет точнее всего синтезироваться, поскольку явно описаны сигналы сброса и разрешения. Еще, непонятно назначение CLK и CLK_INV - это просто деление входной частоты пополам, сигнал разрешения можно убрать, т.к. он все равно у вас не работает. Код always @(posedge main_clk or negedge resetn) begin if(~resetn) begin CLK <= 1'b1; INV_CLK <= 1'b0; end else begin CLK <= ~CLK; INV_CLK <= ~INV_CLK; end Последнее замечание. Если CLK и CLK_INV будут где то использоваться в качестве клоков, то надо их объявить как то так: create_generated_clock CLK CLK -source main_clk -divide_by 2 create_generated_clock CLK_INV -source main_clk -divide_by 2 -invert синтаксис может отличаться, но суть, я надеюсь, понятна.
|
|
|
|
|
Oct 18 2013, 14:39
|

Знающий
   
Группа: Свой
Сообщений: 680
Регистрация: 11-02-08
Из: Msk
Пользователь №: 34 950

|
Напишу по поводу асинхронного сброса. Если сброс синхронный, это по сути еще один аргумент функции входа. А значит, более сложная комбинаторика и как следствие - медленная схема. Недостатки асинхронного сброса (хреновая помехоустойчивость) - понятны.
Поэтому, идут на компромисс, который хорошо ложится на синтез (проверьте, что его поддерживает LUT вашей ПЛИС): сбросы в триггерах используют асинхронно, но источник сброса - выход триггера, т.е. синхронный. Причем в каждом клоковом домене должен быть свой синхронизированный к этому клоку сигнал сброса, который, как я уже писал, используется асинхронно. Можете поэкспериментировать, на большом проекте использование асинхронного сброса повысит FMAX и уменьшит площадь.
И еще, синхронизацию лучше делать не одним триггером, а двумя, а в некоторой литературе пишут даже про три триггера.
|
|
|
|
|
Oct 18 2013, 17:51
|
Гуру
     
Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454

|
Цитата(Shivers @ Oct 18 2013, 18:39)  Напишу по поводу асинхронного сброса. Если сброс синхронный, это по сути еще один аргумент функции входа. А значит, более сложная комбинаторика и как следствие - медленная схема. Недостатки асинхронного сброса (хреновая помехоустойчивость) - понятны.
Поэтому, идут на компромисс, который хорошо ложится на синтез (проверьте, что его поддерживает LUT вашей ПЛИС): сбросы в триггерах используют асинхронно, но источник сброса - выход триггера, т.е. синхронный. Причем в каждом клоковом домене должен быть свой синхронизированный к этому клоку сигнал сброса, который, как я уже писал, используется асинхронно. Можете поэкспериментировать, на большом проекте использование асинхронного сброса повысит FMAX и уменьшит площадь.
И еще, синхронизацию лучше делать не одним триггером, а двумя, а в некоторой литературе пишут даже про три триггера. ну синхронный сброс всяко будет меньше асинхронного или нет? Я как то не страдаю от синхронности сброса. Иногда да бывает надо, но тут как то все синхронное легко легло на проект и все... 2 триггера - это известная штука, для выравнивания фронта внешнего сигнала для всех модулей, но если сигнал идет только на один модуль, то вроде как и без триггера обойтись можно... зачем 3 нужно не знаю...
|
|
|
|
|
Oct 18 2013, 19:34
|

Lazy
     
Группа: Свой
Сообщений: 2 070
Регистрация: 21-06-04
Из: Ukraine
Пользователь №: 76

|
Цитата(Golikov A. @ Oct 18 2013, 20:51)  ну синхронный сброс всяко будет меньше асинхронного или нет? Я как то не страдаю от синхронности сброса. Иногда да бывает надо, но тут как то все синхронное легко легло на проект и все...
2 триггера - это известная штука, для выравнивания фронта внешнего сигнала для всех модулей, но если сигнал идет только на один модуль, то вроде как и без триггера обойтись можно... зачем 3 нужно не знаю... Гуглите. Обсуждалось миллион раз. В общем случае защита от метастабильности + синхронная установка сброса и асинхронное снятие. P.S. причем для каждого клокового домена это надо делать отдельно.
--------------------
"Everything should be made as simple as possible, but not simpler." - Albert Einstein
|
|
|
|
|
Oct 18 2013, 21:02
|
Гуру
     
Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454

|
Цитата(Victor® @ Oct 18 2013, 23:34)  Гуглите. Обсуждалось миллион раз. В общем случае защита от метастабильности + синхронная установка сброса и асинхронное снятие.
P.S. причем для каждого клокового домена это надо делать отдельно. так после миллионов обсуждений не сошлись на том что 2 хватит? Цитата(Victor® @ Oct 18 2013, 23:34)  синхронная установка сброса и асинхронное снятие. нашел что схема с синхронным сбросом "больше" схемы с асинхронным, ибо у триггера есть такой вход, а так приходиться на входе городить мультиплексор. А учитывая что есть и вход установки, то асинхронные схемы могут быть реально меньше и быстрее их синхронных коллег. Правильно я понимаю?
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|