nameless 0 September 23, 2019 Posted September 23, 2019 · Report post 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; Quote Share this post Link to post Share on other sites More sharing options...
andrew_su 1 September 23, 2019 Posted September 23, 2019 · Report post Добрый день. 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; Удачи. Quote Share this post Link to post Share on other sites More sharing options...
nameless 0 September 24, 2019 Posted September 24, 2019 · Report post Спасибо. Но не помогло. Quote Share this post Link to post Share on other sites More sharing options...
Flip-fl0p 4 September 24, 2019 Posted September 24, 2019 · Report post разбейте на счётчики и автомат. Слишком сложная логика, которая ни к чему хорошему не приведет. Quote Share this post Link to post Share on other sites More sharing options...
nameless 0 September 24, 2019 Posted September 24, 2019 · Report post Я как-бы начинающий. И не очень понимаю что значит разбить на счетчики и автомат. Сигналы SHIFT_cntr, nestd_SH_cntr и nestd_SH2_cntr - это разве не счетчики? Quote Share this post Link to post Share on other sites More sharing options...
Nick_K 0 September 24, 2019 Posted September 24, 2019 · Report post 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" нужно ставить точку с запятой. Возможно это Вы так вырезали непонятно кусками, а возможно и в коде ошибки (почему желательно приводить или полный исходный код или пример с аналогичной проблемой, но орбязательно ПОЛНОСТЬЮ). Quote Share this post Link to post Share on other sites More sharing options...
Flip-fl0p 4 September 24, 2019 Posted September 24, 2019 · Report post 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, а одним или несколькими конечными автоматами. Но надо понимать, что не все алгоритмы можно так реализовать... Пусть автор сперва озвучит свою задачу... Quote Share this post Link to post Share on other sites More sharing options...
Volkov 0 September 24, 2019 Posted September 24, 2019 · Report post 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; И не нужно будет гадать - почему синтезатор не синтезирует. Quote Share this post Link to post Share on other sites More sharing options...
nameless 0 September 24, 2019 Posted September 24, 2019 · Report post Ну хорошо. Отдельные процессы. А если я делаю очередь из того, что делается в процессах? Счетчик в одном процессе досчитал до нужного значения и сообщил тем самым другому процессу о начале счета другого. Как при этом сбрасывать счетчики? В третьем процессе? Так синтезатор не дает делать. Quote Share this post Link to post Share on other sites More sharing options...
Flip-fl0p 4 September 24, 2019 Posted September 24, 2019 · Report post 28 минут назад, nameless сказал: Ну хорошо. Отдельные процессы. А если я делаю очередь из того, что делается в процессах? Счетчик в одном процессе досчитал до нужного значения и сообщил тем самым другому процессу о начале счета другого. Как при этом сбрасывать счетчики? В третьем процессе? Так синтезатор не дает делать. Цифровой автомат Вам в помощь. Finit state machine - FSM Quote Share this post Link to post Share on other sites More sharing options...
iosifk 3 September 24, 2019 Posted September 24, 2019 · Report post 28 минут назад, Flip-fl0p сказал: Цифровой автомат Вам в помощь. Finit state machine - FSM Я дополню. У Вас nameless, неправильный подход к описанию. Вы пишите так, как это делается для программирования. Т.е. "условие - действие". И в случае программирования - это правильно. Но не в случае описания железа. Вы должны отдельно описать цифровые узлы, например вот такие счетчики - "sampl_cntr <= sampl_cntr + 1;" и для каждого узла сделать вывод разрешающий какое-то действие: счет, обнуление, хранение и тд. А потом описать отдельный узел, который "ведет" процесс управления другими узлами, при этом он только активизирует сигналы управления. И как правильно сказал Flip-fl0p, удобнее это делать в виде автомата. И видимо личное сообщение к Вам (ТС) не пришло... Quote Share this post Link to post Share on other sites More sharing options...
SII 0 September 24, 2019 Posted September 24, 2019 · Report post 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 или другим "железном" языке будет синтезироваться. Quote Share this post Link to post Share on other sites More sharing options...
Nick_K 0 September 24, 2019 Posted September 24, 2019 · Report post 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 за многие годы разработки. Quote Share this post Link to post Share on other sites More sharing options...
Maverick_ 17 September 24, 2019 Posted September 24, 2019 · Report post Для начала открываем Template у каждого программного продукта он имеется. + coding style guidelines (например) Берем оттуда готовые описания, подгоняем под свои нужды и делаем для каждого описания отдельные файлы. Далее в топе просто их соединяем, как модули Для начала думаю будет норм... Далее смотрит отчет синтезатора и смотрит RTL вьювер - что и как получилось. Вместо рисования схемы на бумаге.. Далее можно попытаться объеденить базовые описания в одном (счетчики, дешифраторы мультиплексоры и т.д. описание памяти желательно оставить в отдельном файле) и посмотреть разницу... Не забываем про симуляцию... Иначе будет каша... Quote Share this post Link to post Share on other sites More sharing options...
Bad0512 2 September 25, 2019 Posted September 25, 2019 · Report post 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 ? Какое событие произойдёт и почему? Quote Share this post Link to post Share on other sites More sharing options...