Amal 0 25 марта, 2013 Опубликовано 25 марта, 2013 · Жалоба Привет Всем! Есть модуль SPI со входным CLK = 40 МГц и шинами данных, запросов записи-чтения и прочим. Тактовая SPI не больше 1.5 МГц. Данные идут по 16 бит. Т.е. за один цикл обмена я, и получаю адрес внутреннего регистра и записываю/читаю данные 8-битного регистра. Поэтому у меня в машине состояния есть обращения в регистры по середине обмена (естественно на 40 МГц) и для этого есть подсчет сколько бит получено/ отправлено. Собственно, синтезатор ругается/информирует на сигналы выделения фронтов, спадов - он их посчитал тактовыми +---------------------+--------------+------+------+------------+-------------+ | Clock Net | Resource |Locked|Fanout|Net Skew(ns)|Max Delay(ns)| +---------------------+--------------+------+------+------------+-------------+ | s_CLK | Local| | 275 | 0.047 | 0.117 | +---------------------+--------------+------+------+------------+-------------+ |Inst_SPI_7v0/fall_ed | | | | | | | ge | Local| | 19 | 0.010 | 1.699 | +---------------------+--------------+------+------+------------+-------------+ |Inst_SPI_7v0/rise_ed | | | | | | | ge | Local| | 6 | 0.098 | 1.842 | +---------------------+--------------+------+------+------------+-------------+ s_sck1 <= SCK; process(CLK, RESET) begin if (rising_edge (CLK)) then if RESET = '1' then s_sck2 <= '1'; s_sck3 <= '1'; state <= IDLE; else s_sck2 <= s_sck1; s_sck3 <= s_sck2; state <= state_next; -- ....... fall_edge <= (not s_sck2) and s_sck3; rise_edge <= s_sck2 and (not s_sck3); end if; end if; end process; process (fall_edge, rise_edge, state) begin if state /= IDLE then if rising_edge (rise_edge) then rise_counter <= rise_counter + 1; end if; if rising_edge (fall_edge) then fall_counter <= fall_counter + 1; end if; else fall_counter <= (others => '0'); rise_counter <= (others => '0'); end if; end process; Регистры fall_counter и rise_counter сбрасываются в машине состояния по IDLE. Вопрос - что здесь не правильно? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Last_point 0 25 марта, 2013 Опубликовано 25 марта, 2013 · Жалоба второй процесс, вы как раз от них и тактируетесь if rising_edge (rise_edge) then rise_counter <= rise_counter + 1; end if; if rising_edge (fall_edge) then fall_counter <= fall_counter + 1; end if; Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Amal 0 25 марта, 2013 Опубликовано 25 марта, 2013 · Жалоба Спасибо за ответ. Тогда проистекает вопрос, если приращение счетчиков "загнать" в один процесс - будет ли эквивалентно? Т.e. s_sck1 <= SCK; process(CLK, RESET) begin if (rising_edge (CLK)) then if RESET = '1' then s_sck2 <= '1'; s_sck3 <= '1'; state <= IDLE; else s_sck2 <= s_sck1; s_sck3 <= s_sck2; state <= state_next; if (not s_sck2) and s_sck3 then fall_counter <= fall_counter + 1; end if; if s_sck2 and (not s_sck3) then rise_counter <= rise_counter + 1; end if; end if; end if; end process; Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
iosifk 3 25 марта, 2013 Опубликовано 25 марта, 2013 · Жалоба Привет Всем! Есть модуль SPI со входным CLK = 40 МГц и шинами данных, запросов записи-чтения и прочим. Тактовая SPI не больше 1.5 МГц. Вопрос - что здесь не правильно? Вообще, все контроллеры связи, как то SPI, UART и пр. удобно делать из нескольких автоматов. На самом нижнем уровне автомат оперирует только с битами: выделяет фронты под системную тактовую, убирает дребезг и пр. Потом, "над ним" делается автомат, который оперирует уже байтами или словами или кадрами. Этот автомат от нижнего получает сигнал готовности бита и сам бит, а наверх отдает свою готовность и принятое слово, кадр данных и т.д... А самый верхний автомат занимается только приемом-передачей сообщений. Он принимает кадр данных, выделяет сигналы управления для запуска приема передачи след. кадра и т.д. Тогда значительно улучшается отладка, т.к. для начала вместо контроллера связи всегда легко убрать нижние автоматы и поставить заглушку. Да и большинство нижних автоматов будут одинаковые... А вообще SPI - где только не описывался. И а аппликухах, и на открытых проектах, и в учебных программмах.. Если будут проблемы, то посмотрите у меня на сайте в статьях, "Краткий Курс", там я об этом писал подробно... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Muscat 0 25 марта, 2013 Опубликовано 25 марта, 2013 · Жалоба process (fall_edge, rise_edge, state) begin if state /= IDLE then if rising_edge (rise_edge) then - В список чувствительности включайте клок и резет, если юзаете асинхронный резет - Для автоматов удобно использовать case - Сигналы фронтов считывайте тем же клоком, которым их формируете. Всякий раз, когда вы пишите новый if rising_edge() от нового сигнала, то вводите новый клоковый домен (сам страдал этим). В данной ситуации это совершенно лишнее. Лучше писать так process (clk) begin if rising_edge(clk) then case (state) is when idle => if (rising_edge='1') then.... Про разделение протокола на иерархии сказали совершенно правильно. Сам делал SPI следующим образом - Один блок ловит фронты и спады SCK и выдает тычки. И все. - Другой блок задвигается данные из MOSI в регистр и выдвигает данные в MISO из другого (другой был нужен да) принимая тычки предыдущего блока. Он не смотрит на сигнал SCK и на содержание данных в шине. - Третий блок читает эти регистры и делает уже нахлобучку протокола с командными словами, словами данных, пакетами и прочими усложнениями. Он работает со словами и ничего не знает о шине моси мисо. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Amal 0 26 марта, 2013 Опубликовано 26 марта, 2013 · Жалоба Спасибо. Я ориентировался на образец проектирования у Pong Chu - там он делит на два модуля , автомат состояния и выходная логика. Буду читать про иерархические модули. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться