jenya7 0 25 ноября, 2018 Опубликовано 25 ноября, 2018 · Жалоба Хочу прояснить один момент. Есть процес process( reg_load, spi_clk ) begin if( reg_load ='1' ) then reg_shift <= data after 1 ns; elsif( falling_edge( spi_clk ) ) then reg_shift <= reg_shift( 6 downto 0 ) & '0' after 1 ns; end if; end process; spi_data_out <= reg_shift(7); Я так понимаю при reg_load ='1' data защелкнется в reg_shift. Сколько тактов может длиться условие reg_load ='1' чтоб выдать наружу старое значение из data? Скажем reg_load ='1' в течении 8 тактов. В первые 4 такта data = 00001111 во вторые 4 такта data = 11110000. Что выйдет наружу? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Flip-fl0p 4 25 ноября, 2018 Опубликовано 25 ноября, 2018 · Жалоба 1 час назад, jenya7 сказал: Хочу прояснить один момент. Есть процес process( reg_load, spi_clk ) begin if( reg_load ='1' ) then reg_shift <= data after 1 ns; elsif( falling_edge( spi_clk ) ) then reg_shift <= reg_shift( 6 downto 0 ) & '0' after 1 ns; end if; end process; spi_data_out <= reg_shift(7); Я так понимаю при reg_load ='1' data защелкнется в reg_shift. Сколько тактов может длиться условие reg_load ='1' чтоб выдать наружу старое значение из data? Скажем reg_load ='1' в течении 8 тактов. В первые 4 такта data = 00001111 во вторые 4 такта data = 11110000. Что выйдет наружу? 1. В синтезируемом коде кнструкция "after 1 ns;" лишена смысла. Лишь только загромождает код. 2. if( reg_load ='1' ) then reg_shift <= data after 1 ns; - Это асинхронная загрузка данных в регистры. По сути такая загрузка данных несет в себе опасности столько же сколько и асинхронный сброс. В FPGA так делать неправильно, и опасно. Тем более у Вас обычный SPI, который не требует таких выкрутасов. 3. falling_edge - почему задний фронт ? Не каждая FPGA имеет "железячне" триггеры, которые работают по заднему фронту. Да и мне сложно представить задачу, где нужен действительно задний фронт. DDR интерфейсы не в счет. 3. elsif( falling_edge( spi_clk ) ) then Для очень быстрой FPGA форма меленного SPI клока - это фактически пила. Вопрос ! Как будет работать триггер, который тактируется пилой ? Удалите этот код от греха подальше. И сделайте сами по всем правилам синхронного проектирования. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jenya7 0 25 ноября, 2018 Опубликовано 25 ноября, 2018 · Жалоба 4 minutes ago, Flip-fl0p said: 1. В синтезируемом коде кнструкция "after 1 ns;" лишена смысла. Лишь только загромождает код. 2. if( reg_load ='1' ) then reg_shift <= data after 1 ns; - Это асинхронная загрузка данных в регистры. По сути такая загрузка данных несет в себе опасности столько же сколько и асинхронный сброс. В FPGA так делать неправильно, и опасно. Тем более у Вас обычный SPI, который не требует таких выкрутасов. 3. falling_edge - почему задний фронт ? Не каждая FPGA имеет "железячне" триггеры, которые работают по заднему фронту. Да и мне сложно представить задачу, где нужен действительно задний фронт. DDR интерфейсы не в счет. 3. elsif( falling_edge( spi_clk ) ) then Для очень быстрой FPGA форма меленного SPI клока - это фактически пила. Вопрос ! Как будет работать триггер, который тактируется пилой ? Удалите этот код от греха подальше. И сделайте сами по всем правилам синхронного проектирования. понял. а по вопросу? значение в reg_shift ? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Flip-fl0p 4 25 ноября, 2018 Опубликовано 25 ноября, 2018 · Жалоба 1 час назад, jenya7 сказал: понял. а по вопросу? значение в reg_shift ? Значение в reg_Shift будет с большей вероятностью иметь значение, загружаемое в него во время reg_load ='1' . Однако из-за того, что возможно нарушения времени установки и удержания, когда произойдут одновременно события: reg_load ='1' и falling_edge(spi_clk), то reg_shift(7) то с некоторой вероятностью будет иметь случайное значение. Это будет на практике. Если взять и немного теоретизировать и считать, что у нас не происходит нарушения времени установки и удержания, то каждый такт в reg_shift(7) будет появляться то значение, которое вы загрузили в reg_Shift. Например вы загрузили b"1111_0000", то сначала будет так: 1, 1,1,1 затем 0,0,0,0. А потом будут каждый такт нули, т.к сдвиговый регистр заполнился нулями... P.S. Иногда очень полезно код представить в виде схемы и нарисовать это на бумажке. Тогда многие вещи будут понятны сразу. В конце концов Вы кодом описываете именно схему. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jenya7 0 25 ноября, 2018 Опубликовано 25 ноября, 2018 · Жалоба 7 minutes ago, Flip-fl0p said: Если взять и немного теоретизировать и считать, что у нас не происходит нарушения времени установки и удержания, то каждый такт в reg_shift(7) будет появляться то значение, которое вы загрузили в reg_Shift. Например вы загрузили b"1111_0000", то сначала будет так: 1, 1,1,1 затем 0,0,0,0. А потом будут каждый такт нули, т.к сдвиговый регистр заполнился нулями... а если после 4 тактов data = 10101010? reg_shift перепишется? и выйдет 11111010? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Flip-fl0p 4 25 ноября, 2018 Опубликовано 25 ноября, 2018 · Жалоба 1 час назад, jenya7 сказал: а если после 4 тактов data = 10101010? reg_shift перепишется? и выйдет 11111010? Я не понимаю что значит перепишется. Каким значением он перепишется ? Вот примерная схема Вашей конструкции: SPI.bmp Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jenya7 0 25 ноября, 2018 Опубликовано 25 ноября, 2018 · Жалоба 25 minutes ago, Flip-fl0p said: Я не понимаю что значит перепишется. Каким значением он перепишется ? Вот примерная схема Вашей конструкции: SPI.bmp Я посмотрел в RTL. Получается если не снять сигнал reg_load в reg_shift загрузиться новое значение. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
andrew_b 15 25 ноября, 2018 Опубликовано 25 ноября, 2018 · Жалоба Ясно же написано: пока reg_load равен единице, данные со входа сразу переходят на выход. Это асинхронно, ни о каких тактах здесь речь не идёт. Вы ожидаете чего-то другого? Учтите, не каждая FPGA имеет триггеры с асинхронной загрузкой. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jenya7 0 25 ноября, 2018 Опубликовано 25 ноября, 2018 (изменено) · Жалоба 26 minutes ago, andrew_b said: Ясно же написано: пока reg_load равен единице, данные со входа сразу переходят на выход. Это асинхронно, ни о каких тактах здесь речь не идёт. Вы ожидаете чего-то другого? Учтите, не каждая FPGA имеет триггеры с асинхронной загрузкой. То что мы видим в RTL Viewer это не конечная реализация? Ну в принципе не важно. Но для правильной работы нужно выставить reg_load и сразу убрать? причем reg_load нужно выставить пока СПИ клок не активен? В принципе reg_load нужно убрать до активности СПИ клока. а можно это как то сделать внутри модуля? снаружи выставить а внутри сбросить? Изменено 25 ноября, 2018 пользователем jenya7 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Flip-fl0p 4 25 ноября, 2018 Опубликовано 25 ноября, 2018 · Жалоба Цитата То что мы видим в RTL Viewer это не конечная реализация? Конечная реализация показана на Technoligy map, где всё упаковано в LUT... Но смотреть на неё смысла нет никакого. Цитата Ну в принципе не важно. Но для правильной работы нужно выставить reg_load и сразу убрать? причем reg_load нужно выставить пока СПИ клок не активен? Для правильной работы нужно разобраться в концепции синхронного проектирования. Разобраться что такое Tsetup, Thold. К чему приводят нарушения этих временных соотношений. В противном случае на выходе будет глючная фигня, работающая с постоянными сбоями. Цитата В принципе reg_load нужно убрать до активности СПИ клока. а можно это как то сделать внутри модуля? снаружи выставить а внутри сбросить? Это шаманство ни к чему. Делать нужно сразу правильно. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться