前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >基于FPGA的IIR滤波器

基于FPGA的IIR滤波器

作者头像
努力努力再努力F
发布2018-09-11 11:04:18
1.1K0
发布2018-09-11 11:04:18
举报
文章被收录于专栏:fangyangcoder

基于FPGA的IIR滤波器

                                                        by方阳

版权声明:本文为博主原创文章,转载请指明转载地址

http://www.cnblogs.com/fydeblog/p/6748998.html

1.说明

写了那么多数字图像处理的,再写点其他的吧,今天写点FPGA的东西,是之前EDA做的综合大实验,拿出来和大家分享分享!

先说一下,此篇文章是基于你有IIR滤波器的原理和FPGA语言(也就是Verilog HDL)基础上的!至于IIR滤波器的原理和Verilog HDL语言,我这里就不说了,网上有一大堆的资料可以观看,IIR可以看数字信号处理的书或直接百度,Verilog HDL推荐《Hello,FPGA》!

申明一下,这边博客很长,请做好心理准备!!!

要感谢的人:感谢电子发烧网的牛哥哥要炸天的指导,感谢小梅哥的指导,感谢Hello FPGA团队的书籍!!!感谢,感谢,感谢!!!

说明:这个IIR滤波器我是用小梅哥的芯航线FPGA开发板——cyclone IV E EP4CE10F1708实现的,还用了他的ADDA模块——集成TLC1544 ADC采集芯片和TLC5620 DAC 输出芯片,软件平台是quartus13.0,测试用的是信号发生器和示波器。

这个共有一个顶层文件,十一个子文件,子文件其中一个是IIR滤波器的顶层文件。拓扑图如下:

2.参考代码

相应的代码如下

2.1 顶层文件

IIR_FY_TOP.V

