Help writing a FIR Filter in Verilog

  • Thread starter archgold
  • Start date
  • #1
1
0
Hi,

Homework Statement


Design and build a co-processor that interfaces to the Leon that implements an FIR filter. Use memory mapped registers on the AMBA APB bus device 12 to communicate with the co-processor. Your C program (and Modelsim Testbench) will transmit the 16 bit filter coefficients and the 16 bit filter inputs to the co-processor, and receive the 16 bit results computed by the co-processor. Assume that the maximum length of the filter is 163. Verify that your co-processor is working correctly in simulation and in hardware. Measure the MAC/s rate that this system can sustain. Compare this to software DSP in part 2a. Report required that covers both parts a) and b) of this project.
Hints:
1) Create a memory mapped register in the PSel12 space with the following format::
a. [2:0] – Op Code
i. InitRAM
ii. Convolve
iii. Load Coefficient
iv. Load Number of Taps
b. [18:3] – 16 bit data to be passed to FSM – InitRAM value, coefficients, filter inputs
c. [31] – Ready bit asserted by FSM indicating status – ready or busy.

Homework Equations


N/A

The Attempt at a Solution


Code:
My Finite state machine:

module MyFSM(Reset,Clk,PWData,PEnable,PWrite,PSel,InitRAM,Busy);
//module MyFSM(Reset, Clk, RAMIn, InitRAM, Busy, Convolution) ;

parameter RAMWidth = 16, RAMAddrWidth = 10, RAMAddrMax = 1023, FilterSize = 163, BufferSize = 61, 
ImpulseSize = 64, DataRAMWidth = 1001;

input InitRAM, Clk, Reset, PWData, PEnable, PWrite, PSel ;
input CtrlReg[3:0];
wire[RAMWidth-1:0] RAMInC ;
output Busy;

reg Busy ;

// State encoding
parameter Init = 0,
			 ParseOpCode = 1,
			 Convolve = 2,
			 LoadCoef = 3,
			 LoadNumTaps = 4;
          
// State Register
reg [3:0] CurrState, NextState ;

// Signals
reg [RAMAddrWidth-1:0] RAMAddrD ;
reg numTaps;
reg [RAMAddrWidth-1:0] RAMAddr ;
wire [RAMWidth-1:0] RAMOut ;
reg RAMWr;
reg CtrlReg[3:0]; // Op Code
reg [32:0] sum;
reg [15:0] RoundedValue;

// Instantiated RAM signals
reg CoeffRAMWr, DataRAMWr;
reg [RAMAddrWidth-1:0]CoeffRAMAddr, DataRAMAddr;
reg [15:0]CoeffRAMIn, CoeffRAMOut, DataRAMIn, DataRAMOut;

assign DRegInLe1 = PSel & PEnable & PWrite & CtrlReg[2:0] ;
assign DRegInLe2 = PSel & PEnable & PWrite & CtrlReg[2:0] ;
assign DRegInLe3 = PSel & PEnable & PWrite & CtrlReg[2:0] ;
assign DRegInLe4 = PSel & PEnable & PWrite & CtrlReg[2:0] ;

//4-input AND gate
//	assign DRegInLe = PSel & PEnable & PWrite;// & PAddr[3:2];


// Instantiate RAM
RAM #(RAMAddrWidth,RAMWidth,RAMAddrMax) CoeffRAM(.Clk(Clk),.LE(DRegInLe1),.RAMAddr(RAMAddrD),.RAMIn(CoeffRAMIn),.RAMOut(CoeffRAMOut)) ;
RAM #(RAMAddrWidth,RAMWidth,RAMAddrMax) DataRAM(.Clk(Clk),.LE(DRegInLe2),.RAMAddr(RAMAddrD),.RAMIn(DataRAMIn),.RAMOut(DataRAMOut)) ;

//	Clk,	LE,	Reset_, 	PAddr, 	PWData, 	PRData

DReg D_Reg1(.Clk(Clk),.LE(DRegInLe1),.Reset_(Reset),.D(RAMInC),.Q(PRDataC)); // Coefficient RAM
DReg D_Reg2(.Clk(Clk),.LE(DRegInLe2),.Reset_(Reset),(PRDataD)); // Data RAM
DReg D_Reg3(.Clk(Clk),.LE(DRegInLe3),.Reset_(Reset),.D(RoundedValue),.Q(PRDataV)); // Convolution Result RAM
//DReg D_Reg4(.PWData(sum),.PSel(PSel),.PEnable(PEnable),.PWrite(PWrite),.Reset_(Reset),.PAddr(RAMAddr),.Clk(Clk),.PRData(PRData));

// Combinational block for fsm
always @ *
begin
// Default behavior
  RAMAddrD = RAMAddr ;
  Busy = 0 ;
  NextState = CurrState ;
  RAMWr = 0 ;
  
// Next State definitions
  case (CurrState)
    Init: 
    begin
      // Reset State
      if (InitRAM)
      begin
        // Start initializing the RAM
        NextState = ParseOpCode;
        Busy = 1 ; 
        RAMAddrD = 0 ;
      end
    end
    ParseOpCode:
    begin
      // Initialize the RAM - Assert Busy until finished.
      Busy = 1 ;
      RAMWr = 1 ;
      if (CtrlReg == 2)
			NextState = Convolve;
		else if (CtrlReg == 3)
			NextState = LoadCoef;
		else if (CtrlReg == 4)
			NextState = LoadNumTaps;
		else
			NextState = Init;
    end
	 LoadCoef:
	 begin
		Busy = 1 ;
		RAMInC = PWData ;
		RAMAddrD = RAMAddr + 1 ;
		NextState = Init ;
	 end
	Convolve:
	 begin
		Busy = 1 ;
		RAMWr = 1 ;
		RAMAddrD = RAMAddr + 1 ;
		//Convolution
		sum = CoeffRAMOut * DataRAMOut;
		sum = sum + 'h0001;
		RoundedValue = RoundedValue + sum[30:15];
		NextState = Init;
	end
	LoadNumTaps:
	begin
		Busy = 1;
		numTaps = 16;
		NextState = Init;
	 end
    default: // Recovery state if you ever get lost
    begin
      NextState = Init;
    end
  endcase
end


// Clocked block for fsm
always @ (posedge Clk)
begin
  if (Reset)
  begin
    CurrState <= Init ;
    RAMAddr <= 0 ;
  end
  else
  begin
    CurrState <= NextState ;
	 CoeffRAMIn <= RAMInC;
    RAMAddr <= RAMAddrD ;
  end
end
endmodule
I am lost on what to do, I know this code is incorrect.
 

Answers and Replies

Related Threads on Help writing a FIR Filter in Verilog

  • Last Post
Replies
2
Views
2K
Replies
0
Views
3K
  • Last Post
Replies
1
Views
1K
  • Last Post
Replies
0
Views
3K
  • Last Post
Replies
1
Views
1K
  • Last Post
Replies
1
Views
3K
Replies
3
Views
9K
  • Last Post
Replies
12
Views
8K
  • Last Post
Replies
0
Views
736
  • Last Post
Replies
0
Views
2K
Top