DSP LAB EVALUATION NO.
2
DIGITAL SIGNAL PROCESSING
Report
Member’s Name Roll No.
Muhammad Bilal Zubairi Cs-21091
Syeda Hafsa Najam Cs-21046
Khansa Asif Cs-21045
Cutoff Frequency (fcf_cfc): The cutoff frequency is the point where the filter starts to attenuate the
signal. For example, let's set fc=1f_c = 1fc=1 kHz, meaning the filter will attenuate frequencies higher
than 1 kHz.
Cutoff Frequency (fcf_cfc): 1 kHz
Sampling Frequency (fsf_sfs): 10 kHz
Filter order will be 10
. Calculate the Normalized Cutoff Frequency
In the MATLAB filter design functions like fir1(), the cutoff frequency is expressed as a
normalized value with respect to the Nyquist frequency, which is half of the sampling
frequency.
Normalized Cutoff Frequency wcw_cwc is given by:
wc=fcfs/2=fcfNyquistw_c = \frac{f_c}{f_s / 2} = \frac{f_c}{f_{Nyquist}}wc=fs/2fc=fNyquist
fc
Where:
fcf_cfc is the cutoff frequency (in Hz).
fsf_sfs is the sampling frequency (in Hz).
fNyquist=fs/2f_{Nyquist} = f_s / 2fNyquist=fs/2.
So for our example:
fc=1f_c = 1fc=1 kHz = 100010001000 Hz.
fs=10f_s = 10fs=10 kHz = 100001000010000 Hz.
Nyquist frequency fNyquist=100002=5000f_{Nyquist} = \frac{10000}{2} =
5000fNyquist=210000=5000 Hz.
Thus, the normalized cutoff frequency is:
wc=10005000=0.2w_c = \frac{1000}{5000} = 0.2wc=50001000=0.2
% Filter Specifications
fc = 1;
fs = 10;
order = 20;
% Convert frequencies to Hz
fc = fc * 1000; % Convert cutoff frequency to Hz
fs = fs * 1000; % Convert sampling frequency to Hz
wc = fc / (fs / 2);
b = fir1(order, wc, 'low', hamming(order + 1));
disp('FIR Filter Coefficients:');
disp(b);
fvtool(b, 1, 'Fs', fs);
Convert coefficients to fixed-point (e.g., 16-bit precision)
fixed_coeffs = round(b * 2^15);
disp(fixed_coeffs);
Vivado
module fir_filter #(parameter N = 3) (
input clk, // Clock signal
input reset, // Reset signal
input [15:0] x_in, // 16-bit input signal (fixed-
point)
output [15:0] y_out // 16-bit output signal (fixed-
point)
);
// Declare the 16-bit fixed-point coefficients array
reg [15:0] coeff [0:N-1]; // Coefficients array (16 bits
each)
// Delay buffer to store the input samples (circular
buffer)
reg [15:0] buffer [0:N-1]; // Buffer to store delayed
input samples
integer i;
// Accumulator for the Multiply-Accumulate (MAC)
operation
reg [31:0] sum; // 32-bit accumulator for the
result
// Initialize the coefficients (from MATLAB fixed-point
values)
initial begin
coeff[0] = 16'h2000; // 8192 in hexadecimal (0.25
in fixed-point)
coeff[1] = 16'h4000; // 16384 in hexadecimal (0.5
in fixed-point)
coeff[2] = 16'h2000; // 8192 in hexadecimal (0.25
in fixed-point)
end
// Always block for the FIR filter logic
always @(posedge clk or posedge reset) begin
if (reset) begin
sum <= 32'b0; // Reset the accumulator
end else begin
// Shift the input samples into the circular buffer
for (i = N-1; i > 0; i = i - 1) begin
buffer[i] <= buffer[i-1]; // Shift previous value
end
buffer[0] <= x_in; // Insert the new input sample
at the start of the buffer
// Reset the sum for the new input
sum <= 32'b0; // Clear previous sum
// Perform the Multiply-Accumulate operation
for (i = 0; i < N; i = i + 1) begin
sum <= sum + (buffer[i] * coeff[i]); // MAC
operation
end
end
end
// Output the final result (scaled back to 16-bit)
assign y_out = sum[31:16]; // Take the most significant
16 bits as output (may need scaling)
endmodule
module tb_fir_filter;
reg clk; // Clock signal
reg reset; // Reset signal
reg [15:0] x_in; // 16-bit input signal (fixed-point)
wire [15:0] y_out; // 16-bit output signal (fixed-
point)
// Instantiate the FIR filter module
fir_filter #(3) uut (
.clk(clk),
.reset(reset),
.x_in(x_in),
.y_out(y_out)
);
// Clock generation
always begin
#5 clk = ~clk; // Toggle clock every 5 time units
end
// Stimulus process
initial begin
// Initialize signals
clk = 0;
reset = 1;
x_in = 16'h0000; // Initial value of 0
// Apply some test inputs (fixed-point values)
#10 reset = 0; // Deassert reset after 10 time
units
x_in = 16'h2000; // Test input value (0.25 in
fixed-point)
#10 x_in = 16'h4000; // Test input value (0.5 in
fixed-point)
#10 x_in = 16'h1000; // Test input value (0.125 in
fixed-point)
#10 x_in = 16'h8000; // Test input value (-0.5 in
fixed-point)
#20 $finish; // End the simulation
end
endmodule
updated code with coefficient change
module fir_filter #(parameter N = 21) (
input clk, // Clock signal
input reset, // Reset signal
input [15:0] x_in, // 16-bit input signal (fixed-
point)
output [15:0] y_out // 16-bit output signal (fixed-
point)
);
// Declare the 16-bit fixed-point coefficients array
reg [15:0] coeff [0:N-1]; // Coefficients array (16 bits
each)
// Delay buffer to store the input samples (circular
buffer)
reg [15:0] buffer [0:N-1]; // Buffer to store delayed
input samples
integer i;
// Accumulator for the Multiply-Accumulate (MAC)
operation
reg [31:0] sum; // 32-bit accumulator for the
result
// Initialize the coefficients (from MATLAB fixed-point
values)
initial begin
coeff[0] = 16'h0000; // 0
coeff[1] = 16'hFFB6; // -70
coeff[2] = 16'hFF57; // -207
coeff[3] = 16'hFF94; // -380
coeff[4] = 16'hFF83; // -405
coeff[5] = 16'h0000; // 0
coeff[6] = 16'h0419; // 1041
coeff[7] = 16'h0A74; // 2668
coeff[8] = 16'h1199; // 4505
coeff[9] = 16'h17A0; // 5968
coeff[10] = 16'h198E; // 6526
coeff[11] = 16'h17A0; // 5968
coeff[12] = 16'h1199; // 4505
coeff[13] = 16'h0A74; // 2668
coeff[14] = 16'h0419; // 1041
coeff[15] = 16'h0000; // 0
coeff[16] = 16'hFF83; // -405
coeff[17] = 16'hFF94; // -380
coeff[18] = 16'hFF57; // -207
coeff[19] = 16'hFFB6; // -70
coeff[20] = 16'h0000; // 0
end
// Always block for the FIR filter logic
always @(posedge clk or posedge reset) begin
if (reset) begin
sum <= 32'b0; // Reset the accumulator
end else begin
// Shift the input samples into the circular buffer
for (i = N-1; i > 0; i = i - 1) begin
buffer[i] <= buffer[i-1]; // Shift previous value
end
buffer[0] <= x_in; // Insert the new input sample
at the start of the buffer
// Reset the sum for the new input
sum <= 32'b0; // Clear previous sum
// Perform the Multiply-Accumulate operation
for (i = 0; i < N; i = i + 1) begin
sum <= sum + (buffer[i] * coeff[i]); // MAC
operation
end
end
end
// Output the final result (scaled back to 16-bit)
assign y_out = sum[31:16]; // Take the most significant
16 bits as output (may need scaling)
endmodule
Updated test bench
module tb_fir_filter;
reg clk; // Clock signal
reg reset; // Reset signal
reg [15:0] x_in; // 16-bit input signal (fixed-point)
wire [15:0] y_out; // 16-bit output signal (fixed-
point)
// Instantiate the FIR filter module (Change N to 21 for
21 coefficients)
fir_filter #(21) uut (
.clk(clk),
.reset(reset),
.x_in(x_in),
.y_out(y_out)
);
// Clock generation
always begin
#5 clk = ~clk; // Toggle clock every 5 time units
end
// Stimulus process
initial begin
// Initialize signals
clk = 0;
reset = 1;
x_in = 16'h0000; // Initial value of 0
// Apply some test inputs (fixed-point values)
#10 reset = 0; // Deassert reset after 10 time
units
x_in = 16'h2000; // Test input value (0.25 in
fixed-point)
#10 x_in = 16'h4000; // Test input value (0.5 in
fixed-point)
#10 x_in = 16'h1000; // Test input value (0.125 in
fixed-point)
#10 x_in = 16'h8000; // Test input value (-0.5 in
fixed-point)
#20 $finish; // End the simulation
end
endmodule