Skip to content

Commit 262df78

Browse files
feat(adaption): 新增DE域自适应控制模块及桥接机制
- 新增Adaption模块,作为DE域自适应控制中枢,实现AGC、DFE抽头在线更新、 判决阈值自适应、CDR控制接口以及安全冻结/回退机制 - 完善文档说明,增加模块结构图、信号流、接口端口及参数表 - 实现多速率调度架构,快路径(阈值调整、CDR PI控制)与慢路径(AGC、DFE更新)分离 - 增加详细自适应算法实现示例,包括PI控制器、LMS/Sign-LMS/NLMS抽头更新及阈值调整 - 定义DE-TDF桥接机制,实现参数与反馈信号的双向传递,保证域间协同 - 补充CDR与Adaption CDR PI控制接口的职责划分与三种使用模式,支持灵活配置 - 新增Adaption模块对应代码实现与测试平台,完善模块源码、头文件及单元测试 - 扩展RX顶层文档及版本历史,增加Adaption模块介绍与集成信息 - 提供自适应模块的测试场景、关键性能指标及典型测试结果分析 - 说明时序对齐、延迟处理、多速率调度实现细节及安全机制触发条件与恢复策略
1 parent 89e7469 commit 262df78

17 files changed

Lines changed: 1350 additions & 190 deletions

docs/modules/rx.md

Lines changed: 579 additions & 61 deletions
Large diffs are not rendered by default.

include/ams/rx_dfe_summer.h

Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
/**
2+
* @file rx_dfe_summer.h
3+
* @brief RX DFE Summer 模块 - 判决反馈均衡求和器
4+
*
5+
* 差分输入/输出架构,从主路径信号减去基于历史判决的反馈信号,
6+
* 抵消后游 ISI,增大眼图开度。
7+
*
8+
* 文档参考:docs/modules/dfesummer.md
9+
*/
10+
11+
#ifndef SERDES_AMS_RX_DFE_SUMMER_H
12+
#define SERDES_AMS_RX_DFE_SUMMER_H
13+
14+
#include <systemc-ams>
15+
#include "common/parameters.h"
16+
#include <vector>
17+
#include <cmath>
18+
19+
namespace serdes {
20+
21+
/**
22+
* @class RxDfeSummerTdf
23+
* @brief 差分 DFE Summer TDF 模块
24+
*
25+
* 功能:
26+
* - 接收差分输入信号 (in_p, in_n)
27+
* - 基于历史判决计算反馈电压
28+
* - 输出均衡后的差分信号 (out_p, out_n)
29+
* - 支持 DE 域抽头系数动态更新
30+
*/
31+
class RxDfeSummerTdf : public sca_tdf::sca_module {
32+
public:
33+
// ========================================================================
34+
// TDF 域差分输入端口
35+
// ========================================================================
36+
sca_tdf::sca_in<double> in_p; ///< 差分输入正端 (来自 VGA)
37+
sca_tdf::sca_in<double> in_n; ///< 差分输入负端 (来自 VGA)
38+
39+
// ========================================================================
40+
// TDF 域历史判决输入端口
41+
// ========================================================================
42+
sca_tdf::sca_in<double> data_in; ///< 历史判决输入 (来自 Sampler,0.0/1.0)
43+
44+
// ========================================================================
45+
// TDF 域差分输出端口
46+
// ========================================================================
47+
sca_tdf::sca_out<double> out_p; ///< 差分输出正端 (送往 Sampler)
48+
sca_tdf::sca_out<double> out_n; ///< 差分输出负端 (送往 Sampler)
49+
50+
// ========================================================================
51+
// DE→TDF 桥接端口 (抽头系数动态更新,可选)
52+
// ========================================================================
53+
sca_tdf::sca_de::sca_in<double> tap1_de; ///< DE 域抽头1更新
54+
sca_tdf::sca_de::sca_in<double> tap2_de; ///< DE 域抽头2更新
55+
sca_tdf::sca_de::sca_in<double> tap3_de; ///< DE 域抽头3更新
56+
sca_tdf::sca_de::sca_in<double> tap4_de; ///< DE 域抽头4更新
57+
sca_tdf::sca_de::sca_in<double> tap5_de; ///< DE 域抽头5更新
58+
59+
// ========================================================================
60+
// 构造函数
61+
// ========================================================================
62+
/**
63+
* @brief 构造函数
64+
* @param nm 模块名称
65+
* @param params DFE Summer 参数
66+
*/
67+
RxDfeSummerTdf(sc_core::sc_module_name nm, const RxDfeSummerParams& params);
68+
69+
// ========================================================================
70+
// TDF 回调函数
71+
// ========================================================================
72+
void set_attributes() override;
73+
void processing() override;
74+
75+
// ========================================================================
76+
// 公共接口
77+
// ========================================================================
78+
/**
79+
* @brief 获取当前抽头系数
80+
*/
81+
const std::vector<double>& get_tap_coeffs() const { return m_tap_coeffs; }
82+
83+
/**
84+
* @brief 获取最近一次反馈电压
85+
*/
86+
double get_last_feedback() const { return m_last_feedback; }
87+
88+
private:
89+
// ========================================================================
90+
// 参数
91+
// ========================================================================
92+
RxDfeSummerParams m_params;
93+
94+
// ========================================================================
95+
// 内部状态
96+
// ========================================================================
97+
std::vector<double> m_tap_coeffs; ///< 当前抽头系数
98+
std::vector<double> m_history_bits; ///< 历史判决缓冲区
99+
double m_last_feedback; ///< 上一次反馈电压(调试用)
100+
bool m_de_ports_connected; ///< DE端口是否连接标志
101+
102+
// ========================================================================
103+
// 内部方法
104+
// ========================================================================
105+
/**
106+
* @brief 比特映射函数
107+
* @param bit_val 输入比特值 (0.0 或 1.0)
108+
* @return 映射后的值 (pm1模式: -1/+1, 01模式: 0/1)
109+
*/
110+
double bit_map(double bit_val) const;
111+
112+
/**
113+
* @brief 计算反馈电压
114+
* @return 反馈电压 v_fb
115+
*/
116+
double compute_feedback() const;
117+
118+
/**
119+
* @brief 软饱和限幅
120+
* @param v_in 输入电压
121+
* @return 限幅后的电压
122+
*/
123+
double soft_saturate(double v_in) const;
124+
125+
/**
126+
* @brief 更新历史缓冲区
127+
* @param new_bit 新的判决比特
128+
*/
129+
void update_history(double new_bit);
130+
131+
/**
132+
* @brief 从 DE 端口读取抽头更新(如果连接)
133+
*/
134+
void read_de_tap_updates();
135+
};
136+
137+
} // namespace serdes
138+
139+
#endif // SERDES_AMS_RX_DFE_SUMMER_H

