最近看了很多的博客,感觉写的不是很全,对于新手小白来说也不是很友好,所以结合自己在实际实现过程中遇到的坑,做一个总结。
首先我是利用查找表做的DDS,在Quartus II中查找表采用的时mif文件,一下是生成mif文件的代码
clear all;
format long g ; %增加显示精度
N = 2^14;
t = [0:1/N:(N-1)/N]; % 时间点
y = 2^8*sin(2*pi*t) + 2^8; % 正弦波加偏移
y = round(y); % 对正弦波数据进行四舍五入
plot(y); % 绘制波形
y1 = min(y);
y2 = max(y);
% 创建mif文件
fild = fopen('sin_wave_16384x10.mif', 'wt');
fprintf(fild, 'WIDTH=10;\n'); % 数据位宽为10
fprintf(fild, 'DEPTH=16384;\n'); % 存储深度为2048
fprintf(fild, 'ADDRESS_RADIX=UNS;\n'); % 地址的基数为10进制
fprintf(fild, 'DATA_RADIX=UNS;\n'); % 数据的基数为10进制
fprintf(fild, 'CONTENT\nBEGIN\n');
% 写入数据,将数据转换为10进制表示
for i = 1:N
decValue = y(i); % 直接使用10进制值
fprintf(fild, '\t%d : %d;\n', i-1, decValue); % 写入文件
end
fprintf(fild, 'END;\n');
fclose(fild);
在生成mif文件后,在Quartus II中将文件加载进去生成ROM表,例化ROM的代码如下
module l_fir (
input sys_clk,
input sys_rst_n,
output [29:0] fir_out
);
parameter k1 =9'd384,k2=9'd128 ;
reg [14:0] fre1,fre2;
wire [9:0] dds1,dds2,dds;
wire [10:0] dds3;
wire clk_100,clk_10;
assign dds3=dds1+dds2;
assign dds=dds3[10:1];
always @(posedge clk_100 or negedge sys_rst_n)
begin
if(sys_rst_n==1'd0)
fre1<=15'd0;
else
fre1<=fre1+k1;
end
always @(posedge clk_100 or negedge sys_rst_n)
begin
if(sys_rst_n==1'd0)
fre2<=15'd0;
else
fre2<=fre2+k2;
end
ROM_IP ROM_IP_inst1 (
.address (fre1[14:1]),
.clock (clk_100),
.q (dds1)
);
ROM_IP ROM_IP_inst2 (
.address ( fre2[14:1] ),
.clock (clk_100),
.q (dds2)
);
j接下来使用matlab中fdatool命令调用滤波器设计工具,打开工具后,首先点滴我圈点的地方,这里一般选取定点
然后点击下图进行参数设置
这里的Fs一定要与例化FIR IP时候的时钟保持一直,否则无法完成滤波。设计好后点击文件-导出将数据导出,存在txt文件中,可以直接在matlab的命令行窗口中输入以下命令
a=Num
fid=fopen('D:\Q_V\fir_tst\doc\fi1r.txt','w');
fprintf(fid,'%8d\r\n',a);
fclose(fid);
然后打开Quartus II软件,点击IP核,这里建议不要把FIR IP单独放在工程的IP核文件里面(一般为了看着舒服,大多数人会在工程下建立一个IP核文件夹),否则在仿真的时候会报错。在打开FIR IP核后,选择第二个IP核输入名字,点击next,
然后进入以下界面,这里的Bit Width就是刚才在matlab中设置的定点位宽,输入根据自己的设置选择有符号数或者无符号数。
然后点击Edit coefficient set将刚才matlab中生成的txt文件导入,然后点击set3生成IP核,生成IP核后在工程中进行例化,
FIR WW (
.clk(clk_10),
.reset_n(sys_rst_n),
.ast_sink_data(dds),
.ast_sink_valid(1'b1),
.ast_source_ready(1'b1),
.ast_sink_error(2'd0),
.ast_source_data(fir_out),
.ast_sink_ready(),
.ast_source_valid(),
.ast_source_error()
);
时钟一定要与matlab中的Fs保持一直,至此就完成了程序的编写,仿真就和其他工程仿真时一样的操作,仿真结果如下