Что это такое
Я пытаюсь создать простой FIR-фильтр. То, что я собираюсь вам представить, может быть не совсем КИХ-фильтром, поскольку я постепенно увеличиваю сложность своего проекта для образовательных целей, пока он не достигнет желаемой функциональности.
Что он должен делать
В основном, что он должен делать до сих пор:
- загрузить данные в регистры после приложения load = 1,
- выгрузить обработанные данные (которые являются произведением умножения выборок с соответствующими коэффициентами) после применения start = 1.
Где это не удается
Однако из того, что я заметил, он не может загружать данные в регистры. Похоже, работает как защелка, поскольку после того, как load упадет до 0, последнее значение вектора на входном порте фиксируется в регистрах. Но я могу ошибаться, это просто похоже на то, как это работает в симуляции. Функциональное моделирование до и после синтеза работает! Только время после синтеза не работает должным образом!
Что я пробовал
- Добавление параметра DONT_TOUCH к объявлению объекта в его .vhd файле,
- Добавление типа буфера (беззнаковая переменная) после порта data_in, из которого данные передаются в регистры - но он даже не появился в схеме после синтеза, может быть, DONT_TOUCH не сработал?
Моделирование картинок
Функционал до синтеза - https://imgur.com/0TaNQyn
Время после синтеза - https://imgur.com/mEOv67t
Программа
Я использую веб-пакет Vivado 2020.2
Testbench
Код Testbench здесь: https://pastebin.pl/view/d2f9a4ad
Основной код
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.numeric_std.ALL;
entity fir is
Port (
clk: in std_logic;
data_in: in unsigned(7 downto 0);
data_out: out unsigned(7 downto 0);
en: in std_logic;
load: in std_logic;
start: in std_logic;
reset: in std_logic
);
end fir;
architecture Behavioral of fir is
-- type coeff_array is array (0 to 7) of integer range 0 to 255;
constant reg_size: integer := 8;
constant filter_order: integer := 7;
type samples_reg is array (0 to reg_size-1) of unsigned(7 downto 0);
type coeffs_reg is array (0 to filter_order) of unsigned(7 downto 0);
begin
process(clk, reset)
-- variable coeffs: coeff_array := (0,0,0,0,0,0,0,0);
--variable b0: unsigned(7 downto 0) := 8D"0";
variable b0: unsigned(7 downto 0) := to_unsigned(1,8);
variable b1: unsigned(7 downto 0) := to_unsigned(2,8);
variable b2: unsigned(7 downto 0) := to_unsigned(3,8);
variable b3: unsigned(7 downto 0) := to_unsigned(4,8);
variable b4: unsigned(7 downto 0) := to_unsigned(5,8);
variable b5: unsigned(7 downto 0) := to_unsigned(6,8);
variable b6: unsigned(7 downto 0) := to_unsigned(7,8);
variable b7: unsigned(7 downto 0) := to_unsigned(8,8);
variable i: integer range 0 to reg_size := 0;
variable samples: samples_reg := (others => (others => '0'));
variable coeffs: coeffs_reg := (b0,b1,b2,b3,b4,b5,b6,b7);
variable data_processed: unsigned(15 downto 0) := (others => '0');
-- variable reg_element:
-- signal s1 : signed(47 downto 0) := 48D"46137344123";
begin
if reset = '1' then
-- data_out <= (others => '0');
samples := (others => (others => '0'));
data_processed := (others => '0');
i := 0;
-- synch part
elsif rising_edge(clk) and en = '1' then
samples := samples;
-- loading data
if load = '1' then
samples(i) := data_in;
i := i+1;
else null;
end if;
-- deloading data
if start = '1' then
data_processed := samples(i)*coeffs(i);
i := i+1;
else null;
end if;
-- reset counter after overflow
if(i = reg_size) then
i := 0;
else null;
end if;
-- reset counter if no data is being transferred
if load = '0' and start = '0' then
i := 0;
data_processed := (others => '0');
else null;
end if;
end if;
data_out <= data_processed(7 downto 0);
end process;
end Behavioral;
Другая информация
- Я только что заметил, что я держу load = 1 для одного чрезмерного цикла, поэтому первым появляется наибольшее число.
- Коэффициенты: 1, 2, 3, 4, 5, 6, 7, 8.
- В постсинтезирующем моделировании после просмотра проверяемого оборудования я заметил, что регистры образцов не загружают данные (за исключением последнего, как я упоминал ранее), i увеличивается и остальное работает нормально.
- Я буду рад услышать о некоторых улучшениях в моем коде в дополнение к решению проблемы!
elsif rising_edge(clk) and en = '1' then
напишите `` elsifising_edge (clk) then if en = '1' then .... end if; конец, если; `` '' - person Oron Port   schedule 14.01.2021i
внутри процесса. Используйте инструкциюfor
. - person Oron Port   schedule 14.01.2021for
, когда я хочу добавлять (или выводить) новые данные за каждый такт. Разве цикл for не будет выполняться за один такт? Не могли бы вы представить пример или реализовать это в моем коде? - person Bartosz Szkoda   schedule 14.01.2021for
генерирует провода. Цикл продвигается только в конце процесса. - person Oron Port   schedule 14.01.2021