Golikov 0 June 19, 2014 Posted June 19, 2014 · Report post переразвели проект - по новой в плис все легло думаю об этом. Но что могло привести к тому что один и тот же текст, в одних и тех же настройках оптимизатор развелся по разному? то есть был текст - разводка не работает изменение - разводка - работает откат изменений обратно - разводка - работает... почитал про фланстер, заключение прикольное... но по сути я его и реализовал... даже не знал что у меня в схеме какие то фланстеры завелись... Quote Share this post Link to post Share on other sites More sharing options...
Maverick_ 16 June 19, 2014 Posted June 19, 2014 · Report post Хорошее решение (правда не думал о нем), но зараза клок SPI пропадает по приему слова (как уже сказали выше). Фактически я и горожу 1 словное фифо со всеми вытекающими. Принимаю данные в буфер, и ставлю сигнал есть данные. Ваш сигнал spi_cs служит для записи данных (типа write/read enable у блочной памяти), Вы по мере поступления данных сразу записываете в фифо (это также переноситься на чтение из фифо). Здесь фифо на входе однобитное (для SPI), на выходе нужная Вам разрядность (преимущества двупортовой памяти). В подтверждение моих слов смотрим "SPI Block Diagram Figure 19-1: SPI Block Diagram" в описании корки - если так делают производители значит так можно делать (берем даташит на корку (здесь альтера)) - блок фифо присутствует как на прием, так и на выдачу данных. PS надо будет самому "поиграться" и проверить, чтобы сказать точно (для Ваших соотношений частот) - правильное решение или нет... Но идея вроде правильная... Quote Share this post Link to post Share on other sites More sharing options...
Golikov 0 June 19, 2014 Posted June 19, 2014 · Report post да идея очень правильная. У меня пока только выигрыш в том что я во время приема сообщения еще считаю контрольную сумму, а тут это надо будет сделать либо параллельным блоком, либо после приема. 2 однобитных фифо на прием и передачу, чип селкт лучше не как разрешение, а как сброс. чтобы всегда можно было привести в исходное состояние начала передачи и всех делов... Интересное решение, не подумал как-то про разнобитный вход - выход... а что с этим always @(posedge clk) begin if(spi_cs == 1'b1) begin WR <= 1'b0; RD <= 1'b0; Data <= 0; Addr <= 0; end end spi_cs - внешний сигнал, который не синхронизирован с клоком и не пропущен через 2 триггера. Addr - это one hot адрес, то есть там все нули и всего одна единичка. Так вот мне кажется ни при каких раскладах не может так получится что выполняя эту конструкцию в адресе загорится другая единичка. То есть может ли 001 снимаясь перейти в 010 или 011? Мне кажется не может, если бы в адресе было много бит, то да, часть снялась, часть не снялась, сигнал RW мог тоже не снятся и фактически произошла бы запись в другой адрес. Но в случае если в векторе всего 1 единичка, никакая мета стабильность не может ее сдвинуть, ведь так? Quote Share this post Link to post Share on other sites More sharing options...
Maverick_ 16 June 19, 2014 Posted June 19, 2014 · Report post да идея очень правильная. У меня пока только выигрыш в том что я во время приема сообщения еще считаю контрольную сумму, а тут это надо будет сделать либо параллельным блоком, либо после приема. 2 однобитных фифо на прием и передачу, чип селкт лучше не как разрешение, а как сброс. чтобы всегда можно было привести в исходное состояние начала передачи и всех делов... Интересное решение, не подумал как-то про разнобитный вход - выход... а что с этим always @(posedge clk) begin if(spi_cs == 1'b1) begin WR <= 1'b0; RD <= 1'b0; Data <= 0; Addr <= 0; end end spi_cs - внешний сигнал, который не синхронизирован с клоком и не пропущен через 2 триггера. Addr - это one hot адрес, то есть там все нули и всего одна единичка. Так вот мне кажется ни при каких раскладах не может так получится что выполняя эту конструкцию в адресе загорится другая единичка. То есть может ли 001 снимаясь перейти в 010 или 011? Мне кажется не может, если бы в адресе было много бит, то да, часть снялась, часть не снялась, сигнал RW мог тоже не снятся и фактически произошла бы запись в другой адрес. Но в случае если в векторе всего 1 единичка, никакая мета стабильность не может ее сдвинуть, ведь так? кажется/возможно я чего-то не до понимаю... Зачем сбрасывать?... Допустим Вам пришел сигнал обновить данные (как Вы написали привести в исходное состояние). Вы просто не берете в обработку старые данные находящиеся в фифо... Схема записи/чтения из SPI в FIFO и наоборот на мой взгляд должна крутиться не зависимо и постоянно. Далее Вы делаете схему обработку счетчиков с фифо и сигнала обновления данных - данные счетчиков фифо Вы можете перенести из клоковых доменов (например при генерации корки фифо это возможно сделать) - соответственно по ним(счетчикам) определяете, где старые данные, а где уже новые данные... Старые данные естественно в обработку после сигнала обновления данных не идут... Да будет пауза, но думаю это не столь проблематично - в принципе паузу можно убрать если заменить FIFO на какую-то свою схему - обеспечивающую смещение адресов/счетчиков на длину старых данных в момент прихода сигнала обновить данные (как Вы написали привести в исходное состояние).... PS Просто напоминаю, в фифо используется счетчики Грея - где меняется только один разряд.... Это мое мнение и видение... Quote Share this post Link to post Share on other sites More sharing options...
Golikov 0 June 19, 2014 Posted June 19, 2014 · Report post Я попробовал, в ксалинксе есть одна трудность фифо только 1 в 8 максимум, и 8 в 1, если надо больше бит на выходе, то и на вход надо больше. На самом деле может это и не плохо, можно побайтно контрольную сумму считать. Зачем нужен сброс: Если передастся часть сообщения (ошибка процессора, неисправный сигнал, сброс процессора, мало ли что) то до получения полного сообщения на выходе придется допринять первое сообщение, если процессор не знает что идет доприем нового сообщения, то как следствие сбой всей синхронизации (начало нового пойдет в конец, а конец нового создаст опять полумертвое сообщение в фифо). Даже просто момент начальной инициализации, мало ли что там на ногах проца было пока все запускалось... Я всегда когда нет обращения к плис поднимаю чип селект, и она переходит в начальное состояние, что придет на вход - это начало сообщения. Мне показалось что так просто надежнее... ну и второй момент, как сигнал окончания обмена. Когда со всех внутренних модулей можно снять данные. Можно конечно по времени, но мне показалось так удобнее... Проц ставит чип селект, шлет сообщение, оно доходит до модуля, тот ставит сигнал что получил или что ошибка контрольной суммы, это сигнал доходит до проца, и тот снимает чип селект (отмечая себе результат транзакции), что в свою очередь снимает выбор модуля и т.д. Пока проц держит чипселект, все сигналы стоят. Так я могу прервать транзакцию до ее завершения если надо, и всегда проследить результат, а также я могу работать с модулями которые готовят-сохраняют данные сколь угодно долго, и всегда знаю момент когда данные сохранены. Quote Share this post Link to post Share on other sites More sharing options...
Maverick_ 16 June 19, 2014 Posted June 19, 2014 · Report post Я попробовал, в ксалинксе есть одна трудность фифо только 1 в 8 максимум, и 8 в 1, если надо больше бит на выходе, то и на вход надо больше. На самом деле может это и не плохо, можно побайтно контрольную сумму считать. Зачем нужен сброс: Если передастся часть сообщения (ошибка процессора, неисправный сигнал, сброс процессора, мало ли что) то до получения полного сообщения на выходе придется допринять первое сообщение, если процессор не знает что идет доприем нового сообщения, то как следствие сбой всей синхронизации (начало нового пойдет в конец, а конец нового создаст опять полумертвое сообщение в фифо). Даже просто момент начальной инициализации, мало ли что там на ногах проца было пока все запускалось... Я всегда когда нет обращения к плис поднимаю чип селект, и она переходит в начальное состояние, что придет на вход - это начало сообщения. Мне показалось что так просто надежнее... предложенный вариант обхода сброса Вам не подходит? Фифо можно заменить на свою схему (в крайнем случае) - предварительно поиследовав двупортовую память на предмет: Я попробовал, в ксалинксе есть одна трудность фифо только 1 в 8 максимум, и 8 в 1, если надо больше бит на выходе, то и на вход надо больше. может это свойство блочной памяти... Quote Share this post Link to post Share on other sites More sharing options...
Golikov 0 June 19, 2014 Posted June 19, 2014 · Report post предложенный вариант обхода сброса Вам не подходит если честно не вижу в нем большой беды, чтобы его обходить... Идею с фифо надо проработать, так не понятно удобно будет, не удобно. По ощущениям удобно, но в данном проекте скорее останется старый вариант. А вот с ним приключения продолжаются. Опять сломалось все. Причем влияет перезагрузка ПЛИС. Если нажать ресет все будет работать, но если что-то сделать, что я пока не понимаю все ломается... Причем ломается очень странно, сбросы модулей не помогают, как будто конфигурация неправильно в ПЛИС загрузилась, может быть такое? как выглядит система: Есть модули, в них регистры, эти регистры можно читать и писать через 2 интерфейса SPI. Эта часть работает, пишется и читается все нормально. Среди модулей есть один с дополнительным массивом регистров, по соображениям размера доступ в них напрямую не получился. Потому в этом модулей реализована схема чтения-записи через временный регистр. Есть временный регистр данных и адреса для обоих SPI. В регистр адреса помещается номер желаемого регистра из массива, и флаг чтения - запись. В данные помещаются данные для записи, или туда попадают данные если было чтение. Так вот в этом модуле один интерфейс работает полностью, то есть через него устанавливаются временные регистры и это приводит к правильному чтению и перезаписи регистров массива. А для второго интерфейса чтение работает верно, а запись нулит данные в массиве, то есть даже запись проходит, только вместо правильных данных туда отправляются нули. Как может схема так выборочно с одним регистром себя вести? Что за бред? При этом сброс схемы помогает... я в панике. Метастабильность может повесить схему, один регистр, чтобы он навсегда перестал меняться? Quote Share this post Link to post Share on other sites More sharing options...
Maverick_ 16 June 19, 2014 Posted June 19, 2014 · Report post если честно не вижу в нем большой беды, чтобы его обходить... Идею с фифо надо проработать, так не понятно удобно будет, не удобно. По ощущениям удобно, но в данном проекте скорее останется старый вариант. Успехов!!! PS Отпишитесь о результатах, плиз (простое любопытство) Quote Share this post Link to post Share on other sites More sharing options...
Golikov 0 June 19, 2014 Posted June 19, 2014 · Report post Успехов!!! PS Отпишитесь о результатах, плиз (простое любопытство) Это не скоро будет... Сначала надо победить то что я нашел. Ошибка все таки есть, но где я не понимаю... И я не понимаю как ее найти. Как можно добиться того что регистр залипает в 0 состоянии? Приславутая мета стабильность может такое сделать? Регистр по всей схеме виден как 0? А когда регистр из такого состояния выйдет? что ему для этого надо? Quote Share this post Link to post Share on other sites More sharing options...
Golikov 0 June 19, 2014 Posted June 19, 2014 · Report post Так... нашел еще один плохой кусок //делитель синхронизации, начальное значение таково, //чтобы сигнал синхронизации был в 0 reg [INTERNAL_WORK_SYNC_COUNTER_LEN - 1 : 0] WorkSyncCouner = INTERNAL_WORK_SYNC_LEN; //сигнал внутренней рабочей синхронизации wire internal_work_sync; assign internal_work_sync = (WorkSyncCouner < INTERNAL_WORK_SYNC_LEN) ? 1'b1 : 1'b0; always @(posedge clk) begin //счетчик всегда идет вперед, если не перегружен ниже WorkSyncCouner <= WorkSyncCouner + 1'b1; //если дошел до конца, сброс счетчика if (WorkSyncCouner == INTERNAL_WORK_SYNC_COUNTER_VAL) WorkSyncCouner <= 0; end вот сигнал internal_work_sync - синхронный с клоком или нет? Для него проверяются констрайны? Он у меня потом участвует в обмене, может он что=то портит... Quote Share this post Link to post Share on other sites More sharing options...
SM 9 June 19, 2014 Posted June 19, 2014 · Report post Addr - это one hot адрес, то есть там все нули и всего одна единичка. Так вот мне кажется ни при каких раскладах не может так получится что выполняя эту конструкцию в адресе загорится другая единичка. То есть может ли 001 снимаясь перейти в 010 или 011? Может, например, меняясь с 001 на 010 "звякнуть разочек" в виде 011 или 000. Примените тут код Грея для адреса, в нем всегда каждый раз меняется только 1 бит при переходе к следующему коду. И особое внимание уделите сбросу адреса, так как в это время меняется сразу несколько бит. Разумеется, если этот адрес идет в таком виде из одного домена в другой. Если никак нельзя обеспечить требование изменения максимум одного бита за такт, то уже такое передавать надо через FIFO, пусть даже самодельное из пары регистров. Также можно просто обойтись одним регистром данных, и флагом, устанавливаемым из одного домена, далее через два триггера принимаемого в другом домене, и оттуда уже асинхронно сбрасываемого. internal_work_sync - синхронный с клоком CLK и констрейны для него проверяются, если он приходит на триггер, который тактируется этим же clk Quote Share this post Link to post Share on other sites More sharing options...
Golikov 0 June 19, 2014 Posted June 19, 2014 · Report post Адрес либо ставить из 0 в какой-то в одну единичку. Либо снимается из этого адреса в 0. Переключения нет. Снимается асинхронным сигналом, но долгим, явно больше 2 клоков, думаю при снятии одной единички в нули звякать не должен. Ставиться и снимается по клоку, асинхронный сигнал только дает разрешение на снятие. Устанавливается тоже через много тактов после изменения асинхронного сигнала... internal_work_sync - понятно. Я на всякий случай явно загнал его под клок, получил задержку в такт и не более... В итоге на текущий момент выяснил что схема регулярно грузиться в 2 режима, примерно 50 на 50, в рабочий или глючный. Характер глюков всегда одинаковый, если крутить оптимизацию то меняется суть, но не смысл глюка. Всегда срубает один интерфейс, и при этом запись через него. Интерфейс пишет в регистр, а регистр дальше в массив, в регистр запись проходит верно, считал его значение, а последующая перезапись в массив с ошибкой. Регистр уже давно в том же клоковом домене что и массив (то есть даже сигналы что шли на регистр уже синхронизованы, а он уж и подавно), констраины все сошлись. Остается подозревать гремлинов.... нелепо все как-то. Буду тестировать на других платах, может правда что-то с микросхемой... Quote Share this post Link to post Share on other sites More sharing options...
SM 9 June 20, 2014 Posted June 20, 2014 · Report post Остается подозревать гремлинов.... Их там нет! Плохо проанализировали возможные последствия метастабильности, не найдя какие-то варианты. Насчет адреса - использовать асинхронный сигнал для разрешения чего либо в принципе некорректно. Его надо использовать или для асинхронного сброса или предустановки (при наличии гарантии, что за положенное время после снятия его не может произойти ничего синхронного с регистром, на который он заведен), или синхронизировать, а затем использовать для разрешения. Кстати, совершенно все равно, сколько тактов длится такой сигнал, главное, чтобы он вовремя появлялся и снимался (в Вашем случае, скорее важнее чтобы именно снимался вовремя), не допуская в моменты его появления и снятия метастабильного состояния, после которого схема может остаться в неадекватном состоянии. Надо еще раз, и еще 10 раз, проанализировать все возможные варианты поведения схемы, когда на междоменном переходе фронт одного сигнала пришел до клока, второго - после клока, при том, что сгенерировались они одновременно. Такая разбежка "как бы симуляция метастабильности". PS ну либо имеется ошибка вообще где-то не там :) Quote Share this post Link to post Share on other sites More sharing options...
Golikov 0 June 20, 2014 Posted June 20, 2014 · Report post скорее последние. Я напихал тестовых выводов, в момент когда ломается интерфейс, все регистры доступные по SPI пишутся корректно, SPI передает - принимает корректно, контрольная сумма сходится, данные сходятся. А вот последующая схема которая должна принятый регистр дописать в массив не работает. ну типа DataToRegAddr == 5; NeedWriteData == 1; а DataWasWriten <= 1'b0; if((NeedWriteData == 1)&&(DataToRegAddr == 5)) begin Reg[5] <= Data; DataWasWrited <= 1'b1; end не выполняется... то DataWasWrited остается 0, то сигнал снимается, но в регистре 5 не оказываются данные. Эта схема уже далеко за междоменным переходом. При этом если схема начала работать после загрузки, работает четко сколь угодно долго. Так же как если после загрузки обмен не проходит, то он сколь угодно долго будет давать ошибку. При этом какая ошибка была, такая и остается, то есть если не ставится флаг, то он так и будет не ставиться до перезагрузки, а если в регистр нули решили писаться, то так и будут там нули. При этом через 2 интерфейс все четко проходит....Я не думаю что это какая-то метостабильность, скорее какие то ошибки при загрузке конфигурации ПЛИС. Кстати прочитал тут про мета стабильность от ксалинкса, они предлагают ее считать не чем иным как увеличением времени выставления триггера. Ну типа, через Т времени после клока Д триггер на выходе принимает то что было на входе. В случае мета стабильности надо считать что он примет это значение через Т + Тмета... Они не рассматривают это как поломку всей схемы. Вероятность что триггер из аз мета стабильности заклиниться в таком состоянии, что дальше все триггеры тоже в цепочке начнут клиниться я так понимаю ничтожна. И опять же со след тактом наверняка триггер перейдет в правильное состояние. Из этого описания следует что мета стабильность не убивает всю схему, а просто ее притормаживает, и при хорошей востанавливаемости схемы все пройдет гладко.... Quote Share this post Link to post Share on other sites More sharing options...
Maverick_ 16 June 20, 2014 Posted June 20, 2014 · Report post если попробовать уменьшить тактовую частоту проекта (если это возможно) если при уменьшении частоты ошибка пропадает, то... Quote Share this post Link to post Share on other sites More sharing options...