Verilog FIR滤波器代码错误

时间:2017-02-27 14:16:43

标签: verilog

我的FIR信号输出有问题。信号没有过滤掉,并且有很多静电信号。虽然我的实现似乎工作正常。我的乘数函数是从quartus软件中的现有库创建的,并设置为有符号乘法。我真的不知道最新情况,并希望得到任何帮助!谢谢!

代码:

`timescale 1ns / 1ps
module fir_filter (input sample_clock, input reset, input [15:0]     input_sample1,     output [15:0] output_sample1);

parameter N = 65; //Specify the number of taps

reg  [15:0] delayholder[N-1:0];

wire [31:0] summation[N-1:0];

wire [15:0] finsummations[N-1:0];
wire [15:0] finsummation;

integer x;
integer z;

//Specifying our coefficients
reg signed[15:0] coeffs[200:0];


always @(*)
begin

for (x=0; x<N; x=x+31)
begin

coeffs[x+0] = 0;
coeffs[x+1] = 2267;
coeffs[x+2] = 0;
coeffs[x+3] = -3030;
coeffs[x+4] = 0;
coeffs[x+5] = 4621;
coeffs[x+6] = 0;
coeffs[x+7] = -6337;
coeffs[x+8] = 0;
coeffs[x+9] = 7985;
coeffs[x+10] = 0;
coeffs[x+11] = -9536;
coeffs[x+12] = 1;
coeffs[x+13] = 10265;
coeffs[x+14] = -1;
coeffs[x+15] = 87720;
coeffs[x+16] = -1;
coeffs[x+17] = 10265;
coeffs[x+18] = 1;
coeffs[x+19] = -9536;
coeffs[x+20] = 0;
coeffs[x+21] = 7985;
coeffs[x+22] = 0;
coeffs[x+23] = -6337;
coeffs[x+24] = 0;
coeffs[x+25] = 4621;
coeffs[x+26] = 0;
coeffs[x+27] = -3030;
coeffs[x+28] = 0;
coeffs[x+29] = 2267;
coeffs[x+30] = 0;
 end
end

generate
genvar i;
for (i=0; i<N; i=i+1)
begin: mult1
    multiplier mult1(.dataa(coeffs[i]),     .datab(delayholder[i]),.result(summation[i]));
end
endgenerate

always @(posedge sample_clock or posedge reset)
begin
if(reset)
    begin
      output_sample1 = 0;
      for (z=0; z<N; z=z+1)
      begin
      delayholder[z] = 0;
      end
end

else
    begin  
      for (z=N-1; z>0; z=z-1)
      begin
      delayholder[z] = delayholder[z-1];
      end
      delayholder[0] = input_sample1;
end

     for (z=0; z<N; z=z+1)
     begin
    finsummations[z] = summation[z] >> 15;  //{summation[z][15],        summation[z][15], summation[z][15:2]}
    end

      finsummation = 0;
     for (z=0; z<N; z=z+1)
      begin
      finsummation = finsummation + finsummations[z];
      end

      output_sample1 = finsummation;
end

endmodule

乘数代码:

`timescale 1 ps / 1 ps
module multiplier (dataa,datab,result);

input  [15:0]  dataa;
input    [15:0]  datab;
output [31:0]  result;

wire [31:0] sub_wire0;
wire [31:0] result = sub_wire0[31:0];

lpm_mult    lpm_mult_component (
            .dataa (dataa),
            .datab (datab),
            .result (sub_wire0),
            .aclr (1'b0),
            .clken (1'b1),
            .clock (1'b0),
            .sum (1'b0));
defparam
    lpm_mult_component.lpm_hint = "MAXIMIZE_SPEED=5",
    lpm_mult_component.lpm_representation = "SIGNED",
    lpm_mult_component.lpm_type = "LPM_MULT",
    lpm_mult_component.lpm_widtha = 16,
    lpm_mult_component.lpm_widthb = 16,
    lpm_mult_component.lpm_widthp = 32;

1 个答案:

答案 0 :(得分:0)

我不是过滤器专家,但我在用于初始化系数的代码块中看到了几个潜在的问题。首先,我建议将其作为初始块,因为它只需要发生一次。其次,对于16位有符号值,您的范围为-32767到+32768,但您的一个系数是87720,这超出了范围。由于Verilog不像VHDL那样强类型,你可以这样做,但结果将不是你想要的。您需要更改系数值或增加系数的位宽,并更改乘数代码以使用增加的宽度。最后,你指定了201个系数,但是你的赋值逻辑只会给coeffs 0到92赋值。这应该在你的模拟中显示为一堆“X”(你在模拟中尝试过这个,对吧? )。在综合你的设计时,你的工具应该抱怨,但它可能只是为初始化的位置分配零值(Xilinx的Vivado这样做,我不知道其他工具怎么样)。无论如何,您希望实现的目标与工具的产生方式之间存在差异。