FM的已调信号的高频对应部分频率很高,远远高于理论上的43khz,但低频部分的频率是正确的,这是实现调制的代码,为什么会出现这样的问题 module generatecos( input clk, input rst_n, input [47:0] step_phase, output reg [15:0] Q ); reg [47:0] phase_acc; reg [15:0] sin_quarter[0:1023]; // 1024???? // ?????? initial $readmemh("sin_quarter_1024.list", sin_quarter); always @(posedge clk or negedge rst_n) begin if (!rst_n) begin phase_acc <= 0; Q <= 0; end else begin phase_acc <= phase_acc + step_phase; case (phase_acc[47:46]) 2'b00: Q <= sin_quarter[1023 - phase_acc[45:36]]; 2'b01: Q <= -sin_quarter[phase_acc[45:36]]; 2'b10: Q <= -sin_quarter[1023 - phase_acc[45:36]]; 2'b11: Q <= sin_quarter[phase_acc[45:36]]; endcase end end endmodule module generatebase( input clk, input rst_n, output signed [15:0] Q ); // 600Hz ????????? 11.05926MHz localparam [47:0] STEP_PHASE = 48'd15258789065; generatecos u_generatecos( .clk(clk), .rst_n(rst_n), .step_phase(STEP_PHASE), .Q(Q) // ???I????Q ); endmodule module FM_modulation( input clk, input signed [15:0] Q_baseband, input rst_n, output signed [15:0] RF_Q ); // ???? 40kHz => 40kHz * 2^48 / 11.05926MHz = 1019252604353 localparam [47:0] CENTER = 48'd1019252604353; // ?? 3kHz => 3kHz * 2^48 / 11.05926MHz = 76293945327 localparam [47:0] DEVI = -48'd76293945327; // localparam [47:0] DEVI = 48'd50000000000; // ?????? // wire signed [63:0] mod_temp = $signed(I_baseband) * $signed(DEVI); // wire signed [47:0] phase_mod = mod_temp[63:16] >>> 2; // ????????? wire signed [63:0] mod_temp_Q = $signed(Q_baseband) * $signed(DEVI); wire signed [47:0] phase_mod = (mod_temp_Q[63:16]) >>> 4; // ?????? // ????????? = ?????? + ???? wire [47:0] current_step = CENTER + phase_mod; generatecos rf_carrier( .clk(clk), .rst_n(rst_n), .step_phase(current_step), .Q(RF_Q) ); endmodule module TOP1( input clk, // 11.05926MHz ?? input rst_n, // ???? output signed [15:0] RF_Q // FM?? ); wire signed [15:0] baseband_Q; // ????? generatebase u_generatebase( .clk(clk), .rst_n(rst_n), .Q(baseband_Q) ); // FM?? FM_modulation u_FM_modulation( .clk(clk), .Q_baseband(baseband_Q), .RF_Q(RF_Q), .rst_n(rst_n) ); endmodule
时间: 2025-06-13 09:30:53 浏览: 19
<think>嗯,用户的问题是关于FM调制实现中高频部分频率远高于理论值43kHz,而低频部分正常,需要分析提供的Verilog代码哪里出了问题。首先,我得先理解整个代码的结构和各模块的功能。
看代码结构,TOP1模块调用了generatebase和FM_modulation。generatebase产生基带信号,应该是600Hz的正弦波,通过generatecos模块生成。FM_modulation则负责调制,将基带信号与载波结合,输出已调信号。
问题出在高频部分频率异常,可能的原因有几个方向:相位累加器的计算、频率偏移量的设置、数据截断或溢出,或者查找表的使用方式。
首先,检查FM_modulation中的相位调制部分。中心频率CENTER和频偏DEVI的计算是否正确?用户提到理论最高频率应该是43kHz,但实际更高。这里需要计算CENTER + DEVI的最大值是否超出预期。CENTER对应40kHz,DEVI是调制信号的频偏,可能设定为±3kHz,所以理论最大频率应该是40kHz + 3kHz = 43kHz。但实际计算时,可能参数设置错误。
查看CENTER和DEVI的数值:代码中CENTER是40kHz对应的相位步进值,计算为40kHz * 2^48 / 11.05926MHz。同样的,DEVI是3kHz的相位步进。但需要确认这里的数值是否正确。例如,计算40kHz的相位步进值是否正确。如果DEVI的实际值过大,会导致调制后的最大频率超过预期。
另外,在相位调制计算中,mod_temp_Q是基带信号Q_baseband乘以DEVI,然后取高位并进行移位。这里可能存在符号扩展或截断的问题。例如,mod_temp_Q是64位有符号数,截取高48位时是否正确?代码中的mod_temp_Q[63:16]截取了高位,然后右移4位。这里移位是否正确?如果移位过多,可能导致实际频偏减小,但如果DEVI原本的数值过大,可能反而导致更大的频偏。
另一个可能的问题是phase_acc的使用。在generatecos模块中,相位累加器的步进是step_phase,每次累加后,取phase_acc的高两位来选择波形的象限,中间10位作为查找表的索引。但这里可能存在相位累加器的位数问题,或者step_phase的数值计算错误,导致实际生成的频率高于预期。
例如,step_phase的数值是否正确?在generatebase模块中,STEP_PHASE被设置为48'd15258789065,用来生成600Hz的基带信号。但需要验证这个数值是否正确。假设系统时钟是11.05926MHz,那么相位步进的计算应为:step_phase = (600Hz * 2^48) / 11.05926e6。计算结果是否等于设定的数值?如果数值错误,可能导致基带信号频率不准确,进而影响调制后的结果。
在FM_modulation中,current_step = CENTER + phase_mod,而phase_mod是基带信号乘以DEVI后的结果。如果基带信号的幅度超过预期,可能导致phase_mod的值过大,从而使得current_step超过CENTER + DEVI的范围,导致载波频率偏移超过3kHz,从而高频部分超过43kHz。
另外,检查基带信号的幅度。基带信号Q_baseband是有符号16位,如果其最大值超过了1(例如,如果生成的基带信号是16位有符号数,范围是-32768到32767),当乘以DEVI时,结果可能非常大,导致phase_mod的值超出预期,从而使得current_step超过预期的最大步进值。例如,如果基带信号的最大值是32767,乘以DEVI后,mod_temp_Q的值会非常大,从而导致phase_mod过大,进而使得current_step超过CENTER + DEVI,导致频率过高。
这可能就是问题所在。例如,DEVI被设置为-48'd76293945327,对应3kHz的频偏。但基带信号的幅度如果是32767,那么phase_mod会是DEVI乘以32767,这会导致频偏远远超过3kHz。正确的做法应该是将基带信号归一化到±1的范围内,再乘以频偏。否则,调制后的频偏会被基带信号的幅度放大,导致最大频偏超出设计值。
例如,假设基带信号是16位有符号数,最大值是32767,那么当基带信号乘以DEVI时,相当于频偏被放大了32767倍,导致最大频偏变成3kHz * 32767,这显然远远超过预期,导致高频部分频率异常高。但实际代码中,可能基带信号应该是归一化的,或者在计算phase_mod时有归一化的步骤。但当前代码中可能没有这一步,导致频偏被错误放大。
所以,问题可能出在没有对基带信号进行归一化处理,导致相位调制量过大,从而使得高频部分的频率远超理论值。而低频部分因为基带信号幅度较小,所以频偏在正常范围内,导致低频部分正确,而高频部分异常。
因此,解决方法是需要将基带信号归一化到合适的范围,例如将基带信号除以最大值(32767),然后再乘以DEVI,或者在计算mod_temp_Q时调整缩放比例,确保相位调制的频偏不超过设计值。</think>在分析代码后,高频异常主要源于相位调制量过载。以下是分步解释:
---
### 关键问题定位:基带信号未归一化导致频偏过载
#### 1. 相位步进计算原理
FM调制公式为:
$$f_{out} = f_c + k_f \cdot m(t)$$
其中:
- $f_c=40kHz$ 对应 `CENTER`
- $k_f=3kHz$ 对应 `DEVI`
- $m(t)$ 是归一化的基带信号(幅度应限制在±1)
#### 2. 问题代码段分析
在 `FM_modulation` 模块中:
```verilog
wire signed [63:0] mod_temp_Q = $signed(Q_baseband) * $signed(DEVI);
wire signed [47:0] phase_mod = (mod_temp_Q[63:16]) >>> 4;
```
- **致命错误**:`Q_baseband` 是 16-bit有符号数(范围:-32768~32767),直接与 `DEVI` 相乘会导致:
$$实际频偏 = 3kHz \times \frac{Q_{baseband}}{32767}$$
当基带信号幅值为32767时,实际频偏会达到:
$$3kHz \times \frac{32767}{32767} = 3kHz$$
但当前代码未做归一化,导致:
$$实际频偏 = 3kHz \times 32767 = 98MHz$$
#### 3. 高频异常的直接原因
- **未归一化的基带信号**使相位调制量 `phase_mod` 超出设计值,导致瞬时频率远超43kHz
- **低频正常的原因**:当基带信号幅值较小时,频偏仍在合理范围内
---
### 修正方案
#### 1. 基带信号归一化
修改相位调制计算:
```verilog
// 新增归一化操作(保留4位精度)
wire signed [19:0] normalized_Q = $signed(Q_baseband) / 32768; // 16-bit转1.15格式
// 调整乘法位数
wire signed [63:0] mod_temp_Q = normalized_Q * $signed(DEVI);
```
#### 2. 验证参数范围
重新计算 `CENTER` 和 `DEVI` 的数值:
- 系统时钟 11.05926MHz
- 中心频率 $f_c$ 的相位步进:
$$step_{center} = \frac{40kHz \times 2^{48}}{11.05926MHz} \approx 1019252604353$$
- 频偏步进量:
$$step_{dev} = \frac{3kHz \times 2^{48}}{11.05926MHz} \approx 76293945327$$
#### 3. 仿真验证点
| 检查点 | 预期值 | 异常现象 |
|-----------------------|------------------|--------------------|
| `Q_baseband` 最大值 | ±32767 | 未归一化导致过载 |
| `mod_temp_Q[63:0]` | < ±7.6e10 | 数值溢出风险 |
| `phase_mod[47:0]` | < ±7.6e10/2^20 | 应与DEVI量级匹配 |
---
### 其他潜在问题
1. **相位累加器截断误差**
- `generatecos` 模块中 `phase_acc[45:36]` 使用10-bit地址,对应1024点查找表
- 确保相位步进分辨率 $\frac{f_{clk}}{2^{48}}$ 足够小(本例为 0.0004Hz/LSB)
2. **符号扩展错误**
```verilog
// 原代码中的危险操作
phase_mod = (mod_temp_Q[63:16]) >>> 4;
```
- 应改为算术右移保持符号位:
```verilog
phase_mod = $signed(mod_temp_Q[63:16]) >>> 4;
```
---
### 总结建议
1. 对基带信号进行归一化处理
2. 重新计算相位调制量的位宽和缩放比例
3. 添加仿真测试:监测 `current_step` 的瞬时值是否在 $f_c ± 3kHz$ 对应范围内
阅读全文
相关推荐

















