作者:桂。
时间:2018-02-05 20:50:54
链接:http://www.cnblogs.com/xingshansi/p/8419452.html
一、仿真思路
设计低通滤波器(5阶,6个系数),滤波器特性:
借助低通滤波器对信号进行滤波:
二、VIVADO仿真
首先利用MATLAB生成定点补码:
%=============设置系统参数==============% f1=500; %设置波形频率 f2=3600; Fs=8000; %设置采样频率 L=1024; %数据长度 N=16; %数据位宽 %=============产生输入信号==============% t=0:1/Fs:(1/Fs)*(L-1); y=sin(2*pi*f1*t)+sin(2*pi*t*f2); y_n=round(y*(2^(N-3)-1)); %N比特量化;如果有n个信号相加,则设置(N-n) %=================画图==================% a=10; %改变系数可以调整显示周期 stem(t,y_n); axis([0 L/Fs/a -2^N 2^N]); %显示 %=============写入外部文件==============% fid=fopen(‘sin_data.txt‘,‘w‘); %把数据写入sin_data.txt文件中,如果没有就创建该文件 for k=1:length(y_n) B_s=dec2bin(y_n(k)+((y_n(k))<0)*2^N,N); for j=1:N if B_s(j)==‘1‘ tb=1; else tb=0; end fprintf(fid,‘%d‘,tb); end fprintf(fid,‘\r\n‘); end fprintf(fid,‘;‘); fclose(fid);
vivado的testbench:
`timescale 1ns / 1ps module tb; // Inputs logic Clk; logic rst; // Outputs logic signed [23:0] Yout; //Generate a clock with 10 ns clock period. initial Clk <= 0; always #5 Clk = ~Clk; //Initialize and apply the inputs. //-------------------------------------// parameter data_num = 32‘d1024; integer i = 0; reg [15:0] Xin[1:data_num]; reg [15:0] data_out; initial begin rst = 1; #20 rst = 0; #40 $readmemb("D:/PRJ/vivado/simulation_ding/009_lpf6tap/matlab/sin_data.txt",Xin); end always @(posedge Clk) begin if(rst) begin data_out <= 0; end else begin data_out <= Xin[i]; i <= i + 8‘d1; end end fir_6tap uut ( .Clk(Clk), .Xin(data_out), .Yout(Yout) ); endmodule
子模块 fir_6tap:
`timescale 1ns / 1ps module fir_6tap( input Clk, input signed [15:0] Xin, output reg signed [23:0] Yout ); //Internal variables. wire signed [7:0] H0,H1,H2,H3,H4,H5; wire signed [23:0] MCM0,MCM1,MCM2,MCM3,MCM4,MCM5,add_out1,add_out2,add_out3,add_out4,add_out5; wire signed [23:0] Q1,Q2,Q3,Q4,Q5; //filter coefficient initializations. //H = [-2 -1 3 4]. assign H0 = -15; assign H1 = 19 ; assign H2 = 123; assign H3 = 123; assign H4 = 19; assign H5 = -15; //Multiple constant multiplications. assign MCM5 = H5*Xin; assign MCM4 = H4*Xin; assign MCM3 = H3*Xin; assign MCM2 = H2*Xin; assign MCM1 = H1*Xin; assign MCM0 = H0*Xin; //adders assign add_out1 = Q1 + MCM4; assign add_out2 = Q2 + MCM3; assign add_out3 = Q3 + MCM2; assign add_out4 = Q4 + MCM1; assign add_out5 = Q5 + MCM0; //flipflop instantiations (for introducing a delay). DFF dff1 (.Clk(Clk),.D(MCM5),.Q(Q1)); DFF dff2 (.Clk(Clk),.D(add_out1),.Q(Q2)); DFF dff3 (.Clk(Clk),.D(add_out2),.Q(Q3)); DFF dff4 (.Clk(Clk),.D(add_out3),.Q(Q4)); DFF dff5 (.Clk(Clk),.D(add_out4),.Q(Q5)); //Assign the last adder output to final output. always@ (posedge Clk) Yout <= add_out5; endmodule
DFF:
`timescale 1ns / 1ps module DFF (input Clk, input [23:0] D, output reg [23:0] Q ); always@ (posedge Clk) Q = D; endmodule
主要电路图(4阶为例):
仿真结果,与MATLAB测试一致: