手把手教会在 FPGA 中的 DDS 调制:从代码看懂 AM 与 FM 的核心思想

大家好,很多FPGA初学者在学习DDS(直接数字频率合成)时,往往觉得“调制”是一个很复杂的概念。其实,它的核心思想非常朴素:让一个参数随着另一个参数的变化而变化。

1. DDS调制的基础:调制信号从哪来?

在开始调制之前,我们首先需要一个“调制信号”。这个信号可以是正弦波、三角波或方波。在代码中,我们通过一个相位累加器和一个波形ROM来生成它。

  • 相位累加器mod_phase <= mod_phase + mod_f_word; 它像一个不停奔跑的计时器,累加的速度由 mod_f_word(频率控制字)决定。

  • 波形查找表:我们通过截取 mod_phase 的高位作为地址,去ROM(bram_sin)里查找对应的幅度值,从而还原出正弦波。同理,三角波和方波则是通过组合逻辑直接对相位进行映射得到的。

核心思想: 调制信号 = f(相位累加器)。我们拥有了一个频率可调、波形可选的基础信号源。

image

 

2. AM调幅:让“大小”动起来

AM(调幅)的直观理解就是让载波的幅度随着调制信号的幅度变化而变化。收音机里的AM广播就是这个原理。

在代码中,这个过程分四步走:

  1. 调制信号变“有符号”:因为幅度要能增大也能减小,所以我们将原本0-1023的调制信号转换为以0为中心的 -512 到 +511 的有符号数 (mod_signals)。

  2. 乘以深度wave <= mod_signals * am_depth; 这一步决定了调制的影响有多大。am_depth 就是调制深度。

  3. 生成包络modul_wave 是对乘法结果的处理,它代表了我们最终要叠加在载波上的“包络形状”。

  4. 乘以载波modul_out <= modul_wave * carrier_signed; 这是最核心的一步:用调制包络去乘载波信号。当调制信号为正时,载波幅度变大;为负时,载波幅度变小。

核心思想: AM = 载波 × (1 + 调制信号)。在数字域,本质上就是两个数的乘法。

image

 

3. FM调频:让“快慢”动起来

FM(调频)的直观理解是让载波的频率随着调制信号的幅度变化而变化。声音大时频率高,声音小时频率低。

这段代码处理FM的方式非常巧妙,它并没有直接去改载波的频率,而是输出了一个频率偏移量 (fm_offset) 给上级模块。

  1. 同样转为有符号:这里复用了之前的 mod_signals

  2. 乘以频偏fm_mult <= mod_signals * fm_dev; fm_dev 决定了频率能偏离中心值多远。

  3. 归一化处理fm_offset_calc = fm_mult[40:9]; 除以512是为了调整数据的量级,使其能正确累加到载波DDS的相位累加器上。

解释一下:上级模块通常有一个产生载波的DDS。当FM使能时,它不再是单纯累加固定的载波频率控制字,而是累加 固定值 + fm_offset。调制信号越大,fm_offset 越大,相位累加器跑得越快,输出的载波频率就越高。

核心思想: FM = 载波频率 + 调制信号 × 频偏系数。在数字域,就是用调制信号去动态调整DDS的“步长”。

image

 

请登录后发表评论

    没有回复内容