<meter id="pryje"><nav id="pryje"><delect id="pryje"></delect></nav></meter>
          <label id="pryje"></label>

          新聞中心

          EEPW首頁(yè) > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > 用FPGA實(shí)現(xiàn)各種數(shù)字濾波器

          用FPGA實(shí)現(xiàn)各種數(shù)字濾波器

          作者: 時(shí)間:2024-09-20 來(lái)源:電子森林 收藏

          實(shí)施概述

          本文引用地址:http://www.ex-cimer.com/article/202409/463056.htm

          本篇部分內(nèi)容來(lái)自網(wǎng)站實(shí)現(xiàn)的一些項(xiàng)目,源于一位在校學(xué)生的學(xué)習(xí)和設(shè)計(jì)- 了解并在上實(shí)現(xiàn)幾種類型的數(shù)字器,設(shè)計(jì)的所有濾波器均為15階濾波器,并使用16位定點(diǎn)數(shù)學(xué)運(yùn)算,該學(xué)生有一篇PPT可供參考:

          FPGA濾波器實(shí)現(xiàn)

          研究項(xiàng)目期間創(chuàng)建的源文件如下。

          FIR濾波器

          FIR濾波器是四個(gè)濾波器中最簡(jiǎn)單、最快的,它利用了預(yù)加器的對(duì)稱性,而且使用加法器樹(shù)來(lái)最小化組合路徑延遲。


          FIR_Filter.v
          `define FILT_LENGTH 16 module FIR_Filter(
              input  clk,
              input  en,
              input  [15:0]din,
              output [15:0]dout    );     reg signed [15:0]coeff[`FILT_LENGTH/2-1:0]; //Filter coefficients.
              reg signed [15:0]delay_line[`FILT_LENGTH-1:0]; //Input delay line.
              wire [31:0]accum; //Accumulator for output filter calculation.    
              integer i; //Initialization integer.
              genvar c;  //Delay line generation variable.     reg signed [16:0]preadd_regs[7:0]; //Save calc after preadd.
              reg signed [31:0]mult_regs[7:0];   //Save calc after multiplication.
              reg signed [31:0]tree1_regs[3:0];  //Save calc after first layer of adder tree.
              reg signed [31:0]tree2_regs[1:0];  //Save calc after first layer of adder tree.
              reg signed [31:0]treeout_reg;      //Save calc after complete.     //assign dout = treeout_reg[31:16];     //Calculate value in the accumulator.
              assign accum = (delay_line[0] + delay_line[15]) * coeff[0] +
                             (delay_line[1] + delay_line[14]) * coeff[1] +
                             (delay_line[2] + delay_line[13]) * coeff[2] +
                             (delay_line[3] + delay_line[12]) * coeff[3] +
                             (delay_line[4] + delay_line[11]) * coeff[4] +
                             (delay_line[5] + delay_line[10]) * coeff[5] +
                             (delay_line[6] + delay_line[9])  * coeff[6] +
                             (delay_line[7] + delay_line[8])  * coeff[7];     //Assign upper 16-bits to output.
              assign dout = accum[31:16];     initial begin   
                  //Load the filter coefficients.
                  coeff[0] = 16'd2320;
                  coeff[1] = 16'd4143;
                  coeff[2] = 16'd4592;
                  coeff[3] = 16'd7278;
                  coeff[4] = 16'd8423;
                  coeff[5] = 16'd10389;
                  coeff[6] = 16'd11269;
                  coeff[7] = 16'd12000;         //Initialize delay line.
                  for(i = 0; i < `FILT_LENGTH; i = i+1'b1) begin
                      delay_line[i] = 16'd0;
                  end         //Initialize the preadder regs.
                  for(i = 0; i < 8; i = i+1'b1) begin
                      preadd_regs[i] = 17'd0;
                  end         //Initialize the multiplier regs.
                  for(i = 0; i < 8; i = i+1'b1) begin
                      mult_regs[i] = 32'd0;
                  end         //Initialize the first layer of the adder tree regs.
                  for(i = 0; i < 4; i = i+1'b1) begin
                      tree1_regs[i] = 32'd0;
                  end         //Initialize the second layer of the adder tree regs.
                  for(i = 0; i < 2; i = i+1'b1) begin
                      tree2_regs[i] = 32'd0;
                  end                 //Initialize the adder tree output reg.
                  treeout_reg = 32'd0;
              end     //Advance the data through the delay line every clock cycle.
              generate
                  for (c = `FILT_LENGTH-1; c > 0; c = c - 1) begin: inc_delay            always @(posedge clk) begin
                          if(en) delay_line[c] <= delay_line[c-1];
                      end
                  end
              endgenerate     //Update with input data.
              always @(posedge clk) begin
                  if(en) delay_line[0] <= din;
              endendmodule
          filter_top.v
          module filter_top(
              input clk,
              input [7:0]sw,
              output [7:0]JA    );     wire [15:0]tout; //The output of the tone lookup table.
              wire [15:0]fout; //The output of the FIR filter.
              wire [15:0]mout; //Selected output.
              wire en;         //Clock enble.
              wire clk_out;    //264MHz System clock.     assign en = 1'b1; 
              clk_wiz_0 cw (.clk_in1(clk), .clk_out1(clk_out));
              //clk_en ce(.clk(clk_out), .en(en));
              ToneGen tg(.clk(clk_out), .en(en), .dout(tout));
              FIR_Filter ff(.clk(clk_out), .en(en), .din(tout), .dout(fout));     //Choose filtered or unfiltered output based on sw0.
              assign mout = sw[0] ? fout : tout;     //Take only the upper 8 bits and make it unsigned.
              //assign JA = mout[15:8] + 8'd128;
              assign {JA[3:0], JA[7:4]} = mout[15:8] + 8'd128; endmodule
          ToneGen.v
          `timescale 1ns/1ps module ToneGen(
              input clk,
              input en,
              output [15:0]dout    );     //Tone generation data.  At a 44KHz sampling rate, the lookup table
              //generates a 440Hz and 4.4KHz tone mixed together.
              reg [15:0]tonetbl[99:0];     //Pointer into the tone table.
              reg [6:0]toneptr = 7'h00;     initial begin
                  tonetbl[0] = 10970;
                  tonetbl[1] = 18151;
                  tonetbl[2] = 19197;
                  tonetbl[3] = 14105;
                  tonetbl[4] = 5211;
                  tonetbl[5] = -3704;
                  tonetbl[6] = -8858;
                  tonetbl[7] = -7914;
                  tonetbl[8] = -876;
                  tonetbl[9] = 9912;
                  tonetbl[10] = 20660;
                  tonetbl[11] = 27581;
                  tonetbl[12] = 28330;
                  tonetbl[13] = 22905;
                  tonetbl[14] = 13642;
                  tonetbl[15] = 4326;
                  tonetbl[16] = -1260;
                  tonetbl[17] = -780;
                  tonetbl[18] = 5767;
                  tonetbl[19] = 16037;
                  tonetbl[20] = 26244;
                  tonetbl[21] = 32601;
                  tonetbl[22] = 32767;
                  tonetbl[23] = 26741;
                  tonetbl[24] = 16863;
                  tonetbl[25] = 6918;
                  tonetbl[26] = 692;
                  tonetbl[27] = 527;
                  tonetbl[28] = 6421;
                  tonetbl[29] = 16037;
                  tonetbl[30] = 25590;
                  tonetbl[31] = 31295;
                  tonetbl[32] = 30814;
                  tonetbl[33] = 24149;
                  tonetbl[34] = 13642;
                  tonetbl[35] = 3081;
                  tonetbl[36] = -3745;
                  tonetbl[37] = -4494;
                  tonetbl[38] = 837;
                  tonetbl[39] = 9912;
                  tonetbl[40] = 18947;
                  tonetbl[41] = 24161;
                  tonetbl[42] = 23217;
                  tonetbl[43] = 16119;
                  tonetbl[44] = 5211;
                  tonetbl[45] = -5718;
                  tonetbl[46] = -12878;
                  tonetbl[47] = -13924;
                  tonetbl[48] = -8853;
                  tonetbl[49] = 0;
                  tonetbl[50] = 8853;
                  tonetbl[51] = 13924;
                  tonetbl[52] = 12878;
                  tonetbl[53] = 5718;
                  tonetbl[54] = -5211;
                  tonetbl[55] = -16119;
                  tonetbl[56] = -23217;
                  tonetbl[57] = -24161;
                  tonetbl[58] = -18947;
                  tonetbl[59] = -9912;
                  tonetbl[60] = -837;
                  tonetbl[61] = 4494;
                  tonetbl[62] = 3745;
                  tonetbl[63] = -3081;
                  tonetbl[64] = -13642;
                  tonetbl[65] = -24149;
                  tonetbl[66] = -30814;
                  tonetbl[67] = -31295;
                  tonetbl[68] = -25590;
                  tonetbl[69] = -16037;
                  tonetbl[70] = -6421;
                  tonetbl[71] = -527;
                  tonetbl[72] = -692;
                  tonetbl[73] = -6918;
                  tonetbl[74] = -16863;
                  tonetbl[75] = -26741;
                  tonetbl[76] = -32767;
                  tonetbl[77] = -32601;
                  tonetbl[78] = -26244;
                  tonetbl[79] = -16037;
                  tonetbl[80] = -5767;
                  tonetbl[81] = 780;
                  tonetbl[82] = 1260;
                  tonetbl[83] = -4326;
                  tonetbl[84] = -13642;
                  tonetbl[85] = -22905;
                  tonetbl[86] = -28330;
                  tonetbl[87] = -27581;
                  tonetbl[88] = -20660;
                  tonetbl[89] = -9912;
                  tonetbl[90] = 876;
                  tonetbl[91] = 7914;
                  tonetbl[92] = 8858;
                  tonetbl[93] = 3704;
                  tonetbl[94] = -5211;
                  tonetbl[95] = -14105;
                  tonetbl[96] = -19197;
                  tonetbl[97] = -18151;
                  tonetbl[98] = -10970;
                  tonetbl[99] = 0;
              end     //Assign the output to the value in the lookup table
              //pointed to by toneptr.
              assign dout = tonetbl[toneptr];     //Increment through the tone lookup table and wrap back
              //to zero when at the end.
              always @(posedge clk) begin
                  if(en) begin
                      if(toneptr == 7'd99) begin
                          toneptr <= 7'd0;
                      end
                      else begin
                          toneptr <= toneptr + 1'b1;
                      end
                  end
              endendmodule
          clk_en.v
          module clk_en(
              input clk,
              output reg en = 1'b0
              );     reg [15:0]en_counter = 16'h0;     always @(posedge clk) begin
                  if(en_counter == 16'd5999) begin
                      en_counter <= 16'h0;
                      en <= 1'b1;
                  end
                  else begin
                      en_counter <= en_counter + 1'b1;
                      en <= 1'b0;
                  end
              end endmodule
          TB_ToneGen.v
          module TB_ToneGen;     reg clk = 1'b0;
              reg sw0 = 1'b1;
              wire [7:0]JA;     wire en;    
              //wire [15:0]cout; 
              filter_top uut(.clk(clk), .sw({15'h00,sw0}), .JA({JA[3:0], JA[7:4]}));     assign en = uut.en;
              //assign cout = uut.ce.en_counter;     //initial begin
              //     #600000 sw0 = 1'b1;
              //end     //100MHz clock
              always #5 clk = ~clk;endmodule

          LMS自適應(yīng)濾波器

          LMS自適應(yīng)濾波器在單個(gè)時(shí)鐘周期內(nèi)完成其輸出計(jì)算和權(quán)重更新。由于其單周期運(yùn)行,因此存在大量的組合延遲。該濾波器只能以FIR濾波器速度的一小部分運(yùn)行。


          LMS_Adapt.v
          `define ADAPT_FILT_LENGTH 16module LMS_Adapt(
              input  clk,
              input  en,
              input  [15:0]din,
              input  signed [15:0]desired,
              output signed [15:0]dout,
              output signed [15:0]err    );     parameter MU = 16'd32767;     reg  signed [15:0]mu = MU;
              reg  signed [15:0]coeff[`ADAPT_FILT_LENGTH-1:0]; //Filter coefficients.
              reg  signed [15:0]delay_line[`ADAPT_FILT_LENGTH-1:0]; //Input delay line.
              wire signed [31:0]accum; //Accumulator for output filter calculation.
              wire signed [31:0]stepped; //Error after step sized applied.    
              integer i; //Initialization integer.
              genvar c;  //Delay line generation variable.     //Calculate the error and multiply it by the step size.
              assign err = desired - dout;   
              //assign stepped = err * mu;
              assign stepped = err << 15;     //Calculate value in the accumulator.
              assign accum = delay_line[0]*coeff[0] +
                             delay_line[1]*coeff[1] +
                             delay_line[2]*coeff[2] +
                             delay_line[3]*coeff[3] +
                             delay_line[4]*coeff[4] +
                             delay_line[5]*coeff[5] +
                             delay_line[6]*coeff[6] +
                             delay_line[7]*coeff[7] +
                             delay_line[8]*coeff[8] +
                             delay_line[9]*coeff[9] +
                             delay_line[10]*coeff[10] +
                             delay_line[11]*coeff[11] +
                             delay_line[12]*coeff[12] +
                             delay_line[13]*coeff[13] +
                             delay_line[14]*coeff[14] +
                             delay_line[15]*coeff[15];     //Assign upper 16-bits to output.
              assign dout = accum[31:16];     initial begin   
                  //Load the filter coefficients.
                  coeff[0]  = 20'd0;
                  coeff[1]  = 20'd0;
                  coeff[2]  = 20'd0;
                  coeff[3]  = 20'd0;
                  coeff[4]  = 20'd0;
                  coeff[5]  = 20'd0;
                  coeff[6]  = 20'd0;
                  coeff[7]  = 20'd0;
                  coeff[8]  = 20'd0;
                  coeff[9]  = 20'd0;
                  coeff[10] = 20'd0;
                  coeff[11] = 20'd0;
                  coeff[12] = 20'd0;
                  coeff[13] = 20'd0;
                  coeff[14] = 20'd0;
                  coeff[15] = 20'd0;         //Initialize delay line.
                  for(i = 0; i < `ADAPT_FILT_LENGTH; i = i+1'b1) begin
                      delay_line[i] = 16'd0;
                  end
              end     //Advance the data through the delay line every clock cycle.
              generate
                  for (c = `ADAPT_FILT_LENGTH-1; c > 0; c = c - 1) begin: inc_delay            always @(posedge clk) begin
                          if(en) delay_line[c] <= delay_line[c-1];
                      end
                  end
              endgenerate     //Update with input data.
              always @(posedge clk) begin
                  if(en) delay_line[0] <= din;
              end     wire signed [31:0]num2[`ADAPT_FILT_LENGTH-1:0];
              wire signed [15:0]n1[`ADAPT_FILT_LENGTH-1:0];
              wire signed [15:0]n2[`ADAPT_FILT_LENGTH-1:0];     //Update the coefficients with the LMS algorithm.
              generate
                  for (c = `ADAPT_FILT_LENGTH; c > 0; c = c - 1) begin: adapt_update            assign n1[c-1] = stepped[31:16];             assign num2[c-1] = n1[c-1]*delay_line[c-1];
                      assign n2[c-1] = num2[c-1][31:16];             always @(posedge clk) begin
                          if(en) coeff[c-1] <= coeff[c-1] + n2[c-1];
                      end
                  end
              endgenerateendmodule
          filter_top.v
          module filter_top(
              input clk,
              input [7:0]sw,
              output [7:0]JA    );     wire signed [15:0]tout;           //Output of the tone lookup table.
              wire [15:0]fout;                  //Output of the FIR filter.
              wire [15:0]aout;                  //Output of the adaptive filter.
              wire [15:0]err;                   //Adaptive filter error.
              wire [15:0]lfsr_out;              //16-bit Random noise variable.
              wire en;                          //Clock enble.
              wire [9:0]rnd;                    //10-bit noise.
              wire signed [15:0]tone_and_noise; //Combination of tone and noise.
              wire signed [15:0]delay_out;      //Output of the delay line.    
              wire [15:0]mout;                  //Selected desired output.
              wire clk19_8MHz;                  //19.8MHz system clock.     assign rnd = lfsr_out[15:6];
              assign tone_and_noise = tout + rnd;
              //assign en = 1'b1; 
              clk_wiz_0 cw(.clk_in1(clk), .clk_out1(clk19_8MHz), .reset(1'b0));
              ToneGen tg(.clk(clk19_8MHz), .en(en), .dout(tout));
              FIR_Filter ff(.clk(clk19_8MHz), .en(en), .din(tone_and_noise), .dout(fout));
              LMS_Adapt af(.clk(clk19_8MHz), .en(en), .din(tone_and_noise), .desired(mout), .dout(aout), .err(err));
              lfsr sr(.clk(clk19_8MHz), .en(en), .lfsr_out(lfsr_out));
              clk_en ce(.clk(clk19_8MHz), .en(en));     //Choose filtered or unfiltered output based on sw0.
              assign mout = sw[0] ? fout : tone_and_noise;//delay_out;     //Take only the upper 8 bits and make it unsigned.
              assign {JA[3:0], JA[7:4]} = aout[15:8] + 8'd128;
              //assign JA[7:0] = aout[15:8] + 8'd128;     //assign {JA[3:0], JA[7:4]} = sw[7:0];   endmodule
          ToneGen.v
          `timescale 1ns/1ps module ToneGen(
              input clk,
              input en,
              output [15:0]dout    );     //Tone generation data.  At a 44KHz sampling rate, the lookup table
              //generates a 440Hz and 4.4KHz tone mixed together.
              reg [15:0]tonetbl[99:0];     //Pointer into the tone table.
              reg [6:0]toneptr = 7'h00;     initial begin
                  tonetbl[0] = 10970;
                  tonetbl[1] = 18151;
                  tonetbl[2] = 19197;
                  tonetbl[3] = 14105;
                  tonetbl[4] = 5211;
                  tonetbl[5] = -3704;
                  tonetbl[6] = -8858;
                  tonetbl[7] = -7914;
                  tonetbl[8] = -876;
                  tonetbl[9] = 9912;
                  tonetbl[10] = 20660;
                  tonetbl[11] = 27581;
                  tonetbl[12] = 28330;
                  tonetbl[13] = 22905;
                  tonetbl[14] = 13642;
                  tonetbl[15] = 4326;
                  tonetbl[16] = -1260;
                  tonetbl[17] = -780;
                  tonetbl[18] = 5767;
                  tonetbl[19] = 16037;
                  tonetbl[20] = 26244;
                  tonetbl[21] = 32601;
                  tonetbl[22] = 32767;
                  tonetbl[23] = 26741;
                  tonetbl[24] = 16863;
                  tonetbl[25] = 6918;
                  tonetbl[26] = 692;
                  tonetbl[27] = 527;
                  tonetbl[28] = 6421;
                  tonetbl[29] = 16037;
                  tonetbl[30] = 25590;
                  tonetbl[31] = 31295;
                  tonetbl[32] = 30814;
                  tonetbl[33] = 24149;
                  tonetbl[34] = 13642;
                  tonetbl[35] = 3081;
                  tonetbl[36] = -3745;
                  tonetbl[37] = -4494;
                  tonetbl[38] = 837;
                  tonetbl[39] = 9912;
                  tonetbl[40] = 18947;
                  tonetbl[41] = 24161;
                  tonetbl[42] = 23217;
                  tonetbl[43] = 16119;
                  tonetbl[44] = 5211;
                  tonetbl[45] = -5718;
                  tonetbl[46] = -12878;
                  tonetbl[47] = -13924;
                  tonetbl[48] = -8853;
                  tonetbl[49] = 0;
                  tonetbl[50] = 8853;
                  tonetbl[51] = 13924;
                  tonetbl[52] = 12878;
                  tonetbl[53] = 5718;
                  tonetbl[54] = -5211;
                  tonetbl[55] = -16119;
                  tonetbl[56] = -23217;
                  tonetbl[57] = -24161;
                  tonetbl[58] = -18947;
                  tonetbl[59] = -9912;
                  tonetbl[60] = -837;
                  tonetbl[61] = 4494;
                  tonetbl[62] = 3745;
                  tonetbl[63] = -3081;
                  tonetbl[64] = -13642;
                  tonetbl[65] = -24149;
                  tonetbl[66] = -30814;
                  tonetbl[67] = -31295;
                  tonetbl[68] = -25590;
                  tonetbl[69] = -16037;
                  tonetbl[70] = -6421;
                  tonetbl[71] = -527;
                  tonetbl[72] = -692;
                  tonetbl[73] = -6918;
                  tonetbl[74] = -16863;
                  tonetbl[75] = -26741;
                  tonetbl[76] = -32767;
                  tonetbl[77] = -32601;
                  tonetbl[78] = -26244;
                  tonetbl[79] = -16037;
                  tonetbl[80] = -5767;
                  tonetbl[81] = 780;
                  tonetbl[82] = 1260;
                  tonetbl[83] = -4326;
                  tonetbl[84] = -13642;
                  tonetbl[85] = -22905;
                  tonetbl[86] = -28330;
                  tonetbl[87] = -27581;
                  tonetbl[88] = -20660;
                  tonetbl[89] = -9912;
                  tonetbl[90] = 876;
                  tonetbl[91] = 7914;
                  tonetbl[92] = 8858;
                  tonetbl[93] = 3704;
                  tonetbl[94] = -5211;
                  tonetbl[95] = -14105;
                  tonetbl[96] = -19197;
                  tonetbl[97] = -18151;
                  tonetbl[98] = -10970;
                  tonetbl[99] = 0;
              end     //Assign the output to the value in the lookup table
              //pointed to by toneptr.
              assign dout = tonetbl[toneptr];     //Increment through the tone lookup table and wrap back
              //to zero when at the end.
              always @(posedge clk) begin
                  if(en) begin
                      if(toneptr == 7'd99) begin
                          toneptr <= 7'd0;
                      end
                      else begin
                          toneptr <= toneptr + 1'b1;
                      end
                  end
              endendmodule
          FIR_Filter.v
          `define FILT_LENGTH 16 module FIR_Filter(
              input  clk,
              input  en,
              input  [15:0]din,
              output [15:0]dout    );     reg signed [15:0]coeff[`FILT_LENGTH/2-1:0]; //Filter coefficients.
              reg signed [15:0]delay_line[`FILT_LENGTH-1:0]; //Input delay line.
              wire [31:0]accum; //Accumulator for output filter calculation.    
              integer i; //Initialization integer.
              genvar c;  //Delay line generation variable.     //Calculate value in the accumulator.
              assign accum = (delay_line[0] + delay_line[15]) * coeff[0] +
                             (delay_line[1] + delay_line[14]) * coeff[1] +
                             (delay_line[2] + delay_line[13]) * coeff[2] +
                             (delay_line[3] + delay_line[12]) * coeff[3] +
                             (delay_line[4] + delay_line[11]) * coeff[4] +
                             (delay_line[5] + delay_line[10]) * coeff[5] +
                             (delay_line[6] + delay_line[9])  * coeff[6] +
                             (delay_line[7] + delay_line[8])  * coeff[7];     //Assign upper 16-bits to output.
              assign dout = accum[31:16];     initial begin   
                  //Load the filter coefficients.
                  coeff[0] = 16'd2552;
                  coeff[1] = 16'd4557;
                  coeff[2] = 16'd5051;
                  coeff[3] = 16'd8006;
                  coeff[4] = 16'd9265;
                  coeff[5] = 16'd11427;
                  coeff[6] = 16'd12396;
                  coeff[7] = 16'd13200;         //Initialize delay line.
                  for(i = 0; i < `FILT_LENGTH; i = i+1'b1) begin
                      delay_line[i] = 16'd0;
                  end
              end     //Advance the data through the delay line every clock cycle.
              generate
                  for (c = `FILT_LENGTH-1; c > 0; c = c - 1) begin: inc_delay            always @(posedge clk) begin
                          if(en) delay_line[c] <= delay_line[c-1];
                      end
                  end
              endgenerate     //Update with input data.
              always @(posedge clk) begin
                  if(en) delay_line[0] <= din;
              endendmodule
          clk_en.v
          module clk_en(
              input clk,
              output reg en = 1'b0
              );     reg [15:0]en_counter = 16'h0;     always @(posedge clk) begin
                  if(en_counter == 16'd449) begin
                      en_counter <= 16'h0;
                      en <= 1'b1;
                  end
                  else begin
                      en_counter <= en_counter + 1'b1;
                      en <= 1'b0;
                  end
              end endmodule
          lfsr.v
          `timescale 1ns / 1ps module lfsr(
              input clk,
              input en,
              input rst,
              output [15:0]lfsr_out    );     //Create a 16-bit linear feedback shift register with
              //maximal polynomial x^16 + x^14 + x^13 + x^11 + 1.
              reg [15:0]lfsr = 16'd1;
              wire feedback;     assign feedback = ((lfsr[15] ^ lfsr[13]) ^ lfsr[12]) ^ lfsr[10];
              assign lfsr_out = lfsr;     //Update the linear feedback shift register.
              always @(posedge clk) begin
                  if(rst) lfsr <= 16'd1;
                  else if(en) lfsr <= {lfsr[14:0], feedback};
              endendmodule
          TB_LMS_Adapt.v
          module TB_LMS_Adapt;     reg  clk = 1'b0;
              reg  [7:0]sw = 1'b1;
              wire [7:0]JA;     wire [15:0]d;
              wire [15:0]y;
              wire [15:0]e;
              wire [15:0]n1; 
              filter_top uut(.clk(clk), .sw(sw), .JA(JA));     assign d = uut.fout;
              assign y = uut.aout;
              assign e = uut.err;
              assign n1 = uut.af.n1[0];     always #5 clk = ~clk;     initial begin
                  //#20000000 sw[0] = 1'b1;
                  //#40000 sw[0] = 1'b1;
              endendmodule

          塊FIR濾波器

          塊FIR濾波器的創(chuàng)建是對(duì)塊概念的初步測(cè)試,因?yàn)槠溆?jì)算塊比LMS濾波器計(jì)算塊簡(jiǎn)單得多。濾波器的核心由四個(gè)計(jì)算模塊組成,每個(gè)時(shí)鐘周期對(duì)四個(gè)數(shù)據(jù)樣本進(jìn)行操作。


          Block_FIR.v
          `timescale 1ns / 1ps module Block_FIR(
              input  clk,
              input  en,
              input  signed [15:0]x0_in,
              input  signed [15:0]x1_in,
              input  signed [15:0]x2_in,
              input  signed [15:0]x3_in,
              output reg signed [15:0]x0_out = 16'd0,
              output reg signed [15:0]x1_out = 16'd0,
              output reg signed [15:0]x2_out = 16'd0,
              output reg signed [15:0]x3_out = 16'd0,
              output signed [15:0]u0,
              output signed [15:0]u1,
              output signed [15:0]u2,
              output signed [15:0]u3    );     //Filter coefficients.
              parameter b0 = 16'd1;
              parameter b1 = 16'd1;
              parameter b2 = 16'd1;
              parameter b3 = 16'd1;     //Coefficient registers.
              reg signed [15:0]_b0 = b0;
              reg signed [15:0]_b1 = b1;
              reg signed [15:0]_b2 = b2;
              reg signed [15:0]_b3 = b3;     //Register unit.
              always @(posedge clk) begin
                  if(en) begin
                      x0_out <= x0_in;
                      x1_out <= x1_in;
                      x2_out <= x2_in;
                      x3_out <= x3_in;
                  end
              end     /******************************IPC1******************************/   
              //Multiplier outputs.
              wire signed [31:0]IPC1_mult0;
              wire signed [31:0]IPC1_mult1;
              wire signed [31:0]IPC1_mult2;
              wire signed [31:0]IPC1_mult3;     //Adder outputs.
              wire signed [31:0]IPC1_add0;
              wire signed [31:0]IPC1_add1;
              wire signed [31:0]IPC1_out;     //Multiply inputs with coefficients.
              assign IPC1_mult0  = x3_in * _b0;
              assign IPC1_mult1  = x2_in * _b1;
              assign IPC1_mult2  = x1_in * _b2;
              assign IPC1_mult3  = x0_in * _b3;     //Add multiplied values together.
              assign IPC1_add0 = IPC1_mult0 + IPC1_mult1;
              assign IPC1_add1 = IPC1_mult2 + IPC1_mult3;
              assign IPC1_out  = IPC1_add0  + IPC1_add1;     //Assign output.
              assign u3 = IPC1_out[31:16];     /******************************IPC2******************************/   
              //Multiplier outputs.
              wire signed [31:0]IPC2_mult0;
              wire signed [31:0]IPC2_mult1;
              wire signed [31:0]IPC2_mult2;
              wire signed [31:0]IPC2_mult3;     //Adder outputs.
              wire signed [31:0]IPC2_add0;
              wire signed [31:0]IPC2_add1;
              wire signed [31:0]IPC2_out;     //Multiply inputs with coefficients.
              assign IPC2_mult0  = x2_in *  _b0;
              assign IPC2_mult1  = x1_in *  _b1;
              assign IPC2_mult2  = x0_in *  _b2;
              assign IPC2_mult3  = x3_out * _b3;     //Add multiplied values together.
              assign IPC2_add0 = IPC2_mult0 + IPC2_mult1;
              assign IPC2_add1 = IPC2_mult2 + IPC2_mult3;
              assign IPC2_out  = IPC2_add0  + IPC2_add1;     //Assign output.
              assign u2 = IPC2_out[31:16];     /******************************IPC3******************************/   
              //Multiplier outputs.
              wire signed [31:0]IPC3_mult0;
              wire signed [31:0]IPC3_mult1;
              wire signed [31:0]IPC3_mult2;
              wire signed [31:0]IPC3_mult3;     //Adder outputs.
              wire signed [31:0]IPC3_add0;
              wire signed [31:0]IPC3_add1;
              wire signed [31:0]IPC3_out;     //Multiply inputs with coefficients.
              assign IPC3_mult0  = x1_in *  _b0;
              assign IPC3_mult1  = x0_in *  _b1;
              assign IPC3_mult2  = x3_out * _b2;
              assign IPC3_mult3  = x2_out * _b3;     //Add multiplied values together.
              assign IPC3_add0 = IPC3_mult0 + IPC3_mult1;
              assign IPC3_add1 = IPC3_mult2 + IPC3_mult3;
              assign IPC3_out  = IPC3_add0  + IPC3_add1;     //Assign output.
              assign u1 = IPC3_out[31:16];     /******************************IPC4******************************/   
              //Multiplier outputs.
              wire signed [31:0]IPC4_mult0;
              wire signed [31:0]IPC4_mult1;
              wire signed [31:0]IPC4_mult2;
              wire signed [31:0]IPC4_mult3;     //Adder outputs.
              wire signed [31:0]IPC4_add0;
              wire signed [31:0]IPC4_add1;
              wire signed [31:0]IPC4_out;     //Multiply inputs with coefficients.
              assign IPC4_mult0  = x0_in *  _b0;
              assign IPC4_mult1  = x3_out * _b1;
              assign IPC4_mult2  = x2_out * _b2;
              assign IPC4_mult3  = x1_out * _b3;     //Add multiplied values together.
              assign IPC4_add0 = IPC4_mult0 + IPC4_mult1;
              assign IPC4_add1 = IPC4_mult2 + IPC4_mult3;
              assign IPC4_out  = IPC4_add0  + IPC4_add1;     //Assign output.
              assign u0 = IPC4_out[31:16];endmodule
          Block_FIR_Top.v
          `timescale 1ns / 1ps module Block_FIR_Top(
              input  clk,
              input  [7:0]sw,
              output [7:0]JA    );     wire clk_100MHz;
              wire clk_25MHz;
              wire en;     wire signed [15:0]tonegen_out;     //Data divider outputs.
              wire en_out;
              wire signed [15:0]d0_out;
              wire signed [15:0]d1_out;
              wire signed [15:0]d2_out;
              wire signed [15:0]d3_out;     //FIR f1 outputs
              wire signed [15:0]f1_x0_out;
              wire signed [15:0]f1_x1_out;
              wire signed [15:0]f1_x2_out;
              wire signed [15:0]f1_x3_out;
              wire signed [15:0]f1_u0;
              wire signed [15:0]f1_u1;
              wire signed [15:0]f1_u2;
              wire signed [15:0]f1_u3;     //FIR f2 outputs
              wire signed [15:0]f2_x0_out;
              wire signed [15:0]f2_x1_out;
              wire signed [15:0]f2_x2_out;
              wire signed [15:0]f2_x3_out;
              wire signed [15:0]f2_u0;
              wire signed [15:0]f2_u1;
              wire signed [15:0]f2_u2;
              wire signed [15:0]f2_u3;     //FIR f3 outputs
              wire signed [15:0]f3_x0_out;
              wire signed [15:0]f3_x1_out;
              wire signed [15:0]f3_x2_out;
              wire signed [15:0]f3_x3_out;
              wire signed [15:0]f3_u0;
              wire signed [15:0]f3_u1;
              wire signed [15:0]f3_u2;
              wire signed [15:0]f3_u3;     //FIR f4 outputs
              wire signed [15:0]f4_x0_out;
              wire signed [15:0]f4_x1_out;
              wire signed [15:0]f4_x2_out;
              wire signed [15:0]f4_x3_out;
              wire signed [15:0]f4_u0;
              wire signed [15:0]f4_u1;
              wire signed [15:0]f4_u2;
              wire signed [15:0]f4_u3;     //Block filter outputs.
              wire signed [15:0]y0;
              wire signed [15:0]y1;
              wire signed [15:0]y2;
              wire signed [15:0]y3;     wire [15:0]serial_dout; //Serialized output.
              wire [15:0]mout;        //Selected output.     assign en = 1'b1; 
              clk_wiz_0 cw(.clk_in1(clk), .clk_out1(clk_100MHz), .clk_out2(clk_25MHz));   
              ToneGen tg(.clk(clk_100MHz), .en(en), .dout(tonegen_out));
              Data_Div4 dd(.clk(clk_100MHz), .en(en), .din(tonegen_out), .en_out(en_out),
                           .d0_out(d0_out), .d1_out(d1_out), .d2_out(d2_out), .d3_out(d3_out));     //Build 16-tap block FIR filter.
              Block_FIR #(.b0(16'd2320), .b1(16'd4143), .b2(16'd4592), .b3(16'd7278))f1(.clk(clk_25MHz), .en(en),
                           .x0_in(d0_out), .x1_in(d1_out), .x2_in(d2_out), .x3_in(d3_out),
                           .x0_out(f1_x0_out), .x1_out(f1_x1_out), .x2_out(f1_x2_out), .x3_out(f1_x3_out),
                           .u0(f1_u0), .u1(f1_u1), .u2(f1_u2), .u3(f1_u3)); 
              Block_FIR #(.b0(16'd8423), .b1(16'd10389), .b2(16'd11269), .b3(16'd12000))f2(.clk(clk_25MHz), .en(en),
                           .x0_in(f1_x0_out), .x1_in(f1_x1_out), .x2_in(f1_x2_out), .x3_in(f1_x3_out),
                           .x0_out(f2_x0_out), .x1_out(f2_x1_out), .x2_out(f2_x2_out), .x3_out(f2_x3_out),
                           .u0(f2_u0), .u1(f2_u1), .u2(f2_u2), .u3(f2_u3)); 
              Block_FIR #(.b0(16'd12000), .b1(16'd11269), .b2(16'd10389), .b3(16'd8423))f3(.clk(clk_25MHz), .en(en),
                           .x0_in(f2_x0_out), .x1_in(f2_x1_out), .x2_in(f2_x2_out), .x3_in(f2_x3_out),
                           .x0_out(f3_x0_out), .x1_out(f3_x1_out), .x2_out(f3_x2_out), .x3_out(f3_x3_out),
                           .u0(f3_u0), .u1(f3_u1), .u2(f3_u2), .u3(f3_u3)); 
              Block_FIR #(.b0(16'd7278), .b1(16'd4592), .b2(16'd4143), .b3(16'd2320))f4(.clk(clk_25MHz), .en(en),
                           .x0_in(f3_x0_out), .x1_in(f3_x1_out), .x2_in(f3_x2_out), .x3_in(f3_x3_out),
                           .x0_out(f4_x0_out), .x1_out(f4_x1_out), .x2_out(f4_x2_out), .x3_out(f4_x3_out),
                           .u0(f4_u0), .u1(f4_u1), .u2(f4_u2), .u3(f4_u3));     //Add outputs together.
              assign y0 = f1_u0 + f2_u0 + f3_u0 + f4_u0;
              assign y1 = f1_u1 + f2_u1 + f3_u1 + f4_u1;
              assign y2 = f1_u2 + f2_u2 + f3_u2 + f4_u2;
              assign y3 = f1_u3 + f2_u3 + f3_u3 + f4_u3;     //Serialize the output data.
              Data_Mult4 dm(.clk(clk_100MHz), .en(en), .d0_in(y0), .d1_in(y1), .d2_in(y2), .d3_in(y3), .dout(serial_dout));     //Choose filtered or unfiltered output based on sw0.
              assign mout = sw[0] ? serial_dout : tonegen_out;     //Take only the upper 8 bits and make it unsigned.
              //assign JA = mout[15:8] + 8'd128;
              assign {JA[3:0], JA[7:4]} = mout[15:8] + 8'd128;endmodule
          ToneGen.v
          `timescale 1ns/1ps module ToneGen(
              input clk,
              input en,
              output [15:0]dout    );     //Tone generation data.  At a 44KHz sampling rate, the lookup table
              //generates a 440Hz and 4.4KHz tone mixed together.
              reg [15:0]tonetbl[99:0];     //Pointer into the tone table.
              reg [6:0]toneptr = 7'h00;     initial begin
                  tonetbl[0] = 10970;
                  tonetbl[1] = 18151;
                  tonetbl[2] = 19197;
                  tonetbl[3] = 14105;
                  tonetbl[4] = 5211;
                  tonetbl[5] = -3704;
                  tonetbl[6] = -8858;
                  tonetbl[7] = -7914;
                  tonetbl[8] = -876;
                  tonetbl[9] = 9912;
                  tonetbl[10] = 20660;
                  tonetbl[11] = 27581;
                  tonetbl[12] = 28330;
                  tonetbl[13] = 22905;
                  tonetbl[14] = 13642;
                  tonetbl[15] = 4326;
                  tonetbl[16] = -1260;
                  tonetbl[17] = -780;
                  tonetbl[18] = 5767;
                  tonetbl[19] = 16037;
                  tonetbl[20] = 26244;
                  tonetbl[21] = 32601;
                  tonetbl[22] = 32767;
                  tonetbl[23] = 26741;
                  tonetbl[24] = 16863;
                  tonetbl[25] = 6918;
                  tonetbl[26] = 692;
                  tonetbl[27] = 527;
                  tonetbl[28] = 6421;
                  tonetbl[29] = 16037;
                  tonetbl[30] = 25590;
                  tonetbl[31] = 31295;
                  tonetbl[32] = 30814;
                  tonetbl[33] = 24149;
                  tonetbl[34] = 13642;
                  tonetbl[35] = 3081;
                  tonetbl[36] = -3745;
                  tonetbl[37] = -4494;
                  tonetbl[38] = 837;
                  tonetbl[39] = 9912;
                  tonetbl[40] = 18947;
                  tonetbl[41] = 24161;
                  tonetbl[42] = 23217;
                  tonetbl[43] = 16119;
                  tonetbl[44] = 5211;
                  tonetbl[45] = -5718;
                  tonetbl[46] = -12878;
                  tonetbl[47] = -13924;
                  tonetbl[48] = -8853;
                  tonetbl[49] = 0;
                  tonetbl[50] = 8853;
                  tonetbl[51] = 13924;
                  tonetbl[52] = 12878;
                  tonetbl[53] = 5718;
                  tonetbl[54] = -5211;
                  tonetbl[55] = -16119;
                  tonetbl[56] = -23217;
                  tonetbl[57] = -24161;
                  tonetbl[58] = -18947;
                  tonetbl[59] = -9912;
                  tonetbl[60] = -837;
                  tonetbl[61] = 4494;
                  tonetbl[62] = 3745;
                  tonetbl[63] = -3081;
                  tonetbl[64] = -13642;
                  tonetbl[65] = -24149;
                  tonetbl[66] = -30814;
                  tonetbl[67] = -31295;
                  tonetbl[68] = -25590;
                  tonetbl[69] = -16037;
                  tonetbl[70] = -6421;
                  tonetbl[71] = -527;
                  tonetbl[72] = -692;
                  tonetbl[73] = -6918;
                  tonetbl[74] = -16863;
                  tonetbl[75] = -26741;
                  tonetbl[76] = -32767;
                  tonetbl[77] = -32601;
                  tonetbl[78] = -26244;
                  tonetbl[79] = -16037;
                  tonetbl[80] = -5767;
                  tonetbl[81] = 780;
                  tonetbl[82] = 1260;
                  tonetbl[83] = -4326;
                  tonetbl[84] = -13642;
                  tonetbl[85] = -22905;
                  tonetbl[86] = -28330;
                  tonetbl[87] = -27581;
                  tonetbl[88] = -20660;
                  tonetbl[89] = -9912;
                  tonetbl[90] = 876;
                  tonetbl[91] = 7914;
                  tonetbl[92] = 8858;
                  tonetbl[93] = 3704;
                  tonetbl[94] = -5211;
                  tonetbl[95] = -14105;
                  tonetbl[96] = -19197;
                  tonetbl[97] = -18151;
                  tonetbl[98] = -10970;
                  tonetbl[99] = 0;
              end     //Assign the output to the value in the lookup table
              //pointed to by toneptr.
              assign dout = tonetbl[toneptr];     //Increment through the tone lookup table and wrap back
              //to zero when at the end.
              always @(posedge clk) begin
                  if(en) begin
                      if(toneptr == 7'd99) begin
                          toneptr <= 7'd0;
                      end
                      else begin
                          toneptr <= toneptr + 1'b1;
                      end
                  end
              endendmodule
          Data_Div4.v
          `timescale 1ns / 1ps module Data_Div4(
              input clk,
              input en,
              input [15:0]din,
              output reg en_out = 1'b0,
              output reg [15:0]d0_out = 16'd0,
              output reg [15:0]d1_out = 16'd0,
              output reg [15:0]d2_out = 16'd0,
              output reg [15:0]d3_out = 16'd0
              );     reg [1:0]count = 2'd0;     //Internal registers for holding data.
              reg [15:0]d0 = 16'd0;
              reg [15:0]d1 = 16'd0;
              reg [15:0]d2 = 16'd0;     always @(posedge clk) begin
                  if(en) begin
                      count <= count + 1'b1;             if(count == 2'b00) begin
                          d0 <= din;
                          en_out <= 1'b0;
                      end
                      else if(count == 2'b01) begin
                          d1 <= din;
                          en_out <= 1'b0;
                      end
                      else if(count == 2'b10) begin
                          d2 <= din;
                          en_out <= 1'b0;
                      end
                      else begin
                          d0_out <= d0;
                          d1_out <= d1;
                          d2_out <= d2;
                          d3_out <= din;
                          en_out <= 1'b1;
                      end
                  end
              endendmodule
          Data_Mult4.v
          `timescale 1ns / 1ps module Data_Mult4(
              input clk,
              input en,
              input [15:0]d0_in,
              input [15:0]d1_in,
              input [15:0]d2_in,
              input [15:0]d3_in,
              output reg [15:0]dout = 16'd0
              );     reg [1:0]count = 2'd0;     //Internal registers for holding data.
              reg [15:0]d0 = 16'd0;
              reg [15:0]d1 = 16'd0;
              reg [15:0]d2 = 16'd0;
              reg [15:0]d3 = 16'd0;     always @(posedge clk) begin
                  if(en) begin
                      count <= count + 1'b1;             if(count == 2'b00) begin
                          dout <= d0;
                      end
                      else if(count == 2'b01) begin
                          dout <= d1;  
                      end
                      else if(count == 2'b10) begin
                          dout <= d2;
                      end
                      else begin
                          d0 <= d0_in;
                          d1 <= d1_in;
                          d2 <= d2_in;
                          d3 <= d3_in;
                          dout <= d3;      
                      end
                  end
              end endmodule
          Block_FIR_TB.v
          `timescale 1ns / 1ps module Block_FIR_TB;
              reg  clk = 1'b0;
              reg  [7:0]sw = 8'd0;
              wire [7:0]JA; 
              Block_FIR_Top uut(.clk(clk), .sw(sw), .JA(JA));     initial begin
                  #50000 sw = 8'd1;
              end     always #5 clk = ~clk;   endmodule

          LMS濾波器

          最后也是最復(fù)雜的濾波器是Block LMS濾波器。它還具有四個(gè)計(jì)算模塊,一次可以處理四個(gè)數(shù)據(jù)樣本,但是它具有一個(gè)簡(jiǎn)單的狀態(tài)機(jī),可以將其操作分成兩個(gè)時(shí)鐘周期。一個(gè)時(shí)鐘周期計(jì)算輸出值,而另一個(gè)時(shí)鐘周期更新權(quán)重。


          BLMS_Block.v
          `timescale 1ns / 1ps module BLMS_Block(
              input clk,      //Filter clock.
              input x_en,     //X registers enable.
              input w_en,     //Weight registers enable.
              input mux_sel,  //MUX selection input.
              input dmux_sel, //DMUX selection input.     input signed [15:0]xin0, //
              input signed [15:0]xin1, //16-bit Data input.
              input signed [15:0]xin2, //
              input signed [15:0]xin3, //     input signed [15:0]r0, //
              input signed [15:0]r1, //Weight adjust input.
              input signed [15:0]r2, //
              input signed [15:0]r3, //     output signed [15:0]u0, //
              output signed [15:0]u1, //u output for calculating y.
              output signed [15:0]u2, //
              output signed [15:0]u3, //     output reg signed [15:0]xout0 = 16'd0, //
              output reg signed [15:0]xout1 = 16'd0, //Data to cascade
              output reg signed [15:0]xout2 = 16'd0, //to the next block.
              output reg signed [15:0]xout3 = 16'd0  //
              );     //Filter weights.
              parameter b0 = 16'd0;
              parameter b1 = 16'd0;
              parameter b2 = 16'd0;
              parameter b3 = 16'd0;     //Weight registers.
              reg signed [15:0]_b0 = b0;
              reg signed [15:0]_b1 = b1;
              reg signed [15:0]_b2 = b2;
              reg signed [15:0]_b3 = b3;     /*************************Register Unit**************************/
              always @(posedge clk) begin
                  if(x_en) begin
                      xout0 <= xin0;
                      xout1 <= xin1;
                      xout2 <= xin2;
                      xout3 <= xin3;
                  end
              end     /******************************IPC1******************************/
              //Multiplier inputs.
              wire signed [15:0]IPC1_mult0_in;
              wire signed [15:0]IPC1_mult1_in;
              wire signed [15:0]IPC1_mult2_in;
              wire signed [15:0]IPC1_mult3_in;     //Multiplier outputs.
              wire signed [31:0]IPC1_mult0_out;
              wire signed [31:0]IPC1_mult1_out;
              wire signed [31:0]IPC1_mult2_out;
              wire signed [31:0]IPC1_mult3_out;     //Adder outputs.
              wire signed [31:0]IPC1_add0;
              wire signed [31:0]IPC1_add1;
              wire signed [31:0]IPC1_out;     //Do multiplications.
              assign IPC1_mult0_out  = xin3 * IPC1_mult0_in;
              assign IPC1_mult1_out  = xin2 * IPC1_mult1_in;
              assign IPC1_mult2_out  = xin1 * IPC1_mult2_in;
              assign IPC1_mult3_out  = xin0 * IPC1_mult3_in;     //Do additions.
              assign IPC1_add0 = IPC1_mult0_out + IPC1_mult1_out;
              assign IPC1_add1 = IPC1_mult2_out + IPC1_mult3_out;
              assign IPC1_out  = IPC1_add0  + IPC1_add1;     /******************************IPC2******************************/
              //Multiplier inputs.
              wire signed [15:0]IPC2_mult0_in;
              wire signed [15:0]IPC2_mult1_in;
              wire signed [15:0]IPC2_mult2_in;
              wire signed [15:0]IPC2_mult3_in;     //Multiplier outputs.
              wire signed [31:0]IPC2_mult0_out;
              wire signed [31:0]IPC2_mult1_out;
              wire signed [31:0]IPC2_mult2_out;
              wire signed [31:0]IPC2_mult3_out;     //Adder outputs.
              wire signed [31:0]IPC2_add0;
              wire signed [31:0]IPC2_add1;
              wire signed [31:0]IPC2_out;     //Do multiplications.
              assign IPC2_mult0_out  = xin2  * IPC2_mult0_in;
              assign IPC2_mult1_out  = xin1  * IPC2_mult1_in;
              assign IPC2_mult2_out  = xin0  * IPC2_mult2_in;
              assign IPC2_mult3_out  = xout3 * IPC2_mult3_in;     //Do additions.
              assign IPC2_add0 = IPC2_mult0_out + IPC2_mult1_out;
              assign IPC2_add1 = IPC2_mult2_out + IPC2_mult3_out;
              assign IPC2_out  = IPC2_add0  + IPC2_add1;     /******************************IPC3******************************/
              //Multiplier inputs.
              wire signed [15:0]IPC3_mult0_in;
              wire signed [15:0]IPC3_mult1_in;
              wire signed [15:0]IPC3_mult2_in;
              wire signed [15:0]IPC3_mult3_in;     //Multiplier outputs.
              wire signed [31:0]IPC3_mult0_out;
              wire signed [31:0]IPC3_mult1_out;
              wire signed [31:0]IPC3_mult2_out;
              wire signed [31:0]IPC3_mult3_out;     //Adder outputs.
              wire signed [31:0]IPC3_add0;
              wire signed [31:0]IPC3_add1;
              wire signed [31:0]IPC3_out;     //Do multiplications.
              assign IPC3_mult0_out  = xin1  * IPC3_mult0_in;
              assign IPC3_mult1_out  = xin0  * IPC3_mult1_in;
              assign IPC3_mult2_out  = xout3 * IPC3_mult2_in;
              assign IPC3_mult3_out  = xout2 * IPC3_mult3_in;     //Do additions.
              assign IPC3_add0 = IPC3_mult0_out + IPC3_mult1_out;
              assign IPC3_add1 = IPC3_mult2_out + IPC3_mult3_out;
              assign IPC3_out  = IPC3_add0  + IPC3_add1;     /******************************IPC4******************************/
              //Multiplier inputs.
              wire signed [15:0]IPC4_mult0_in;
              wire signed [15:0]IPC4_mult1_in;
              wire signed [15:0]IPC4_mult2_in;
              wire signed [15:0]IPC4_mult3_in;     //Multiplier outputs.
              wire signed [31:0]IPC4_mult0_out;
              wire signed [31:0]IPC4_mult1_out;
              wire signed [31:0]IPC4_mult2_out;
              wire signed [31:0]IPC4_mult3_out;     //Adder outputs.
              wire signed [31:0]IPC4_add0;
              wire signed [31:0]IPC4_add1;
              wire signed [31:0]IPC4_out;     //Do multiplications.
              assign IPC4_mult0_out  = xin0  * IPC4_mult0_in;
              assign IPC4_mult1_out  = xout3 * IPC4_mult1_in;
              assign IPC4_mult2_out  = xout2 * IPC4_mult2_in;
              assign IPC4_mult3_out  = xout1 * IPC4_mult3_in;     //Do additions.
              assign IPC4_add0 = IPC4_mult0_out + IPC4_mult1_out;
              assign IPC4_add1 = IPC4_mult2_out + IPC4_mult3_out;
              assign IPC4_out  = IPC4_add0  + IPC4_add1;     /***************************DMUX Unit****************************/     //DMUX outputs.
              wire signed [15:0]dmux1_out0;
              wire signed [15:0]dmux1_out1;   
              wire signed [15:0]dmux2_out0;
              wire signed [15:0]dmux2_out1;
              wire signed [15:0]dmux3_out0;
              wire signed [15:0]dmux3_out1;
              wire signed [15:0]dmux4_out0;
              wire signed [15:0]dmux4_out1;     //Assign outputs.
              assign dmux1_out0 = dmux_sel ? 16'd0           : IPC1_out[31:16];
              assign dmux1_out1 = dmux_sel ? IPC1_out[31:16] : 16'd0;     assign dmux2_out0 = dmux_sel ? 16'd0           : IPC2_out[31:16];
              assign dmux2_out1 = dmux_sel ? IPC2_out[31:16] : 16'd0;     assign dmux3_out0 = dmux_sel ? 16'd0           : IPC3_out[31:16];
              assign dmux3_out1 = dmux_sel ? IPC3_out[31:16] : 16'd0;     assign dmux4_out0 = dmux_sel ? 16'd0           : IPC4_out[31:16];
              assign dmux4_out1 = dmux_sel ? IPC4_out[31:16] : 16'd0;     //Assign u values.
              assign u3 = dmux1_out1;
              assign u2 = dmux2_out1;
              assign u1 = dmux3_out1;
              assign u0 = dmux4_out1;     /****************************WU Unit*****************************/
              always @(posedge clk) begin
                  if(w_en) begin
                      _b0 <= _b0 + dmux1_out0;
                      _b1 <= _b1 + dmux2_out0;
                      _b2 <= _b2 + dmux3_out0;
                      _b3 <= _b3 + dmux4_out0;
                  end
              end     /****************************MUX Unit****************************/
              //MUX outputs.
              wire signed [15:0]mux0_out;
              wire signed [15:0]mux1_out;
              wire signed [15:0]mux2_out;
              wire signed [15:0]mux3_out;     //Assign MUX outputs.
              assign mux0_out = mux_sel ? _b0 : r0;
              assign mux1_out = mux_sel ? _b1 : r1;
              assign mux2_out = mux_sel ? _b2 : r2;
              assign mux3_out = mux_sel ? _b3 : r3;     //Assign MUX outputs to IPC inputs.
              assign IPC1_mult0_in = mux0_out;
              assign IPC2_mult0_in = mux0_out;
              assign IPC3_mult0_in = mux0_out;
              assign IPC4_mult0_in = mux0_out;
              assign IPC1_mult1_in = mux1_out;
              assign IPC2_mult1_in = mux1_out;
              assign IPC3_mult1_in = mux1_out;
              assign IPC4_mult1_in = mux1_out;
              assign IPC1_mult2_in = mux2_out;
              assign IPC2_mult2_in = mux2_out;
              assign IPC3_mult2_in = mux2_out;
              assign IPC4_mult2_in = mux2_out;
              assign IPC1_mult3_in = mux3_out;
              assign IPC2_mult3_in = mux3_out;
              assign IPC3_mult3_in = mux3_out;
              assign IPC4_mult3_in = mux3_out;endmodule
          BLMS_ECU.v
          `timescale 1ns / 1ps module BLMS_ECU(
              input clk,     //Filter clock.
              input r_en,    //Weight adjust registers enable.     input signed [15:0]din0, //
              input signed [15:0]din1, //Desired inputs.
              input signed [15:0]din2, //
              input signed [15:0]din3, //     input signed [15:0]yin0, //
              input signed [15:0]yin1, //From filter output.
              input signed [15:0]yin2, //
              input signed [15:0]yin3, //     output reg signed [15:0]r0 = 16'd0, //
              output reg signed [15:0]r1 = 16'd0, //Stepped error output.
              output reg signed [15:0]r2 = 16'd0, //
              output reg signed [15:0]r3 = 16'd0  //
              );     //Adder outputs.
              wire signed [15:0]add_out0;
              wire signed [15:0]add_out1;
              wire signed [15:0]add_out2;
              wire signed [15:0]add_out3;     //Mu outputs.
              wire signed [31:0]mu0;
              wire signed [31:0]mu1;
              wire signed [31:0]mu2;
              wire signed [31:0]mu3;     //Assign outputs.
              assign add_out0 = din0 - yin0;
              assign add_out1 = din1 - yin1;
              assign add_out2 = din2 - yin2;
              assign add_out3 = din3 - yin3;     //Multiply error by mu (hard coded).
              assign mu0 = add_out0 << 15;
              assign mu1 = add_out1 << 15;
              assign mu2 = add_out2 << 15;
              assign mu3 = add_out3 << 15;     //Update delay registers.
              always @(posedge clk) begin
                  if(r_en) begin
                      r0 <= mu0[31:16];
                      r1 <= mu1[31:16];
                      r2 <= mu2[31:16];
                      r3 <= mu3[31:16];
                  end
              endendmodule
          BLMS_Top.v
          `timescale 1ns / 1ps module BLMS_Top(
              input  clk,
              input  [7:0]sw,
              output [7:0]JA    );     wire clk_50MHz;
              wire clk_25MHz;
              wire en;     wire signed [15:0]tonegen_out;    //Output of the tone lookup table.
              wire signed [15:0]fout;           //Output of the FIR filter.
              wire signed [15:0]lfsr_out;       //16-bit Random noise variable.
              wire signed [9:0]rnd;             //10-bit noise.
              wire signed [15:0]tone_and_noise; //Combination of tone and noise.
              wire signed [15:0]serial_dout;    //Serialized output.     //Selected desired output.
              wire signed [15:0]mout;                                    //Parallelized desired output.
              wire signed [15:0]dout0;
              wire signed [15:0]dout1;
              wire signed [15:0]dout2;
              wire signed [15:0]dout3;     //Parallelized input to BLMS filter.
              wire signed [15:0]blms_din0;
              wire signed [15:0]blms_din1;
              wire signed [15:0]blms_din2;
              wire signed [15:0]blms_din3;     //Stepped error.
              wire signed [15:0]r0;
              wire signed [15:0]r1;
              wire signed [15:0]r2;
              wire signed [15:0]r3;     //BLMS block1 outputs.
              wire signed [15:0]b1_x0_out;
              wire signed [15:0]b1_x1_out;
              wire signed [15:0]b1_x2_out;
              wire signed [15:0]b1_x3_out;
              wire signed [15:0]b1_u0;
              wire signed [15:0]b1_u1;
              wire signed [15:0]b1_u2;
              wire signed [15:0]b1_u3;     //BLMS block2 outputs.
              wire signed [15:0]b2_x0_out;
              wire signed [15:0]b2_x1_out;
              wire signed [15:0]b2_x2_out;
              wire signed [15:0]b2_x3_out;
              wire signed [15:0]b2_u0;
              wire signed [15:0]b2_u1;
              wire signed [15:0]b2_u2;
              wire signed [15:0]b2_u3;     //BLMS block3 outputs.
              wire signed [15:0]b3_x0_out;
              wire signed [15:0]b3_x1_out;
              wire signed [15:0]b3_x2_out;
              wire signed [15:0]b3_x3_out;
              wire signed [15:0]b3_u0;
              wire signed [15:0]b3_u1;
              wire signed [15:0]b3_u2;
              wire signed [15:0]b3_u3;     //BLMS block4 outputs.
              wire signed [15:0]b4_x0_out;
              wire signed [15:0]b4_x1_out;
              wire signed [15:0]b4_x2_out;
              wire signed [15:0]b4_x3_out;
              wire signed [15:0]b4_u0;
              wire signed [15:0]b4_u1;
              wire signed [15:0]b4_u2;
              wire signed [15:0]b4_u3;     //BLMS filter outputs.
              wire signed [15:0]y0;
              wire signed [15:0]y1;
              wire signed [15:0]y2;
              wire signed [15:0]y3;     reg [1:0]en_counter = 2'b00;     //Generate enable signal for BLMS filter.
              always@(posedge clk_50MHz) begin
                  en_counter <= en_counter + 1'b1;
              end     //Toggle enable signal.
              assign en = (en_counter == 2'b10|| en_counter == 2'b11) ? 1'b1 : 1'b0;     //Instantiate clock generator.
              clk_wiz_0 clk_wiz(.clk_in1(clk), .clk_out1(clk_50MHz), .clk_out2(clk_25MHz));     //Instantiate tone generator.
              ToneGen tg(.clk(clk_50MHz), .en(1'b1), .dout(tonegen_out));     //Instatiate LFSR for random noise generation.
              lfsr lr(.clk(clk_50MHz), .en(1'b1), .rst(1'b0), .lfsr_out(lfsr_out));     //Add the random noise to the tone.
              assign rnd = lfsr_out[15:6];
              assign tone_and_noise = tonegen_out + rnd;     //Instantiate the FIR filter.
              FIR_Filter ff(.clk(clk_50MHz), .en(1'b1), .din(tone_and_noise), .dout(fout));     //Choose filtered or unfiltered output based on sw0.
              assign mout = sw[0] ? fout : tone_and_noise;     //Instantiate desired out div 4.
              Data_Div4 d4_fir(.clk(clk_50MHz), .en(1'b1), .din(mout), .d0_out(dout0),
                               .d1_out(dout1), .d2_out(dout2), .d3_out(dout3));     //Instantiate BLMS filter div 4.
              Data_Div4 d4_blms(.clk(clk_50MHz), .en(1'b1), .din(tone_and_noise), .d0_out(blms_din0),
                                .d1_out(blms_din1), .d2_out(blms_din2), .d3_out(blms_din3));     //Build 16-tap block FIR filter.
              BLMS_Block b1(.clk(clk_25MHz), .x_en(en), .w_en(en), .mux_sel(~en), .dmux_sel(~en), .xin0(blms_din0),
                            .xin1(blms_din1), .xin2(blms_din2), .xin3(blms_din3), .r0(r0), .r1(r1),
                            .r2(r2), .r3(r3), .u0(b1_u0), .u1(b1_u1), .u2(b1_u2), .u3(b1_u3),
                            .xout0(b1_x0_out), .xout1(b1_x1_out), .xout2(b1_x2_out), .xout3(b1_x3_out)); 
              BLMS_Block b2(.clk(clk_25MHz), .x_en(en), .w_en(en), .mux_sel(~en), .dmux_sel(~en), .xin0(b1_x0_out),
                            .xin1(b1_x1_out), .xin2(b1_x2_out), .xin3(b1_x3_out), .r0(r0), .r1(r1),
                            .r2(r2), .r3(r3), .u0(b2_u0), .u1(b2_u1), .u2(b2_u2), .u3(b2_u3),
                            .xout0(b2_x0_out), .xout1(b2_x1_out), .xout2(b2_x2_out), .xout3(b2_x3_out)); 
              BLMS_Block b3(.clk(clk_25MHz), .x_en(en), .w_en(en), .mux_sel(~en), .dmux_sel(~en), .xin0(b2_x0_out),
                            .xin1(b2_x1_out), .xin2(b2_x2_out), .xin3(b2_x3_out), .r0(r0), .r1(r1),
                            .r2(r2), .r3(r3), .u0(b3_u0), .u1(b3_u1), .u2(b3_u2), .u3(b3_u3),
                            .xout0(b3_x0_out), .xout1(b3_x1_out), .xout2(b3_x2_out), .xout3(b3_x3_out));     
              BLMS_Block b4(.clk(clk_25MHz), .x_en(en), .w_en(en), .mux_sel(~en), .dmux_sel(~en), .xin0(b3_x0_out),
                            .xin1(b3_x1_out), .xin2(b3_x2_out), .xin3(b3_x3_out), .r0(r0), .r1(r1),
                            .r2(r2), .r3(r3), .u0(b4_u0), .u1(b4_u1), .u2(b4_u2), .u3(b4_u3),
                            .xout0(b4_x0_out), .xout1(b4_x1_out), .xout2(b4_x2_out), .xout3(b4_x3_out));     //Add outputs together.
              assign y0 = b1_u0 + b2_u0 + b3_u0 + b4_u0;
              assign y1 = b1_u1 + b2_u1 + b3_u1 + b4_u1;
              assign y2 = b1_u2 + b2_u2 + b3_u2 + b4_u2;
              assign y3 = b1_u3 + b2_u3 + b3_u3 + b4_u3;     //Instantiate ECU module.
              BLMS_ECU be(.clk(clk_25MHz), .r_en(~en), .din0(dout0), .din1(dout1), .din2(dout2),
                          .din3(dout3), .yin0(y0), .yin1(y1), .yin2(y2), .yin3(y3), .r0(r0), .r1(r1),
                          .r2(r2), .r3(r3));     //Serialize the BLMS output.
              Data_Mult4 dm(.clk(clk_50MHz), .en(1'b1), .d0_in(y0), .d1_in(y1), .d2_in(y2), .d3_in(y3), .dout(serial_dout));     //Take only the upper 8 bits and make it unsigned.
              assign {JA[3:0], JA[7:4]} = serial_dout[15:8] + 8'd128;
              //assign JA[7:0] = serial_dout[15:8] + 8'd128;     //assign {JA[3:0], JA[7:4]} = sw[7:0];   endmodule
          ToneGen.v
          `timescale 1ns/1ps module ToneGen(
              input clk,
              input en,
              output [15:0]dout    );     //Tone generation data.  At a 44KHz sampling rate, the lookup table
              //generates a 440Hz and 4.4KHz tone mixed together.
              reg [15:0]tonetbl[99:0];     //Pointer into the tone table.
              reg [6:0]toneptr = 7'h00;     initial begin
                  tonetbl[0] = 2743;
                  tonetbl[1] = 4538;
                  tonetbl[2] = 4799;
                  tonetbl[3] = 3526;
                  tonetbl[4] = 1303;
                  tonetbl[5] = -926;
                  tonetbl[6] = -2214;
                  tonetbl[7] = -1978;
                  tonetbl[8] = -219;
                  tonetbl[9] = 2478;
                  tonetbl[10] = 5165;
                  tonetbl[11] = 6895;
                  tonetbl[12] = 7083;
                  tonetbl[13] = 5726;
                  tonetbl[14] = 3411;
                  tonetbl[15] = 1082;
                  tonetbl[16] = -315;
                  tonetbl[17] = -195;
                  tonetbl[18] = 1442;
                  tonetbl[19] = 4009;
                  tonetbl[20] = 6561;
                  tonetbl[21] = 8151;
                  tonetbl[22] = 8192;
                  tonetbl[23] = 6685;
                  tonetbl[24] = 4216;
                  tonetbl[25] = 1729;
                  tonetbl[26] = 173;
                  tonetbl[27] = 132;
                  tonetbl[28] = 1605;
                  tonetbl[29] = 4009;
                  tonetbl[30] = 6398;
                  tonetbl[31] = 7824;
                  tonetbl[32] = 7704;
                  tonetbl[33] = 6037;
                  tonetbl[34] = 3411;
                  tonetbl[35] = 770;
                  tonetbl[36] = -936;
                  tonetbl[37] = -1124;
                  tonetbl[38] = 209;
                  tonetbl[39] = 2478;
                  tonetbl[40] = 4737;
                  tonetbl[41] = 6040;
                  tonetbl[42] = 5804;
                  tonetbl[43] = 4030;
                  tonetbl[44] = 1303;
                  tonetbl[45] = -1430;
                  tonetbl[46] = -3219;
                  tonetbl[47] = -3481;
                  tonetbl[48] = -2213;
                  tonetbl[49] = 0;
                  tonetbl[50] = 2213;
                  tonetbl[51] = 3481;
                  tonetbl[52] = 3219;
                  tonetbl[53] = 1430;
                  tonetbl[54] = -1303;
                  tonetbl[55] = -4030;
                  tonetbl[56] = -5804;
                  tonetbl[57] = -6040;
                  tonetbl[58] = -4737;
                  tonetbl[59] = -2478;
                  tonetbl[60] = -209;
                  tonetbl[61] = 1124;
                  tonetbl[62] = 936;
                  tonetbl[63] = -770;
                  tonetbl[64] = -3411;
                  tonetbl[65] = -6037;
                  tonetbl[66] = -7704;
                  tonetbl[67] = -7824;
                  tonetbl[68] = -6398;
                  tonetbl[69] = -4009;
                  tonetbl[70] = -1605;
                  tonetbl[71] = -132;
                  tonetbl[72] = -173;
                  tonetbl[73] = -1729;
                  tonetbl[74] = -4216;
                  tonetbl[75] = -6685;
                  tonetbl[76] = -8192;
                  tonetbl[77] = -8151;
                  tonetbl[78] = -6561;
                  tonetbl[79] = -4009;
                  tonetbl[80] = -1442;
                  tonetbl[81] = 195;
                  tonetbl[82] = 315;
                  tonetbl[83] = -1082;
                  tonetbl[84] = -3411;
                  tonetbl[85] = -5726;
                  tonetbl[86] = -7083;
                  tonetbl[87] = -6895;
                  tonetbl[88] = -5165;
                  tonetbl[89] = -2478;
                  tonetbl[90] = 219;
                  tonetbl[91] = 1978;
                  tonetbl[92] = 2214;
                  tonetbl[93] = 926;
                  tonetbl[94] = -1303;
                  tonetbl[95] = -3526;
                  tonetbl[96] = -4799;
                  tonetbl[97] = -4538;
                  tonetbl[98] = -2743;
                  tonetbl[99] = 0;
              end     //Assign the output to the value in the lookup table
              //pointed to by toneptr.
              assign dout = tonetbl[toneptr];     //Increment through the tone lookup table and wrap back
              //to zero when at the end.
              always @(posedge clk) begin
                  if(en) begin
                      if(toneptr == 7'd99) begin
                          toneptr <= 7'd0;
                      end
                      else begin
                          toneptr <= toneptr + 1'b1;
                      end
                  end
              endendmodule
          Data_Div4.v
          `timescale 1ns / 1ps module Data_Div4(
              input clk,
              input en,
              input [15:0]din,
              output reg en_out = 1'b0,
              output reg [15:0]d0_out = 16'd0,
              output reg [15:0]d1_out = 16'd0,
              output reg [15:0]d2_out = 16'd0,
              output reg [15:0]d3_out = 16'd0
              );     reg [1:0]count = 2'd0;     //Internal registers for holding data.
              reg [15:0]d0 = 16'd0;
              reg [15:0]d1 = 16'd0;
              reg [15:0]d2 = 16'd0;     always @(posedge clk) begin
                  if(en) begin
                      count <= count + 1'b1;             if(count == 2'b00) begin
                          d0 <= din;
                          en_out <= 1'b0;
                      end
                      else if(count == 2'b01) begin
                          d1 <= din;
                          en_out <= 1'b0;
                      end
                      else if(count == 2'b10) begin
                          d2 <= din;
                          en_out <= 1'b0;
                      end
                      else begin
                          d0_out <= d0;
                          d1_out <= d1;
                          d2_out <= d2;
                          d3_out <= din;
                          en_out <= 1'b1;
                      end
                  end
              endendmodule
          Data_Mult4.v
          `timescale 1ns / 1ps module Data_Mult4(
              input clk,
              input en,
              input [15:0]d0_in,
              input [15:0]d1_in,
              input [15:0]d2_in,
              input [15:0]d3_in,
              output reg [15:0]dout = 16'd0
              );     reg [1:0]count = 2'd0;     //Internal registers for holding data.
              reg [15:0]d0 = 16'd0;
              reg [15:0]d1 = 16'd0;
              reg [15:0]d2 = 16'd0;
              reg [15:0]d3 = 16'd0;     always @(posedge clk) begin
                  if(en) begin
                      count <= count + 1'b1;             if(count == 2'b00) begin
                          d0 <= d0_in;
                          d1 <= d1_in;
                          d2 <= d2_in;
                          d3 <= d3_in;
                          dout <= d3;
                      end
                      else if(count == 2'b01) begin
                          dout <= d0;  
                      end
                      else if(count == 2'b10) begin
                          dout <= d1;
                      end
                      else begin 
                          dout <= d2;      
                      end
                  end
              end endmodule
          FIR_Filter.v
          `timescale 1ns / 1ps `define FILT_LENGTH 16 module FIR_Filter(
              input  clk,
              input  en,
              input  [15:0]din,
              output [15:0]dout    );     reg signed [15:0]coeff[`FILT_LENGTH/2-1:0]; //Filter coefficients.
              reg signed [15:0]delay_line[`FILT_LENGTH-1:0]; //Input delay line.
              wire [31:0]accum; //Accumulator for output filter calculation.    
              integer i; //Initialization integer.
              genvar c;  //Delay line generation variable.     //Calculate value in the accumulator.
              assign accum = (delay_line[0] + delay_line[15]) * coeff[0] +
                             (delay_line[1] + delay_line[14]) * coeff[1] +
                             (delay_line[2] + delay_line[13]) * coeff[2] +
                             (delay_line[3] + delay_line[12]) * coeff[3] +
                             (delay_line[4] + delay_line[11]) * coeff[4] +
                             (delay_line[5] + delay_line[10]) * coeff[5] +
                             (delay_line[6] + delay_line[9])  * coeff[6] +
                             (delay_line[7] + delay_line[8])  * coeff[7];     //Assign upper 16-bits to output.
              assign dout = accum[31:16];     initial begin   
                  //Load the filter coefficients.
                  coeff[0] = 16'd2552;
                  coeff[1] = 16'd4557;
                  coeff[2] = 16'd5051;
                  coeff[3] = 16'd8006;
                  coeff[4] = 16'd9265;
                  coeff[5] = 16'd11427;
                  coeff[6] = 16'd12396;
                  coeff[7] = 16'd13200;         //Initialize delay line.
                  for(i = 0; i < `FILT_LENGTH; i = i+1'b1) begin
                      delay_line[i] = 16'd0;
                  end
              end     //Advance the data through the delay line every clock cycle.
              generate
                  for (c = `FILT_LENGTH-1; c > 0; c = c - 1) begin: inc_delay            always @(posedge clk) begin
                          if(en) delay_line[c] <= delay_line[c-1];
                      end
                  end
              endgenerate     //Update with input data.
              always @(posedge clk) begin
                  if(en) delay_line[0] <= din;
              endendmodule
          lfsr.v
          `timescale 1ns / 1ps module lfsr(
              input clk,
              input en,
              input rst,
              output [15:0]lfsr_out    );     //Create a 16-bit linear feedback shift register with
              //maximal polynomial x^16 + x^14 + x^13 + x^11 + 1.
              reg [15:0]lfsr = 16'd1;
              wire feedback;     assign feedback = ((lfsr[15] ^ lfsr[13]) ^ lfsr[12]) ^ lfsr[10];
              assign lfsr_out = lfsr;     //Update the linear shift feedback register.
              always @(posedge clk) begin
                  if(rst) lfsr <= 16'd1;
                  else if(en) lfsr <= {lfsr[14:0], feedback};
              endendmodule
          BLMS_TB.v
          `timescale 1ns / 1ps module BLMS_TB;
              reg  clk = 1'b0;
              reg  [7:0]sw = 8'd0;
              wire [7:0]JA;     wire clk_50MHz;
              wire clk_25MHz;     wire signed [15:0]tone_and_noise;
              wire signed [15:0]fout;
              wire signed [15:0]dout0;
              wire signed [15:0]dout1;
              wire signed [15:0]dout2;
              wire signed [15:0]dout3;
              wire signed [15:0]blms_din0;
              wire signed [15:0]blms_din1;
              wire signed [15:0]blms_din2;
              wire signed [15:0]blms_din3;
              wire en; 
              BLMS_Top uut(.clk(clk), .sw(sw), .JA(JA));     assign clk_50MHz = uut.clk_50MHz;
              assign clk_25MHz = uut.clk_25MHz;     assign tone_and_noise = uut.tone_and_noise;
              assign fout = uut.fout;
              assign dout0 = uut.dout0;
              assign dout1 = uut.dout1;
              assign dout2 = uut.dout2;
              assign dout3 = uut.dout3;
              assign blms_din0 = uut.blms_din0;
              assign blms_din1 = uut.blms_din1;
              assign blms_din2 = uut.blms_din2;
              assign blms_din3 = uut.blms_din3;
              assign en = uut.en;     //Generate 100MHz clock.
              always #5 clk = ~clk;     initial begin
                  #500000 sw = 8'd1;
              endendmodule


          關(guān)鍵詞: FPGA 濾波器 Verilog

          評(píng)論


          相關(guān)推薦

          技術(shù)專區(qū)

          關(guān)閉
          看屁屁www成人影院,亚洲人妻成人图片,亚洲精品成人午夜在线,日韩在线 欧美成人 (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })();