--- Quote Start ---
to get initial values correctly you need to set accumulators to zero start.
you are scaling by discarding 19 bits. Is that what you wanted?
--- Quote End ---
Yep, those X's are related to the initial values of the C matrix.
As long as I need only 16 bit I have to take only the MSbs at the output. The magnitude is ok. I was a little confused because the very first values at the output of the filter where not shown due to the lack of initialization of the C matrix.
One curiosity, now the filter coefficient are uploaded at the same clock of the input signal. By the way I want to control the coefficient uploading with a different clock (I want to set the coefficient via NIOS PIOs).
I've thought to use a first pio to load the coefficient into c_in and a secondo pio to get the c_in loaded (so it acts like the clock of the previus code). I ended up with this code:
-- This is a generic FIR filter generator
-- It uses W1 bit data/coefficients bits
LIBRARY lpm; -- Using predefined packages
USE lpm.lpm_components.ALL;
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
USE ieee.numeric_std.all;
ENTITY transposed_fir_test IS ------> Interface
GENERIC (W1 : INTEGER := 16; -- Input bit width
W2 : INTEGER := 32; -- Multiplier bit width 2*W1
W3 : INTEGER := 35; -- Adder width = W2+log2(L)-1
W4 : INTEGER := 16; -- Output bit width
L : INTEGER := 15; -- Filter length
Mpipe : INTEGER := 0-- Pipeline steps of multiplier
);
PORT ( clk : IN STD_LOGIC;
rst : IN STD_LOGIC;
Load_x : IN STD_LOGIC;
x_in : IN STD_LOGIC_VECTOR(W1-1 DOWNTO 0);
c_in : IN STD_LOGIC_VECTOR(W1-1 DOWNTO 0);
wr_clk : IN STD_LOGIC;
y_out : OUT STD_LOGIC_VECTOR(W4-1 DOWNTO 0));
END transposed_fir_test;
ARCHITECTURE fpga OF transposed_fir_test IS
SUBTYPE N1BIT IS STD_LOGIC_VECTOR(W1-1 DOWNTO 0);
SUBTYPE N2BIT IS STD_LOGIC_VECTOR(W2-1 DOWNTO 0);
SUBTYPE N3BIT IS STD_LOGIC_VECTOR(W3-1 DOWNTO 0);
TYPE ARRAY_N1BIT IS ARRAY (0 TO L-1) OF N1BIT;
TYPE ARRAY_N2BIT IS ARRAY (0 TO L-1) OF N2BIT;
TYPE ARRAY_N3BIT IS ARRAY (0 TO L-1) OF N3BIT;
SIGNAL x : N1BIT;
SIGNAL y : N3BIT;
SIGNAL c : ARRAY_N1BIT; -- Coefficient array
SIGNAL p : ARRAY_N2BIT; -- Product array
SIGNAL a : ARRAY_N3BIT; -- Adder array
BEGIN
x <= x_in;
Load: PROCESS(wr_clk,Load_x) ------> Load data or coefficient
BEGIN
if(rising_edge(wr_clk)) then
IF (Load_x = '0') THEN
c(L-1) <= c_in; -- Store coefficient in register
FOR I IN L-2 DOWNTO 0 LOOP -- Coefficients shift one
c(I) <= c(I+1);
END LOOP;
ELSE
;
END IF;
end if;
END PROCESS Load;
SOP: PROCESS (clk) ------> Compute sum-of-products
BEGIN
IF rising_edge(clk) THEN
FOR I IN 0 TO L-2 LOOP -- Compute the transposed
a(I) <= std_logic_vector(signed(p(I)) + signed(a(I+1))); -- filter adds
END LOOP;
a(L-1) <=std_logic_vector(resize(signed(p(L-1)),W3)); -- First TAP has
END IF; -- only a register
y <= a(0);
END PROCESS SOP;
-- Instantiate L pipelined multiplier
MulGen: FOR I IN 0 TO L-1 GENERATE
Muls: lpm_mult -- Multiply p(i) = c(i) * x;
GENERIC MAP ( LPM_WIDTHA => W1, LPM_WIDTHB => W1,
LPM_PIPELINE => Mpipe,
LPM_REPRESENTATION => "SIGNED",
LPM_WIDTHP => W2,
LPM_WIDTHS => W2)
PORT MAP ( dataa => x,
datab => c(I), result => p(I));
END GENERATE;
y_out <=y(W3-1 DOWNTO W3-W4);
END fpga;
Any suggestions ?
What can I do if I want to intialize to 0's the C matrix while resetting ?
ty !