Continue to Site

# direct form low pass FIR filter in Verilog

Status
Not open for further replies.

#### jpglotzer

##### Newbie level 5
Hi everyone!

I'm doing a project on altera quartus, where I need to implement a fir low pass filter in direct form. I was just about finishing writing it up, when I came to the realization that what I've done is not direct form (I don't think). My code is below, and I was wondering if anyone could suggest how to change it to get a direct form structure? Any help would be much appreciated!

Code:
module fir_filter(x,rst,y)

input [7:0] x;
input rst;

output [24:0] y;

parameter signed c0=16b'1111100110110001,
c1=16b'0001111100000100,
c2=16b'0100011010100101,
c3=16b'0110111010100111,
c4=16b'0111111101010101;

reg [9:0] scaled_x;

reg signed [9:0] tap0,tap1,tap2,tap3,tap4,tap5,tap6,tap7,tap8;

reg signed [25:0] product0,product1,product2,product3,product4;

reg signed [26:0] sum;

always@(posedge clk)
begin

if(rst)
begin
tap8<=0;
tap7<=0;
tap6<=0;
tap5<=0;
tap4<=0;
tap3<=0;
tap2<=0;
tap1<=0;
tap0<=0;
end

t0<=tap0+tap8;
t1<=tap1+tap7;
t2<=tap2+tap6;
t3<=tap3+tap5;
t4<=tap4;

product0<=c0*t0;
product1<=c1*t1;
product2<=c2*t2;
product3<=c3*t3;
product4<=c4*t4;

sum<=product0+product1+product2+product3+product4;

scaled_x<={x[7]}{x[7]}{x[7:0]};
x_2comp<={scaled_x[9]}{scaled_x[8:0]};

tap8<=tap7;
tap7<=tap6;
tap6<=tap5;
tap5<=tap4;
tap4<=tap3;
tap3<=tap2;
tap2<=tap1;
tap1<=tap0;
tap0<=x_2comp;

y<=sum;

end

endmodule

---------- Post added at 23:38 ---------- Previous post was at 23:37 ----------

oops, I've just noticed one mistake, there should be a bitwise inversion:

x_2comp<={~scaled_x[9]}{scaled_x[8:0]};

also, for the x_2comp line, that is a bit lazy. ask yourself why you need another register stage between scaled_x, which is just a register, and x_2comp. This is one of HDL's weaknesses -- the addition of pipeline stages due to code style choices.

this comment also applies to other lines if you didn't intended to have multiple registers in the design. As written, it is a pipelined version of the FIR filter, and the signals all seem to line up correctly making this appear intentional.

Otherwise it seems good. You've basically just done the pre-add optimization for linear phase filters. From an implementation perspective, you might look into using multiply-add structures for this number of inputs -- the final sum line might be the longest path.

yea, that was a bit lazy haha, i've changed that now. do you know how to implement this in direct form?

it appears to be in direct form. The only difference between the standard graph and yours is the linear phase optimization -- the pre-add.

oh, also, I'm not sure your reset works. notice that the main body gets evaluated in the reset case. the nonblocking assigns will see:
tap1 <= 0 followed by tap1 <= tap0. result tap1 <= tap0.

Status
Not open for further replies.