Code
Code
module equalizer (
input logic sample_clock,
input logic reset,
input logic signed [23:0] input_sample,
input logic [2:0] bass_gain_select, // 3-bit switch for bass gain (0.25 to 2.0)
input logic [2:0] mid_gain_select, // 3-bit switch for mid gain (0.25 to 2.0)
input logic [2:0] treb_gain_select, // 3-bit switch for treble gain (0.25 to 2.0)
output logic signed [23:0] output_sample
);
// Parameters
parameter int tap = 20;
// FIR Coefficients
logic signed [23:0] bass_coeff[0:tap-1] = '{
24'd1409, 24'd1478, 24'd1541, 24'd1597, 24'd1647, 24'd1689, 24'd1724,
24'd1750, 24'd1768, 24'd1777, 24'd1777, 24'd1768, 24'd1750, 24'd1724,
24'd1689, 24'd1647, 24'd1597, 24'd1541, 24'd1478, 24'd1409
};
// Gain values
logic signed [15:0] gain_values[0:7] = '{
16'd64, // 0.25x
16'd128, // 0.5x
16'd192, // 0.75x
16'd256, // 1.0x
16'd320, // 1.25x
16'd384, // 1.5x
16'd448, // 1.75x
16'd512 // 2.0x
};
logic signed [15:0] bass_gain, mid_gain, treb_gain;
// Scaled coefficients
logic signed [23:0] scaled_bass_coeff[0:tap-1];
logic signed [23:0] scaled_mid_coeff [0:tap-1];
logic signed [23:0] scaled_treb_coeff[0:tap-1];
fir_20 mid_filter (
.sample_clock(sample_clock),
.reset(reset),
.input_sample(input_sample),
.coeff(scaled_mid_coeff),
.output_sample(mid_out)
);
fir_20 treb_filter (
.sample_clock(sample_clock),
.reset(reset),
.input_sample(input_sample),
.coeff(scaled_treb_coeff),
.output_sample(treb_out)
);
// Debugging logic
always_ff @(posedge sample_clock or negedge reset) begin
if (!reset) begin
$display("Reset applied. Gains set to zero.");
end else begin
$display("Bass Gain: %d, Mid Gain: %d, Treble Gain: %d", bass_gain, mid_gain, treb_gain);
end
end
endmodule
module fir_20 (
input logic sample_clock,
input logic reset,
input logic signed [23:0] input_sample,
input logic signed [23:0] coeff [0:19], // FIR coefficients (dynamic input)
output logic signed [23:0] output_sample
);
parameter int tap = 20;
endmodule
module equalizer_tb();
localparam FILE_PATH = "audio.hex";
localparam OUT_PATH = "output.hex";
localparam FREQ = 100_000_000;
localparam WD_IN = 24;
localparam WD_OUT = 24;
localparam PERIOD = 1_000_000_000 / FREQ;
localparam HALF_PERIOD = PERIOD / 2;
// Instantiate DUT
equalizer dut (
.sample_clock(clk),
.reset(reset_n),
.input_sample(input_sample),
.bass_gain_select(bass_gain_select),
.mid_gain_select(mid_gain_select),
.treb_gain_select(treb_gain_select),
.output_sample(output_sample)
);
// Clock generation
always #HALF_PERIOD clk = ~clk;
// Testbench logic
initial begin
// Initialize signals
clk = 0;
reset_n = 0;
input_sample = 0;
$display("Initial Bass Gain Select = %b, Mid Gain Select = %b, Treble Gain Select = %b",
bass_gain_select, mid_gain_select, treb_gain_select);
// Apply reset
$display("Applying reset...");
repeat (5) @(posedge clk);
reset_n = 1;
$display("Reset released...");
@(posedge clk);
$fdisplay(outfile, "Gain Case %0d: Input = %h | Output = %h",
gain_case, input_sample, output_sample);
end
$rewind(file); // Rewind file for the next gain case
end
// Monitor signals
initial begin
$monitor("Time = %0t | Reset = %b | Gain Case = %0d | Bass Gain Select = %b | Mid Gain Select =
%b | Treble Gain Select = %b",
$time, reset_n, gain_case, bass_gain_select, mid_gain_select, treb_gain_select);
end
endmodule