include/ams/rx_top.h

Lines changed: 99 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -5,30 +5,34 @@
55
#include "common/parameters.h"
66
#include "ams/rx_ctle.h"
77
#include "ams/rx_vga.h"
8-
#include "ams/rx_dfe.h"
8+
#include "ams/rx_dfe_summer.h"
99
#include "ams/rx_sampler.h"
1010
#include "ams/rx_cdr.h"
11+
#include "ams/adaption.h"
1112

1213
namespace serdes {
1314

1415
/**
1516
* @brief RX Top-level Module
1617
*
1718
* Integrates the complete RX signal chain:
18-
* Differential Input → CTLE → VGA → DFE_P/DFE_N → Sampler ↔ CDR → Digital Output
19+
* Differential Input → CTLE → VGA → DFE Summer → Sampler ↔ CDR → Digital Output
20+
* ↑ ↓
21+
* Adaption (DE domain) ←───┘
1922
*
2023
* Signal Flow:
2124
* - External differential input (from Channel or test source)
2225
* - CTLE: Continuous-Time Linear Equalizer for high-frequency boost
2326
* - VGA: Variable Gain Amplifier for amplitude adjustment
24-
* - DFE: Decision Feedback Equalizer (dual instances for differential)
25-
* - DFE_P: Positive path with normal taps
26-
* - DFE_N: Negative path with negated taps (for differential symmetry)
27+
* - DFE Summer: Decision Feedback Equalizer (差分架构,单实例)
2728
* - Sampler: Decision circuit with hysteresis
2829
* - CDR: Clock and Data Recovery (closed-loop with Sampler)
30+
* - Adaption: DE domain adaptive control (AGC, DFE tap update, threshold adaptation)
2931
*
3032
* Key Features:
31-
* - Dual DFE architecture for differential processing
33+
* - 差分 DFE Summer 架构替代双 DFE 实例
34+
* - Adaption 模块集成 (DE 域自适应控制)
35+
* - DE-TDF 桥接使用 sca_tdf::sca_de::sca_in/out
3236
* - CDR closed-loop: Sampler.phase_offset ← CDR.phase_out
3337
* - Phase-driven sampling mode (CDR controls sampling phase)
3438
*
@@ -58,9 +62,12 @@ SC_MODULE(RxTopModule) {
5862
/**
5963
* @brief Construct RX top module
6064
* @param nm Module name
61-
* @param rx_params RX parameters (CTLE, VGA, DFE, Sampler, CDR)
65+
* @param rx_params RX parameters (CTLE, VGA, DFE Summer, Sampler, CDR)
66+
* @param adaption_params Adaption parameters (DE 域自适应控制)
6267
*/
63-
RxTopModule(sc_core::sc_module_name nm, const RxParams& rx_params);
68+
RxTopModule(sc_core::sc_module_name nm,
69+
const RxParams& rx_params,
70+
const AdaptionParams& adaption_params);
6471

6572
/**
6673
* @brief Destructor - clean up sub-modules
@@ -127,38 +134,81 @@ SC_MODULE(RxTopModule) {
127134

128135
private:
129136
// ========================================================================
130-
// Sub-modules
137+
// Sub-modules (TDF domain)
131138
// ========================================================================
132-
RxCtleTdf* m_ctle; ///< Continuous-Time Linear Equalizer
133-
RxVgaTdf* m_vga; ///< Variable Gain Amplifier
134-
RxDfeTdf* m_dfe_p; ///< DFE for P path (normal taps)
135-
RxDfeTdf* m_dfe_n; ///< DFE for N path (negated taps)
136-
RxSamplerTdf* m_sampler; ///< Decision circuit
137-
RxCdrTdf* m_cdr; ///< Clock and Data Recovery
139+
RxCtleTdf* m_ctle; ///< Continuous-Time Linear Equalizer
140+
RxVgaTdf* m_vga; ///< Variable Gain Amplifier
141+
RxDfeSummerTdf* m_dfe_summer; ///< 差分 DFE Summer (替代双 DFE)
142+
RxSamplerTdf* m_sampler; ///< Decision circuit
143+
RxCdrTdf* m_cdr; ///< Clock and Data Recovery
138144

139145
// ========================================================================
140-
// Internal Signals
146+
// Sub-modules (DE domain)
147+
// ========================================================================
148+
AdaptionDe* m_adaption; ///< DE 域自适应控制模块
149+
150+
// ========================================================================
151+
// Internal TDF Signals
141152
// ========================================================================
142153

143154
// CTLE output → VGA input
144155
sca_tdf::sca_signal<double> m_sig_ctle_out_p; ///< CTLE positive output
145156
sca_tdf::sca_signal<double> m_sig_ctle_out_n; ///< CTLE negative output
146157

147-
// VGA output → DFE input
158+
// VGA output → DFE Summer input
148159
sca_tdf::sca_signal<double> m_sig_vga_out_p; ///< VGA positive output
149160
sca_tdf::sca_signal<double> m_sig_vga_out_n; ///< VGA negative output
150161

151-
// DFE output → Sampler input
152-
sca_tdf::sca_signal<double> m_sig_dfe_out_p; ///< DFE_P output
153-
sca_tdf::sca_signal<double> m_sig_dfe_out_n; ///< DFE_N output
162+
// DFE Summer output → Sampler input
163+
sca_tdf::sca_signal<double> m_sig_dfe_out_p; ///< DFE Summer positive output
164+
sca_tdf::sca_signal<double> m_sig_dfe_out_n; ///< DFE Summer negative output
154165

155166
// Sampler → CDR → Sampler (closed loop)
156167
sca_tdf::sca_signal<double> m_sig_sampler_out; ///< Sampler decision output
157168
sca_tdf::sca_signal<double> m_sig_cdr_phase; ///< CDR phase output → Sampler
169+
sca_tdf::sca_signal<double> m_sig_cdr_in; ///< CDR input (from splitter)
170+
171+
// Sampler → DFE Summer (历史判决反馈)
172+
sca_tdf::sca_signal<double> m_sig_data_feedback; ///< Data feedback for DFE
158173

159174
// Dummy clock for Sampler (unused in phase-driven mode but required)
160175
sca_tdf::sca_signal<double> m_sig_clk;
161176

177+
// ========================================================================
178+
// DE-TDF Bridge Signals (Adaption ↔ TDF modules)
179+
// ========================================================================
180+
181+
// Adaption outputs (DE domain) → TDF modules
182+
sc_core::sc_signal<double> m_sig_vga_gain_de; ///< VGA gain control
183+
sc_core::sc_signal<double> m_sig_dfe_tap1_de; ///< DFE tap 1
184+
sc_core::sc_signal<double> m_sig_dfe_tap2_de; ///< DFE tap 2
185+
sc_core::sc_signal<double> m_sig_dfe_tap3_de; ///< DFE tap 3
186+
sc_core::sc_signal<double> m_sig_dfe_tap4_de; ///< DFE tap 4
187+
sc_core::sc_signal<double> m_sig_dfe_tap5_de; ///< DFE tap 5
188+
sc_core::sc_signal<double> m_sig_sampler_threshold_de; ///< Sampler threshold
189+
sc_core::sc_signal<double> m_sig_sampler_hysteresis_de; ///< Sampler hysteresis
190+
sc_core::sc_signal<double> m_sig_phase_cmd_de; ///< Phase command
191+
192+
// TDF modules → Adaption inputs (DE domain)
193+
sc_core::sc_signal<double> m_sig_phase_error_de; ///< Phase error from CDR
194+
sc_core::sc_signal<double> m_sig_amplitude_rms_de; ///< Amplitude RMS
195+
sc_core::sc_signal<int> m_sig_error_count_de; ///< Error count
196+
sc_core::sc_signal<double> m_sig_isi_metric_de; ///< ISI metric
197+
sc_core::sc_signal<int> m_sig_mode_de; ///< Operating mode
198+
sc_core::sc_signal<bool> m_sig_reset_de; ///< Reset signal
199+
sc_core::sc_signal<double> m_sig_scenario_switch_de; ///< Scenario switch
200+
sc_core::sc_signal<bool> m_sig_sampler_data_out_de; ///< Sampler DE output
201+
202+
// Adaption 其他输出信号
203+
sc_core::sc_signal<double> m_sig_ctle_zero_de;
204+
sc_core::sc_signal<double> m_sig_ctle_pole_de;
205+
sc_core::sc_signal<double> m_sig_ctle_dc_gain_de;
206+
sc_core::sc_signal<double> m_sig_dfe_tap6_de;
207+
sc_core::sc_signal<double> m_sig_dfe_tap7_de;
208+
sc_core::sc_signal<double> m_sig_dfe_tap8_de;
209+
sc_core::sc_signal<int> m_sig_update_count_de;
210+
sc_core::sc_signal<bool> m_sig_freeze_flag_de;
211+
162212
// ========================================================================
163213
// Internal Helper Modules
164214
// ========================================================================
@@ -196,24 +246,40 @@ SC_MODULE(RxTopModule) {
196246
void processing() override { out.write(in.read()); }
197247
};
198248

199-
ConstClockSource* m_clk_src; ///< Dummy clock source
200-
SignalPassThrough* m_data_out_tap; ///< Pass-through for external data_out
249+
/**
250+
* @brief Signal splitter - reads one signal and writes to two outputs
251+
* Used to split sampler output to CDR and data feedback
252+
*/
253+
class SignalSplitter : public sca_tdf::sca_module {
254+
public:
255+
sca_tdf::sca_in<double> in;
256+
sca_tdf::sca_out<double> out1;
257+
sca_tdf::sca_out<double> out2;
258+
259+
SignalSplitter(sc_core::sc_module_name nm)
260+
: sca_tdf::sca_module(nm), in("in"), out1("out1"), out2("out2") {}
261+
262+
void set_attributes() override {
263+
in.set_rate(1);
264+
out1.set_rate(1);
265+
out2.set_rate(1);
266+
}
267+
void processing() override {
268+
double val = in.read();
269+
out1.write(val);
270+
out2.write(val);
271+
}
272+
};
273+
274+
ConstClockSource* m_clk_src; ///< Dummy clock source
275+
SignalPassThrough* m_data_out_tap; ///< Pass-through for external data_out
276+
SignalSplitter* m_sampler_splitter; ///< Splitter for sampler output
201277

202278
// ========================================================================
203279
// Parameters
204280
// ========================================================================
205281
RxParams m_params;
206-
RxDfeParams m_dfe_params_n; ///< Negated taps for DFE_N path
207-
208-
// ========================================================================
209-
// Private Methods
210-
// ========================================================================
211-
212-
/**
213-
* @brief Setup negated DFE taps for N path
214-
* For differential symmetry: taps_n[i] = -taps_p[i]
215-
*/
216-
void setup_dfe_negated_taps();
282+
AdaptionParams m_adaption_params;
217283
};
218284

