Verilog FIR滤波器

时间:2014-11-26 20:49:24

标签: filter verilog electronics intel-fpga

您好我正在使用DE2板在Verilog中实现FIR滤波器。出于某种原因,扬声器的输出充满了静电,尽管它似乎过滤掉了某些频率。这是FIR的代码:

// Local wires.
    wire read_ready, write_ready, read, write;
    wire [23:0] readdata_left, readdata_right;
    wire [23:0] writedata_left, writedata_right;

    assign writedata_left = output_sample;

    assign writedata_right = output_sample;
    assign read = 1;
    assign write = 1;

    wire [23:0] input_sample = readdata_left;

    reg [23:0] output_sample;

输入样本通过FIR,输出样本放在左右扬声器上以简化。

//The FIR filter
parameter N = 40;
reg signed[23:0] coeffs[39:0];
reg [23:0] holderBefore[39:0];

wire [23:0] toAdd[39:0];

// -- 1000-1100
always @(*)
begin
    coeffs[0]=24'b100000000110101001111110; // -- 1
    coeffs[1]=24'b100000000110100011011011; // -- 2
    coeffs[2]=24'b100000000111000100001100; // -- 3
    coeffs[3]=24'b100000000111111000101000;// -- 4
    coeffs[4]=24'b100000001000011111111100;// -- 5
    coeffs[5]=24'b100000001000011001011001;// -- 6
    coeffs[6]=24'b100000000111010001010011;// -- 7
    coeffs[7]=24'b100000000100100110111010;// -- 8
    coeffs[8]=24'b100000000000011010001101;// -- 9
    coeffs[9]=24'b000000000101101111000000;// -- 10
    coeffs[10]=24'b000000001101100001000100;// -- 11
    coeffs[11]=24'b000000010110111100000000;// -- 12
    coeffs[12]=24'b000000100001011111000001;// -- 13
     coeffs[13]=24'b000000101100101001010111;// -- 14
    coeffs[14]=24'b000000111000000000110100;// -- 15
    coeffs[15]=24'b000001000010101010011001;// -- 16
    coeffs[16]=24'b000001001100001011111000;// -- 17
    coeffs[17]=24'b000001010011111101111100;// -- 18
    coeffs[18]=24'b000001011001011001010010;// -- 19
    coeffs[19]=24'b000001011100010000110010;// -- 20
    coeffs[20]=24'b000001011100010000110010;// -- 20
    coeffs[21]=24'b000001011001011001010010;// -- 19
    coeffs[22]=24'b000001001100001011111000;// -- 18
    coeffs[23]=24'b000001001100001011111000;// -- 17
    coeffs[24]=24'b000001000010101010011001;// -- 16
    coeffs[25]=24'b000000111000000000110100;// -- 15
     coeffs[26]=24'b000000101100101001010111;// -- 14
    coeffs[27]=24'b000000100001011111000001;// -- 13
    coeffs[28]=24'b000000010110111100000000;// -- 12
    coeffs[29]=24'b000000001101100001000100;// -- 11
    coeffs[30]=24'b000000000101101111000000;// -- 10
    coeffs[31]=24'b100000000000011010001101;// -- 9
    coeffs[32]=24'b100000000100100110111010;// -- 8
    coeffs[33]=24'b100000000111010001010011;// -- 7
    coeffs[34]=24'b100000001000011001011001;// -- 6
    coeffs[35]=24'b100000001000011111111100;// -- 5
    coeffs[36]=24'b100000000111111000101000;// -- 4
    coeffs[37]=24'b100000000111000100001100;// -- 3
     coeffs[38]=24'b100000000110100011011011;// -- 2
    coeffs[39]=24'b100000000110101001111110;// -- 1
end

genvar i;

generate
for (i=0; i<N; i=i+1)
    begin: mult
        multiplier mult1(
          .dataa(coeffs[i]),
          .datab(holderBefore[i]),
          .out(toAdd[i]));
    end
endgenerate