代码语言:javascript
复制
module IIR_FY_TOP
(
    Clk,
    Rst_n,
    
    TLC5620_CLK,
    TLC5620_DATA,
    TLC5620_LOAD,
    TLC5620_LDAC,
    
    TLV1544_SDO,    
    TLV1544_SDI,    
    TLV1544_SCLK,    
    TLV1544_NCS,    
    TLV1544_FS,
    TLV1544_EOC

);

    input Clk;
    input Rst_n;

    output TLC5620_CLK;
    output TLC5620_DATA;
    output TLC5620_LOAD;
    output TLC5620_LDAC;
    
    input TLV1544_SDO;    
    output TLV1544_SDI;    
    output TLV1544_SCLK;    
    output TLV1544_NCS;    
    output TLV1544_FS;
    input TLV1544_EOC;
    
    wire AD_DONE;
    wire [9:0]ADC_DATA;
    wire DATA_Valid;
    wire [10:0]CtrlWord;
    wire signed[15:0] din;
    wire signed[15:0] dout;

    
    TLV1544_CTRL TLV1544_CTRL0(

        .Clk(Clk),
        .Rst_n(Rst_n),
        
        .Do_Conv(1'b1),    //开始转换使能信号
        .AD_DONE(AD_DONE),    //转换完成信号
        .ADC_CHSEL(4'b0),    //通道选择
        
        .ADC_DATA(ADC_DATA),    //采样结果
        .DATA_Valid(DATA_Valid),
        
        .TLV1544_SDO(TLV1544_SDO),    
        .TLV1544_SDI(TLV1544_SDI),    
        .TLV1544_SCLK(TLV1544_SCLK),    
        .TLV1544_NCS(TLV1544_NCS),    
        .TLV1544_FS(TLV1544_FS),
        .TLV1544_EOC(TLV1544_EOC)
    );
    
    ADC_to_filter ADC_to_filter0(

    .ADC_DATA(ADC_DATA),
    .din(din)

    );
    
     myiir myiir0(
        .rst(Rst_n),
        .clk(Clk),
        .din(din),
        .dout(dout),
        .din_valid(DATA_Valid),
        .dout_valid()
        );
        
    filter_to_DAC filter_to_DAC0(
          .dout(dout),
          .CtrlWord(CtrlWord)
        );
        
        TLC5620_CTRL TLC5620_CTRL0(
        .Clk(Clk),
        .Rst_n(Rst_n),
        .UpdateReq(1'b1),
        .CtrlWord(CtrlWord),

        .UpdateDone(),
        .TLC5620_CLK(TLC5620_CLK),
        .TLC5620_DATA(TLC5620_DATA),
        .TLC5620_LOAD(TLC5620_LOAD),
        .TLC5620_LDAC(TLC5620_LDAC)
    );        
                    
endmodule

2.2 TLV1544驱动

TLV1544_CTRL.V

代码语言:javascript
复制
module TLV1544_CTRL(

    Clk,
    Rst_n,
    
    Do_Conv,    //开始转换使能信号
    AD_DONE,    //转换完成信号
    ADC_CHSEL,    //通道选择
    
    ADC_DATA,    //采样结果
    DATA_Valid,
    
    TLV1544_SDO,    
    TLV1544_SDI,    
    TLV1544_SCLK,    
    TLV1544_NCS,    
    TLV1544_FS,
    TLV1544_EOC
);

    input Clk;
    input Rst_n;
    input Do_Conv;    //开始转换使能信号

    input [3:0]ADC_CHSEL;    //通道选择
    
    output reg [9:0]ADC_DATA;    //采样结果
    output reg AD_DONE;    //转换完成信号
    output reg DATA_Valid;
    
    input TLV1544_SDO;
    input TLV1544_EOC;
    output reg TLV1544_SDI;    
    output reg TLV1544_SCLK;    
    output reg TLV1544_NCS;
    output wire TLV1544_FS;
    
    assign TLV1544_FS = 1'b1;
    
    reg [7:0] LSM_CNT;//序列计数器
    reg [9:0] rADC_DATA;
    
    always@(posedge Clk or negedge Rst_n)
    if(!Rst_n)
        LSM_CNT <= 8'd0;
    else if(LSM_CNT <204 && (TLV1544_EOC == 1'b1) && (Do_Conv || LSM_CNT > 8'd0))
        LSM_CNT <= LSM_CNT + 1'b1;
    else if(LSM_CNT < 204 && (TLV1544_EOC == 1'b0))
        LSM_CNT <= LSM_CNT;
    else if(LSM_CNT == 204 && (TLV1544_EOC == 1'b1))
        LSM_CNT <= 8'd0;
        
    always@(posedge Clk or negedge Rst_n)
    if(!Rst_n)begin
        rADC_DATA <= 10'd0;
        TLV1544_SDI <= 1'b0;    
        TLV1544_SCLK <= 1'b0;    
        TLV1544_NCS <= 1'b1;    
        AD_DONE <= 1'b0;
        DATA_Valid <= 1'b0;
        ADC_DATA <= 10'd0;
    end
    else begin
        case(LSM_CNT)
            0:
                begin
                    rADC_DATA <= 10'd0;
                    TLV1544_SDI <= 1'b0;    
                    TLV1544_SCLK <= 1'b0;    
                    TLV1544_NCS <= 1'b1;    
                    AD_DONE <= 1'b0;
                end
                
            1:
                begin
                    TLV1544_NCS <= 1'b0;    
                    TLV1544_SDI <= ADC_CHSEL[3];    
                end
                
            9:
                begin
                    TLV1544_SCLK <= 1'b1;
                    rADC_DATA[9] <= TLV1544_SDO;
                end
                
            19:
                begin
                    TLV1544_SDI <= ADC_CHSEL[2];
                    TLV1544_SCLK <= 1'b0;            
                end
            
            29:
                begin
                    TLV1544_SCLK <= 1'b1;
                    rADC_DATA[8] <= TLV1544_SDO;
                end
                
            39:
                begin
                    TLV1544_SDI <= ADC_CHSEL[1];
                    TLV1544_SCLK <= 1'b0;            
                end
                
            49:
                begin
                    TLV1544_SCLK <= 1'b1;
                    rADC_DATA[7] <= TLV1544_SDO;
                end
                
            59:
                begin
                    TLV1544_SDI <= ADC_CHSEL[0];
                    TLV1544_SCLK <= 1'b0;            
                end
                
            69:
                begin
                    TLV1544_SCLK <= 1'b1;
                    rADC_DATA[6] <= TLV1544_SDO;
                end
                
            79:TLV1544_SCLK <= 1'b0;
            
            89:
                begin
                    TLV1544_SCLK <= 1'b1;
                    rADC_DATA[5] <= TLV1544_SDO;
                end
            99:TLV1544_SCLK <= 1'b0;
            
            109:
                begin
                    TLV1544_SCLK <= 1'b1;
                    rADC_DATA[4] <= TLV1544_SDO;
                end
                
            119:TLV1544_SCLK <= 1'b0;
            
            129:
                begin
                    TLV1544_SCLK <= 1'b1;
                    rADC_DATA[3] <= TLV1544_SDO;
                end
                
           139:TLV1544_SCLK <= 1'b0;
            
           149:
                begin
                    TLV1544_SCLK <= 1'b1;
                    rADC_DATA[2] <= TLV1544_SDO;
                end
                
            159:TLV1544_SCLK <= 1'b0;
            
            169:
                begin
                    TLV1544_SCLK <= 1'b1;
                    rADC_DATA[1] <= TLV1544_SDO;
                end
                
           179:TLV1544_SCLK <= 1'b0;
            
          189:
                begin
                    TLV1544_SCLK <= 1'b1;
                    //rADC_DATA[0] <= TLV1544_SDO;
                    if(TLV1544_EOC)
                        DATA_Valid <= 1'b1;
                    else
                        DATA_Valid <= 1'b0;
                    ADC_DATA <= {rADC_DATA[9:1],TLV1544_SDO};
                end
                
          199:
                begin
                    TLV1544_SCLK <= 1'b0;
                    TLV1544_NCS <= 1'b1;
                end
                
            204:AD_DONE <= 1'b1;
            
            default:DATA_Valid <= 1'b0;
        endcase
    end

endmodule

2.3 ADC转filter模块

ADC_to_filter.V

代码语言:javascript
复制
module ADC_to_filter (

ADC_DATA,
din

);

input        [9:0]ADC_DATA;
output signed[15:0]din;

assign din = ADC_DATA<<6;


endmodule

2.4 myiir模块

myiir.V

代码语言:javascript
复制
module myiir(
rst,
clk,
din,
dout,
din_valid,
dout_valid,
);
input rst;
input clk;
input signed[15:0] din;
input din_valid;
output reg signed[15:0] dout;
output reg dout_valid;

wire signed[15:0] dout1;
wire signed[15:0] dout2;
wire signed[15:0] dout3;
wire signed[15:0] dout4;
wire signed[15:0] dout5;
wire signed[15:0] dout_reg;

wire din_valid1;
wire dout_valid1;
wire din_valid2;
wire dout_valid2;
wire din_valid3;
wire dout_valid3;
wire din_valid4;
wire dout_valid4;
wire din_valid5;
wire dout_valid5;
wire din_valid6;
wire dout_valid6;

assign din_valid1=din_valid;
assign din_valid2=dout_valid1;
assign din_valid3=dout_valid2;
assign din_valid4=dout_valid3;
assign din_valid5=dout_valid4;
assign din_valid6=dout_valid5;

//assign dout_prevalid=dout_valid1;

myiir_first_step U1(
.rst(rst),
.clk(clk),
.din(din),
.dout(dout1),
.din_valid(din_valid1),
.dout_valid(dout_valid1)
);

myiir_second_step U2(
.rst(rst),
.clk(clk),
.din(dout1),
.dout(dout2),
.din_valid(din_valid2),
.dout_valid(dout_valid2)
);

myiir_third_step U3(
.rst(rst),
.clk(clk),
.din(dout2),
.dout(dout3),
.din_valid(din_valid3),
.dout_valid(dout_valid3)
);

myiir_fourth_step U4(
.rst(rst),
.clk(clk),
.din(dout3),
.dout(dout4),
.din_valid(din_valid4),
.dout_valid(dout_valid4)
);

myiir_fifth_step U5(
.rst(rst),
.clk(clk),
.din(dout4),
.dout(dout5),
.din_valid(din_valid5),
.dout_valid(dout_valid5)
);

myiir_sixth_step U6(
.rst(rst),
.clk(clk),
.din(dout5),
.dout(dout_reg),
.din_valid(din_valid6),
.dout_valid(dout_valid6)
);

always @(negedge rst,posedge clk) begin
        if(!rst) begin
                dout<=16'd0;
                dout_valid=1'b0;
        end
        else if(dout_valid6) begin
                dout_valid=1'b1;
                dout<=dout_reg;        
        end
        else begin
                dout<=dout;
                dout_valid=1'b0;
        end
end

endmodule

2.5 filter转DAC模块

filter_to_DAC.V

代码语言:javascript
复制
module filter_to_DAC
(
  dout,
  CtrlWord

);

input signed[15:0] dout;
output [10:0]CtrlWord;

assign CtrlWord[7:0]=dout[7:0];
assign CtrlWord[10:8]=3'b0;


endmodule

2.6 TLC5620驱动

TLC5620_CTRL.V

代码语言:javascript
复制
module TLC5620_CTRL(
    Clk,
    Rst_n,
    UpdateReq,
    CtrlWord,

    UpdateDone,
    TLC5620_CLK,
    TLC5620_DATA,
    TLC5620_LOAD,
    TLC5620_LDAC
);


    input Clk;
    input Rst_n;
    input UpdateReq;
    input [10:0]CtrlWord;

    output reg UpdateDone;
    output reg TLC5620_CLK;
    output reg TLC5620_DATA;
    output reg TLC5620_LOAD;
    output reg TLC5620_LDAC;
    
    reg [9:0] Cnt;
    
    always@(posedge Clk or negedge Rst_n)
    if(!Rst_n)
        Cnt <= 10'd0;
    else if(UpdateReq == 1 | (Cnt != 10'd0))begin
        if(Cnt == 10'd820)
            Cnt <= 10'd0;
        else
            Cnt <= Cnt + 10'd1;
    end
    else
        Cnt <= 10'd0;

    always@(posedge Clk or negedge Rst_n)
    if(!Rst_n)begin
        TLC5620_CLK <= 1'b0;
        TLC5620_DATA <= 1'b0;
        TLC5620_LOAD <= 1'b0;
        TLC5620_LDAC <= 1'b0;
        UpdateDone <= 1'b0;
    end
    else begin
        case(Cnt)
            0:
                begin         
                    TLC5620_CLK <= 1'b0;
                    TLC5620_DATA <= 1'b0;
                    TLC5620_LOAD <= 1'b1;
                    TLC5620_LDAC <= 1'b0;
                    UpdateDone <= 1'b0;
                end
            10:
                begin         
                    TLC5620_CLK <= 1'b1;
                    TLC5620_DATA <= CtrlWord[10];
                end
            40: TLC5620_CLK <= 1'b0;
                
            70:
                begin         
                    TLC5620_CLK <= 1'b1;
                    TLC5620_DATA <= CtrlWord[9];
                end
            
            100: TLC5620_CLK <= 1'b0;
            130:
                begin         
                    TLC5620_CLK <= 1'b1;
                    TLC5620_DATA <= CtrlWord[8];
                end
            160: TLC5620_CLK <= 1'b0;
            190:
                begin         
                    TLC5620_CLK <= 1'b1;
                    TLC5620_DATA <= CtrlWord[7];
                end
            220: TLC5620_CLK <= 1'b0;
            250:
                begin         
                    TLC5620_CLK <= 1'b1;
                    TLC5620_DATA <= CtrlWord[6];
                end
            280: TLC5620_CLK <= 1'b0;
            310:
                begin         
                    TLC5620_CLK <= 1'b1;
                    TLC5620_DATA <= CtrlWord[5];
                end
            340: TLC5620_CLK <= 1'b0;
            370:
                begin         
                    TLC5620_CLK <= 1'b1;
                    TLC5620_DATA <= CtrlWord[4];
                end
            400: TLC5620_CLK <= 1'b0;
            430:
                begin         
                    TLC5620_CLK <= 1'b1;
                    TLC5620_DATA <= CtrlWord[3];
                end
            460: TLC5620_CLK <= 1'b0;
            490:
                begin         
                    TLC5620_CLK <= 1'b1;
                    TLC5620_DATA <= CtrlWord[2];
                end
            520: TLC5620_CLK <= 1'b0;
            550:
                begin         
                    TLC5620_CLK <= 1'b1;
                    TLC5620_DATA <= CtrlWord[1];
                end
            580: TLC5620_CLK <= 1'b0;
            610:
                begin         
                    TLC5620_CLK <= 1'b1;
                    TLC5620_DATA <= CtrlWord[0];
                end
            640: TLC5620_CLK <= 1'b0;
            670:TLC5620_LOAD <= 1'b0;
            800:TLC5620_LOAD <= 1'b1;
            820:UpdateDone <= 1'b1;
            default:;
        endcase    
    end

endmodule

2.7 myiir_first_step模块

myiir_first_step.V

代码语言:javascript
复制
module myiir_first_step(
rst,
clk,
din,
dout,
din_valid,
dout_valid
);

parameter b0=16145;
parameter b1=-23383;
parameter b2=16145;
parameter a1=-26283;
parameter a2=14526;

input rst;
input clk;
input signed[15:0] din;
input din_valid;

output signed[15:0] dout;
output dout_valid;

reg[4:0] cState,nState;
reg signed[15:0] x_reg0;
reg signed[15:0] x_reg1;

reg signed[31:0] x_mul1;
reg signed[31:0] x_mul2;
reg signed[31:0] x_mul3;

wire signed[15:0] x_int_mul1;
wire signed[15:0] x_int_mul2;
wire signed[15:0] x_int_mul3;

reg signed[17:0] x_sum;
wire signed[15:0] x_temp;

reg signed[15:0] y_reg0;
reg signed[15:0] y_reg1;

reg signed[31:0] y_mul1;
reg signed[31:0] y_mul2;

wire signed[15:0] y_int_mul1;
wire signed[15:0] y_int_mul2;

reg signed[16:0] y_sum;
wire signed[15:0] y_temp;

reg signed[16:0] dout_sum;
wire signed[15:0] dout_temp;

always @(negedge rst,posedge clk) begin
        if(!rst) begin
                cState<=0;
        end
        else begin
                cState<=nState;                
        end
end

always @(*) begin
        case(cState)
                0:if(din_valid) begin
                        nState<=1;
                  end
                  else begin
                        nState<=0;
                  end
                1:nState<=2;
                2:nState<=3;
                3:nState<=4;
                4:nState<=5;
                5:nState<=6;
                6:nState<=0;
                default:nState<=nState;
        endcase
end

always @(*) begin
        if(rst) begin
                case(cState)
                        1:x_mul1=b0*din;
                        2:begin
                                x_mul2=b1*x_reg0;
                                y_mul1=a1*y_reg0;
                        end
                        3:begin
                                x_mul3=b2*x_reg1;
                                y_mul2=a2*y_reg1;
                        end
                        4:begin
                                x_sum=x_int_mul1+x_int_mul2+x_int_mul3;
                                y_sum=y_int_mul1+y_int_mul2;
                        end
                        5:dout_sum=x_temp-y_temp;
                        default:;
                endcase
        end
end

always @(cState) begin
        if(rst) begin
                if(cState==4) begin
                        x_reg0<=din;
                        x_reg1<=x_reg0;
                end
                else begin
                        x_reg0<=x_reg0;
                        x_reg1<=x_reg1;
                end
        end
        else begin
                x_reg0<=16'd0;
                x_reg1<=16'd0;
        end
end

always @(cState) begin
        if(rst) begin
                if(cState==6) begin
                        y_reg0<=dout;
                        y_reg1<=y_reg0;
                end 
                else begin
                        y_reg0<=y_reg0;
                        y_reg1<=y_reg1;
                end
        end
        else begin
                y_reg0<=16'd0;
                y_reg1<=16'd0;
        end
end

assign x_int_mul1=(x_mul1[31]^x_mul1[30])?x_mul1[31:16]:x_mul1[30:15];
assign x_int_mul2=(x_mul2[31]^x_mul2[30])?x_mul2[31:16]:x_mul2[30:15];
assign x_int_mul3=(x_mul3[31]^x_mul3[30])?x_mul3[31:16]:x_mul3[30:15];
assign x_temp=(x_sum[17:15]==3'b000||x_sum[17:15]==3'b111)?x_sum[15:0]:(x_sum[17])?16'h8000:16'h7fff;

assign y_int_mul1=(y_mul1[31]^y_mul1[30])?y_mul1[31:16]:y_mul1[30:15];
assign y_int_mul2=(y_mul2[31]^y_mul2[30])?y_mul2[31:16]:y_mul2[30:15];
assign y_temp=(y_sum[16:15]==2'b00||y_sum[16:15]==2'b11)?y_sum[15:0]:(y_sum[16])?16'h8000:16'h7fff;

assign dout_temp=(dout_sum[16:15]==2'b00||dout_sum[16:15]==2'b11)?dout_sum[15:0]:(dout_sum[16])?16'h8000:16'h7fff;
assign dout=(!rst)?16'd0:dout_temp;

assign dout_valid=(cState==6 && nState==0)?1'b1:1'b0;

endmodule

2.8 myiir_second_step模块

myiir_second_step.V

代码语言:javascript
复制
module myiir_second_step(
rst,
clk,
din,
dout,
din_valid,
dout_valid
);

parameter b0=13569;
parameter b1=-18494;
parameter b2=13569;
parameter a1=-19700;
parameter a2=9712;

input rst;
input clk;
input signed[15:0] din;
input din_valid;

output signed[15:0] dout;
output dout_valid;

reg[4:0] cState,nState;
reg signed[15:0] x_reg0;
reg signed[15:0] x_reg1;

reg signed[31:0] x_mul1;
reg signed[31:0] x_mul2;
reg signed[31:0] x_mul3;

wire signed[15:0] x_int_mul1;
wire signed[15:0] x_int_mul2;
wire signed[15:0] x_int_mul3;

reg signed[17:0] x_sum;
wire signed[15:0] x_temp;

reg signed[15:0] y_reg0;
reg signed[15:0] y_reg1;

reg signed[31:0] y_mul1;
reg signed[31:0] y_mul2;

wire signed[15:0] y_int_mul1;
wire signed[15:0] y_int_mul2;

reg signed[16:0] y_sum;
wire signed[15:0] y_temp;

reg signed[16:0] dout_sum;
wire signed[15:0] dout_temp;

always @(negedge rst,posedge clk) begin
        if(!rst) begin
                cState<=0;
        end
        else begin
                cState<=nState;
        end
end

always @(*) begin
        case(cState)
                0:if(din_valid) begin
                        nState<=1;
                  end
                  else begin
                        nState<=0;
                  end
                1:nState<=2;
                2:nState<=3;
                3:nState<=4;
                4:nState<=5;
                5:nState<=6;
                6:nState<=0;
                default:nState<=nState;
        endcase
end

always @(*) begin
        if(rst) begin
                case(cState)
                        1:x_mul1=b0*din;
                        2:begin
                                x_mul2=b1*x_reg0;
                                y_mul1=a1*y_reg0;
                        end
                        3:begin
                                x_mul3=b2*x_reg1;
                                y_mul2=a2*y_reg1;
                        end
                        4:begin
                                x_sum=x_int_mul1+x_int_mul2+x_int_mul3;
                                y_sum=y_int_mul1+y_int_mul2;
                        end
                        5: dout_sum=x_temp-y_temp;
                        default:;
                endcase
        end
end

assign x_int_mul1=(x_mul1[31]^x_mul1[30])?x_mul1[31:16]:x_mul1[30:15];
assign x_int_mul2=(x_mul2[31]^x_mul2[30])?x_mul2[31:16]:x_mul2[30:15];
assign x_int_mul3=(x_mul3[31]^x_mul3[30])?x_mul3[31:16]:x_mul3[30:15];
assign x_temp=(x_sum[17:15]==3'b000||x_sum[17:15]==3'b111)?x_sum[15:0]:(x_sum[17])?16'h8000:16'h7fff;

assign y_int_mul1=(y_mul1[31]^y_mul1[30])?y_mul1[31:16]:y_mul1[30:15];
assign y_int_mul2=(y_mul2[31]^y_mul2[30])?y_mul2[31:16]:y_mul2[30:15];
assign y_temp=(y_sum[16:15]==2'b00||y_sum[16:15]==2'b11)?y_sum[15:0]:(y_sum[16])?16'h8000:16'h7fff;

assign dout_temp=(dout_sum[16:15]==2'b00||dout_sum[16:15]==2'b11)?dout_sum[15:0]:(dout_sum[16])?16'h8000:16'h7fff;
assign dout=(!rst)?16'd0:dout_temp;

always @(cState) begin
        if(rst) begin
                if(cState==4) begin
                        x_reg0<=din;
                        x_reg1<=x_reg0;
                end
                else begin
                        x_reg0<=x_reg0;
                        x_reg1<=x_reg1;
                end
        end
        else begin
                x_reg0<=16'd0;
                x_reg1<=16'd0;
        end
end

always @(cState) begin
        if(rst) begin
                if(cState==6) begin
                        y_reg0<=dout;
                        y_reg1<=y_reg0;
                end 
                else begin
                        y_reg0<=y_reg0;
                        y_reg1<=y_reg1;
                end
        end
        else begin
                y_reg0<=16'd0;
                y_reg1<=16'd0;
        end
end

assign dout_valid=(cState==6 && nState==0)?1'b1:1'b0;

endmodule

2.9 myiir_third_step模块

myiir_third_step.V

代码语言:javascript
复制
module myiir_third_step(
rst,
clk,
din,
dout,
din_valid,
dout_valid
);

parameter b0=10302;
parameter b1=-11731;
parameter b2=10302;
parameter a1=-11633;
parameter a2=5561;

input rst;
input clk;
input signed[15:0] din;
input din_valid;

output signed[15:0] dout;
output dout_valid;

reg[4:0] cState,nState;
reg signed[15:0] x_reg0;
reg signed[15:0] x_reg1;

reg signed[31:0] x_mul1;
reg signed[31:0] x_mul2;
reg signed[31:0] x_mul3;

wire signed[15:0] x_int_mul1;
wire signed[15:0] x_int_mul2;
wire signed[15:0] x_int_mul3;

reg signed[17:0] x_sum;
wire signed[15:0] x_temp;

reg signed[15:0] y_reg0;
reg signed[15:0] y_reg1;

reg signed[31:0] y_mul1;
reg signed[31:0] y_mul2;

wire signed[15:0] y_int_mul1;
wire signed[15:0] y_int_mul2;

reg signed[16:0] y_sum;
wire signed[15:0] y_temp;

reg signed[16:0] dout_sum;
wire signed[15:0] dout_temp;

always @(negedge rst,posedge clk) begin
        if(!rst) begin
                cState<=0;
        end
        else begin
                cState<=nState;
        end
end

always @(*) begin
        case(cState)
                0:if(din_valid) begin
                        nState<=1;
                  end
                  else begin
                        nState<=0;
                  end
                1:nState<=2;
                2:nState<=3;
                3:nState<=4;
                4:nState<=5;
                5:nState<=6;
                6:nState<=0;
                default:nState<=nState;
        endcase
end

always @(*) begin
        if(rst) begin
                case(cState)
                        1:x_mul1=b0*din;
                        2:begin
                                x_mul2=b1*x_reg0;
                                y_mul1=a1*y_reg0;
                        end
                        3:begin
                                x_mul3=b2*x_reg1;
                                y_mul2=a2*y_reg1;
                        end
                        4:begin
                                x_sum=x_int_mul1+x_int_mul2+x_int_mul3;
                                y_sum=y_int_mul1+y_int_mul2;
                        end
                        5: dout_sum=x_temp-y_temp;
                        default:;
                endcase
        end
end

assign x_int_mul1=(x_mul1[31]^x_mul1[30])?x_mul1[31:16]:x_mul1[30:15];
assign x_int_mul2=(x_mul2[31]^x_mul2[30])?x_mul2[31:16]:x_mul2[30:15];
assign x_int_mul3=(x_mul3[31]^x_mul3[30])?x_mul3[31:16]:x_mul3[30:15];
assign x_temp=(x_sum[17:15]==3'b000||x_sum[17:15]==3'b111)?x_sum[15:0]:(x_sum[17])?16'h8000:16'h7fff;

assign y_int_mul1=(y_mul1[31]^y_mul1[30])?y_mul1[31:16]:y_mul1[30:15];
assign y_int_mul2=(y_mul2[31]^y_mul2[30])?y_mul2[31:16]:y_mul2[30:15];
assign y_temp=(y_sum[16:15]==2'b00||y_sum[16:15]==2'b11)?y_sum[15:0]:(y_sum[16])?16'h8000:16'h7fff;

assign dout_temp=(dout_sum[16:15]==2'b00||dout_sum[16:15]==2'b11)?dout_sum[15:0]:(dout_sum[16])?16'h8000:16'h7fff;
assign dout=(!rst)?16'd0:dout_temp;

always @(cState) begin
        if(rst) begin
                if(cState==4) begin
                                x_reg0<=din;
                                x_reg1<=x_reg0;
                end
                else begin
                                x_reg0<=x_reg0;
                                x_reg1<=x_reg1;                
                end
        end
        else begin
                x_reg0<=16'd0;
                x_reg1<=16'd0;
        end
end

always @(cState) begin
        if(rst) begin
                if(cState==6) begin
                        y_reg0<=dout;
                        y_reg1<=y_reg0;
                end 
                else begin
                        y_reg0<=y_reg0;
                        y_reg1<=y_reg1;
                end
        end
        else begin
                y_reg0<=16'd0;
                y_reg1<=16'd0;
        end
end

assign dout_valid=(cState==6 && nState==0)?1'b1:1'b0;

endmodule

2.10 myiir_fourth_step模块

myiir_fourth_step.V

代码语言:javascript
复制
module myiir_fourth_step(
rst,
clk,
din,
dout,
din_valid,
dout_valid
);

parameter b0=6724;
parameter b1=-4060;
parameter b2=6724;
parameter a1=-7317;
parameter a2=2520;

input rst;
input clk;
input signed[15:0] din;
input din_valid;

output signed[15:0] dout;
output dout_valid;

reg[4:0] cState,nState;
reg signed[15:0] x_reg0;
reg signed[15:0] x_reg1;

reg signed[31:0] x_mul1;
reg signed[31:0] x_mul2;
reg signed[31:0] x_mul3;

wire signed[15:0] x_int_mul1;
wire signed[15:0] x_int_mul2;
wire signed[15:0] x_int_mul3;

reg signed[17:0] x_sum;
wire signed[15:0] x_temp;

reg signed[15:0] y_reg0;
reg signed[15:0] y_reg1;

reg signed[31:0] y_mul1;
reg signed[31:0] y_mul2;

wire signed[15:0] y_int_mul1;
wire signed[15:0] y_int_mul2;

reg signed[16:0] y_sum;
wire signed[15:0] y_temp;

reg signed[16:0] dout_sum;
wire signed[15:0] dout_temp;

always @(negedge rst,posedge clk) begin
        if(!rst) begin
                cState<=0;
        end
        else begin
                cState<=nState;
        end
end

always @(*) begin
        case(cState)
                0:if(din_valid) begin
                        nState<=1;
                  end
                  else begin
                        nState<=0;
                  end
                1:nState<=2;
                2:nState<=3;
                3:nState<=4;
                4:nState<=5;
                5:nState<=6;
                6:nState<=0;
                default:nState<=nState;
        endcase
end

always @(*) begin
        if(rst) begin
                case(cState)
                        1:x_mul1=b0*din;
                        2:begin
                                x_mul2=b1*x_reg0;
                                y_mul1=a1*y_reg0;
                        end
                        3:begin
                                x_mul3=b2*x_reg1;
                                y_mul2=a2*y_reg1;
                        end
                        4:begin
                                x_sum=x_int_mul1+x_int_mul2+x_int_mul3;
                                y_sum=y_int_mul1+y_int_mul2;
                        end
                        5: dout_sum=x_temp-y_temp;
                        default:;
                endcase
        end
end

assign x_int_mul1=(x_mul1[31]^x_mul1[30])?x_mul1[31:16]:x_mul1[30:15];
assign x_int_mul2=(x_mul2[31]^x_mul2[30])?x_mul2[31:16]:x_mul2[30:15];
assign x_int_mul3=(x_mul3[31]^x_mul3[30])?x_mul3[31:16]:x_mul3[30:15];
assign x_temp=(x_sum[17:15]==3'b000||x_sum[17:15]==3'b111)?x_sum[15:0]:(x_sum[17])?16'h8000:16'h7fff;

assign y_int_mul1=(y_mul1[31]^y_mul1[30])?y_mul1[31:16]:y_mul1[30:15];
assign y_int_mul2=(y_mul2[31]^y_mul2[30])?y_mul2[31:16]:y_mul2[30:15];
assign y_temp=(y_sum[16:15]==2'b00||y_sum[16:15]==2'b11)?y_sum[15:0]:(y_sum[16])?16'h8000:16'h7fff;

assign dout_temp=(dout_sum[16:15]==2'b00||dout_sum[16:15]==2'b11)?dout_sum[15:0]:(dout_sum[16])?16'h8000:16'h7fff;
assign dout=(!rst)?16'd0:dout_temp;

always @(cState) begin
        if(rst) begin
                case(cState) 
                        4: begin
                                x_reg0<=din;
                                x_reg1<=x_reg0;
                        end
                        default:begin
                                x_reg0<=x_reg0;
                                x_reg1<=x_reg1;
                        end
                endcase
        end
        else begin
                x_reg0<=16'd0;
                x_reg1<=16'd0;
        end
end

always @(cState) begin
        if(rst) begin
                if(cState==6) begin
                        y_reg0<=dout;
                        y_reg1<=y_reg0;
                end 
                else begin
                        y_reg0<=y_reg0;
                        y_reg1<=y_reg1;
                end
        end
        else begin
                y_reg0<=16'd0;
                y_reg1<=16'd0;
        end
end

assign dout_valid=(cState==6 && nState==0)?1'b1:1'b0;

endmodule

2.11 myiir_fifth_step模块

myiir_fifth_step.V

代码语言:javascript
复制
module myiir_fifth_step(
rst,
clk,
din,
dout,
din_valid,
dout_valid
);

parameter b0=3736;
parameter b1=-2448;
parameter b2=3736;
parameter a1=-3526;
parameter a2=921;

input rst;
input clk;
input signed[15:0] din;
input din_valid;

output signed[15:0] dout;
output dout_valid;

reg[4:0] cState,nState;
reg signed[15:0] x_reg0;
reg signed[15:0] x_reg1;

reg signed[31:0] x_mul1;
reg signed[31:0] x_mul2;
reg signed[31:0] x_mul3;

wire signed[15:0] x_int_mul1;
wire signed[15:0] x_int_mul2;
wire signed[15:0] x_int_mul3;

reg signed[17:0] x_sum;
wire signed[15:0] x_temp;

reg signed[15:0] y_reg0;
reg signed[15:0] y_reg1;

reg signed[31:0] y_mul1;
reg signed[31:0] y_mul2;

wire signed[15:0] y_int_mul1;
wire signed[15:0] y_int_mul2;

reg signed[16:0] y_sum;
wire signed[15:0] y_temp;

reg signed[16:0] dout_sum;
wire signed[15:0] dout_temp;

always @(negedge rst,posedge clk) begin
        if(!rst) begin
                cState<=0;
        end
        else begin
                cState<=nState;
        end
end

always @(*) begin
        case(cState)
                0:if(din_valid) begin
                        nState<=1;
                  end
                  else begin
                        nState<=0;
                  end
                1:nState<=2;
                2:nState<=3;
                3:nState<=4;
                4:nState<=5;
                5:nState<=6;
                6:nState<=0;
                default:nState<=nState;
        endcase
end

always @(*) begin
        if(rst) begin
                case(cState)
                        1:x_mul1=b0*din;
                        2:begin
                                x_mul2=b1*x_reg0;
                                y_mul1=a1*y_reg0;
                        end
                        3:begin
                                x_mul3=b2*x_reg1;
                                y_mul2=a2*y_reg1;
                        end
                        4:begin
                                x_sum=x_int_mul1+x_int_mul2+x_int_mul3;
                                y_sum=y_int_mul1+y_int_mul2;
                        end
                        5: dout_sum=x_temp-y_temp;
                        default:;
                endcase
        end
end

assign x_int_mul1=(x_mul1[31]^x_mul1[30])?x_mul1[31:16]:x_mul1[30:15];
assign x_int_mul2=(x_mul2[31]^x_mul2[30])?x_mul2[31:16]:x_mul2[30:15];
assign x_int_mul3=(x_mul3[31]^x_mul3[30])?x_mul3[31:16]:x_mul3[30:15];
assign x_temp=(x_sum[17:15]==3'b000||x_sum[17:15]==3'b111)?x_sum[15:0]:(x_sum[17])?16'h8000:16'h7fff;

assign y_int_mul1=(y_mul1[31]^y_mul1[30])?y_mul1[31:16]:y_mul1[30:15];
assign y_int_mul2=(y_mul2[31]^y_mul2[30])?y_mul2[31:16]:y_mul2[30:15];
assign y_temp=(y_sum[16:15]==2'b00||y_sum[16:15]==2'b11)?y_sum[15:0]:(y_sum[16])?16'h8000:16'h7fff;

assign dout_temp=(dout_sum[16:15]==2'b00||dout_sum[16:15]==2'b11)?dout_sum[15:0]:(dout_sum[16])?16'h8000:16'h7fff;
assign dout=(!rst)?16'd0:dout_temp;

always @(cState) begin
        if(rst) begin
                case(cState) 
                        4: begin
                                x_reg0<=din;
                                x_reg1<=x_reg0;
                        end
                        default:begin
                                x_reg0<=x_reg0;
                                x_reg1<=x_reg1;
                        end
                endcase
        end
        else begin
                x_reg0<=16'd0;
                x_reg1<=16'd0;
        end
end

always @(cState) begin
        if(rst) begin
                if(cState==6) begin
                        y_reg0<=dout;
                        y_reg1<=y_reg0;
                end 
                else begin
                        y_reg0<=y_reg0;
                        y_reg1<=y_reg1;
                end
        end
        else begin
                y_reg0<=16'd0;
                y_reg1<=16'd0;
        end
end

assign dout_valid=(cState==6 && nState==0)?1'b1:1'b0;

endmodule

2.12 myiir_sixth_step模块

myiir_sixth_step.V

代码语言:javascript
复制
module myiir_sixth_step(
rst,
clk,
din,
dout,
din_valid,
dout_valid
);

parameter b0=9119;
parameter b1=9119;
parameter a1=-4044;

input rst;
input clk;
input signed[15:0] din;
input din_valid;

output signed[15:0] dout;
output dout_valid;

reg[4:0] cState,nState;

reg signed[15:0] x_reg0;

reg signed[31:0] x_mul1;
reg signed[31:0] x_mul2;

wire signed[15:0] x_int_mul1;
wire signed[15:0] x_int_mul2;

reg signed[16:0] x_sum;
wire signed[15:0] x_temp;

reg signed[15:0] y_reg0;

reg signed[31:0] y_mul1;
wire signed[15:0] y_int_mul1;

reg signed[16:0] dout_sum;
wire signed[15:0] dout_temp;

always @(negedge rst,posedge clk) begin
        if(!rst) begin
                cState<=0;
        end
        else begin
                cState<=nState;
        end
end

always @(*) begin
        case(cState)
                0:if(din_valid) begin
                        nState<=1;
                  end
                  else begin
                        nState<=0;
                  end
                1:nState<=2;
                2:nState<=3;
                3:nState<=4;
                4:nState<=5;
                5:nState<=0;
                default:nState<=0;
        endcase
end

always @(*) begin
        if(rst) begin
                case(cState)
                        1:x_mul1=b0*din;
                        2:begin
                                x_mul2=b1*x_reg0;
                                y_mul1=a1*y_reg0;
                        end
                        3:begin
                                x_sum=x_int_mul1+x_int_mul2;
                        end
                        4:begin
                                dout_sum=x_temp-y_int_mul1;
                        end
                        default:;
                endcase
        end
end

assign x_int_mul1=(x_mul1[31]^x_mul1[30])?x_mul1[31:16]:x_mul1[30:15];
assign x_int_mul2=(x_mul2[31]^x_mul2[30])?x_mul2[31:16]:x_mul2[30:15];
assign x_temp=(x_sum[16:15]==2'b00||x_sum[16:15]==2'b11)?x_sum[15:0]:(x_sum[16])?16'h8000:16'h7fff;

assign y_int_mul1=(y_mul1[31]^y_mul1[30])?y_mul1[31:16]:y_mul1[30:15];

assign dout_temp=(dout_sum[16:15]==2'b00||dout_sum[16:15]==2'b11)?dout_sum[15:0]:(dout_sum[16])?16'h8000:16'h7fff;
assign dout=(!rst)?16'd0:dout_temp;

always @(cState) begin
        if(rst) begin
                if(cState==4) begin 
                        x_reg0<=din;
                end
                else begin
                        x_reg0<=x_reg0;
                end
        end
        else begin
                x_reg0<=16'd0;
        end
end

always @(cState) begin
        if(rst) begin
                if(cState==5) begin
                        y_reg0<=dout;
                end
                else begin
                        y_reg0<=y_reg0;
                end
        end
        else begin
                y_reg0<=16'd0;
        end
end

assign dout_valid=(cState==5 && nState==0)?1'b1:1'b0;

endmodule

代码到这里终于结束了!辛苦观看。。

3.仿真与引脚分配

 3.1 仿真

实验使用modelsim进行仿真,从matlab获得量化后的输入波形文件,经过仿真后得到滤波后的波形。

3.2 引脚分配

4.心得

本次实验好艰辛啊!从最开始的晕头晕脑,到最后有效果,时间挺长的,但确实学到了许多!通过这次实验,不仅更加熟练地学习到了FPGA设计的流程,更加深了数字信号处理滤波器的设计和实现!重要是坚持!!!

5.视频地址

前篇

http://v.youku.com/v_show/id_XMjcyMjkwNDY3Mg==.html

后篇

 http://v.youku.com/v_show/id_XMjcyMjkyOTYzMg==.html

end

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2017-04-23 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 2.1 顶层文件
相关产品与服务
图像处理
图像处理基于腾讯云深度学习等人工智能技术,提供综合性的图像优化处理服务,包括图像质量评估、图像清晰度增强、图像智能裁剪等。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档