219285
} // namespace serdes

include/ams/serdes_link_top.h

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,22 @@ struct SerdesLinkParams {
2121
WaveGenParams wave; ///< Wave generation parameters
2222
TxParams tx; ///< TX parameters (FFE, Mux, Driver)
2323
ChannelParams channel; ///< Channel parameters
24-
RxParams rx; ///< RX parameters (CTLE, VGA, DFE, Sampler, CDR)
24+
RxParams rx; ///< RX parameters (CTLE, VGA, DFE Summer, Sampler, CDR)
25+
AdaptionParams adaption; ///< Adaption parameters (AGC, DFE tap adaptation)
2526
double sample_rate; ///< Sampling rate (Hz)
2627
unsigned int seed; ///< Random seed for PRBS
2728

2829
SerdesLinkParams()
2930
: sample_rate(100e9)
30-
, seed(12345) {}
31+
, seed(12345) {
32+
// Default adaption parameters (disabled)
33+
adaption.agc.enabled = false;
34+
adaption.dfe.enabled = false;
35+
adaption.threshold.enabled = false;
36+
adaption.cdr_pi.enabled = false;
37+
adaption.safety.freeze_on_error = false;
38+
adaption.safety.rollback_enable = false;
39+
}
3140
};
3241

3342
/**

0 commit comments

Comments
 (0)