Michael358 0 30 марта, 2021 Опубликовано 30 марта, 2021 (изменено) · Жалоба Пытаюсь проинициализировать массив чисел(коэффициенты для умножителей) из файла. Почему, если вызывать функцию инициализации при объявлении сигнала, то умножители не синтезируются вообще? А если вызывать инициализацию после begin-а, то умножители синтезируются, но у всех второй множитель равен 1? library IEEE; use IEEE.STD_LOGIC_1164.ALL; USE ieee.numeric_std.ALL; use std.textio.all; -- КИХ-фильтр entity fir is generic( COEF_NUMBER: integer := 32 ); Port( din: in signed(11 downto 0); sout: out signed(31 downto 0); rst: in std_logic; clk: in std_logic); end fir; architecture Behavioral of fir is type t_coef is array (0 to COEF_NUMBER-1) of integer; -- Коэффициенты type t_samples is array (0 to COEF_NUMBER-1) of signed(11 downto 0); -- Отсчёты с АЦП type t_mults is array (0 to COEF_NUMBER-1) of signed(23 downto 0); -- Умножители signal samples: t_samples; signal mults: t_mults; -- Загрузка коэффициентов из файла impure function init_coef return t_coef is file coef_file : text open read_mode is "c:\Users\Mike\Documents\Projects\Projects\FIR\coef.txt"; variable text_line : line; variable var_coef : t_coef ; begin for i in 0 to COEF_NUMBER-1 loop readline(coef_file, text_line); read(text_line, var_coef(i)); end loop; return var_coef; end function; signal coef: t_coef := init_coef; -- !!! Если вызывать функцию инициализации здесь, то умножители не синтезируются вообще begin coef <= init_coef; -- !!! Если инициализировать коэффициенты здесь, то умножители синтезируются, но у всех второй множитель равен 1 -- Поступление очередного отсчёта с АЦП process(rst, clk) begin if rst = '1' then samples <= (others => (others => '0')); elsif rising_edge(clk) then samples(1 to COEF_NUMBER-1) <= samples(0 to COEF_NUMBER-2); samples(0) <= din; end if; end process; -- Умножители mult: for i in 0 to COEF_NUMBER-1 generate mults(i) <= samples(i)*(to_signed(coef(i),12)); end generate; -- Суммирование выходов умножителей process(rst, clk) variable var_sout: signed(31 downto 0); begin if rst = '1' then var_sout := (others => '0'); sout <= (others => '0'); elsif rising_edge(clk) then var_sout := (others => '0'); for i in 0 to COEF_NUMBER-1 loop var_sout := var_sout + mults(i); end loop; sout <= var_sout; end if; end process; end Behavioral; P.S. В modelsim-е всё работает. Но, насколько я понял, это не показатель синтезируемости кода Изменено 30 марта, 2021 пользователем Michael358 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Maverick_ 15 30 марта, 2021 Опубликовано 30 марта, 2021 · Жалоба Для квартуса нужно делать инициализацию из файла *.mif Либо присваивать значения массива прямо из описания... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
des00 25 31 марта, 2021 Опубликовано 31 марта, 2021 · Жалоба Всегда в таких темах интересовало, зачем в RTL коде натягивать сову на глобус? Ну опишите вы массив констант и используйте в коде. Это же не IP корка, где жестко указано что и куда. Если у вас коэффициенты это выход генератора с софта, то небольшой скрипт на питоне завернет эти коэффициенты в массив в пакете/файле и используйте на здоровье. Нет, надо напихать поведенческий код в RTL, а потом долго и упорно бороть почему синтезатор его не видит Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Michael358 0 1 апреля, 2021 Опубликовано 1 апреля, 2021 (изменено) · Жалоба On 3/31/2021 at 6:02 AM, des00 said: скрипт на питоне завернет эти коэффициенты в массив в пакете/файле Спасибо. Сделали так. On 3/31/2021 at 6:02 AM, des00 said: Нет, надо напихать поведенческий код в RTL, а потом долго и упорно бороть почему синтезатор его не видит Я ещё учусь... Хотелось разобраться, почему не работает Изменено 1 апреля, 2021 пользователем Michael358 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться