功能描述
- 具有产生正弦波、三角波、方波、锯齿波四种周期性波形的功能。
- 输出波形的频率范围为61Hz-915Hz,频率分辨率1Hz。
- 由外界按键输入选择产生波形的种类、频率。
输入输出描述
顶层划分
顶层模块说明
- fenpin:用于将系统时钟分成所需时钟。
- addr: 用于相位累加。
- rom: 用于将相位转化成幅度。
- pmodDA2:用于将数字量转化成模拟量。
设计思想说明
- 选择端和频率控制端在时钟控制下,用相位累加器输出的地址,作为查找表的输入,得到各种波形的数字量输出。
- 数字量输出作为D/A模块的输入,得到模拟量的输出,连接示波器进行观察,若波形不理想可以用示波器上的数字滤波器,用低通滤波器,选择上限截止频率进行观察。
子模块描述
分频模块
本次设计需要1MHz,所以首先对系统时钟(50MHz)来进行分频,使其为1MHz来正常相位模块。
相位累加器模块
相位累加器由14位地址加法器与14位累加寄存器构成。每来一个时钟脉冲, 地址加法器将频率控制字与累加寄存器出的累加相位数据相加, 并把相加后的结果送至累加寄存器的输入端。累加寄存器将上一时钟周期作用后所产生的新的相位数据反馈到地址加法器的输入端,使地址加法器在下一时钟的作用下继续与频率控制字相加,这样, 相位累加器在时钟的作用下, 进行相位累加, 当相位累加器累加满量时就会产生一次溢出, 完成一个周期性的动作, 这个周期也就是 DDS信号的一个频率周期(基频)。
备注:因为我的rom地址线为10位(因为存的点越多,精度越高,但同时使用资源也在成几何倍数增长),频率控制4位,所以想要采样到我存到rom中的所有点的话,必须要相位累加器的位宽不小于14位。
存储模块
用MATLAB生成.coe文件,调用rom核,用相位累加器输出的相位数据作为波形存储器的地址,在时钟下进行波形的相位与幅值转换, 按照地址和选择端的不同可以输出相应相位的正弦波、 方波、 三角波、锯齿波得到离散样值序列。
备注:我是用ISE级联modelsim仿真,查看输出端men_out的波形,ISE中我找不到查看模拟量的选项。级联方式找度娘。
clc;clear;
depth=2^10; %存储单元;
widths=12; %数据宽度为12位;
index = linspace(0,pi*2,depth);
sin_value = sin(index);
sin_value = 2 * sin_value * (depth -1); %扩大正弦幅度值
sin_value = fix((sin_value)+0.5);
plot(sin_value);
number = [0:depth];
fid=fopen('sin_table.coe','w+');
fprintf(fid,'memory_initialization_radix=10;\n');
fprintf(fid,'memory_initialization_vector=\n');
for i = 1 : depth
fprintf(fid, '%d,\n', sin_value(i)+2048); %将波形上移使其全部为正值
end
fprintf(fid, '%d;', sin_value(depth));
fclose(fid);
备注:其他生成波形的代码丢失,如有需要,请找度娘。
D/A转换模块
Digilent官网下载是英文手册,看的比较麻烦,网上找的唯一的中文资料
验证方案
- seclet = 0,change_freq在1到15之间取值,看是否是正弦波和相对应的频率。
备注: - 其他波形通过改变seclet 的值,可以得到相应的仿真图。
- 由于实验条件的限制,只是做的仿真这一步。
顶层模块代码片
module dds(
input clk_50M,
input rst_n,
input [1:0] select,
input [3:0] change_freq,
input key,
output dina,
output sclk,
output sync
);
//内部变量
wire [11:0] mem_out;//数据线12位
wire [9:0] addr_data;//地址线10位 采样点1024
wire clk_1M;
fenpin n1(.clk_50M(clk_50M),.rst_n(rst_n),.clk_1M(clk_1M));
addr n2( .rst_n(rst_n),.clk_1M(clk_1M),.change_freq(change_freq),.addr_data(addr_data));
rom n3(.clk_1M(clk_1M),.rst_n(rst_n),.select(select),.addr_data(addr_data),.mem_out(mem_out));
pmod_DA2 n4 (.clk(clk_1M), .rst_n(rst_n), .key(key), .X(mem_out), .dina(dina), .sclk(sclk), .sync(sync));
endmodule
备注:子模块代码丢失。
如果有其他问题,请发邮件联系我,一起探讨。doupengchang@outlook.com