大家好,很多FPGA初学者在学习DDS(直接数字频率合成)时,往往觉得“调制”是一个很复杂的概念。其实,它的核心思想非常朴素:让一个参数随着另一个参数的变化而变化。
1. DDS调制的基础:调制信号从哪来?
在开始调制之前,我们首先需要一个“调制信号”。这个信号可以是正弦波、三角波或方波。在代码中,我们通过一个相位累加器和一个波形ROM来生成它。
-
相位累加器:
mod_phase <= mod_phase + mod_f_word;它像一个不停奔跑的计时器,累加的速度由mod_f_word(频率控制字)决定。 -
波形查找表:我们通过截取
mod_phase的高位作为地址,去ROM(bram_sin)里查找对应的幅度值,从而还原出正弦波。同理,三角波和方波则是通过组合逻辑直接对相位进行映射得到的。
核心思想: 调制信号 = f(相位累加器)。我们拥有了一个频率可调、波形可选的基础信号源。

2. AM调幅:让“大小”动起来
AM(调幅)的直观理解就是让载波的幅度随着调制信号的幅度变化而变化。收音机里的AM广播就是这个原理。
在代码中,这个过程分四步走:
-
调制信号变“有符号”:因为幅度要能增大也能减小,所以我们将原本0-1023的调制信号转换为以0为中心的 -512 到 +511 的有符号数 (
mod_signals)。 -
乘以深度:
wave <= mod_signals * am_depth;这一步决定了调制的影响有多大。am_depth就是调制深度。 -
生成包络:
modul_wave是对乘法结果的处理,它代表了我们最终要叠加在载波上的“包络形状”。 -
乘以载波:
modul_out <= modul_wave * carrier_signed;这是最核心的一步:用调制包络去乘载波信号。当调制信号为正时,载波幅度变大;为负时,载波幅度变小。
核心思想: AM = 载波 × (1 + 调制信号)。在数字域,本质上就是两个数的乘法。

3. FM调频:让“快慢”动起来
FM(调频)的直观理解是让载波的频率随着调制信号的幅度变化而变化。声音大时频率高,声音小时频率低。
这段代码处理FM的方式非常巧妙,它并没有直接去改载波的频率,而是输出了一个频率偏移量 (fm_offset) 给上级模块。
-
同样转为有符号:这里复用了之前的
mod_signals。 -
乘以频偏:
fm_mult <= mod_signals * fm_dev;fm_dev决定了频率能偏离中心值多远。 -
归一化处理:
fm_offset_calc = fm_mult[40:9];除以512是为了调整数据的量级,使其能正确累加到载波DDS的相位累加器上。
解释一下:上级模块通常有一个产生载波的DDS。当FM使能时,它不再是单纯累加固定的载波频率控制字,而是累加 固定值 + fm_offset。调制信号越大,fm_offset 越大,相位累加器跑得越快,输出的载波频率就越高。
核心思想: FM = 载波频率 + 调制信号 × 频偏系数。在数字域,就是用调制信号去动态调整DDS的“步长”。



没有回复内容