nameless 0 23 сентября, 2019 Опубликовано 23 сентября, 2019 · Жалоба type ac_array is array (0 to (slide_len - 1)) of std_logic_vector(9 downto 0); signal A_ac_buff : ac_array; attribute ram_style of A_ac_buff : signal is "bram"; --------------------------------- COMPONENT SR1024 PORT ( d : IN STD_LOGIC; clk : IN STD_LOGIC; ce : IN STD_LOGIC; q : OUT STD_LOGIC );END COMPONENT; ----------------------------------- begin SR1024_0 : SR1024 PORT MAP (d => sr1k_0_in, clk => clk50, ce => sr1k_0_en, q => sr1k_0_out); SR1024_1 : SR1024 PORT MAP (d => sr1k_1_in, clk => clk50, ce => sr1k_1_en, q => sr1k_1_out); ----------------------------------- process(clk50) begin if rising_edge(clk50) then if(...) then sampl_cntr <= 0; AQ1_cntr <= 0; AQ2_cntr <= 0; SHIFT_cntr <= 0; nestd_SH_cntr <= 0; nestd_SH2_cntr <= 0; end if if(sampl_cntr /= sampl) then A_buff(sampl_cntr) <= DA; sampl_cntr <= sampl_cntr + 1; elsif((sampl_cntr=sampl) AND (SHIFT_cntr /= slide_len)) then if(nestd_SH_cntr /= slide_len) then if((sr1k_0_out xor sr1k_1_out) = '1') then ACC0 <= ACC0 + 1; end if; nestd_SH_cntr <= nestd_SH_cntr + 1; elsif((nestd_SH_cntr = slide_len) AND (nestd_SH2_cntr /= 1)) then -- здесь +1 такт для дополнительного сдвига (не описано) buff_10bit_std <= conv_std_logic_vector(ACC0,16)(11 downto 2); nestd_SH2_cntr <= nestd_SH2_cntr + 1; elsif((nestd_SH_cntr = slide_len) AND (nestd_SH2_cntr = 1)) then nestd_SH_cntr <= 0; nestd_SH2_cntr <= 0; ACC0 <= 0; SHIFT_cntr <= SHIFT_cntr + 1; end if; A_ac_buff(SHIFT_cntr) <= buff_10bit_std; --conv_std_logic_vector(SHIFT_cntr,16)(9 downto 0);-- ВОТ ЗДЕСЬ!!!!!!!!!!!!!!!!!!!!!!!!!!!! elsif(...)then divider <= divider + 1; if(...) then if(...) then Tx_data_int <= A_ac_buff(...); end if; end if; end if; end if; end process; Прошу прощения за длинные имена. Почему синтезатор "внешний" счетчик (SHIFT_cntr) писать в память A_ac_buff() позволяет а buff_10bit_std - нет? Не позволяет - это значит синтезирует бесконечно. sr1k_0_out и sr1k_1_out - выходы сдвиговых регистров. Длина сдвиговых регистров не влияет на собираемость проекта. Может быть что-то не так с моим сдвиговым? library IEEE; use IEEE.STD_LOGIC_1164.ALL; entity SR1024 is -------------------------------------------------------------------------- generic ( n : integer := 1024 ); port ( d : in std_logic; clk : in std_logic; ce : in std_logic; q : out std_logic); end SR1024; architecture Behavioral of SR1024 is signal tmp: std_logic_vector(n-1 downto 0) := (Others => '0'); begin process (clk) begin if (clk'event and clk = '1') then if (ce = '1') then tmp(0) <= d; for idx in 1 to n-1 loop tmp(idx) <= tmp(idx-1); end loop; end if; end if; end process; q <= tmp(n-1); end Behavioral; Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
andrew_su 1 23 сентября, 2019 Опубликовано 23 сентября, 2019 · Жалоба Добрый день. library IEEE; use IEEE.STD_LOGIC_1164.ALL; entity top is generic ( n : integer := 1024 ); port ( d : in std_logic; clk : in std_logic; ce : in std_logic; q : out std_logic); end top; architecture Behavioral of top is signal tmp: std_logic_vector(n-1 downto 0) := (Others => '0'); begin process (clk) begin if (clk'event and clk = '1') then if (ce = '1') then ---------------------------------------------------------------------------------------------------------------- -- Вместо ---------------------------------------------------------------------------------------------------------------- -- tmp(0) <= d; -- for idx in 1 to n-1 loop tmp(idx) <= tmp(idx-1); end loop; ---------------------------------------------------------------------------------------------------------------- -- вот это ---------------------------------------------------------------------------------------------------------------- tmp <= tmp(n-2 downto 0) & d; ---------------------------------------------------------------------------------------------------------------- end if; end if; end process; q <= tmp(n-1); end Behavioral; Удачи. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
nameless 0 24 сентября, 2019 Опубликовано 24 сентября, 2019 · Жалоба Спасибо. Но не помогло. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Flip-fl0p 4 24 сентября, 2019 Опубликовано 24 сентября, 2019 · Жалоба разбейте на счётчики и автомат. Слишком сложная логика, которая ни к чему хорошему не приведет. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
nameless 0 24 сентября, 2019 Опубликовано 24 сентября, 2019 · Жалоба Я как-бы начинающий. И не очень понимаю что значит разбить на счетчики и автомат. Сигналы SHIFT_cntr, nestd_SH_cntr и nestd_SH2_cntr - это разве не счетчики? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Nick_K 0 24 сентября, 2019 Опубликовано 24 сентября, 2019 · Жалоба 1 hour ago, nameless said: разбить на счетчики и автомат Это значит сделать, грубо говоря, в одном процессе описание поведения только одного сигнала (если есть очень схожие сигналы по поведению, то их можно добавить в этот процесс). В результате должно получится несколько процессов с 1-2мя условиями if-else не более. Иначе синтезатор может сойти с ума, а в ISE вообще могут вылезти "волшебные" приколы. Sample_proc: process(clk50) begin if rising_edge(clk50) then if reset = '1' then sampl_cntr <= 0; end if; if(sampl_cntr /= sampl) then sampl_cntr <= sampl_cntr + 1; end if; end if; end process Sample_proc' Nested_counter: process(clk50) begin if rising_edge(clk50) then if reset = '1' then nestd_SH_cntr <= 0; end if; if(sampl_cntr=sampl) AND (SHIFT_cntr /= slide_len) AND (nestd_SH_cntr /= slide_len) then nestd_SH_cntr <= nestd_SH_cntr + 1; end if; end if; end process Nested_counter; // и так далее. Это просто пример, логика может быть не соблюдена. Кстати, после "end if" нужно ставить точку с запятой. Возможно это Вы так вырезали непонятно кусками, а возможно и в коде ошибки (почему желательно приводить или полный исходный код или пример с аналогичной проблемой, но орбязательно ПОЛНОСТЬЮ). Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Flip-fl0p 4 24 сентября, 2019 Опубликовано 24 сентября, 2019 · Жалоба 2 часа назад, Nick_K сказал: Это значит сделать, грубо говоря, в одном процессе описание поведения только одного сигнала (если есть очень схожие сигналы по поведению, то их можно добавить в этот процесс). В результате должно получится несколько процессов с 1-2мя условиями if-else не более. Иначе синтезатор может сойти с ума, а в ISE вообще могут вылезти "волшебные" приколы. Sample_proc: process(clk50) begin if rising_edge(clk50) then if reset = '1' then sampl_cntr <= 0; end if; if(sampl_cntr /= sampl) then sampl_cntr <= sampl_cntr + 1; end if; end if; end process Sample_proc' Nested_counter: process(clk50) begin if rising_edge(clk50) then if reset = '1' then nestd_SH_cntr <= 0; end if; if(sampl_cntr=sampl) AND (SHIFT_cntr /= slide_len) AND (nestd_SH_cntr /= slide_len) then nestd_SH_cntr <= nestd_SH_cntr + 1; end if; end if; end process Nested_counter; // и так далее. Это просто пример, логика может быть не соблюдена. Именно так. Сложную задачу лучше разбить на несколько мелких. Хоть и количество строчек кода будет больше. Но главное качество, а не количество. Если алгоритм сложный - его, как правило проще реализовать не кучей условий if-else, а одним или несколькими конечными автоматами. Но надо понимать, что не все алгоритмы можно так реализовать... Пусть автор сперва озвучит свою задачу... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Volkov 0 24 сентября, 2019 Опубликовано 24 сентября, 2019 · Жалоба On 9/23/2019 at 3:26 PM, nameless said: Почему синтезатор "внешний" счетчик (SHIFT_cntr) писать в память A_ac_buff() позволяет а buff_10bit_std - нет? Не позволяет - это значит синтезирует бесконечно. Если у вас память двух-портовая, опишите память отдельными процессами чтения и записи. UG901. Chapter 4: HDL Coding Techniques process(clk) begin if clk'event and clk = '1' then if ena = '1' then if wea = '1' then RAM(conv_integer(addra)) := dia; end if; end if; end if; end process; process(clk) begin if clk'event and clk = '1' then if enb = '1' then dob <= RAM(conv_integer(addrb)); end if; end if; end process; Если одно-портовая, то одним отдельным процессом. process(clk) begin if clk'event and clk = '1' then if en = '1' then if we = '1' then RAM(conv_integer(addr)) <= di; end if; do <= RAM(conv_integer(addr)); end if; end if; end process; И не нужно будет гадать - почему синтезатор не синтезирует. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
nameless 0 24 сентября, 2019 Опубликовано 24 сентября, 2019 · Жалоба Ну хорошо. Отдельные процессы. А если я делаю очередь из того, что делается в процессах? Счетчик в одном процессе досчитал до нужного значения и сообщил тем самым другому процессу о начале счета другого. Как при этом сбрасывать счетчики? В третьем процессе? Так синтезатор не дает делать. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Flip-fl0p 4 24 сентября, 2019 Опубликовано 24 сентября, 2019 · Жалоба 28 минут назад, nameless сказал: Ну хорошо. Отдельные процессы. А если я делаю очередь из того, что делается в процессах? Счетчик в одном процессе досчитал до нужного значения и сообщил тем самым другому процессу о начале счета другого. Как при этом сбрасывать счетчики? В третьем процессе? Так синтезатор не дает делать. Цифровой автомат Вам в помощь. Finit state machine - FSM Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
iosifk 3 24 сентября, 2019 Опубликовано 24 сентября, 2019 · Жалоба 28 минут назад, Flip-fl0p сказал: Цифровой автомат Вам в помощь. Finit state machine - FSM Я дополню. У Вас nameless, неправильный подход к описанию. Вы пишите так, как это делается для программирования. Т.е. "условие - действие". И в случае программирования - это правильно. Но не в случае описания железа. Вы должны отдельно описать цифровые узлы, например вот такие счетчики - "sampl_cntr <= sampl_cntr + 1;" и для каждого узла сделать вывод разрешающий какое-то действие: счет, обнуление, хранение и тд. А потом описать отдельный узел, который "ведет" процесс управления другими узлами, при этом он только активизирует сигналы управления. И как правильно сказал Flip-fl0p, удобнее это делать в виде автомата. И видимо личное сообщение к Вам (ТС) не пришло... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
SII 0 24 сентября, 2019 Опубликовано 24 сентября, 2019 · Жалоба 6 hours ago, Nick_K said: Sample_proc: process(clk50) begin if rising_edge(clk50) then if reset = '1' then sampl_cntr <= 0; end if; if(sampl_cntr /= sampl) then sampl_cntr <= sampl_cntr + 1; end if; end if; end process Sample_proc' Nested_counter: process(clk50) begin if rising_edge(clk50) then if reset = '1' then nestd_SH_cntr <= 0; end if; if(sampl_cntr=sampl) AND (SHIFT_cntr /= slide_len) AND (nestd_SH_cntr /= slide_len) then nestd_SH_cntr <= nestd_SH_cntr + 1; end if; end if; end process Nested_counter; // и так далее. Это просто пример, логика может быть не соблюдена. Подобным образом писать процессы нельзя, поскольку может игнорироваться сигнал сброса. Правильно примерно так: process (Clk) is begin if rising_edge(Clk) then if Reset = '1' then Counter <= 0; elsif Count_Enable = '1' then Counter <= Counter + 1; end if; end if; end process; Ошибка в том, что, если не делать else, будут проверяться все условия, и в итоге счётчик получит значение, определяемое последним истинным условием. 1 hour ago, iosifk said: У Вас nameless, неправильный подход к описанию. Вы пишите так, как это делается для программирования. Это обычная беда начинающих, а временами и не очень-то начинающих "железописателей". Как по мне, осваивать электронику надо всё ж с рассыпухи -- реальных логических элементов, триггеров и т.п., чтоб на практике понять, а как оно в действительности работает, и приучить себя мыслить соответствующим образом. Заодно будешь понимать, во что примерно код на VHDL или другим "железном" языке будет синтезироваться. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Nick_K 0 24 сентября, 2019 Опубликовано 24 сентября, 2019 · Жалоба 3 minutes ago, SII said: Подобным образом писать процессы нельзя, поскольку может игнорироваться сигнал сброса. Правильно примерно так: Во-первых я написал, что Это просто пример, логика может быть не соблюдена. Я и не собирался писать абсолютно правильную конструкцию. Во-вторых Xilinx рекомендует писать ваш пример так: process (Clk) is begin if rising_edge(Clk) then if Reset = '1' then Counter <= 0; else if Count_Enable = '1' then Counter <= Counter + 1; end if; end if; end if; end process; Думаю альтера где-то так же. В-третьих если написать так: process (Clk) is begin if rising_edge(Clk) then if Count_Enable = '1' then Counter <= Counter + 1; end if; if Reset = '1' then Counter <= 0; end if; end if; end process; то конструкция всегда будет синтезирована правильно (как задумывается) даже если у вас будет нескколько условий сброса (например (Reset = '1' and Clear = '1')) чего не скажешь про первую конструкцию, которая может потребовать дополнительного сигнала Reset_and <= Reset and Clear либо воткнёт где ненужно мультиплексор. По крайней мере это было проверено неоднократно в ISE за многие годы разработки. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Maverick_ 15 24 сентября, 2019 Опубликовано 24 сентября, 2019 · Жалоба Для начала открываем Template у каждого программного продукта он имеется. + coding style guidelines (например) Берем оттуда готовые описания, подгоняем под свои нужды и делаем для каждого описания отдельные файлы. Далее в топе просто их соединяем, как модули Для начала думаю будет норм... Далее смотрит отчет синтезатора и смотрит RTL вьювер - что и как получилось. Вместо рисования схемы на бумаге.. Далее можно попытаться объеденить базовые описания в одном (счетчики, дешифраторы мультиплексоры и т.д. описание памяти желательно оставить в отдельном файле) и посмотреть разницу... Не забываем про симуляцию... Иначе будет каша... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Bad0512 2 25 сентября, 2019 Опубликовано 25 сентября, 2019 · Жалоба 14 hours ago, Nick_K said: В-третьих если написать так: process (Clk) is begin if rising_edge(Clk) then if Count_Enable = '1' then Counter <= Counter + 1; end if; if Reset = '1' then Counter <= 0; end if; end if; end process; то конструкция всегда будет синтезирована правильно (как задумывается) даже если у вас будет нескколько условий сброса (например (Reset = '1' and Clear = '1')) чего не скажешь про первую конструкцию, которая может потребовать дополнительного сигнала Reset_and <= Reset and Clear либо воткнёт где ненужно мультиплексор. По крайней мере это было проверено неоднократно в ISE за многие годы разработки. Что вы понимаете под "правильно"? В коде есть неоднозначность, которая позволяет синтезатору по своему разумению расставить приритеты между сигналами reset и count_enable. Думаете он знает как "правильно" с вашей точки зрения? Что будет в случае если reset = 1 и count_enable = 1 ? Какое событие произойдёт и почему? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться