Complex FIR filtering of complex input requires 4 multipliers per tap. It is possible to reduce that to 3 at the expense of extra adder/two subtractors. This can be verified by simple algebra, as follows:
(A+jB)(C+jD) = AC-BD + j(AD+BC)
Add BC-BC to the real term: AC-BD = AC-BD + BC-BC
= B(C-D) - C(B-A)
Add AC-AC to the imaginary term: AD+BC = AD+BC + AC-AC
= A(C+D) + C(B-A)
Thus, the term C*(B-A) is shared between real and imaginary outputs. The new structure is made up of three subfilters. The code below describes and verifies the structure functionality and can be modified into bit true model.
Additionally, if your design can run at three times the speed of input then you can time fold the three subfilters neatly.
%random input I_in = randn(1,1024); Q_in = randn(1,1024); %random test filter h = randn(1,20)+j*randn(1,20); %split up into 3 subfilters h1 = real(h)+imag(h); %extra adder h2 = real(h); h3 = real(h)-imag(h); %extra subtractor %apply subfilter ch1 = filter(h1,1,I_in); ch2 = filter(h2,1,Q_in-I_in); %extra subtractor ch3 = filter(h3,1,Q_in); %combine outputs yr = round((ch3-ch2)*2^15); yi = round((ch1+ch2)*2^15); IQ_out = complex(yr,yi); %direct computation ref = round(2^15*filter(h,1,complex(I_in,Q_in))); plot(IQ_out - ref);