zoukankan      html  css  js  c++  java
  • matlab 与 modelsim 联调 cic抽取滤波器

    注:本设计的参数为:D=2,R=5,N=3;时钟频率为50mhz,输入信号为有符号8位,根据公式bmax=bin+N*log(2,R*D);可以得到bmax=18;

    1,cic抽取滤波器原理

    网上资料一大堆,不说了。重点在于传递函数,以及各个部分的结构。

    2,simulink仿真

    模型图

    频谱仪显示结果

    3,cic滤波器verilog 代码

    module cic_dec(clk,rst_n,datain,dataout);
    input clk,rst_n;
    input [7:0] datain;
    output [7:0] dataout;
    reg [17:0] data_buff;
    always@(posedge clk or negedge rst_n)
    begin
    if(!rst_n)
    data_buff<=0;
    else
    data_buff<={{10{datain[7]}},datain};
    end

    reg [17:0] integ1_result;

    always@(posedge clk or negedge rst_n)
    begin
    if(!rst_n)
    integ1_result<=0;
    else
    integ1_result<=data_buff+integ1_result;
    end

    reg [17:0] integ2_result;

    always@(posedge clk or negedge rst_n)
    begin
    if(!rst_n)
    integ2_result<=0;
    else
    integ2_result<=integ1_result+integ2_result;
    end

    reg [17:0] integ3_result;
    always@(posedge clk or negedge rst_n)
    begin
    if(!rst_n)
    integ3_result<=0;
    else
    integ3_result<=integ2_result+integ3_result;
    end
    //integrator end
    //decimation start
    reg dec_flag;
    reg [17:0] dec_result;
    reg [2:0] cnt1;
    always@(posedge clk or negedge rst_n)
    begin
    if(!rst_n)
    cnt1<=0;
    else if(cnt1==3'd4)
    cnt1<=0;
    else
    cnt1<=cnt1+1'b1;
    end
    always@(posedge clk or negedge rst_n)
    begin
    if(!rst_n)
    dec_result<=0;
    else if(cnt1==3'd4)
    dec_result<=integ3_result;
    end
    always@(posedge clk or negedge rst_n)
    begin
    if(!rst_n)
    dec_flag<=1'b0;
    else if(cnt1==3'd4)
    dec_flag<=1'b1;
    else
    dec_flag<=1'b0;
    end
    //decimation end
    // comb filter begin
    reg [2:0] cnt2;
    always@(posedge clk or negedge rst_n)
    begin
    if(!rst_n)
    cnt2<=0;
    else if(dec_flag)
    cnt2<=0;
    else
    cnt2<=cnt2+1'b1;
    end
    reg [17:0] comb1_delay1;
    reg [17:0] comb1_delay2;
    reg [17:0] comb1_result;
    always@(posedge clk or negedge rst_n)//first comb
    begin
    if(!rst_n)
    begin
    comb1_delay1<=0;
    comb1_delay2<=0;
    end
    else if(cnt2==3'd3)
    begin
    comb1_delay1<=dec_result;
    comb1_delay2<=comb1_delay1;
    end
    end
    always@(posedge clk or negedge rst_n)
    begin
    if(!rst_n)
    comb1_result<=0;
    else if(dec_flag)
    comb1_result<=dec_result-comb1_delay2;
    end

    reg [17:0] comb2_delay1;
    reg [17:0] comb2_delay2;
    reg [17:0] comb2_result;
    always@(posedge clk or negedge rst_n)//second comb
    begin
    if(!rst_n)
    begin
    comb2_delay1<=0;
    comb2_delay2<=0;
    end
    else if(cnt2==3'd3)
    begin
    comb2_delay1<=comb1_result;
    comb2_delay2<=comb2_delay1;
    end
    end
    always@(posedge clk or negedge rst_n)
    begin
    if(!rst_n)
    comb2_result<=0;
    else if(dec_flag)
    comb2_result<=comb1_result-comb2_delay2;
    end

    reg [17:0] comb3_delay1;
    reg [17:0] comb3_delay2;
    reg [17:0] comb3_result;
    always@(posedge clk or negedge rst_n)//third comb
    begin
    if(!rst_n)
    begin
    comb3_delay1<=0;
    comb3_delay2<=0;
    end
    else if(cnt2==3'd3)
    begin
    comb3_delay1<=comb2_result;
    comb3_delay2<=comb3_delay1;
    end
    end
    always@(posedge clk or negedge rst_n)
    begin
    if(!rst_n)
    comb3_result<=0;
    else if(dec_flag)
    comb3_result<=comb2_result-comb3_delay2;
    end
    reg [7:0] dataout_buff;
    always@(posedge clk or negedge rst_n)
    begin
    if(!rst_n)
    dataout_buff<=0;
    else
    dataout_buff<=(comb3_result[17:0]+{!comb3_result[17],{9{comb3_result[17]}}})>>10;
    end
    assign dataout=dataout_buff;
    endmodule

    4,matlab产生正弦波形文件采样频率50m,正弦频率1m

    0=1e6;
    fs=50e6;
    N=fs/f0;
    n=0:N-1;
    t=n/fs;
    width=8;

    sinwave=sin(2*pi*f0*t);
    sindata = round(sinwave .* (2^(width-1) - 1));
    for i=1:N
    if(sindata(i)<0)
    sindata(i)=2^width+sindata(i);
    else
    sindata(i)=sindata(i);
    end
    end


    fid=fopen('sindata.txt','a');
    for i=1:N
    fprintf(fid,'%x ',sindata(i));
    i=i+1;
    end
    fclose(fid);

    5,verilog读取波形文件产生正弦波

    module sin_gen(clk,rst_n,sin_out);
    input clk,rst_n;
    output [7:0] sin_out;
    parameter N = 50;
    reg [7:0] mem[0:N-1];
    initial
    begin
    $readmemh("sindata.txt",mem);
    end
    reg [7:0] sin_out_buff;
    reg [5:0] i;
    always@(posedge clk or negedge rst_n)
    begin
    if(!rst_n)
    begin
    sin_out_buff<=0;
    i<=6'd0;
    end
    else
    begin
    sin_out_buff<=mem[i];
    if(i==6'd49)
    i<=6'd0;
    else
    i<=i+1'b1;
    end
    end
    assign sin_out=sin_out_buff;
    endmodule

     6, testbench

    `timescale 1ns/1ps
    module testbench();
    reg clk,rst_n;
    initial
    begin
    clk=0;
    forever #10 clk=~clk;
    end
    initial
    begin
    rst_n=0;
    #50 rst_n=1'b1;
    end
    wire [7:0] sin_out;
    sin_gen u0_sin_gen(.clk(clk),.rst_n(rst_n),.sin_out(sin_out));
    wire [7:0] data_out;
    cic_dec u0_cic_dec(.clk(clk),.rst_n(rst_n),.datain(sin_out),.dataout(data_out));
    reg [10:0] cnt;
    always@(posedge clk or negedge rst_n )
    begin
    if(!rst_n)
    cnt<=0;
    else if(cnt==11'd1024)
    cnt<=cnt;
    else
    cnt<=cnt+1'b1;
    end
    integer fid;
    initial
    begin
    fid=$fopen("dataout.txt","a");
    end
    always@(posedge clk )
    begin
    $fwrite(fid,"%x ",data_out);
    end
    always@(posedge clk)
    begin
    if(cnt==11'd1024)
    begin

    $fclose(fid);

    $stop;
    end

    end

    endmodule

    7,modelsim 仿真波形

  • 相关阅读:
    网络检查思路和步骤
    查看网络状态
    【Linux常见命令】lsof命令
    【Linux常见命令】ip命令
    【Linux常见命令】ifconfig命令:配置与查看网络信息
    【Linux常见命令】netstat命令
    Java-MD5
    Java发送邮件
    Maven基础02
    Maven基础01
  • 原文地址:https://www.cnblogs.com/lianjiehere/p/4155917.html
Copyright © 2011-2022 走看看