Why am I getting don't-care in the output of IIR filter?

87 Views Asked by At
module IIR_filter(xn, clk, rst_n, yn);
  input signed [3:0]xn;
  input clk,rst_n;
  output reg signed [3:0]yn;
  reg signed [3:0]y_1,y_2,x_1,x_2,x_3;
  
  always @(*)begin
    yn = xn - (x_1) + (x_2) + (x_3)+ (y_1>>>1) + (y_2>>>2);
  end
  always @(posedge clk or negedge rst_n)
    begin 
      if(rst_n == 0)
        begin
          y_1 <=0;y_2<=0;x_1<=0;x_2<=0;x_3<=0;
        end
      else
        begin
          y_1 <=yn; y_2<=y_1;
          x_1<=xn; x_2<=x_1; x_3<=x_2;
        end
    end
endmodule

The code above is the design with combinational and sequential logic.

// Code your testbench here
// or browse Examples
module IIR_filter_tb();
  reg [3:0]xn;
  reg clk,rst_n;
  wire [3:0]yn;
  integer i;
  IIR_filter test(.xn(xn),
                  .clk(clk),
                  .rst_n(rst_n),
                  .yn(yn)); 
  initial 
begin 
  clk = 0;
  #5 rst_n = 0;
  xn = 4'b0000;
  rst_n=1;
  for(i = 0; i<4;i=i+1)
    #20 xn = i;
  $display("yn = %d", yn);
    $finish; 
end 
  always
    begin
    #10 clk = ~clk;
  end
endmodule

The code above is the testbench.

The issue is that I'm not understanding the shift operator implementation and the recursive result being pushed to the next register one by one is causing the issue.

I'm getting don't-care as output.

1

There are 1 best solutions below

0
On

The bug is in your testbench code. You did not drive the reset signal properly. You are setting the reset signal to 0, then immediately setting it to 1 at the same simulation time. This means that the reset is never really 0, and you do not reset the signals in your design, leaving them unknown (x).

This was obvious to me when I looked at waveforms. If you are relying only on $display statements, it is much more efficient to dump waves.

Change:

  #5 rst_n = 0;

to:

  rst_n = 0;
  #5;

This fixes the "don't-cares" (unknowns) on the output (after the reset is released).

enter image description here