des00 25 5 июня, 2019 Опубликовано 5 июня, 2019 · Жалоба 1 minute ago, Bad0512 said: нарезал бы всё внутренним 400 МГц клоком и жил бы припеваючи. :)) это для тех кому старшие семерки и ультрас достаются бесплатно) такие люди, спиай давно уже не используют. Оке, уточним задачу, берем чип класса спартан6/сыклон 5, самый медленный. SPI 90 МГц. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Bad0512 2 5 июня, 2019 Опубликовано 5 июня, 2019 · Жалоба 5 minutes ago, des00 said: это для тех кому старшие семерки и ультрас достаются бесплатно) такие люди, спиай давно уже не используют. Оке, уточним задачу, берем чип класса спартан6/сыклон 5, самый медленный. SPI 90 МГц. Вот тут уже включаем голову и применяем системный подход. После беглого анализа понимаем что 90МГц SPI и дохленький чип ПЛИС как-то между собой не коррелируют. И решаем либо частоту SPI понизить, либо решить проблему сменой ПЛИС (дохленький цинк с аппаратной поддрежкой SPI в PS вполне прокатит, кстати). P.S. А по поводу "не используют" скажу так. Эти люди иногда такое унылое говно используют, что становится страшно за будущее нашей оборонки. Из примеров - преобразователь электрика-оптика-электрика на скорости до 100 мегабит на цинке 7030. Как вам такое, Илон Маск? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Inanity 1 5 июня, 2019 Опубликовано 5 июня, 2019 (изменено) · Жалоба 5 hours ago, des00 said: Оке, уточним задачу, берем чип класса спартан6/сыклон 5, самый медленный. SPI 90 МГц. Вопрос не мне, но отвечу. Когда-то делал специфический SPI на 64MHz 16 бит. Тактовый сигнал и данные держал в двух регистрах. В момент передачи оба регистра синхронно выдвигал. Выходные регистры были упакованы в IO буфферы ПЛИС. За счёт всего этого удалось добиться полного отсутствия разницы фаз между клоком и данными и достаточно простым управлением тактового сигнала в период пачки. Минус в том, что внутренняя логика должна в этом случае работать на удвоенной частоте. Но думаю, что даже 100MHz SPI (200Mhz внутренней частоты) этот дизайн бы запросто потянул, при условии согласованности линии и возможности ведомого принять такой поток. Но это если делать на чистом HDL. Не знаю как на C5, но на спартане6 есть ODDR2 (выходной буфер DDR). Думаю, что тот же фокус с двумя регистрами можно провернуть и с ним, только в этом случае удвоенная внутренняя частота уже не будет нужна. А топикстартеру рекомендую изучить неблокирующие присваивания, иначе этот ад не заработает никогда. Изменено 5 июня, 2019 пользователем Inanity Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Bad0512 2 5 июня, 2019 Опубликовано 5 июня, 2019 · Жалоба 20 minutes ago, Inanity said: Вопрос не мне, но отвечу. Когда-то делал специфический SPI на 64MHz 16 бит. Тактовый сигнал и данные держал в двух регистрах. В момент передачи оба регистра синхронно выдвигал. Выходные регистры были упакованы в IO буфферы ПЛИС. За счёт всего этого удалось добиться полного отсутствия разницы фаз между клоком и данными и достаточно простым управлением тактового сигнала в период пачки. Минус в том, что внутренняя логика должна в этом случае работать на удвоенной частоте. Но думаю, что даже 100MHz SPI (200Mhz внутренней частоты) этот дизайн бы запросто потянул, при условии согласованности линии и возможности ведомого принять такой поток. Но это если делать на чистом HDL. Не знаю как на C5, но на спартане6 есть ODDR2 (выходной буфер DDR). Думаю, что тот же фокус с двумя регистрами можно провернуть и с ним, только в этом случае удвоенная внутренняя частота уже не будет нужна. А топикстартеру рекомендую изучить неблокирующие присваивания, иначе этот ад не заработает никогда. на передачу вообще на любой почти частоте можно сделать легко. Тут речь идёт за slave, то есть надо сделать приёмник, соответственно надо переложить всё на внутренний клок заведомо более быстрый (ну хотя бы в 3 раза быстрее) чтобы не потерять фронты. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Inanity 1 5 июня, 2019 Опубликовано 5 июня, 2019 · Жалоба 22 minutes ago, Bad0512 said: на передачу вообще на любой почти частоте можно сделать легко. Тут речь идёт за slave, то есть надо сделать приёмник, соответственно надо переложить всё на внутренний клок заведомо более быстрый (ну хотя бы в 3 раза быстрее) чтобы не потерять фронты. Какой-то странный подход. Это же не асинхронный интерфейс. Зачем тогда лишний провод на тактовый сигнал тратить? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Bad0512 2 5 июня, 2019 Опубликовано 5 июня, 2019 · Жалоба 3 minutes ago, Inanity said: Какой-то странный подход. Это же не асинхронный интерфейс. Зачем тогда лишний провод на тактовый сигнал тратить? Без перехода на внутренний клок получится унылое асинхронное говнище, которое будет нестабильно работать из-за дребезга и периодически залипать наглухо по причине того, что клок SCK присутствует только в момент передачи данных, а паузах может и вообще отсутствовать. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Inanity 1 5 июня, 2019 Опубликовано 5 июня, 2019 · Жалоба 1 minute ago, Bad0512 said: Без перехода на внутренний клок получится унылое асинхронное говнище, которое будет нестабильно работать из-за дребезга и периодически залипать наглухо по причине того, что клок SCK присутствует только в момент передачи данных, а паузах может и вообще отсутствовать. Переход на внутренний клок будет в любом случае, но приёмный каскад должен работать по клоку приходящему. Это какой-то непонятный огород, который вас не спасёт, т.к. кроме фронта приходящего тактового сигнала нет никаких других способов детектировать валидные данные на шине. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Nick_K 0 5 июня, 2019 Опубликовано 5 июня, 2019 · Жалоба 23 hours ago, des00 said: Оке, уточним задачу, берем чип класса спартан6/сыклон 5, самый медленный. SPI 90 МГц. 17 hours ago, Inanity said: Но думаю, что даже 100MHz SPI (200Mhz внутренней частоты) этот дизайн бы запросто потянул, У меня сейчас лежит проект на Спартан 6 с клоком 200MHz. В основном всё работает без проблем, если не загружать все ненужные блоки одновременно. И при определённой сноровке можно спокойно поднять детектирование входным буффером до 300MHz, а дальше уже логику на любой частоте прикрутить. Так что не вижу необходимости заводить клок от SPI и тактировать им внутренние ФФ. Разве что выше 100MHz что-то будет. А может я просто ленивый и мне лень констрейнить все сопли SPI Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Bad0512 2 5 июня, 2019 Опубликовано 5 июня, 2019 · Жалоба 11 minutes ago, Inanity said: Переход на внутренний клок будет в любом случае, но приёмный каскад должен работать по клоку приходящему. Это какой-то непонятный огород, который вас не спасёт, т.к. кроме фронта приходящего тактового сигнала нет никаких других способов детектировать валидные данные на шине. Неизбежный дребезг как побеждать будете в этом случае? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Cianid 0 5 июня, 2019 Опубликовано 5 июня, 2019 · Жалоба Собственно решил проблему, как подсказал des00. Cделал срабатывание по по фронту SS. module spi_slave (rstb,ss,sck,sdin,done,rdata, sdout); input rstb; input ss; input sck; input sdin; output reg done; output reg [7:0] rdata; output reg sdout; reg [7:0] rreg; reg [3:0] nb; reg [3:0] nf; always @(posedge sck or negedge rstb or posedge ss) begin if (rstb == 0) begin done <= 0; nb <= 0; nf <= 0; sdout <= 0; end else if (ss) begin nb <= 0; done <= 0; nf <= 0; sdout <= 0; end else begin rreg ={rreg[6:0],sdin}; nb <= nb + 1; if(nb != 7) done <= 0; else begin rdata=rreg; done <= 1; nb <= 0; nf <= nf + 1; if(nf == 7) begin sdout <= 1; nf <= 0; end end end end endmodule Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Inanity 1 5 июня, 2019 Опубликовано 5 июня, 2019 (изменено) · Жалоба 49 minutes ago, Bad0512 said: Неизбежный дребезг как побеждать будете в этом случае? Для начала установить природу дребезга или глитча. В 90% уверен, что проблема в несогласованности линии, сигнал отражается от приёмника и гуляет по проводу, создавая внеочередные фронты, провалы, короче говоря глитчи. Решать эту проблему надо на схемотехническом уровне (согласование/экранирование и т.д.). Если все эти вопросы решены, но всё равно есть проблемы с приёмом данных ввиду внешних наводок и т.д. то проблему можно попробовать решить на уровне протокола, т.е. контрольные суммы, запрос-ответ и т.д. В худшем случае SPI как интерфейс может вам и не подойти совсем. Тогда нужен асинхронный протокол с нормальной преамбулой, ECC и т.д. Вы же, насколько я понимаю, предлагаете оверсемплингом восстанавливать клок, который поможет детектировать данные. Не могу сказать, что это не будет работать, но зачем тогда вообще применять не предназначенный для таких задач синхронный интерфейс? Стоит ли программировать навороченный гибрид SPI-приёмника и осциллографа, чтобы принять шумный SPI? Не знаю, возможно, когда другого выхода нет, то это оправданно, но во всех других ситуациях это не рационально. Изменено 5 июня, 2019 пользователем Inanity Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Nieve 0 5 июня, 2019 Опубликовано 5 июня, 2019 · Жалоба 3 hours ago, Cianid said: Собственно решил проблему, как подсказал des00. Cделал срабатывание по по фронту SS. Что такое 《posedge sck or negedge rstb or posedge ss 》 ? С точки зрения синтеза весьма любопытно. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
iosifk 3 5 июня, 2019 Опубликовано 5 июня, 2019 · Жалоба 2 минуты назад, Nieve сказал: Что такое 《posedge sck or negedge rstb or posedge ss 》 ? С точки зрения синтеза весьма любопытно. А это заявка записаться в расстрельный список. Чтобы начальник знал кого и за что... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Maverick_ 15 5 июня, 2019 Опубликовано 5 июня, 2019 · Жалоба 6 minutes ago, Nieve said: Что такое 《posedge sck or negedge rstb or posedge ss 》 ? С точки зрения синтеза весьма любопытно. простое описание слейва (vhdl): library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.NUMERIC_STD.ALL; -- THE SPI SLAVE MODULE SUPPORT ONLY SPI MODE 0 (CPOL=0, CPHA=0)!!! entity SPI_SLAVE is Port ( CLK : in std_logic; -- system clock RST : in std_logic; -- high active synchronous reset -- SPI SLAVE INTERFACE SCLK : in std_logic; CS_N : in std_logic; MOSI : in std_logic; MISO : out std_logic; -- USER INTERFACE READY : out std_logic; -- when READY = 1, SPI slave is ready to accept input data DIN : in std_logic_vector(7 downto 0); -- input data for master DIN_VLD : in std_logic; -- when DIN_VLD = 1, input data are valid and can be accept DOUT : out std_logic_vector(7 downto 0); -- output data from master DOUT_VLD : out std_logic -- when DOUT_VLD = 1, output data are valid ); end SPI_SLAVE; architecture RTL of SPI_SLAVE is signal spi_clk_reg : std_logic; signal spi_clk_redge_en : std_logic; signal spi_clk_fedge_en : std_logic; signal load_data : std_logic; signal data_shreg : std_logic_vector(7 downto 0); signal bit_cnt : unsigned(2 downto 0); signal last_bit_en : std_logic; signal slave_ready : std_logic; signal data_busy_reg : std_logic; signal rx_data_vld : std_logic; begin load_data <= slave_ready and DIN_VLD; READY <= slave_ready; DOUT <= data_shreg; -- ------------------------------------------------------------------------- -- SPI CLOCK REGISTER -- ------------------------------------------------------------------------- spi_clk_reg_p : process (CLK) begin if (rising_edge(CLK)) then if (RST = '1') then spi_clk_reg <= '0'; else spi_clk_reg <= SCLK; end if; end if; end process; -- ------------------------------------------------------------------------- -- SPI CLOCK EDGES FLAGS -- ------------------------------------------------------------------------- spi_clk_fedge_en <= not SCLK and spi_clk_reg; spi_clk_redge_en <= SCLK and not spi_clk_reg; -- ------------------------------------------------------------------------- -- DATA BUSY REGISTER -- ------------------------------------------------------------------------- data_busy_reg_p : process (CLK) begin if (rising_edge(CLK)) then if (RST = '1') then data_busy_reg <= '0'; else if (DIN_VLD = '1' and CS_N = '1') then data_busy_reg <= '1'; elsif (rx_data_vld = '1') then data_busy_reg <= '0'; else data_busy_reg <= data_busy_reg; end if; end if; end if; end process; slave_ready <= CS_N and not data_busy_reg; -- ------------------------------------------------------------------------- -- MISO REGISTER -- ------------------------------------------------------------------------- miso_p : process (CLK) begin if (rising_edge(CLK)) then if (load_data = '1') then MISO <= DIN(7); elsif (spi_clk_fedge_en = '1' and CS_N = '0') then MISO <= data_shreg(7); end if; end if; end process; -- ------------------------------------------------------------------------- -- DATA SHIFT REGISTER -- ------------------------------------------------------------------------- data_shreg_p : process (CLK) begin if (rising_edge(CLK)) then if (load_data = '1') then data_shreg <= DIN; elsif (spi_clk_redge_en = '1' and CS_N = '0') then data_shreg <= data_shreg(6 downto 0) & MOSI; end if; end if; end process; -- ------------------------------------------------------------------------- -- DATA OUT VALID FLAG REGISTER -- ------------------------------------------------------------------------- rx_data_vld <= spi_clk_fedge_en and last_bit_en; dout_vld_reg_p : process (CLK) begin if (rising_edge(CLK)) then if (RST = '1') then DOUT_VLD <= '0'; else DOUT_VLD <= rx_data_vld; end if; end if; end process; -- ------------------------------------------------------------------------- -- BIT COUNTER -- ------------------------------------------------------------------------- bit_cnt_p : process (CLK) begin if (rising_edge(CLK)) then if (RST = '1') then bit_cnt <= (others => '0'); elsif (spi_clk_fedge_en = '1' and CS_N = '0') then if (bit_cnt = "111") then bit_cnt <= (others => '0'); else bit_cnt <= bit_cnt + 1; end if; end if; end if; end process; -- ------------------------------------------------------------------------- -- LAST BIT FLAG REGISTER -- ------------------------------------------------------------------------- last_bit_en_p : process (CLK) begin if (rising_edge(CLK)) then if (RST = '1') then last_bit_en <= '0'; else if (bit_cnt = "111") then last_bit_en <= '1'; else last_bit_en <= '0'; end if; end if; end if; end process; end RTL; Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
alexadmin 0 5 июня, 2019 Опубликовано 5 июня, 2019 · Жалоба 30 minutes ago, iosifk said: А это заявка записаться в расстрельный список. Чтобы начальник знал кого и за что... И обратите внимание, если что - можно сказать, что des00 подсказал ;) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться