jenya7 0 28 февраля, 2021 Опубликовано 28 февраля, 2021 · Жалоба Можно так сделать? CLK = 120 Mhz MS_CLK = 100 Mhz constant TICKS_FOR_1MS : std_logic_vector(31 downto 0) := X"000186A0"; process (CLK) begin if (count_reset = '1') then ticks_counter <= (others => '0'); ms_counter <= (others => '0'); else if (rising_edge(MS_CLK)) then ticks_counter <= ticks_counter + '1'; if (ticks_counter = TICKS_FOR_1MS) then ticks_counter <= (others => '0'); ms_counter <= ms_counter + '1'; end if; end if; end if; end process; Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Flip-fl0p 4 28 февраля, 2021 Опубликовано 28 февраля, 2021 · Жалоба 12 минут назад, jenya7 сказал: Можно так сделать? CLK = 120 Mhz MS_CLK = 100 Mhz constant TICKS_FOR_1MS : std_logic_vector(31 downto 0) := X"000186A0"; process (CLK) begin if (count_reset = '1') then ticks_counter <= (others => '0'); ms_counter <= (others => '0'); else if (rising_edge(MS_CLK)) then ticks_counter <= ticks_counter + '1'; if (ticks_counter = TICKS_FOR_1MS) then ticks_counter <= (others => '0'); ms_counter <= ms_counter + '1'; end if; end if; end if; end process; Сделать можно. Работать не будет. Изучайте как работает список чувствительности в VHDL. Эта тема обсасывалась уже 100 раз на форуме. Подсказка: в VHDL список чувствительности не влияет на синтез (Qartus и Vivado). Вы описали обычную пару счетчиков. Правильно делать: 2 процесса на разных частотах. И сигнал из одного процесса переносить в другой через CDC синхронизаторы, удлинители сигнала и детекторы фронта. Совсем правильно делать: по возможности на одной частоте. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jenya7 0 28 февраля, 2021 Опубликовано 28 февраля, 2021 (изменено) · Жалоба 14 minutes ago, Flip-fl0p said: Сделать можно. Работать не будет. Изучайте как работает список чувствительности в VHDL. Эта тема обсасывалась уже 100 раз на форуме. Подсказка: в VHDL список чувствительности не влияет на синтез (Qartus и Vivado). Вы описали обычную пару счетчиков. Правильно делать: 2 процесса на разных частотах. И сигнал из одного процесса переносить в другой через CDC синхронизаторы, удлинители сигнала и детекторы фронта. а так? cnt_rst3 <= not cnt_rst2 and cnt_rst1; process (CLK) begin if (rising_edge(CLK)) then cnt_rst1 <= count_reset; cnt_rst2 <= cnt_rst1; end if; end process; process (MS_CLK) begin if (rising_edge(MS_CLK)) then if (cnt_rst3 = '1') then ticks_counter <= (others => '0'); ms_counter <= (others => '0'); else ticks_counter <= ticks_counter + '1'; if (ticks_counter = TICKS_FOR_1MS) then ticks_counter <= (others => '0'); ms_counter <= ms_counter + '1'; end if; end if; end if; end process; Изменено 28 февраля, 2021 пользователем jenya7 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Flip-fl0p 4 28 февраля, 2021 Опубликовано 28 февраля, 2021 · Жалоба 6 минут назад, jenya7 сказал: а так? cnt_rst3cnt_rst3 <= not cnt_rst2 and cnt_rst1; process (CLK) begin if (rising_edge(CLK)) then cnt_rst1 <= count_reset; cnt_rst2 <= cnt_rst1; end if; end process; process (MS_CLK) begin if (rising_edge(MS_CLK)) then if (cnt_rst3 = '1') then ticks_counter <= (others => '0'); ms_counter <= (others => '0'); else ticks_counter <= ticks_counter + '1'; if (ticks_counter = TICKS_FOR_1MS) then ticks_counter <= (others => '0'); ms_counter <= ms_counter + '1'; end if; end if; end if; end process; И так плохо. Где перенос сигнала cnt_rest3 из домена CLK в домен MS_CLK ? Вы неправильно сигнал переносите. 1. Сначала формируем сигнал. 2. Удлиняем его на время, чтобы его длительность была гарантированно больше чем 2 периода частоты MS_CLK 3. Переносим через синхронизатор. 4. Выделяем фронт в домене MS_CLK. PS. Источник сигнала, который Вы переносите через домен должен быть порожден регистром, а не комбинационной логикой. Поэтому в зависимости от логики удлинения сигнала возможно надо будет сигнал защелкнуть на регистре в домене CLK. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jenya7 0 28 февраля, 2021 Опубликовано 28 февраля, 2021 · Жалоба 1 minute ago, Flip-fl0p said: И так плохо. Где перенос сигнала cnt_rest3 из домена CLK в домен MS_CLK ? Вы неправильно сигнал переносите. 1. Сначала формируем сигнал. 2. Удлиняем его на время, чтобы его длительность была гарантированно больше чем 2 периода частоты MS_CLK 3. Переносим через синхронизатор. 4. Выделяем фронт в домене MS_CLK. пункт 2 не понятен - как удлиняем? то есть можно конечно, у меня обнуление идет в другом процессе case LaunchState is when ST_STATE_1 => count_reset <= '1'; when ST_STATE_2 => count_reset <= '0'; можно добавить промежуточный стейт но что то не нравиться мне такое решение. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Flip-fl0p 4 28 февраля, 2021 Опубликовано 28 февраля, 2021 · Жалоба 11 минут назад, jenya7 сказал: пункт 2 не понятен - как удлиняем? то есть можно конечно, у меня обнуление идет в другом процессе case LaunchState is when ST_STATE_1 => count_reset <= '1'; when ST_STATE_2 => count_reset <= '0'; можно добавить промежуточный стейт но что то не нравиться мне такое решение. У Вас сейчас сигнал cnt_rest3 формируется в домене CLK(120 Mhz). Передаете Вы его в домен 100 МHz. Думаю очевидно что период 8,33ns меньше чем 10 ns. Если просто передавать сигнал с меньшим в периодов в домен с большим периодом могут возникнуть ситуации, когда сигнал не попадет на передний фронт тактового сигнала домена с большим периодом, и просто потеряется. Ваша задача сделать так, чтобы сигнал, который Вы перекидываете между доменами имел длительность как минимум 2 периода частоты 100 Мгц. Т.е 20ns. 20ns/8,33ns = 2,4. Т.е сигнал должен иметь длительность не менее 3 такта частоты 120 Мгц. В случае, если не стоит цель сэкономить ресурсы, можно сделать схему с внутренним Handshakе, которая будет гарантированно переводить сигнал из домена А в домен Б при любых соотношениях частот. Однако придется потратить дополительные ресурсы на это. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jenya7 0 28 февраля, 2021 Опубликовано 28 февраля, 2021 (изменено) · Жалоба 16 minutes ago, Flip-fl0p said: У Вас сейчас сигнал cnt_rest3 формируется в домене CLK(120 Mhz). Передаете Вы его в домен 100 МHz. Думаю очевидно что период 8,33ns меньше чем 10 ns. Если просто передавать сигнал с меньшим в периодов в домен с большим периодом могут возникнуть ситуации, когда сигнал не попадет на передний фронт тактового сигнала домена с большим периодом, и просто потеряется. Ваша задача сделать так, чтобы сигнал, который Вы перекидываете между доменами имел длительность как минимум 2 периода частоты 100 Мгц. Т.е 20ns. 20ns/8,33ns = 2,4. Т.е сигнал должен иметь длительность не менее 3 такта частоты 120 Мгц. В случае, если не стоит цель сэкономить ресурсы, можно сделать схему с внутренним Handshakе, которая будет гарантированно переводить сигнал из домена А в домен Б при любых соотношениях частот. Однако придется потратить дополительные ресурсы на это. может так тогда? process (CLK) begin if (rising_edge(CLK)) then if (count_reset = '1') then locked_reset <= '1'; end if; end if; if (locked_reset = '1') then del := del + 1; if (del = 2) then del := 0; locked_reset <= '0'; end if; end if; end process; process (MS_CLK) begin if (rising_edge(MS_CLK)) then if (locked_reset = '1') then ticks_counter <= (others => '0'); ms_counter <= (others => '0'); else ticks_counter <= ticks_counter + '1'; if (ticks_counter = TICKS_FOR_1MS) then ticks_counter <= (others => '0'); ms_counter <= ms_counter + '1'; end if; end if; end if; end process; а сколько ресурсов берёт Handshakе? Изменено 28 февраля, 2021 пользователем jenya7 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Flip-fl0p 4 28 февраля, 2021 Опубликовано 28 февраля, 2021 · Жалоба 4 минуты назад, jenya7 сказал: может так тогда? Значица так. Берете 2 разных цветных пишущих изделия и рисуете схему. Каждый домен своим цветом. Когда схему нарисуете и выложите сюда - можно будет продолжить разговор. Не вижу смысла дальше что-то Вам объяснять. Пересечения CDC - это базовые вещи, которые должен знать каждый, кто работает с FPGA. Изучайте матчасть. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jenya7 0 28 февраля, 2021 Опубликовано 28 февраля, 2021 · Жалоба 1 minute ago, Flip-fl0p said: Значица так. Берете 2 разных цветных пишущих изделия и рисуете схему. Каждый домен своим цветом. Когда схему нарисуете и выложите сюда - можно будет продолжить разговор. Не вижу смысла дальше что-то Вам объяснять. Пересечения CDC - это базовые вещи, которые должен знать каждый, кто работает с FPGA. Изучайте матчасть. я сделал то что вы предлагали - удлинение сигнала. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Flip-fl0p 4 28 февраля, 2021 Опубликовано 28 февраля, 2021 · Жалоба 1 минуту назад, jenya7 сказал: я сделал то что вы предлагали - удлинение сигнала. А кто будет выполнять пункты: Цитата 3. Переносим через синхронизатор. 4. Выделяем фронт в домене MS_CLK. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jenya7 0 28 февраля, 2021 Опубликовано 28 февраля, 2021 (изменено) · Жалоба а если вынести в отдельный модуль с асинхронным рисетом? entity MS_COUNT is generic ( TICKS_FOR_1MS : std_logic_vector(31 downto 0); COUNTER_LENGTH : integer ); port ( CLK : in std_logic; RST : in std_logic; COUNTER : out std_logic_vector(15 downto 0) ); end MS_COUNT; architecture behavior of MS_COUNT is signal ticks_counter : std_logic_vector(31 downto 0); signal ms_counter : std_logic_vector(COUNTER_LENGTH-1 downto 0) := X"00"; begin COUNTER <= ms_counter; process(CLK, RST) begin if RST = '1' then ticks_counter <= (others => '0'); ms_counter <= (others => '0'); elsif rising_edge(CLK) then ticks_counter <= ticks_counter + '1'; if (ticks_counter = TICKS_FOR_1MS) then ticks_counter <= (others => '0'); ms_counter <= ms_counter + '1'; end if; end if; end process; end behavior; Изменено 28 февраля, 2021 пользователем jenya7 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Flip-fl0p 4 28 февраля, 2021 Опубликовано 28 февраля, 2021 · Жалоба 6 минут назад, jenya7 сказал: а если вынести в отдельный модуль с асинхронным рисетом? Асинхронный сброс должен иметь синхронное снятие. https://www.eetimes.com/how-do-i-reset-my-fpga/ Вместо CDC синхронизатора нужно будет ставить reset bridge. Так-что таки придется сделать синхронизатор Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Nick_K 0 1 марта, 2021 Опубликовано 1 марта, 2021 · Жалоба 15 hours ago, jenya7 said: elsif rising_edge(CLK) then ticks_counter <= ticks_counter + '1'; if (ticks_counter = TICKS_FOR_1MS) then ticks_counter <= (others => '0'); ms_counter <= ms_counter + '1'; end if; end if; Я уже немного подзабыл специфику VHDL, но кажется так нельзя делать. В языке нет переприсвоения, соответственно придётся писать так: elsif rising_edge(CLK) then if (ticks_counter = TICKS_FOR_1MS) then ticks_counter <= (others => '0'); ms_counter <= ms_counter + '1'; else ticks_counter <= ticks_counter + '1'; end if; end if; Впринципе второй модуль выглядит вполне синтезабельным. И ресетить можно через CDC с определёнными оговорками и головной болью для человека, который будет писать констрейны. з.ы. Синхронизатор - это просто 2 флопа включенных последовательно и работающих на другой частоте. Такая схема с очень большой долей вероятности предотвратит метастабильность на входе последующей логики. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jenya7 0 1 марта, 2021 Опубликовано 1 марта, 2021 · Жалоба 14 minutes ago, Nick_K said: Я уже немного подзабыл специфику VHDL, но кажется так нельзя делать. В языке нет переприсвоения, соответственно придётся писать так: Впринципе второй модуль выглядит вполне синтезабельным. И ресетить можно через CDC с определёнными оговорками и головной болью для человека, который будет писать констрейны. з.ы. Синхронизатор - это просто 2 флопа включенных последовательно и работающих на другой частоте. Такая схема с очень большой долей вероятности предотвратит метастабильность на входе последующей логики. модуль компилируется. но проблема в том что сигнал рисета приходит от процесса на 120 Мега в процесс 100 Мега и я могу его пропустить. решил заморочиться и сделать модуль счетчика и модуль формирования сигнала рисета Spoiler entity MS_COUNT is generic ( TICKS_FOR_1MS : std_logic_vector(31 downto 0); COUNTER_LENGTH : integer ); port ( CLK : in std_logic; RST : in std_logic; COUNTER : out std_logic_vector(COUNTER_LENGTH-1 downto 0) ); end MS_COUNT; architecture behavior of MS_COUNT is signal rst_1 : std_logic; signal rst_2 : std_logic; signal rst_3 : std_logic; signal ticks_counter : std_logic_vector(31 downto 0); signal ms_counter : std_logic_vector(COUNTER_LENGTH-1 downto 0) := (others => '0'); begin rst_3 <= not rst_2 and rst_1; --rising COUNTER <= ms_counter; process (CLK) begin if (rising_edge(CLK)) then rst_1 <= RST; rst_2 <= rst_1; end if; end process; process(CLK) begin if (rising_edge(CLK)) then if (rst_3 = '1') then ticks_counter <= (others => '0'); ms_counter <= (others => '0'); else ticks_counter <= ticks_counter + '1'; if (ticks_counter = TICKS_FOR_1MS) then ticks_counter <= (others => '0'); ms_counter <= ms_counter + '1'; end if; end if; end if; end process; end behavior; entity PULSE_FORMER is generic ( DELAY : integer ); port ( CLK : in std_logic; SIG_IN : in std_logic; SIG_OUT : out std_logic; ); end PULSE_FORMER; architecture behavior of PULSE_FORMER is signal sig_1 : std_logic; signal sig_2 : std_logic; signal sig_3 : std_logic; signal rise_sig : std_logic; begin SIG_OUT <= rise_sig; sig_3 <= not sig_2 and sig_1; --rising process (CLK) begin if (rising_edge(CLK)) then sig_1 <= SIG_IN; sig_2 <= sig_1; end if; end process; process(CLK) variable del : integer := 0; begin if (rising_edge(CLK)) then if (sig_3 = '1') then rise_sig <= '1'; end if; if (rise_sig = '1') then del := del + 1; if (del = DELAY) then del := 0; rise_sig <= '0'; end if; end if; end if; end process; end behavior; Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Flip-fl0p 4 1 марта, 2021 Опубликовано 1 марта, 2021 · Жалоба 2 часа назад, jenya7 сказал: модуль компилируется. но проблема в том что сигнал рисета приходит от процесса на 120 Мега в процесс 100 Мега и я могу его пропустить. решил заморочиться и сделать модуль счетчика и модуль формирования сигнала рисета Показать содержимое entity MS_COUNT is generic ( TICKS_FOR_1MS : std_logic_vector(31 downto 0); COUNTER_LENGTH : integer ); port ( CLK : in std_logic; RST : in std_logic; COUNTER : out std_logic_vector(COUNTER_LENGTH-1 downto 0) ); end MS_COUNT; architecture behavior of MS_COUNT is signal rst_1 : std_logic; signal rst_2 : std_logic; signal rst_3 : std_logic; signal ticks_counter : std_logic_vector(31 downto 0); signal ms_counter : std_logic_vector(COUNTER_LENGTH-1 downto 0) := (others => '0'); begin rst_3 <= not rst_2 and rst_1; --rising COUNTER <= ms_counter; process (CLK) begin if (rising_edge(CLK)) then rst_1 <= RST; rst_2 <= rst_1; end if; end process; process(CLK) begin if (rising_edge(CLK)) then if (rst_3 = '1') then ticks_counter <= (others => '0'); ms_counter <= (others => '0'); else ticks_counter <= ticks_counter + '1'; if (ticks_counter = TICKS_FOR_1MS) then ticks_counter <= (others => '0'); ms_counter <= ms_counter + '1'; end if; end if; end if; end process; end behavior; entity PULSE_FORMER is generic ( DELAY : integer ); port ( CLK : in std_logic; SIG_IN : in std_logic; SIG_OUT : out std_logic; ); end PULSE_FORMER; architecture behavior of PULSE_FORMER is signal sig_1 : std_logic; signal sig_2 : std_logic; signal sig_3 : std_logic; signal rise_sig : std_logic; begin SIG_OUT <= rise_sig; sig_3 <= not sig_2 and sig_1; --rising process (CLK) begin if (rising_edge(CLK)) then sig_1 <= SIG_IN; sig_2 <= sig_1; end if; end process; process(CLK) variable del : integer := 0; begin if (rising_edge(CLK)) then if (sig_3 = '1') then rise_sig <= '1'; end if; if (rise_sig = '1') then del := del + 1; if (del = DELAY) then del := 0; rise_sig <= '0'; end if; end if; end if; end process; end behavior; Так чего мы ждем ?! Вкорячить синхронизатор на нужный сигнал и горя не знать. Почему еще не сделали это ? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться