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.

direct form low pass FIR filter in Verilog

Status
Not open for further replies.

jpglotzer

Newbie level 5
Joined
Apr 15, 2011
Messages
10
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,281
Activity points
1,395
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.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top