Dismiss Notice
Join Physics Forums Today!
The friendliest, high quality science and math community on the planet! Everyone who loves science is here!

Homework Help: 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
Share this great discussion with others via Reddit, Google+, Twitter, or Facebook

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