我正在用 Verilog 设计一个 50 抽头低通 FIR 滤波器。我有一个非常简单的用例:我有一个向量,它是两个正弦波的总和,我想过滤出较高频率的一个。我的数据向量是 4096 字节长。我的系数(抽头)向量是 50 个 32 位数字长。我不确定波浪的结果向量应该有多长和多宽。现在我有一个 46 位的数字作为结果,但这对我来说听起来不对。如果过滤后的波只有一个 46 位长,我看不出它是如何绘制的;我最初是这样做的,因为我在上一个问题中读到长度应该是这样的:(data_width + coeff_width + integer(ceil(log2(real(taps)))) - 1) DOWNTO 0)
which would be (8 + 32 + 5) DOWNTO 0 = 46 bits long
.
我可以就结果的长度和宽度获得指导吗?
以防万一,这是我的过滤器代码的相关部分:
LIBRARY ieee;
USE ieee.std_logic_1164.all;
USE ieee.numeric_std.all;
USE ieee.math_real.all;
USE work.types.all;
ENTITY fir_filter IS
PORT(
clk : IN STD_LOGIC; --system clock
reset_n : IN STD_LOGIC; --active low asynchronous reset
--filt_data: IN STD_LOGIC_VECTOR(7 DOWNTO 0); --data stream
--coeff_stream: IN STD_LOGIC_VECTOR(31 DOWNTO 0);
--coefficients: IN coefficient_array; --coefficient array
--result : OUT STD_LOGIC_VECTOR((data_width + coeff_width + integer(ceil(log2(real(taps)))) - 1) DOWNTO 0)); --filtered result
result : OUT STD_LOGIC_VECTOR((data_width + coeff_width + integer(ceil(log2(real(taps)))) - 1) DOWNTO 0));
END fir_filter;
ARCHITECTURE behavior OF fir_filter IS
SIGNAL coeff_int : coefficient_array; --array of latched in coefficient values
SIGNAL data_pipeline : data_array; --pipeline of historic data values
SIGNAL products : product_array; --array of coefficient*data products
SIGNAL coefficients : coefficient_array;
SIGNAL addr_coeff: STD_LOGIC_VECTOR(7 DOWNTO 0);
SIGNAL count_coeff: STD_LOGIC_VECTOR(7 DOWNTO 0);
SIGNAL addr_filt: STD_LOGIC_VECTOR(11 DOWNTO 0);
SIGNAL filt_data: STD_LOGIC_VECTOR(7 DOWNTO 0);
SIGNAL coeff_stream: STD_LOGIC_VECTOR(31 DOWNTO 0);
COMPONENT single_port_rom_data
PORT(clk: in STD_LOGIC;
addr: in STD_LOGIC_VECTOR (11 DOWNTO 0);
data: out STD_LOGIC_VECTOR (7 DOWNTO 0)
);
END COMPONENT;
COMPONENT single_port_rom_coeff
PORT(clk: in STD_LOGIC;
addr: in STD_LOGIC_VECTOR (7 DOWNTO 0);
data: out STD_LOGIC_VECTOR (31 DOWNTO 0)
);
END COMPONENT;
BEGIN
rom_data: single_port_rom_data PORT MAP(
clk => clk ,
addr => addr_filt,
data => filt_data);
rom_coeff: single_port_rom_coeff PORT MAP(
clk => clk ,
addr => addr_coeff,
data=> coeff_stream);
PROCESS(clk, coeff_stream)
BEGIN
FOR j IN 0 TO (taps - 1) LOOP
count_coeff <= std_logic_vector(to_unsigned(j,8));
addr_coeff <= count_coeff;
coefficients(j) <= coeff_stream;
END LOOP;
END PROCESS;
PROCESS(clk, filt_data)
BEGIN
FOR jj IN 0 TO (size - 1) LOOP
addr_filt <= std_logic_vector(to_unsigned(jj, 12));
--using filt_data below
END LOOP;
END PROCESS;
PROCESS(clk, reset_n)
VARIABLE sum : SIGNED((data_width + coeff_width + integer(ceil(log2(real(taps)))) - 1) DOWNTO 0); --sum of products
BEGIN
IF(reset_n = '0') THEN --asynchronous reset
data_pipeline <= (OTHERS => (OTHERS => '0')); --clear data pipeline values
coeff_int <= (OTHERS => (OTHERS => '0')); --clear internal coefficient registers
result <= (OTHERS => '0'); --clear result output
ELSIF(clk'EVENT AND clk = '1') THEN --not reset
coeff_int <= coefficients; --input coefficients
data_pipeline <= SIGNED(filt_data) & data_pipeline(0 TO size-2); --shift new data into data pipeline (was taps-2)
sum := (OTHERS => '0'); --initialize sum
FOR i IN 0 TO taps-1 LOOP
sum := sum + products(i); --add the products
END LOOP;
result <= STD_LOGIC_VECTOR(sum); --output result
END IF;
END PROCESS;
--perform multiplies
product_calc: FOR i IN 0 TO taps-1 GENERATE
products(i) <= data_pipeline(i) * SIGNED(coeff_int(i));
END GENERATE;
END behavior;
类型.vhd:
PACKAGE types IS
CONSTANT taps : INTEGER := 50; --number of fir filter taps
CONSTANT data_width : INTEGER := 8; --width of data input including sign bit
CONSTANT coeff_width : INTEGER := 32; --width of coefficients including sign bit
CONSTANT size : INTEGER := 4096; --length of sign wave
TYPE coefficient_array IS ARRAY (0 TO taps-1) OF STD_LOGIC_VECTOR(coeff_width-1 DOWNTO 0); --array of all coefficients
--TYPE data_array IS ARRAY (0 TO taps-1) OF SIGNED(data_width-1 DOWNTO 0); --array of historic data values
--TYPE product_array IS ARRAY (0 TO taps-1) OF SIGNED((data_width + coeff_width)-1 DOWNTO 0); --array of coefficient * data products
TYPE data_array IS ARRAY (0 TO size-1) OF SIGNED(data_width-1 DOWNTO 0); --array of historic data values
TYPE product_array IS ARRAY (0 TO size-1) OF SIGNED((data_width + coeff_width)-1 DOWNTO 0);
END PACKAGE types;