Verilog code for fixed-point 16-bit 4-tap FIR filter module (state machine version)

乗算器を並列に使うのではなくシリアルに使えるように状態機械で実装してみた版。まだ係数は固定。

乗算器を並列に使うのではなくシリアルに使えるように状態機械で実装してみた版。まだ係数は固定。

// Fixed-point 16 bit 4-tap FIR filter module [state machine version] -----------------------
module FIRfilterS (
  input wire[15:0] indata,
  input wire update,
  input wire clk,
  output wire [15:0] outdata
  );
  parameter NTAPS = 4;
  wire signed [15:0] coef[NTAPS-1:0];
  reg  signed [15:0] buff[NTAPS-1:0];
  reg  signed [15:0] outreg,mul_in1,mul_in2;
  wire signed [31:0] mul_out;
  reg  signed [31:0] addreg;
  integer statecnt,rptr,wptr;
  reg inprocess;
  assign outdata = outreg;
  
  // coefficients --------------- change here
  assign coef[0] = 16'h2000;
  assign coef[1] = 16'h2000;
  assign coef[2] = 16'h2000;
  assign coef[3] = 16'h2000;  
  // ------------------------------
  
  // initital register settings
  initial begin
    rptr <= 0;
    wptr <= 0;
    inprocess <= 0;
    statecnt <= NTAPS*4+1;
  end
  // mulitplication module
  multiplier mul(.clk(clk),.a(mul_in1),.b(mul_in2),.p(mul_out)); 
    // Optimized 'black-box' module : p = a * b
    //    input clk
    //    input [15:0] a
    //    input [15:0] b
    //    output [31:0] p
  
  // internal calculations
  always @(posedge clk) begin
    // inpute detection
    if(update==1 && inprocess==0) begin 
      buff[wptr] <= indata;
      statecnt <= 0;
      rptr <= wptr; 
      addreg <= 0;
      inprocess <= 1;
    end
    // processing state machine
    if(statecnt<NTAPS*4) begin 
      if(statecnt%4==0) begin // input data to multiplier
        mul_in1 <= buff[rptr];
        mul_in2 <= coef[statecnt>>4];
      end
      if(statecnt%4==3) begin // get data from multiplier and accumulate
        addreg <= addreg + mul_out;
        rptr <= (rptr+NTAPS-1)%NTAPS;
      end
      statecnt <= statecnt+1;
    end
    if(statecnt==NTAPS*4) begin // output data
      outreg <= addreg>>>15;
      wptr <= (wptr+1)%NTAPS;
      statecnt <= statecnt+1;
    end
    if(statecnt==NTAPS*4+1 && inprocess==1 && update==0) begin 
      inprocess <= 0;
    end
  end
endmodule