justontime 0 15 июня, 2017 Опубликовано 15 июня, 2017 · Жалоба можно было и по переднему фронту. Так времянке даже легче будет, на распространение сигнала будет 1 такт, а не половина. Сигнал так же попадет под анализ синтезатора. Второй триггер в цепочке синхронизации нужен для защиты от мета-стабильности. Один триггер который щелкает входной сигнал может быть в состоянии 0, 1, или Х - это если неудачно попал фронт. Это состояние рано или поздно свалиться к 1 или 0. И беда что остальные участники схемы смотрят на это состояние и по разному его видят, кто-то может его принять за 0, а кто-то за 1. Поэтому ставят второй триггер, чтобы он принял какое-то решение единолично, а остальные уже работали от него. Вероятность поймать мета-стабильность сильно меньше чем вероятность поймать гонку в исходном примере, поэтому все и заработало. Но природу не обманешь, когда-то и это стрельнет, так что лучше все же 2 триггера. Ну это даже я понимаю :) Просто хотелось посмотреть, насколько кардинально поменяет ситуацию такое минимальное изменение. Кстати, вроде бы дошло, почему гонки возникали так часто. Мне с самого начала было очень подозрительно, что проблема повторяется крайне регулярно, вроде статистически при моих частотах это должно происходить НАМНОГО реже. А сейчас сообразил, что у меня формирование StartCmd нельзя назвать по настоящему асинхронным по отношению к тактовому сигналу FSM - все тактовые начинаются от одного выхода PLL. Потом ветки этих тактовых сигналов расходятся, формируются по разному и т.д., но все равно их фронты более-менее совпадают каждый шестой (вроде бы, если правильно прикинул) раз, т.е. условия для гонки присутствуют постоянно. Мне даже стало интересно взять старую схему, но использовать 2 независимые PLL, чтобы посмотреть, уйдет ли такая регулярность проблемы... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Flip-fl0p 4 15 июня, 2017 Опубликовано 15 июня, 2017 · Жалоба Ну это даже я понимаю :) Просто хотелось посмотреть, насколько кардинально поменяет ситуацию такое минимальное изменение. Кстати, вроде бы дошло, почему гонки возникали так часто. Мне с самого начала было очень подозрительно, что проблема повторяется крайне регулярно, вроде статистически при моих частотах это должно происходить НАМНОГО реже. А сейчас сообразил, что у меня формирование StartCmd нельзя назвать по настоящему асинхронным по отношению к тактовому сигналу FSM - все тактовые начинаются от одного выхода PLL. Потом ветки этих тактовых сигналов расходятся, формируются по разному и т.д., но все равно их фронты более-менее совпадают каждый шестой (вроде бы, если правильно прикинул) раз, т.е. условия для гонки присутствуют постоянно. Мне даже стало интересно взять старую схему, но использовать 2 независимые PLL, чтобы посмотреть, уйдет ли такая регулярность проблемы... А не проще сразу делать правильно - обрабатывать асинхронный сигнал по идеологии пересечения клоковых доменов ? Зачем жалеть 2 несчастных регистра ? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Maverick_ 15 15 июня, 2017 Опубликовано 15 июня, 2017 · Жалоба Синхронизация цепочка library IEEE; use IEEE.STD_LOGIC_1164.ALL; entity synchronizer is generic ( stages : natural := 3 ); Port ( clk : in STD_LOGIC; i : in STD_LOGIC; o : out STD_LOGIC); end synchronizer; architecture Behavioral of synchronizer is signal flipflops : std_logic_vector(stages-1 downto 0):= (others => '0'); attribute ASYNC_REG : string; attribute ASYNC_REG of flipflops: signal is "true"; begin o <= flipflops(flipflops'high); clk_proc: process(clk) begin if rising_edge(clk) then flipflops <= flipflops(flipflops'high-1 downto 0) & i; end if; end process; end Behavioral; Возможно применение двуклокового FIFO для передачи принятых данных, возможно применение синхронизирующей цепочки для строба-готовности данных - что данные приняты и записаны в FIFO Дальше автомат отсчитывает например N стробов-готовности данных и производит вычитку из FIFO этих данных, производя их обработку... Можно учесть синхронизацию при описании SPI slave и работать на 1 частоте, если описать например так 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; Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Golikov 0 15 июня, 2017 Опубликовано 15 июня, 2017 · Жалоба А сейчас сообразил, что у меня формирование StartCmd нельзя назвать по настоящему асинхронным по отношению к тактовому сигналу FSM - все тактовые начинаются от одного выхода PLL. Потом ветки этих тактовых сигналов расходятся, формируются по разному и т.д., но все равно их фронты более-менее совпадают каждый шестой (вроде бы, если правильно прикинул) раз, т.е. условия для гонки присутствуют постоянно. Хм, так они если от одного PLL то должны были попасть автоматом под анализ. Другое дело если частоты не кратные, то конечно развести не удастся, но об этом должен сказать синтезатор. Вы варнинги и ероры тайм анализа не читали? По идее там должно быть написано что ничего не получилось.... А насчет проверять - это конечно дело ваше, но мировая практика все это уже проверила 100500 раз, нам можно верить, и мета-стабильности и гонки сигналов в реальном мире существуют... :) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
justontime 0 15 июня, 2017 Опубликовано 15 июня, 2017 · Жалоба Вы варнинги и ероры тайм анализа не читали? По идее там должно быть написано что ничего не получилось.... Признаюсь честно - я по подобным сообщениям делаю supress message, практически не читая... Наверное, в настоящее время time analysis - первоочередное, что мне нужно еще освоить. Брался за него пару раз, но становилось скучно :( Мои игрушки работают на частотах меньше 20МГц, поэтому в большинстве случаев проблем с быстродействием не возникает. Другое дело, что понимание основ могло бы выявить проблемы, аналогичные описанной в этой теме, на раннем этапе... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться