1. Limited time only! Sign up for a free 30min personal tutor trial with Chegg Tutors
    Dismiss Notice
Dismiss Notice
Join Physics Forums Today!
The friendliest, high quality science and math community on the planet! Everyone who loves science is here!

Help writing a FIR Filter in Verilog

  1. Oct 7, 2011 #1
    Hi,
    1. The problem statement, all variables and given/known data
    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.

    2. Relevant equations
    N/A

    3. The attempt at a solution
    Code (Text):

    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.
     
  2. jcsd
Know someone interested in this topic? Share this thread via Reddit, Google+, Twitter, or Facebook

Can you offer guidance or do you also need help?
Draft saved Draft deleted



Similar Discussions: Help writing a FIR Filter in Verilog
  1. FIR Filter (Replies: 1)

Loading...