作者:桂。
时间: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测试一致:
