一、项目需求
1、任务要求
- FPGA 内实现任意波形发生器,支持正弦、三角、锯齿与自定义波形,频率、幅度、直流偏置可调。
- 使用 ADC 采样 DAC 输出(可回环),建立闭环幅度校准:在不同负载或衰减条件下自动修正幅度误差。
- 对输出波形进行谐波评估,至少计算二次、三次谐波幅度并给出总谐波失真估计。
- OLED显示当前波形类型、频率、幅度、谐波与失真指标;数码管显示实时频率。
- 给出校准流程、误差分析与失真测试结果。
2、硬件介绍
- 名称:基于小脚丫FPGA的电赛训练平台
- 核心模块:Altera MAX10系列10M02SCM芯片
- 信息显示:128*64OLED,通过SPI总线驱动
- 控制输入: 旋转编码器/按键
- 信号采集:10bit/50Msps高速ADC
- 信号生成:10bit/120Msps高速DAC
3、功能分配

二、设计思路
1、人机交互输入:由用户自主选择波形类型并自主设置波形的频率、幅度、直流偏置等。
2、信号产生:采用DDS原理,根据指定的波形类型、频率和幅度,输出定点的数字样本点。
3、闭环控制与分析:
- 对比DDS产生的理想幅度和ADC实体回采的波形,建立闭环反馈并实时矫正。
- 对采集到的波形实时分析,计算谐波分量与总谐波失真
4、人机交互输出:驱动OLED与数码管显示波形信息
三、功能框图:
四、实现方式
1、硬件平台
- 基于小脚丫FPGA的电赛训练平台,核心芯片为STEP-Altera-MAX10-02
2、软件工具
- 软件:Quartus Prime 18.1(Lite Edition)
- 编程语言:Verilog HDL
- 调试工具:Signal Tap
3、系统功能流程

该系统实现功能的完整流程可以分为以下四个主要阶段:
1.用户交互与参数设置
- 采集输入:系统实时扫描开发板上的“独立按键”和“旋转编码器”。
- 参数更新:检测到用户操作,参数配置模块立即响应。
- 下发指令:配置模块将更新后的参数以并行数字信号的形式发送给整个系统的下游模块。
2.数字波形生成
- DDS:波形发生器接收到配置的参数后,内部相位累加器根据设定的目标频率不断累加,产生地址索引。
- 查表输出:通过线性增长的地址,查找对应的波形表或函数算法,不断输出10位未校准数字波形数据。
- 相位同步:DDS将其内部的相位累加值作为同步信号发送给失真分析模块。
3.闭环反馈与失真分析
外部的物理ADC芯片持续对模拟输出波形进行采样。ADC控制器将数据读入FPGA,经过滤波去除高频底噪和突发毛刺,得到纯净的数字回采数据。将得到的数据传入以下两个路径:
- 路径一,自适应校准:
纯净数据送入adaptive_calibration(自适应幅度校准模块)。将回采的实际幅度与系统记录的基准幅度进行对比。如果由于外接负载导致幅度衰减,自动增大数字增益;如果过冲,则减小增益。最后将DDS发来的原始未校准波形乘以上述自定自应增益,得到校正后的10位数据。
- 路径二,谐波分析:
纯净数据送入harmonic_analyzer(谐波分析模块)。利用之前DDS传来的相位同步信号对回波进行数学运算,实时剥离并计算出实际波形中的二次谐波幅度和三次谐波幅度,并以此估算出当前的总谐波失真。
4.输出与显示
- 模拟输出致动:DAC控制器接收经过闭环校正后的数据,按照时序驱动外部DAC芯片,在硬件引脚上输出补偿后的精确波形。
- 双屏状态显像:OLED显示模块汇总来自参数配置模块的设定值和来自谐波分析模块的实测失真数据,通过SPI总线将所有信息格式化刷新到OLED屏幕上。同时七段数码管显示模块将当前频率的最低两位数值驱动到两位七段数码管上显示。
五、主要代码讲解
1、波形生成模块
使用相位累加器,利用32位的加法器,每个12MHz时钟累加一次,累加满溢出表示走完一个波形周期。提取相位累加器高8位作为地址存储波形信息。
其中正弦波采用了四分之一波对称法,创建含有65个精确点的四分之一周期正弦波查找表。利用`a[7]` (半周期选择位,为0时处于正弦波的0°~180°,查表结果取正值,为1时取负值)控制符号,`a[6]`(四分之一周期选择位,为0时处于正弦波的0°~90°或180°~270°,采用正序查表,为1时采用镜像查表)控制地址正序/镜像扫描。
波形的输出范围为-511 ~ +511的有符号值,乘以幅度因子并右移10位,再叠加加上直流偏置,最后限幅保护,得到10位的DAC输出。
module dds (
input wire clk,
input wire rst_n,
input wire [15:0] frequency, //频率设定值
input wire [9:0] amplitude, //幅度设定值
input wire [9:0] dc_offset, //直流偏置
input wire [2:0] wave_type, //波形类型选择
output reg [31:0] phase_accum, //相位累加器输出
output reg [9:0] waveform_out //波形数据输出
);
//相位累加器
//当累加器溢出时,完成一个完整波形周期
always @(posedge clk or negedge rst_n) begin
if(!rst_n)
phase_accum <= 32'd0; //复位:相位归零
else
phase_accum <= phase_accum + (frequency * 358); //累加频率
end
wire [7:0] addr = phase_accum[31:24]; //取相位累加器高8位作为波形表地址(256个采样点/周期)
//波形查表 → 缩放 → 偏置 → 限幅
reg signed [9:0] wave_reg; //波形原始样本
reg signed [19:0] scaled_reg; //幅度缩放结果
reg signed [11:0] sum_reg; //叠加DC偏置后的结果
always @(posedge clk or negedge rst_n) begin
if(!rst_n) begin
wave_reg <= 0;
scaled_reg <= 0;
sum_reg <= 12'sd512; //复位:输出中间值
waveform_out <= 10'd512; //复位:DAC输出中间值(零偏置点)
end else begin
//根据波形类型查表获取原始样本值
//所有波形函数输出范围:-511 ~ +511
case(wave_type)
3'd0: wave_reg <= get_sine(addr); //正弦波:256点查找表
3'd1: wave_reg <= get_triangle(addr); //三角波:分段线性
3'd2: wave_reg <= get_sawtooth(addr); //锯齿波:线性递增
3'd3: wave_reg <= get_square(addr); //方 波:±511跳变
3'd4: wave_reg <= get_staircase(addr); //阶梯波:8级台阶
default: wave_reg <= get_sine(addr); //默认正弦波
endcase
//幅度缩放
scaled_reg <= wave_reg * $signed({1'b0, amplitude});
//DC偏置叠加
sum_reg <= (scaled_reg >>> 10) + $signed({1'b0, dc_offset});
//输出限幅
if(sum_reg > 12'sd1023)
waveform_out <= 10'd1023; //上限钳位
else if(sum_reg < 12'sd0)
waveform_out <= 10'd0; //下限钳位
else
waveform_out <= sum_reg[9:0]; //正常输出
end
end
//正弦波查找表(四分之一波对称法)
function signed [9:0] get_sine;
input [7:0] a;
reg [6:0] idx; //四分之一波表索引
reg [9:0] mag; //幅度
begin
//计算四分之一波表索引,a[6]决定是否镜像
if(a[6])
idx = 7'd64 - {1'b0, a[5:0]};
else
idx = {1'b0, a[5:0]};
//查找四分之一波表
// 公式: mag = round(511 × sin(idx × π / 128))
case(idx)
// idx: mag | idx: mag | idx: mag | idx: mag
0: mag = 0; 1: mag = 13; 2: mag = 25; 3: mag = 38;
4: mag = 50; 5: mag = 63; 6: mag = 75; 7: mag = 87;
8: mag = 100; 9: mag = 112; 10: mag = 124; 11: mag = 136;
12: mag = 148; 13: mag = 160; 14: mag = 172; 15: mag = 184;
16: mag = 196; 17: mag = 207; 18: mag = 218; 19: mag = 230;
20: mag = 241; 21: mag = 252; 22: mag = 263; 23: mag = 273;
24: mag = 284; 25: mag = 294; 26: mag = 304; 27: mag = 314;
28: mag = 324; 29: mag = 334; 30: mag = 343; 31: mag = 352;
32: mag = 361; 33: mag = 370; 34: mag = 379; 35: mag = 387;
36: mag = 395; 37: mag = 403; 38: mag = 410; 39: mag = 418;
40: mag = 425; 41: mag = 432; 42: mag = 438; 43: mag = 445;
44: mag = 451; 45: mag = 456; 46: mag = 462; 47: mag = 467;
48: mag = 472; 49: mag = 477; 50: mag = 481; 51: mag = 485;
52: mag = 489; 53: mag = 492; 54: mag = 496; 55: mag = 499;
56: mag = 501; 57: mag = 503; 58: mag = 505; 59: mag = 507;
60: mag = 509; 61: mag = 510; 62: mag = 510; 63: mag = 511;
64: mag = 511;
default: mag = 0;
endcase
//根据象限决定符号
if(a[7])
get_sine = -$signed({1'b0, mag}); //Q3/Q4:取反
else
get_sine = $signed({1'b0, mag}); //Q1/Q2:保持正
end
endfunction
//三角波生成函数
function signed [9:0] get_triangle;
input [7:0] addr;
if(addr < 128)
get_triangle = -511 + ($signed({2'b0, addr}) << 3); //上升段
else
get_triangle = 511 - ($signed({2'b0, addr-128}) << 3); //下降段
endfunction
//锯齿波生成函数
function signed [9:0] get_sawtooth;
input [7:0] addr;
get_sawtooth = -511 + ($signed({2'b0, addr}) << 2);
endfunction
//方波生成函数
function signed [9:0] get_square;
input [7:0] addr;
get_square = (addr[7]) ? -10'd511 : 10'd511;
endfunction
//阶梯波生成函数(自定义波形示例)
//利用地址高3位(addr[7:5])生成8级台阶
//每级宽度=256/8=32个采样点
//台阶值=addr[7:5]×128-448,范围约-448 ~ +448
function signed [9:0] get_staircase;
input [7:0] addr;
get_staircase = $signed({1'b0, addr[7:5], 7'b0}) - 10'sd448;
endfunction
endmodule
2、谐波分析模块
由于芯片逻辑单元有限,无法采样复杂的FFT算法,利用简化版8点DFT,提取特定频率成分的幅值,将输入交变信号使用硬件的相量矩阵进行求点累加。
时分复用的提取借用位移加减实现。且为了减少寄存器面积,基波、二次谐波和三次谐波在3个采样周期内使用一套实部/虚部累加器,轮流提取。
THD串行除法:在求出基波、二次谐波和三次谐波的绝对幅度后,以`(H2+H3)*1000`作为分子,采用12次移位试减的方式求得千分比。
无限冲激响应滤波器:在最初的设计中断开DAC与ADC的物理连接后H2、H3与THD的数值都会卡死在某一固定值,加入一个低通滤波,修复阈值死区的卡值问题,确保在断开连接输入极弱信号时参数会衰减为0。
module harmonic_analyzer (
input wire clk,
input wire rst_n,
input wire [9:0] adc_sample, //ADC采样值
input wire adc_valid, //ADC采样有效标志
input wire [31:0] phase_accum, //DDS相位累加器
output reg [15:0] harmonic_2, //二次谐波幅度
output reg [15:0] harmonic_3, //三次谐波幅度
output reg [15:0] thd //总谐波失真THD
);
//输入预处理:去DC+缩放
wire signed [10:0] s_raw = $signed({1'b0, adc_sample}) - 11'sd512; //去DC
wire signed [5:0] s = s_raw[10:5]; //右移5位(÷32),保留符号
//m ≈ 0.75 × s, 用于近似 cos(45°) ≈ 0.707
//实现: m = s/2 + s/4 = 0.75s (位移代替乘法)
wire signed [5:0] m = (s >>> 1) + (s >>> 2);
//相位区间:取相位累加器高3位
wire [2:0] ph = phase_accum[31:29];
//共享累加器(时分复用)
reg signed [19:0] re, im; //实部/虚部累加器
//时分选择:当前正在计算哪个谐波
reg [1:0] harm_sel; //0=基波(k=1),1=二次(k=2),2=三次(k=3)
//周期检测
reg prev_msb; //上一拍的相位累加器最高位
//幅度结果存储
reg [15:0] mag_h1; // 基波幅度
reg [15:0] mag_h2; // 二次谐波幅度
reg [15:0] mag_h3; // 三次谐波幅度
//幅度计算中间变量
reg [1:0] calc_step; // 计算步骤
reg [15:0] abs_a, abs_b; //|Re|和|Im|
//THD串行除法器
reg [23:0] div_num; //分子:(H2+H3)×1000
reg [15:0] div_den; //分母:H1
reg [15:0] div_res; //结果:THD‰值
reg [3:0] div_cnt; //除法位计数器
//状态机
localparam ST_RUN = 2'd0; //运行:累积相关值
localparam ST_CALC = 2'd1; //计算:求幅度
localparam ST_DIV = 2'd2; //除法:计算THD
localparam ST_OUT = 2'd3; //输出:IIR平滑并更新输出
reg [1:0] state;
//主状态机
always @(posedge clk or negedge rst_n) begin
if(!rst_n) begin
state <= ST_RUN;
re <= 0; im <= 0;
harm_sel <= 0;
prev_msb <= 0;
harmonic_2 <= 0; harmonic_3 <= 0; thd <= 0;
mag_h1 <= 0; mag_h2 <= 0; mag_h3 <= 0;
calc_step <= 0;
abs_a <= 0; abs_b <= 0;
div_num <= 0; div_den <= 0; div_res <= 0; div_cnt <= 0;
end else begin
prev_msb <= phase_accum[31]; //记录上一拍的相位MSB(用于检测周期完成)
case(state)
//ST_RUN:相关累积 (在一个完整信号周期内持续累加)
//Re(k) += sample × cos(k × 2π × ph/8)
//Im(k) += sample × sin(k × 2π × ph/8)
//使用预存的系数(1, 0.75, 0, -0.75, -1)简化乘法
ST_RUN: begin
if(adc_valid) begin
case(harm_sel)
//k=1:基波相关系数
2'd0: case(ph)
3'd0: re <= re + s; //cos=1,sin=0
3'd1: begin re <= re + m; im <= im - m; end //cos≈0.75,sin≈-0.75
3'd2: im <= im - s; //cos=0,sin=-1
3'd3: begin re <= re - m; im <= im - m; end //cos≈-0.75,sin≈-0.75
3'd4: re <= re - s; //cos=-1,sin=0
3'd5: begin re <= re - m; im <= im + m; end //cos≈-0.75,sin≈0.75
3'd6: im <= im + s; //cos=0,sin=1
3'd7: begin re <= re + m; im <= im + m; end //cos≈0.75,sin≈0.75
endcase
//k=2:二次谐波相关系数
2'd1: case(ph)
3'd0: re <= re + s; //cos=1,sin=0
3'd1: im <= im - s; //cos=0,sin=-1
3'd2: re <= re - s; //cos=-1,sin=0
3'd3: im <= im + s; //cos=0,sin=1
3'd4: re <= re + s; //cos=1,sin=0
3'd5: im <= im - s; //cos=0,sin=-1
3'd6: re <= re - s; //cos=-1,sin=0
3'd7: im <= im + s; //cos=0,sin=1
endcase
//k=3:三次谐波相关系数
default: case(ph)
3'd0: re <= re + s; //cos=1,sin=0
3'd1: begin re <= re - m; im <= im - m; end //cos≈-0.75,sin≈-0.75
3'd2: im <= im + s; //cos=0,sin=1
3'd3: begin re <= re + m; im <= im - m; end //cos≈0.75,sin≈-0.75
3'd4: re <= re - s; //cos=-1,sin=0
3'd5: begin re <= re + m; im <= im + m; end //cos≈0.75,sin≈0.75
3'd6: im <= im - s; //cos=0,sin=-1
3'd7: begin re <= re - m; im <= im + m; end //cos≈-0.75,sin≈0.75
endcase
endcase
end
//完整周期检测
//当phase_accum[31]从1→0, 表示一个完整的信号周期结束
//此时进入计算阶段, 求当前谐波的幅度
if(prev_msb && !phase_accum[31]) begin
calc_step <= 0;
state <= ST_CALC;
end
end
//ST_CALC:幅度计算+谐波切换
ST_CALC: begin
case(calc_step)
2'd0: begin //取绝对值(截掉低4位)
abs_a <= re[19] ? (-re[19:4]) : re[19:4]; //|Re|
abs_b <= im[19] ? (-im[19:4]) : im[19:4]; //|Im|
calc_step <= 1;
end
2'd1: begin //估算幅度|X| ≈ max(a,b) + 0.5 × min(a,b)
case(harm_sel)
2'd0: mag_h1 <= (abs_a >= abs_b) ?
(abs_a + (abs_b >> 1)) : (abs_b + (abs_a >> 1)); //基波
2'd1: mag_h2 <= (abs_a >= abs_b) ?
(abs_a + (abs_b >> 1)) : (abs_b + (abs_a >> 1)); //二次
default: mag_h3 <= (abs_a >= abs_b) ?
(abs_a + (abs_b >> 1)) : (abs_b + (abs_a >> 1)); //三次
endcase
calc_step <= 2;
end
2'd2: begin //清零累加器,切换到下一个谐波或计算THD
re <= 0; im <= 0; //清零,为下一轮累积做准备
if(harm_sel < 2'd2) begin
harm_sel <= harm_sel + 1; //还有更高次谐波要计算,切换到下一个
state <= ST_RUN; //回到累积状态
end else begin //三个谐波都计算完毕, 准备计算THD
harm_sel <= 0; //重置到基波
if(mag_h1 > 16'd2) begin //基波幅度足够大,可以计算THD
// THD(‰) = (H2 + H3) × 1000 / H1
div_num <= (mag_h2 + mag_h3) * 12'd1000; //分子
div_den <= mag_h1; //分母
div_res <= 0; //商清零
div_cnt <= 4'd12; //12位除法
state <= ST_DIV;
end else begin
div_res <= 0; //基波太弱,THD无意义,输出0
state <= ST_OUT;
end
end
end
endcase
end
//ST_DIV:串行除法器
ST_DIV: begin
if(div_cnt > 0) begin
//试减:分子是否大于等于移位后的分母
if(div_num >= ({8'd0, div_den} << (div_cnt - 1))) begin
//是:分子减去,商的对应位置1
div_num <= div_num - ({8'd0, div_den} << (div_cnt - 1));
div_res[div_cnt-1] <= 1'b1;
end
div_cnt <= div_cnt - 1; //处理下一位
end else
state <= ST_OUT; //除法完成
end
//ST_OUT:IIR低通滤波输出
ST_OUT: begin
// IIR平滑+整数截断死值修复
harmonic_2 <= (harmonic_2 < 16 && mag_h2 < 16) ? 16'd0 :
harmonic_2 - (harmonic_2 >> 4) + (mag_h2 >> 4);
harmonic_3 <= (harmonic_3 < 16 && mag_h3 < 16) ? 16'd0 :
harmonic_3 - (harmonic_3 >> 4) + (mag_h3 >> 4);
thd <= (thd < 16 && div_res < 16) ? 16'd0 :
thd - (thd >> 4) + (div_res >> 4);
state <= ST_RUN; //返回累积状态,开始新一轮测量
end
endcase
end
end
endmodule
3、幅度校准模块
对比DDS产生的理想幅度与ADC回采的实际波形幅度,建立闭环反馈并实时矫正。
(详细流程见附件“自适应幅度校准流程”)
module adaptive_calibration (
input wire clk,
input wire rst_n,
input wire [9:0] waveform_in, //DDS原始波形输入
input wire [9:0] adc_sample, //ADC回采样值
input wire [9:0] amplitude, //用户设定幅度
input wire [2:0] wave_type, //用户设定波形类型
output reg [9:0] calibrated_out //校准后的波形输出
);
//参数定义
parameter ERROR_THRESHOLD = 5; //误差阈值
parameter CALIB_TIMEOUT = 240000; //测量窗口=240000/12MHz=20ms
//内部寄存器
reg [15:0] calib_gain; //当前校准增益
reg [2:0] calib_state; //校准状态机当前状态
reg [31:0] timeout_counter; //多用途计数器
reg [9:0] max_sample; //测量窗口内的最大ADC值
reg [9:0] min_sample; //测量窗口内的最小ADC值
reg [9:0] learned_target; //开机自学习测量目标
reg target_learned; //自学习完成标志
//参数变化检测
reg [9:0] prev_amplitude; //上一拍的幅度设定值
reg [2:0] prev_wave_type; //上一拍的波形类型
wire param_changed = (amplitude != prev_amplitude) || (wave_type != prev_wave_type);
wire [9:0] w_measured = max_sample - min_sample; //实测峰峰値
//校准状态定义
localparam IDLE = 3'd0; //空闲:初始化测量参数
localparam MEASURE = 3'd1; //测量:采集ADC数据,记录极值
localparam CALCULATE = 3'd2; //计算:比较幅度与增量补偿
localparam VALID = 3'd3; //有效:校准收敛,等待定期重校准
// 校准状态机
always @(posedge clk or negedge rst_n) begin
if(!rst_n) begin //异步复位:所有状态归位
calib_state <= VALID;
timeout_counter <= 32'd0;
max_sample <= 10'd0;
min_sample <= 10'd1023;
calib_gain <= 16'h0100; //初始增益1.0
target_learned <= 1'b0; //复位学习标志
prev_amplitude <= 10'd0;
prev_wave_type <= 3'd0;
end else begin
//参数变化检测:手动调节幅度或切换波形时,重新学习基准
prev_amplitude <= amplitude;
prev_wave_type <= wave_type;
if(param_changed && target_learned) begin
target_learned <= 1'b0; //清除学习标志,触发重新学习
calib_gain <= 16'h0100; //增益复位为1.0
calib_state <= IDLE; //重新进入测量流程
end else begin
case(calib_state)
IDLE: begin //IDLE:初始化测量参数
timeout_counter <= 32'd0; //重置测量计时
max_sample <= 10'd0; //最大值初始化为最小
min_sample <= 10'd1023; //最小值初始化为最大
calib_state <= MEASURE; //进入测量阶段
end
MEASURE: begin //MEASURE:采集ADC数据,记录极值
if(adc_sample > max_sample)
max_sample <= adc_sample; //更新最大值
if(adc_sample < min_sample)
min_sample <= adc_sample; //更新最小值
timeout_counter <= timeout_counter + 1;
if(timeout_counter >= CALIB_TIMEOUT) begin
calib_state <= CALCULATE; //测量窗口结束,进入计算阶段
end
end
CALCULATE: begin //CALCULATE:自适应幅度比较与增量补偿
//如果是开机后的第一次测量,记录下正常连接时的基准波幅
if (!target_learned) begin
learned_target <= w_measured; //记录空载时的峰峰值
target_learned <= 1'b1; //学习完成
calib_state <= VALID; //第一次学习完毕,进入正常待机
end
else begin
//将空载的峰峰值与实际的峰峰值进行对比
if (learned_target > w_measured + ERROR_THRESHOLD) begin
//如果峰峰值衰减,增大校准增益
if (calib_gain + 16'd1 > 16'h0200)
calib_gain <= 16'h0200;
else
calib_gain <= calib_gain + 16'd1;
calib_state <= IDLE;
end
else if (learned_target + ERROR_THRESHOLD < w_measured) begin
//如果峰峰值增加,减小校准增益
if (calib_gain < 16'h0020 + 16'd1)
calib_gain <= 16'h0020;
else
calib_gain <= calib_gain - 16'd1;
calib_state <= IDLE;
end
else begin
calib_state <= VALID; //完成校准后进入有效状态
end
end
end
//VALID:校准有效,等待定期重校准
VALID: begin
timeout_counter <= timeout_counter + 1;
if(timeout_counter >= 32'd2000000) begin
calib_state <= IDLE; // 定期重新校准
end
end
default: calib_state <= IDLE;
endcase
end
end
end
//增益应用:AC 耦合方式,仅对交流分量施加校准增益,保持DC偏置不受影响
reg signed [12:0] ac_component; //交流分量(去DC后)
reg signed [29:0] scaled_ac_full; //增益缩放后的交流分量
always @(posedge clk or negedge rst_n) begin
if(!rst_n) begin
calibrated_out <= 10'd512; //复位:输出中间值
ac_component <= 13'd0;
scaled_ac_full <= 30'd0;
end else begin
// 第1级:提取交流分量
ac_component <= $signed({1'b0, waveform_in}) - 13'sd512;
// 第2级:应用校准增益
scaled_ac_full <= ac_component * $signed({1'b0, calib_gain});
// 第3级:恢复DC偏置并限幅
begin : clamp
reg signed [12:0] out_tmp; //13位有符号数,取scaled_ac_full低13位
out_tmp = scaled_ac_full[20:8]; //Q8.8→整数
if(out_tmp + 13'sd512 > 13'sd1023)
calibrated_out <= 10'd1023;
else if(out_tmp + 13'sd512 < 13'sd0)
calibrated_out <= 10'd0;
else
calibrated_out <= out_tmp + 13'sd512;
end
end
end
endmodule
其他功能模块代码见附件
六、实物初始上电状态展示

将DAC的输出端口与ADC的输入端口分别接入示波器的CH1与CH2(后续接入负载可直接看出两端波形信号的差异,方便观测系统的自适应幅度调节功能,具体现象见视频),上电后初始波形如下

七、FPGA资源占用

八、其他资源
项目工程、完整源代码、自适应幅度较准流程文档、失真度测试结果与误差分析文档见附件