always @(posedge CLOCK_50 or posedge reset)
begin
    if(reset)
        begin
            holderBefore[39]     <= 0;
            holderBefore[38]     <= 0;
            holderBefore[37]     <= 0;
            holderBefore[36]     <= 0;
            holderBefore[35]     <= 0;
            holderBefore[34]     <= 0;
            holderBefore[33]     <= 0;
            holderBefore[32]     <= 0;
            holderBefore[31]     <= 0;
            holderBefore[30]     <= 0;
                holderBefore[29]    <= 0;
                holderBefore[28]    <= 0;
            holderBefore[27]    <= 0;
            holderBefore[26]    <= 0;
            holderBefore[25]    <= 0;
            holderBefore[24]     <= 0;
            holderBefore[23]     <= 0;
            holderBefore[22]     <= 0;
            holderBefore[21]     <= 0;
            holderBefore[20]     <= 0;
            holderBefore[19]     <= 0;
            holderBefore[18]     <= 0;
            holderBefore[17]     <= 0;
            holderBefore[16]     <= 0;
            holderBefore[15]     <= 0;
                holderBefore[14]    <= 0;
                holderBefore[13]    <= 0;
            holderBefore[12]    <= 0;
            holderBefore[11]    <= 0;
            holderBefore[10]    <= 0;
            holderBefore[9]     <= 0;
            holderBefore[8]     <= 0;
            holderBefore[7]     <= 0;
            holderBefore[6]     <= 0;
            holderBefore[5]     <= 0;
            holderBefore[4]     <= 0;
            holderBefore[3]     <= 0;
            holderBefore[2]     <= 0;
            holderBefore[1]     <= 0;
            holderBefore[0]     <= 0;
            output_sample       <= 0;
        end
    else
        begin
            holderBefore[39]     <= holderBefore[38];
            holderBefore[38]     <= holderBefore[37];
            holderBefore[37]     <= holderBefore[36];
            holderBefore[36]    <= holderBefore[35];
            holderBefore[35]    <= holderBefore[34];
            holderBefore[34]    <= holderBefore[33];
            holderBefore[33]     <= holderBefore[32];
            holderBefore[32]     <= holderBefore[31];
            holderBefore[31]     <= holderBefore[30];
            holderBefore[30]     <= holderBefore[29];
            holderBefore[29]     <= holderBefore[28];
            holderBefore[28]     <= holderBefore[27];
            holderBefore[27]     <= holderBefore[26];
            holderBefore[26]     <= holderBefore[25];
            holderBefore[25]     <= holderBefore[24];
                holderBefore[24]    <= holderBefore[23];
            holderBefore[23]    <= holderBefore[22];
            holderBefore[22]    <= holderBefore[21];
            holderBefore[21]     <= holderBefore[20];
            holderBefore[20]     <= holderBefore[19];
            holderBefore[19]     <= holderBefore[18];
            holderBefore[18]     <= holderBefore[17];
            holderBefore[17]     <= holderBefore[16];
            holderBefore[16]     <= holderBefore[15];
            holderBefore[15]     <= holderBefore[14];
            holderBefore[14]     <= holderBefore[13];
            holderBefore[13]     <= holderBefore[12];
            holderBefore[12]    <= holderBefore[11];
            holderBefore[11]    <= holderBefore[10];
            holderBefore[10]    <= holderBefore[9];
            holderBefore[9]     <= holderBefore[8];
            holderBefore[8]     <= holderBefore[7];
            holderBefore[7]     <= holderBefore[6];
            holderBefore[6]     <= holderBefore[5];
            holderBefore[5]     <= holderBefore[4];
            holderBefore[4]     <= holderBefore[3];
            holderBefore[3]     <= holderBefore[2];
            holderBefore[2]     <= holderBefore[1];
            holderBefore[1]     <= holderBefore[0];
            holderBefore[0]     <= input_sample;
            output_sample <= (input_sample + toAdd[0] + toAdd[1] + 
                              toAdd[2] + toAdd[3] + toAdd[4] + toAdd[5] +
                              toAdd[6] + toAdd[7] + toAdd[8] + toAdd[9] + 
                              toAdd[10] + toAdd[11] + toAdd[12]+ toAdd[13] + toAdd[14] + 
                              toAdd[15] + toAdd[16] + toAdd[17] + toAdd[18] +
                              toAdd[19] + toAdd[20] + toAdd[21] + toAdd[22] + 
                              toAdd[23] + toAdd[24] + toAdd[25] +toAdd[26] + toAdd[27] + toAdd[28] + toAdd[29] +
                              toAdd[19] + toAdd[20] + toAdd[21] + toAdd[22] + 
                              toAdd[30] + toAdd[31] + toAdd[32]+ toAdd[33] + toAdd[34] + toAdd[35] + toAdd[36] +
                              toAdd[37] + toAdd[38] + toAdd[39]);
        end
end

//The multiplier
module multiplier (dataa,datab,out);
input [23:0]dataa;
input [23:0]datab;
reg [47:0]result;
output[23:0]out;
always@(*)begin
    result = dataa*datab;
end
assign out = result[46:24]; 
endmodule

假设系数正确,代码有问题吗?我假设二进制中系数的表示存在问题,或者乘数是错误的,但我无法弄清楚。 谢谢

1 个答案:

答案 0 :(得分:2)

乘数不执行有符号乘法。

Verilog默认为无符号,如果等式的任何部分是无符号的,它将是无符号的。如果进行了位选择(即使它是全宽度),则算术将是无符号的。

以下代码应执行带符号的算术。

module multiplier (
  input      signed [23:0] dataa,
  input      signed [23:0] datab,
  output reg signed [23:0] out
);
reg signed [47:0] result;

  always @* begin
    result = dataa*datab;
    out    = result[46:24];
  end  
endmodule

您没有将result的MSB捕获到out,这看起来像无符号或正数的增益错误,但可能会失去负数的符号。

当您将总和执行到output_sample时,数字可能会溢出。每增加一个,你应该增加1位净空,然后限制。如果在此阶段溢出/剪切,可以添加一些标记来记录。