Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

IIR filter in SystemVerilog

Status
Not open for further replies.

Haraldovs

Newbie level 3
Joined
Apr 7, 2018
Messages
4
Helped
0
Reputation
0
Reaction score
0
Trophy points
1
Activity points
48
Hello,

I am trying to implement a 2.order IIR filter using SystemVerilog, and I am having some trouble.

a0*y[n] = -a1*y[n-1] - a2*y[n-2] + b0*x[n] + b1*x[n-1] + b2*x[n-2]

The simulation results i get using a square wave input and low- or highpass coefficients is garbage, but when running audio through a cascade of 12 allpass filters i hear no difference from original.

I reckon the filter doesn't work, but with the allpass filters I start thinking it works, but only for positive only coefficients.

I have only had DSP in school, and my SystemVerilog skills are slightly noobish, if anyone
can look at my code below i'd be grateful.


Code:
module second_order_iir #(parameter B0=1732852,B1=3465704,B2=1732852, A1=-3099820,A2=1642621)
(
output logic signed [23:0] out, 
output logic output_ready,
input logic signed [23:0] in,
input logic clk, rst, input_ready
);

 typedef logic signed [23:0] coeffs;
const coeffs [4:0] coefficients = {A2[23:0], A1[23:0], B2[23:0], B1[23:0], B0[23:0]};


logic [2:0] address;
logic signed [4:0][23:0] samples;

enum {waiting,loading, processing,done} state, next_state;

logic load, reset_sum, count, save_output;

logic signed [23:0] coefficient, sample;
logic signed [47:0] sum, product;

always_ff @(posedge clk, negedge rst)
if(~rst)
 begin
  out <= '0;
  state<= waiting;
  samples <= '0;
  end
  else
  begin
  state <= next_state;
  
  if(save_output)
    out <= sum[46:23];
	
  if(load)
    begin
  samples[4] <= samples[3];
  samples[3] <= out;
  samples[2] <= samples[1];
  samples[1] <= samples[0];
  samples[0] <= in;
     end
	 
  end
  
 always_ff @(posedge clk)
if(reset_sum)
  sum <= '0;
else
 if(address < 3'b011)
  sum <= sum + product;
 else
  sum <= sum - product;    //subtract y[n-1] & y[n-2]
 
 always_ff @ (posedge clk)
 if(!count)
   address <= '0;
 else
   address <= address + 1;
   
 always_comb
 coefficient = coefficients[address];
 
 always_comb
  sample = samples[address];

always_comb
   product = sample * coefficient;



  
  
  
always_comb
begin
next_state = state;
load = 0;
reset_sum = 0;
save_output = 0;
count = 0;
output_ready = 0;

case(state)
  waiting: begin
  if(input_ready)
    next_state = loading;
  reset_sum = 1;
  
end
loading: begin
  next_state = processing;
  reset_sum = 1;
  load = 1;
end
processing: begin
 if(address == 3'b100)
   next_state = done;
 count = 1;
end
done: begin
next_state = waiting;
save_output = 1;
output_ready = 1;
end
endcase  
end


endmodule
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top