GPelya 0 6 мая, 2010 Опубликовано 6 мая, 2010 (изменено) · Жалоба Вот такой простой код на VHDL entity test is port ( clk : in std_ulogic; reset : in std_ulogic; w : out std_ulogic ); end test; architecture test_arh of test is constant clk_counter_width : integer := 3; constant reset_clk_count : integer := 4; signal clk_count : unsigned(2 downto 0); begin clk_proc:process (clk, clk_count, reset) begin if(reset = '1') then clk_count <= to_unsigned(0, clk_counter_width); elsif (clk'event and clk = '1') then if(clk_count = to_unsigned(reset_clk_count, clk_counter_width)) then clk_count <= to_unsigned(0, clk_counter_width); else clk_count <= clk_count + 1; end if; end if; end process; inner_data_w_proc:process (clk_count) begin if(clk_count = to_unsigned(0, clk_counter_width)) then w <= '1'; else w <= '0'; end if; end process; end test_arh; То есть каждый пятый clk такт на выход w устанавливаться единица длительностью в один clk такт. Но при симуляции в Квартусе на микросхеме MAX2 EMP240F100C4, в момент, я так понимаю, когда на входе защёлки сигнал clk_count меняет своё значения с 4h на 0h, на выходной шине регистра на короткое время (0.8 нс) устанавливаются нулевые сигналы на всей выходной шине. Вот схема из RTL Viewer Вот временная диаграмма симуляции Подскажите пожалуйста что это за импульсы и как от них избавиться. Заранее спасибо. С уважением Пётр Сёмкин. Изменено 6 мая, 2010 пользователем GPelya Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
vetal 0 6 мая, 2010 Опубликовано 6 мая, 2010 · Жалоба 1. У вас там не защелка, а компаратор обычный. 2. Импульсы появляются из-за неодновременности срабатывания всех элементов компаратора 3. Решается установкой триггера, работающего по тактовому сигналу счетчика. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
GPelya 0 6 мая, 2010 Опубликовано 6 мая, 2010 · Жалоба 1. У вас там не защелка, а компаратор обычный. 2. Импульсы появляются из-за неодновременности срабатывания всех элементов компаратора 3. Решается установкой триггера, работающего по тактовому сигналу счетчика. Спасибо за разъяснения. Тогда будет задержка на целый такт или пол такта если установить триггер по заднему фронту clk. Что-бы минимизировать задержку, можно ввести искусственные элементы в схему которые будут задерживать сигнал clk до выходного триггера. Может-быть существуют ещё какие-либо пути решения этой проблемы ? С уважением Пётр Сёмкин. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
vetal 0 6 мая, 2010 Опубликовано 6 мая, 2010 · Жалоба Может-быть существуют ещё какие-либо пути решения этой проблемы ? Да: 1. Сравнивать с константой не выход счетчика, а его вход. 2. Сравнивать не с 0, а с предшествующем ему значением. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Des333 0 6 мая, 2010 Опубликовано 6 мая, 2010 · Жалоба ... Что-бы минимизировать задержку, можно ввести искусственные элементы в схему которые будут задерживать сигнал clk до выходного триггера... Вот так ни в коем случае делать не стоит. :bb-offtopic: Еще в теме про ШИМ стало интересно - если не секрет, почему решили изучать VHDL, а не Verilog? :) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
GPelya 0 6 мая, 2010 Опубликовано 6 мая, 2010 (изменено) · Жалоба Да: 1. Сравнивать с константой не выход счетчика, а его вход. 2. Сравнивать не с 0, а с предшествующем ему значением. Можно ли как-то в процедурном стиле на VHDL вставить свой компаратор на шину между мультиплексором и триггером, или в этом случае необходимо использовать структурный стиль VHDL ? Вот так ни в коем случае делать не стоит. :bb-offtopic: Еще в теме про ШИМ стало интересно - если не секрет, почему решили изучать VHDL, а не Verilog? :) Да, я так понимаю, это не переносимо и задержки такого рода зависят от внешних факторов. Спасибо за совет. Решил изучать VHDL, просто потому что на него первого наткнулся. Наверно, если понадобится перейти на Verilog, это не будет очень сложным. Видемо VHDL и Verilog созданы в сущности для одного и того-же. Просто как я понял у них немного отличаются языковые конструкции. Изменено 6 мая, 2010 пользователем GPelya Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Des333 0 6 мая, 2010 Опубликовано 6 мая, 2010 · Жалоба Решил изучать VHDL, просто потому что на него первого наткнулся. Наверно, если понадобится перейти на Verilog, это не будет очень сложным. Видемо VHDL и Verilog созданы в сущности для одного и того-же. Просто как я понял у них немного отличаются языковые конструкции. Не для разведение холивара, а просто свое личное мнение. Лучше изучать Verilog, так как существует еще SystemVerilog - если собираетесь заниматься верификацией, очень пригодится. У него есть еще плюсы, но эти языки столько раз обсуждали и сравнивали, что еще раз начинать не стоит. :) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
glock17 0 7 мая, 2010 Опубликовано 7 мая, 2010 · Жалоба Тогда будет задержка на целый такт или пол такта если установить триггер по заднему фронту clk. добрый совет: придерживайтесь одного фронта внутри дизайна. не надо по заднему... :rolleyes: не для разведения холивара, а токмо для сравнения: VERILOG: module test ( input clk, input reset, output reg w ); parameter reset_clk_count = 3'd4; reg [2:0] clk_count; always @(posedge clk or posedge reset) if (reset) begin clk_count <= 3'b0; w <= 1'b0; end else begin if (clk_count == reset_clk_count) begin clk_count <= 3'b0; w <= 1'b1; end else begin clk_count <= clk_count + 1'b1; w <= 1'b0; end end endmodule VHDL: library IEEE; use IEEE.std_logic_1164.all; use IEEE.numeric_std.all; entity test is port ( clk : in std_ulogic; reset : in std_ulogic; w : out std_ulogic ); end test; architecture test_arh of test is constant clk_counter_width : integer := 3; constant reset_clk_count : integer := 4; signal clk_count : unsigned(2 downto 0); begin clk_proc:process (clk, clk_count, reset) begin if(reset = '1') then clk_count <= to_unsigned(0, clk_counter_width); w <= '0'; elsif (clk'event and clk = '1') then if(clk_count = to_unsigned(reset_clk_count, clk_counter_width)) then clk_count <= to_unsigned(0, clk_counter_width); w <= '1'; else clk_count <= clk_count + 1; w <= '0'; end if; end if; end process; end test_arh; UPD: нет обработки сигнала w в ветке reset, некоторые синтезаторы (в частности ква) ох сильно сие не любят %) согласен, проглядел... как грицца, и на старуху бывает проруха... поправил Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
des00 25 7 мая, 2010 Опубликовано 7 мая, 2010 · Жалоба :rolleyes: не для разведения холивара, а токмо для сравнения: нет обработки сигнала w в ветке reset, некоторые синтезаторы (в частности ква) ох сильно сие не любят %) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
GPelya 0 7 мая, 2010 Опубликовано 7 мая, 2010 · Жалоба добрый совет: придерживайтесь одного фронта внутри дизайна. не надо по заднему... :rolleyes: не для разведения холивара, а токмо для сравнения: Добрый день Спасибо за помощь. Verilog лаконичней. Такую схему RTL Viewer создал из вашего примера. Два триггера (clk_count и w_reg0) сидят на одном clk сигнале, получается если задержка на компараторе будет больше чем время срабатывания триггера (например будут высоко-разрядная шина), то сигнал w будет отставать на один синхро-импульс. Добавил процесс, который по сути делает то-же самое (судя по RTL схеме). inner_data_w_proc:process (clk_count, clk) begin if(reset = '1') then w <= '0'; elsif(clk'event and clk = '1') then if(clk_count = to_unsigned(0, clk_counter_width)) then w <= '1'; else w <= '0'; end if; end if; end process; RTL схема При таком решении сигнал w действительно запаздывает на одни clk. И там и там оба триггера защелкиваются от одного clk сигнала. И там и там между ними компаратор. Разница только в том, как я понимаю, что в первом случае мультиплексор управляется сигналом после триггера clk_count , во втором случае мультиплексор переключаться до триггера. Пожалуйста проясните, столь разное поведение этих схем. С уважением Пётр Сёмкин. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
glock17 0 7 мая, 2010 Опубликовано 7 мая, 2010 · Жалоба Добавил процесс, который по сути делает то-же самое (судя по RTL схеме). не то же самое. появление еще одного компаратора в схеме не насторожило? в первом случае: if(clk_count = to_unsigned(reset_clk_count, clk_counter_width)) then w <= '1'; во втором: if(clk_count = to_unsigned(0, clk_counter_width)) then w <= '1'; разницу заметили? если нет, посмотрите внимательно на входы "B" обоих компараторов... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
GPelya 0 7 мая, 2010 Опубликовано 7 мая, 2010 (изменено) · Жалоба не то же самое. появление еще одного компаратора в схеме не насторожило? в первом случае: if(clk_count = to_unsigned(reset_clk_count, clk_counter_width)) then w <= '1'; во втором: if(clk_count = to_unsigned(0, clk_counter_width)) then w <= '1'; разницу заметили? если нет, посмотрите внимательно на входы "B" обоих компараторов... Насторожило, но невнимательно смотрел. Триггер w использует предыдущее значение с триггера clk_count и компаратора, к тому времени как входной на него сигнал изменился (отработал clk_count триггер и компаратор), он уже защёлкнул входящее состояние установленное на предыдущем шаге(единице при clk_count равным четырем) . Спасибо за разъяснения. Такой-же результат получается отдельным процессом при сравнении не с нулем а с reset_clk_count inner_data_w_proc:process (clk_count, clk) begin if(reset = '1') then w <= '0'; elsif(clk'event and clk = '1') then if(clk_count = to_unsigned(reset_clk_count, clk_counter_width)) then w <= '1'; else w <= '0'; end if; end if; end process; С уважение Пётр Сёмкин. Изменено 7 мая, 2010 пользователем GPelya Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
GPelya 0 7 мая, 2010 Опубликовано 7 мая, 2010 · Жалоба У нас получается, сигнал w дает первый единичный импульс спустя 5 тактов clk после спада сигнала reset. Хотелось-бы сократить эту задержку на один clk такт. Попробовал по reset установить clk_count в reset_clk_count. Но RTL Viewer к сожалению показал немного непонятную схему и симуляция тоже дала неожиданные значения clk_count . clk_proc:process (clk, clk_count, reset) begin if(reset = '1') then clk_count <= to_unsigned(reset_clk_count, clk_counter_width); w <= '0'; elsif (clk'event and clk = '1') then if(clk_count = to_unsigned(reset_clk_count, clk_counter_width)) then clk_count <= to_unsigned(0, clk_counter_width); w <= '1'; else clk_count <= clk_count + 1; w <= '0'; end if; end if; end process; RTL Viewer Временная диаграмма симуляции Разъясните пожалуйста в чем тут проблема. И каким способом можно добиться желаемого поведения сигнала w сохранить правильный порядок счётчика clk_count. Заранее спасибо. С уважением Пётр Сёмкин. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Des333 0 7 мая, 2010 Опубликовано 7 мая, 2010 · Жалоба У нас получается, сигнал w дает первый единичный импульс спустя 5 тактов clk после спада сигнала reset. Хотелось-бы сократить эту задержку на один clk такт. Счтитайте не до n, а до n-1 :) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
GPelya 0 7 мая, 2010 Опубликовано 7 мая, 2010 (изменено) · Жалоба Счтитайте не до n, а до n-1 :) Прошу прощения я опечатался. Имелось в виду не на один clk такт, а до одного такта. И я имею ввиду сократить не интервал между тактами w, а интервал между спадам reset и первым импульсом w. Добавил выходной порт out_clk_count, вывожу на него clk_count. out_clk_count <= clk_count; clk_proc:process (clk, clk_count, reset) begin if(reset = '1') then clk_count <= to_unsigned(reset_clk_count, clk_counter_width); w <= '0'; elsif (clk'event and clk = '1') then if(clk_count = to_unsigned(reset_clk_count, clk_counter_width)) then clk_count <= to_unsigned(0, clk_counter_width); w <= '1'; else clk_count <= clk_count + 1; w <= '0'; end if; end if; end process; Вот временная диаграмма Как видно out_clk_count полностью соответствует ожиданиям. Видимо такие "странные" сигналы внутренней шины clk_count связанны с оптимизацией схемы. Что по определению не должно сказывается на логике её работы. С уважением Пётр Сёмкин. Изменено 7 мая, 2010 пользователем GPelya Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться