FIR with complex coefficients- VHDL implementation

E

Emel

Hi,
I took MATLAB fdatool HDL coder's VHDL code for an FIR filter
(length=8) and tried to adjust it such that it accepts complex inputs
and filter coefficients. To do this, I had to handle the real and
imaginary parts separately using (a+bi)(c+di)=(ac-bd)+(ad+bc)i.
Although there is no syntax problem, I get unknown outputs (x). I am
using Xilinx ISE Simulator. I first take reset=1 and then I take
reset=0 and exoect to get good outputs when clk_enable=1. Below is my
code. It is actually very simple. Could you please look at it and tell
me where the problem is?

LIBRARY IEEE;
USE IEEE.std_logic_1164.all;
USE IEEE.numeric_std.ALL;

ENTITY fir IS
PORT( clk : IN std_logic;
clk_enable : IN std_logic;
reset : IN std_logic;
filter_inr : IN std_logic_vector(11
DOWNTO 0); -- 1 sign bit,3 integer,8 frac
filter_ini : IN std_logic_vector(11
DOWNTO 0); -- 1 sign bit,3 integer,8 frac
filter_outr : OUT std_logic_vector(28
DOWNTO 0); -- 1 sign bit,12 integer,16 frac
filter_outi : OUT std_logic_vector(28
DOWNTO 0) -- 1 sign bit,12 integer,16 frac
);

END fir;

ARCHITECTURE rtl OF fir IS

-- Type Definitions
TYPE delay_pipeline_type IS ARRAY (NATURAL range <>) OF signed(11
DOWNTO 0); -- 1 sign bit,3 integer,8 frac
-- Constants
CONSTANT coeff1r : signed(15 DOWNTO 0) :=
to_signed(1, 9); -- 1 sign bit, 8 frac
CONSTANT coeff2r : signed(15 DOWNTO 0) :=
to_signed(2, 9); -- 1 sign bit, 8 frac
CONSTANT coeff3r : signed(15 DOWNTO 0) :=
to_signed(2, 9); -- 1 sign bit, 8 frac
CONSTANT coeff4r : signed(15 DOWNTO 0) :=
to_signed(3, 9); -- 1 sign bit, 8 frac
CONSTANT coeff5r : signed(15 DOWNTO 0) :=
to_signed(3, 9); -- 1 sign bit, 8 frac
CONSTANT coeff6r : signed(15 DOWNTO 0) :=
to_signed(3, 9); -- 1 sign bit, 8 frac
CONSTANT coeff7r : signed(15 DOWNTO 0) :=
to_signed(4, 9); -- 1 sign bit, 8 frac
CONSTANT coeff8r : signed(15 DOWNTO 0) :=
to_signed(4, 9); -- 1 sign bit, 8 frac
CONSTANT coeff1i : signed(15 DOWNTO 0) :=
to_signed(2, 9); -- 1 sign bit, 8 frac
CONSTANT coeff2i : signed(15 DOWNTO 0) :=
to_signed(5, 9); -- 1 sign bit, 8 frac
CONSTANT coeff3i : signed(15 DOWNTO 0) :=
to_signed(8, 9); -- 1 sign bit, 8 frac
CONSTANT coeff4i : signed(15 DOWNTO 0) :=
to_signed(7, 9); -- 1 sign bit, 8 frac
CONSTANT coeff5i : signed(15 DOWNTO 0) :=
to_signed(6, 9); -- 1 sign bit, 8 frac
CONSTANT coeff6i : signed(15 DOWNTO 0) :=
to_signed(5, 9); -- 1 sign bit, 8 frac
CONSTANT coeff7i : signed(15 DOWNTO 0) :=
to_signed(2, 9); -- 1 sign bit, 8 frac
CONSTANT coeff8i : signed(15 DOWNTO 0) :=
to_signed(1, 9); -- 1 sign bit, 8 frac
-- Signals
SIGNAL delay_pipeliner : delay_pipeline_type(0 TO
7);
SIGNAL delay_pipelinei : delay_pipeline_type(0 TO
7);
SIGNAL product8r : signed(28 DOWNTO 0); -- 1
sign bit,12 integer,16 frac
SIGNAL product8i : signed(28 DOWNTO 0); -- 1
sign bit,12 integer,16 frac
SIGNAL product7r : signed(28 DOWNTO 0); -- 1
sign bit,12 integer,16 frac
SIGNAL product7i : signed(28 DOWNTO 0); -- 1
sign bit,12 integer,16 frac
SIGNAL product6r : signed(28 DOWNTO 0); -- 1
sign bit,12 integer,16 frac
SIGNAL product6i : signed(28 DOWNTO 0); -- 1
sign bit,12 integer,16 frac
SIGNAL product5r : signed(28 DOWNTO 0); -- 1
sign bit,12 integer,16 frac
SIGNAL product5i : signed(28 DOWNTO 0); -- 1
sign bit,12 integer,16 frac
SIGNAL product4r : signed(28 DOWNTO 0); -- 1
sign bit,12 integer,16 frac
SIGNAL product4i : signed(28 DOWNTO 0); -- 1
sign bit,12 integer,16 frac
SIGNAL product3r : signed(28 DOWNTO 0); -- 1
sign bit,12 integer,16 frac
SIGNAL product3i : signed(28 DOWNTO 0); -- 1
sign bit,12 integer,16 frac
SIGNAL product2r : signed(28 DOWNTO 0); -- 1
sign bit,12 integer,16 frac
SIGNAL product2i : signed(28 DOWNTO 0); -- 1
sign bit,12 integer,16 frac
SIGNAL product1r : signed(28 DOWNTO 0); -- 1
sign bit,12 integer,16 frac
SIGNAL product1i : signed(28 DOWNTO 0); -- 1
sign bit,12 integer,16 frac
SIGNAL sum1r : signed(28 DOWNTO 0); -- 1
sign bit,12 integer,16 frac
SIGNAL sum1i : signed(28 DOWNTO 0); -- 1
sign bit,12 integer,16 frac
SIGNAL sum2r : signed(28 DOWNTO 0); -- 1
sign bit,12 integer,16 frac
SIGNAL sum2i : signed(28 DOWNTO 0); -- 1
sign bit,12 integer,16 frac
SIGNAL sum3r : signed(28 DOWNTO 0); -- 1
sign bit,12 integer,16 frac
SIGNAL sum3i : signed(28 DOWNTO 0); -- 1
sign bit,12 integer,16 frac
SIGNAL sum4r : signed(28 DOWNTO 0); -- 1
sign bit,12 integer,16 frac
SIGNAL sum4i : signed(28 DOWNTO 0); -- 1
sign bit,12 integer,16 frac
SIGNAL sum5r : signed(28 DOWNTO 0); -- 1
sign bit,12 integer,16 frac
SIGNAL sum5i : signed(28 DOWNTO 0); -- 1
sign bit,12 integer,16 frac
SIGNAL sum6r : signed(28 DOWNTO 0); -- 1
sign bit,12 integer,16 frac
SIGNAL sum6i : signed(28 DOWNTO 0); -- 1
sign bit,12 integer,16 frac
SIGNAL sum7r : signed(28 DOWNTO 0); -- 1
sign bit,12 integer,16 frac
SIGNAL sum7i : signed(28 DOWNTO 0); -- 1
sign bit,12 integer,16 frac
SIGNAL output_typeconvertr : signed(28 DOWNTO 0); -- 1
sign bit,12 integer,16 frac
SIGNAL output_typeconverti : signed(28 DOWNTO 0); -- 1
sign bit,12 integer,16 frac
SIGNAL output_registerr : signed(28 DOWNTO 0); -- 1
sign bit,12 integer,16 frac
SIGNAL output_registeri : signed(28 DOWNTO 0); -- 1
sign bit,12 integer,16 frac

BEGIN

-- Block Statements
Delay_Pipeline_process : PROCESS (clk, reset)
BEGIN
IF reset = '1' THEN
delay_pipeliner(0 TO 7) <= (OTHERS => (OTHERS => '0'));
delay_pipelinei(0 TO 7) <= (OTHERS => (OTHERS => '0'));
ELSIF clk'event AND clk = '1' THEN
IF clk_enable = '1' THEN
delay_pipeliner(0) <= signed(filter_inr);
delay_pipeliner(1 TO 7) <= delay_pipeliner(0 TO 6);
delay_pipelinei(0) <= signed(filter_ini);
delay_pipelinei(1 TO 7) <= delay_pipelinei(0 TO 6);
END IF;
END IF;
END PROCESS Delay_Pipeline_process;


product8r <= resize(delay_pipeliner(7) * coeff8r, 29) -
resize(delay_pipelinei(7) * coeff8i, 29);
product8i <= resize(delay_pipelinei(7) * coeff8r, 29) +
resize(delay_pipeliner(7) * coeff8i, 29);
product7r <= resize(delay_pipeliner(6) * coeff7r, 29) -
resize(delay_pipelinei(6) * coeff7i, 29);
product7i <= resize(delay_pipelinei(6) * coeff7r, 29) +
resize(delay_pipeliner(6) * coeff7i, 29);
product6r <= resize(delay_pipeliner(5) * coeff6r, 29) -
resize(delay_pipelinei(5) * coeff6i, 29);
product6i <= resize(delay_pipelinei(5) * coeff6r, 29) +
resize(delay_pipeliner(5) * coeff6i, 29);
product5r <= resize(delay_pipeliner(4) * coeff5r, 29) -
resize(delay_pipelinei(4) * coeff5i, 29);
product5i <= resize(delay_pipelinei(4) * coeff5r, 29) +
resize(delay_pipeliner(4) * coeff5i, 29);
product4r <= resize(delay_pipeliner(3) * coeff4r, 29) -
resize(delay_pipelinei(3) * coeff4i, 29);
product4i <= resize(delay_pipelinei(3) * coeff4r, 29) +
resize(delay_pipeliner(3) * coeff4i, 29);
product3r <= resize(delay_pipeliner(2) * coeff3r, 29) -
resize(delay_pipelinei(2) * coeff3i, 29);
product3i <= resize(delay_pipelinei(2) * coeff3r, 29) +
resize(delay_pipeliner(2) * coeff3i, 29);
product2r <= resize(delay_pipeliner(1) * coeff2r, 29) -
resize(delay_pipelinei(1) * coeff2i, 29);
product2i <= resize(delay_pipelinei(1) * coeff2r, 29) +
resize(delay_pipeliner(1) * coeff2i, 29);
product1r <= resize(delay_pipeliner(0) * coeff1r, 29) -
resize(delay_pipelinei(0) * coeff1i, 29);
product1i <= resize(delay_pipelinei(0) * coeff1r, 29) +
resize(delay_pipeliner(0) * coeff1i, 29);

sum1r <= product1r + product2r;
sum1i <= product1i + product2i;
sum2r <= sum1r + product3r;
sum2i <= sum1i + product3i;
sum3r <= sum2r + product4r;
sum3i <= sum2i + product4i;
sum4r <= sum3r + product5r;
sum4i <= sum3i + product5i;
sum5r <= sum4r + product6r;
sum5i <= sum4i + product6i;
sum6r <= sum5r + product7r;
sum6i <= sum5i + product7i;
sum7r <= sum6r + product8r;
sum7i <= sum6i + product8i;

output_typeconvertr <= sum7r;
output_typeconverti <= sum7i;

Output_Register_process : PROCESS (clk, reset)
BEGIN
IF reset = '1' THEN
output_registerr <= (OTHERS => '0');
output_registeri <= (OTHERS => '0');

ELSIF clk'event AND clk = '1' THEN
IF clk_enable = '1' THEN
output_registerr <= output_typeconvertr;
output_registeri <= output_typeconverti;

END IF;
END IF;
END PROCESS Output_Register_process;

-- Assignment Statements
filter_outr <= std_logic_vector(output_registerr);
filter_outi <= std_logic_vector(output_registeri);

END rtl;
 
M

Mike Treseler

Emel said:
I took MATLAB fdatool HDL coder's VHDL code for an FIR filter
(length=8) and tried to adjust it such that it accepts complex inputs
and filter coefficients. To do this, I had to handle the real and
imaginary parts separately using (a+bi)(c+di)=(ac-bd)+(ad+bc)i.
Although there is no syntax problem,

Modelsim found several:

vcom -93 -quiet -work work /evtfs/home/tres/vhdl/play/fir.vhd
** Error: /evtfs/home/tres/vhdl/play/fir.vhd(32):
Length of expected is 16; length of actual is 9.
** Error: /evtfs/home/tres/vhdl/play/fir.vhd(34):
Length of expected is 16; length of actual is 9.
.... etc. etc.

I am using Xilinx ISE Simulator.

Maybe the next revision will work better.

-- Mike Treseler
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,578
Members
45,052
Latest member
LucyCarper

Latest Threads

Top