目的:设计一个DDS,可以输出两个波形,输出的波形的周期可以修改,相位可以修改,种类也可以修改
输入:clk,reset,一个控制T的按键,一个控制相位的按键,一个控制波形种类的按键。
思路:双通道——需要两个DDS。
波形种类可控——每个DDS需要四个ROM分别存放正弦波,三角波,锯齿波,方波。
频率可控——一个频率控制按钮,按一下切换一次频率,可供选择的频率是固定的,用计数器来设计。
相位可控——一个相位控制按钮,按一下切换一次相位,可供选择的相位是固定的,用计数器来设计。
有按钮——引入按键消抖模块,提高准确性。
可控——计数器+查找表 可以实现简单切换。(其他,如矩阵键盘等,后续)
建模:

细节:输出波形的周期与频率控制的关系
ROM存储一个波形,而相位累加器的内存存储一个波形的离散点。一般来说相位累加器内存大于ROM。而取点间隔就是频率控制字。
比如ROM是十位【9:0】,而相位累加器是【15:0】,那么取点时相位累加器应该取高10位来ROM中取幅度,即【15:6】,这样子输出的波形的周期会随着频率控制字(即取点步长)的大小而改变。如果频率比较小(如2),那么取ROM中一个点要停留很多个系统时钟周期,且ROM中每个点都会被取到,输出的波形周期就长,如果频率比较大(如128),那么取ROM中一个点只停留一个系统时钟周期,且会跳过ROM中的某些点,输出的波形周期就短。
验证结果:
第一行:频率可控
第二行:波形可控


代码:
module DDS_advanced(
clk,
reset,
f_change_A,
f_change_B,
p_change_A,
p_change_B,
wave_change_A,
wave_change_B,
dout_A,
dout_B
);
input clk ;
input reset ;
input f_change_A ;
input f_change_B ;
input p_change_A ;
input p_change_B ;
input wave_change_A ;
input wave_change_B ;
output wire[9:0]dout_A ;
output wire[9:0]dout_B ;
reg [1:0]f_cnt_A ;//设置A通道的频率选择按钮的消抖,计数
wire tx_fA ;
wire f_change_A_sign ;
buttopn_debounde
#(
.delay(1000)
)
buttopn_debounde_fA (//消抖,取释放符号为+1信号
.clk(clk),
.tx(f_change_A),
.reset(reset),
.bd_tx(tx_fA),
.release_sign(f_change_A_sign)
);
always@(posedge clk or negedge reset)//计数
if (!reset)
f_cnt_A <= 2'd0 ;
else if(f_change_A_sign)
f_cnt_A <= f_cnt_A + 1'd1 ;
else
f_cnt_A <= f_cnt_A ;
reg [1:0]p_cnt_A ;//设置A通道的相位选择按钮的消抖,计数
wire tx_pA ;
wire p_change_A_sign ;

该博客介绍了一个双通道直接数字频率合成器(DDS)的设计,每个通道具有独立的频率、相位和波形选择。通过使用四个ROM分别存储正弦、三角、锯齿和方波,实现了波形种类的切换。频率通过计数器和频率控制按钮实现,相位同样通过计数器和相位控制按钮调整。文章还详细解释了输出波形周期与频率控制字的关系,并提供了Verilog代码实现。通过按键消抖模块提高系统稳定性,最后进行了功能验证。
最低0.47元/天 解锁文章
2186

被折叠的 条评论
为什么被折叠?



