HowTo+-+FIR+filter+design+in+GNU+Octave

To design filters in Octave (Or Matlab), we can use the following commands:

Equirippipple methods: b = **fir1**(N, f0); % FIR filter with a given cut-off frequency, low-, high-, bandpass and band stop. b = **fir2**(N, [f0 f1 f2 f3], [a0 a1 a2 a3]); **%**: FIR filter with an arbitrary frequency response.

Least Squares Method: b = **firls**(N, [f_passband] f_stopband], [weight_passb weight_stopb]) %FIR filter with arbitrary frequency response

Details can be found here: []

Example:Create a 10-order low-pass FIR filter with a cut-off frequency of 1KHz. Sampling frequency is 10KHz (=>Nyquist = 5KHz)

code f0 = 1000/5000;  % norm. frequency b = fir1(10, f0); % FIR filter coefficients freqz(b);        % Plot Frequency Response

code

Note that the graphs are plottet vs the normalized frequency (1.0 = Nyquist = Fsample/2)

Listing b's values we see that the coefficients are decimal values: code format="matlab" b            % List b values 1.0538e-004 1.0769e-002 5.4319e-002 1.3901e-001 2.2926e-001 2.6849e-001 2.2926e-001 1.3901e-001 5.4319e-002 1.0769e-002 1.0538e-004

code As we are using fixed point arithmetic in the FPGA, we convert the numbers to integer values: code bb = round(b*256) 0   3   14   36   59   69   59   36   14    3    0

code Plotting the frequency response with the rounded coefficients we get: code freqz(bb) code

The frequency response is very similar to the previous plot.

We can compare the filter's impulse response to see if the filters are identical: code x= [1 ; zeros(99, 1)];             % Create impulse vector: [10000000000] figure                           % create a new figure plot(filter(b, 1, x));           % plot orig filter (FIR = all zero => a=1) hold on                          % plot another graph in the same figure plot(filter(bb, 1, x)./256, 'r'); % plot quantizised filter. Scaled by 256 code

The Impulse response of the two filters is identical and the approximated 8-bit coefficients are OK.

Inspecting the coefficients and note that we have a symmetry around c(5). We can also see that c(0) and c(9) are both zero. This leads us to implement a reduced multiplier solution where:

y(n) = (x(n-1) + x(n-8)) * c(1) + (x(n-2) + x(n-7)) * c(2) + (x(n-3) + x(n-3)) * c(3) + (x(n-4) + x(n-6)) * c(4) + x(n-5)* c(5)

This leaves us with 8 additions and 5 multiplications for a 10-th order FIR filter.