Filter Verilog FIR滤波器

Filter Verilog FIR滤波器,filter,verilog,intel-fpga,Filter,Verilog,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 wri

您好,我正在使用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
//FIR滤波器
参数N=40;
注册签名[23:0]系数[39:0];
reg[23:0]在[39:0]之前持有;
导线[23:0]至添加[39:0];
// -- 1000-1100
始终@(*)
开始
系数[0]=24'b100000000110101001111110;/--1.
系数[1]=24'B10000000011010001011011011;/--2.
系数[2]=24'b100000000111000100001100;/--3.
系数[3]=24'b100000000111111000101000;/--4.
系数[4]=24'B1000000010000111111100;/--5.
系数[5]=24'B10000000100001100011001;/--6.
系数[6]=24'b100000000111010001010011;/--7.
系数[7]=24'B100000000100110111010;/--8.
系数[8]=24'b100000000000011010001101;/--9
系数[9]=24'B00000000010111000000;/--10
系数[10]=24'B000000001101010000100;/--11
系数[11]=24'B000000010111100000000;/--12
系数[12]=24'B00000100001011111000001;/--13
系数[13]=24'B00000101100101001010111;//--14
系数[14]=24'B0000001100000000011010;/--15
系数[15]=24'B000001010000101010011001;//--16
系数[16]=24'B0000010110000101111000;/--17
系数[17]=24'B00000101001111111111100;/--18
系数[18]=24'B00000101000010;/--19
系数[19]=24'B00000101100010000110010;/--20
系数[20]=24'B00000101100010000110010;/--20
系数[21]=24'B00000101000010;/--19
系数[22]=24'B0000010110000101111000;/--18
系数[23]=24'B0000010110000101111000;/--17
系数[24]=24'B000001010000101010011001;//--16
系数[25]=24'B0000001100000000011010;/--15
系数[26]=24'B00000101100101001010111;//--14
系数[27]=24'B00000100001011111000001;/--13
系数[28]=24'B000000010111100000000;/--12
系数[29]=24'B000000001101010000100;/--11
系数[30]=24'B00000000010111000000;/--10
系数[31]=24'b100000000000011010001101;/--9
系数[32]=24'B100000000100110111010;/--8.
系数[33]=24'b100000000111010001010011;/--7.
系数[34]=24'B10000000100001100011001;/--6.
系数[35]=24'B10000000100001111111100;/--5.
系数[36]=24'b100000000111111000101000;/--4.
系数[37]=24'b100000000111000100001100;/--3.
系数[38]=24'B10000000011010001011011011;/--2.
系数[39]=24'b100000000110101001111110;/--1.
结束
genvar i;
生成

对于(i=0;i,乘法器不执行有符号乘法

Verilog默认为unsigned,如果方程的任何部分是unsigned的,它将是unsigned的。如果进行了位选择(即使是全宽),则算术将是unsigned的

以下代码应执行有符号算术

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
您没有将
结果
的MSB捕获到
输出
中,这看起来像是无符号或正数的增益错误,但可能会丢失负数的符号


当您在
output\u sample
中执行求和时,数字可能会溢出。对于每一次加法,您应该添加1位余量,然后进行限制。如果在此阶段溢出/剪裁,可能需要添加一些标志来记录。

为什么用二进制表示系数?为什么不使用十六进制或十进制值,它们会更容易阅读。你似乎暗示了40个乘法器,以及40个值的运算和加法。我很惊讶它是合成的,并且符合时间。40个乘法器必须占用大量的面积,40个输入加法器的时间必须相当长。合成中有任何警告或错误吗?除非你的第一个系数是1,否则你可能会不希望将
input\u sample
直接输入到output\u sample等式中。合成确实需要很多时间,但不会产生任何错误。我如何在Verilog中将-0.1984表示为十进制?是的,它们是有符号的,我认为使用“reg signed”会使系数有符号。我如何使乘法器有符号?T谢谢你的回答。因为系数乘以2^个小数位。所以你得到一个整数。十六进制通常使用,因为它更紧凑。