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.
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:
to:
This fixes the "don't-cares" (unknowns) on the output (after the reset is released).