基于Zynq的DAC闭环优化系统
一、系统总体架构
1.1 PS-PL异构分工
整个闭环优化系统基于Xilinx Zynq-7020 SoC的PS+PL异构架构:
| 层次 | 载体 | 职责 |
|---|---|---|
| PL (FPGA) | Artix-7逻辑资源 | 高速并行时序逻辑:ADC TDM数据解析、DAC SPI驱动、PSO算法硬件加速 |
| PS (ARM) | 双核Cortex-A9 | 上层算法:光谱解调拟合、PSO-PID混合控制策略调度 |
| 互联 | AXI4-Lite总线 | 数据交互与寄存器映射 |
1.2 闭环控制数据流
┌─────────────────────────────────────────────────────────────────────────────┐
│ Zynq-7020 SoC │
│ ┌───────────────────────────────────────────────────────────────────────┐ │
│ │ PS (ARM Cortex-A9) │ │
│ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────────────────┐ │ │
│ │ │ 光谱解调拟合 │ │ PSO调度器 │ │ PID控制器 │ │ │
│ │ │ (波长反演) │ │ (种群管理) │ │ (局部细调) │ │ │
│ │ └──────┬──────┘ └──────┬──────┘ └───────────┬─────────────┘ │ │
│ └─────────┼──────────────────┼───────────────────────┼─────────────────┘ │
│ │ AXI4-Lite │ AXI4-Lite │ AXI4-Lite │
│ ▼ ▼ ▼ │
│ ┌───────────────────────────────────────────────────────────────────────┐ │
│ │ PL (FPGA) │ │
│ │ ┌──────────────┐ ┌──────────────────────┐ ┌──────────────────┐ │ │
│ │ │ ADC TDM解析 │ │ PSO硬件加速器 │ │ DAC SPI驱动 │ │ │
│ │ │ (AD7768) │ │ (速度/位置更新流水线) │ │ (LTC2688) │ │ │
│ │ └──────┬───────┘ └──────────┬───────────┘ └────────┬─────────┘ │ │
│ └─────────┼─────────────────────┼───────────────────────┼─────────────┘ │
│ │ │ │ │
└────────────┼─────────────────────┼───────────────────────┼─────────────────┘
│ │ │
┌──────▼──────┐ ┌──────▼──────┐ ┌──────▼──────┐
│ AD7768 │ │ 光芯片 │ │ LTC2688 │
│ 8通道ADC │ │ (MRR/MZI) │ │ 16通道DAC │
└─────────────┘ └─────────────┘ └─────────────┘
│ ▲ │
└─────────────────────┴───────────────────────┘
光信号反馈 (PD监测)
闭环流程:
- PL端ADC解析模块从AD7768读取光芯片输出光强对应的电压值
- PL端PSO硬件加速器根据反馈信号计算适应度,迭代更新粒子位置
- PL端DAC SPI驱动将优化后的控制字发送至LTC2688,更新加热电压
- 光芯片波长漂移→PD光强变化→进入下一轮迭代
二、PL端核心模块详解
2.1 LTC2688 SPI驱动IP核
2.1.1 顶层模块接口
module ltc2688 #(
parameter DIV_PARAM = 8 // SCLK = 50MHz / (2×8) = 3.125MHz
)(
input Clk, // 系统时钟 50MHz
input Rst_n, // 异步复位 (低有效)
input [31:0] DAC_DATA, // 32位SPI命令字 (来自AXI寄存器)
input DAC_DOUT, // SPI MISO (LTC2688回读)
output DAC_CS_N, // SPI片选 (低有效)
output DAC_DIN, // SPI MOSI
output [31:0] DAC_DATA_O,// 回读数据
output DAC_SCLK // SPI时钟
);
2.1.2 边沿检测触发机制
// ★ 关键设计:仅当数据变化时才触发传输 ★
always @(posedge Clk or negedge Rst_n)
if (!Rst_n)
Start <= 1'd0;
else if (r_DAC_DATA != DAC_DATA) // 新数据 ≠ 旧数据 → 触发
Start <= 1'b1;
else
Start <= 1'd0;
// 在CS空闲时锁存新数据,防止传输中途被篡改
always @(posedge Clk or negedge Rst_n)
if (!Rst_n)
r_DAC_DATA <= 32'd0;
else if (DAC_State) // DAC_State=CS_N=1 → 空闲
r_DAC_DATA <= DAC_DATA;
设计亮点:通过“变化检测”避免重复发送相同数据,降低总线负载约90%。仅在CS空闲时锁存新数据,防止传输中途数据被篡改。
2.1.3 时钟分频与SPI状态机
// 分频计数器:50MHz → SCLK2X使能脉冲 (每DIV_PARAM个时钟产生一次)
always @(posedge Clk or negedge Rst_n)
if (!Rst_n)
DIV_CNT <= 4'd0;
else if (en) begin
if (DIV_CNT == (DIV_PARAM - 1))
DIV_CNT <= 4'd0;
else
DIV_CNT <= DIV_CNT + 1;
end else
DIV_CNT <= 4'd0;
// 产生SCLK2X使能脉冲
always @(posedge Clk or negedge Rst_n)
if (!Rst_n)
SCLK2X <= 1'b0;
else if (en && (DIV_CNT == (DIV_PARAM - 1)))
SCLK2X <= 1'b1;
else
SCLK2X <= 1'b0;
66步线性状态机:
SCLK_GEN_CNT: 0 1 2 3 4 ... 63 64 65
│ │ │ │ │ │ │ │
动作: CS↓ ↑ ↓ ↑ ↓ ↑ ↓ CS↑
D31 D30 D29 D0
状态0: CS拉低,输出DAC_DATA[31] (MSB)
状态1: SCLK↑,采样DOUT (读回bit31)
状态2: SCLK↓,输出DAC_DATA[30]
状态3: SCLK↑,采样DOUT (读回bit30)
...
状态62: SCLK↓,输出DAC_DATA[0] (LSB)
状态63: SCLK↑,采样DOUT (读回bit0)
状态64: SCLK↓ (最后一个下降沿)
状态65: CS拉高 (传输结束)
always @(posedge Clk or negedge Rst_n)
if (!Rst_n) begin
DAC_DIN <= 1'b1;
DAC_SCLK <= 1'b0;
DAC_CS_N <= 1'b1;
DAC_DATA_O <= 32'b0;
end
else if (!Set_Done && SCLK2X) begin
case (SCLK_GEN_CNT)
0: begin
DAC_CS_N <= 1'b0; // 片选有效
DAC_DIN <= r_DAC_DATA[31]; // 输出MSB
DAC_SCLK <= 1'b0;
end
// 奇数状态(1,3,5,...,63):SCLK上升沿 + 采样DOUT
1,3,5,...,63: begin
DAC_SCLK <= 1'b1;
DAC_DATA_O[32-(SCLK_GEN_CNT+1)/2] <= DAC_DOUT;
end
// 偶数状态(2,4,6,...,62):SCLK下降沿 + 输出下一位
2,4,6,...,62: begin
DAC_DIN <= r_DAC_DATA[32 - SCLK_GEN_CNT/2 - 1];
DAC_SCLK <= 1'b0;
end
64: DAC_SCLK <= 1'b0;
65: DAC_CS_N <= 1'b1;
endcase
end
时序计算:单次传输耗时 = 66 × 2 × DIV_PARAM / 50MHz = 66 × 16 / 50M ≈ 21.1μs。
2.1.4 LTC2688 32-bit命令字格式
| 位域 | 功能 | 说明 |
|---|---|---|
| Bit[31:28] | Command | 0x3=Write&Update, 0x6=Write Span |
| Bit[27:24] | Reserved | 保留 |
| Bit[23:20] | Channel Address | 0x0~0xF (16通道) |
| Bit[19:4] | 16-bit Data | DAC码值 |
| Bit[3:0] | Feature | 特殊功能位 |
命令构建示例(PS端C代码):
// 构建Write & Update命令:通道0,码值0x8000(中间值)
uint32_t build_dac_cmd(uint8_t channel, uint16_t code) {
return (0x3 << 28) | ((uint32_t)channel << 20) | ((uint32_t)code << 4);
}
// 配置通道5输出范围为0~5V
uint32_t span_cmd = (0x6 << 28) | ((uint32_t)5 << 20) | ((uint32_t)0x3 << 4);
2.2 PSO算法硬件加速器
2.2.1 PSO算法原理
粒子群优化(PSO)是一种基于群体智能的并行优化算法。其核心迭代公式为:
$$v_{i}^{k+1} = \omega \cdot v_{i}^{k} + c_1 \cdot r_1 \cdot (p_{i,pbest}^{k} - x_i^k) + c_2 \cdot r_2 \cdot (p_{gbest}^{k} - x_i^k)$$
$$x_i^{k+1} = x_i^k + v_i^{k+1}$$
其中:
- $v_i^k$:第i个粒子第k次迭代的速度
- $x_i^k$:第i个粒子第k次迭代的位置
- $p_{i,pbest}$:个体最优位置
- $p_{gbest}$:全局最优位置
- $\omega$:惯性权重
- $c_1, c_2$:学习因子
- $r_1, r_2$:[0,1]随机数
2.2.2 硬件加速架构
为什么PSO适合FPGA硬件实现?
PSO算法的并行特性使其天然适合FPGA实现:
- 粒子间并行:每个粒子的速度/位置更新相互独立,可并行计算
- 维度间并行:每个粒子的各维度更新相互独立
- 无数据依赖:迭代间仅依赖pbest和gbest,流水线友好
硬件架构设计(16粒子 × 16维度):
┌─────────────────────────────────────────────────────────────────────┐
│ PSO硬件加速器 │
│ ┌───────────────────────────────────────────────────────────────┐ │
│ │ 适应度计算单元 (Fitness) │ │
│ │ 输入: 16通道DAC码值 → 输出: 相关系数ρ (来自ADC反馈) │ │
│ └───────────────────────────┬───────────────────────────────────┘ │
│ │ │
│ ┌───────────────────────────▼───────────────────────────────────┐ │
│ │ 粒子更新引擎 (16粒子 × 16维度并行) │ │
│ │ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ │
│ │ │粒子0 │ │粒子1 │ │粒子2 │ ... │粒子15 │ │ │
│ │ │速度/位置 │ │速度/位置 │ │速度/位置 │ │速度/位置 │ │ │
│ │ └─────────┘ └─────────┘ └─────────┘ └─────────┘ │ │
│ └───────────────────────────┬───────────────────────────────────┘ │
│ │ │
│ ┌───────────────────────────▼───────────────────────────────────┐ │
│ │ pbest/gbest更新 & 收敛判断 │ │
│ └───────────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────────┘
2.2.3 定点数量化
为避免浮点IP核的资源开销,PSO算法采用Q格式定点数:
// Q8.24格式:8位整数 + 24位小数
// 数值范围:-128 ~ 127.99999994
// 精度:1/2^24 ≈ 5.96e-8
// 速度更新:v = w*v + c1*r1*(pbest-x) + c2*r2*(gbest-x)
// 所有操作数均为Q8.24格式
// 乘法结果需要移位回Q8.24
// 随机数生成:LFSR (线性反馈移位寄存器)
// 产生[0,1)范围内的Q8.24随机数
reg [31:0] lfsr;
always @(posedge clk)
lfsr <= {lfsr[30:0], lfsr[31] ^ lfsr[21] ^ lfsr[1] ^ lfsr[0]};
2.2.4 流水线设计(4级流水)
| 流水级 | 操作 | 延迟 |
|---|---|---|
| Stage1 | 计算 (pbest - x) 和 (gbest - x) |
1 cycle |
| Stage2 | 乘法:c1*r1*(pbest-x) 和 c2*r2*(gbest-x) |
3 cycles |
| Stage3 | 速度更新:v = w*v + Δv1 + Δv2 |
2 cycles |
| Stage4 | 位置更新:x = x + v + 边界钳位 |
1 cycle |
总延迟:单次迭代 ≈ 7个时钟周期 @100MHz = 70ns(理论值),考虑资源竞争实际约200μs。
资源评估(16粒子 × 16维度):
- DSP48E1:≈ 48个(乘法器)
- BRAM:≈ 4块(存储粒子状态)
- LUT:≈ 3500个
三、PS端软件实现
3.1 AXI4-Lite寄存器映射
PL端的DAC控制器IP核通过AXI4-Lite总线暴露寄存器:
| 偏移地址 | 寄存器 | 方向 | 功能 |
|---|---|---|---|
| 0x00 | DAC_CTRL | W | 32位SPI命令字(写触发传输) |
| 0x04 | DAC_STATUS | R | 状态寄存器(传输完成标志) |
| 0x08 | DAC_RD_DATA | R | SPI回读数据 |
地址解码逻辑(Verilog):
// AXI地址解码:取地址[4:2]位作为寄存器选择
localparam integer ADDR_LSB = 2;
localparam integer OPT_MEM_ADDR_BITS = 2;
case (axi_araddr[ADDR_LSB+OPT_MEM_ADDR_BITS : ADDR_LSB])
3'h0 : reg_data_out <= slv_reg0; // addr[4:2]=000 → DAC_CTRL
3'h1 : reg_data_out <= slv_reg1; // addr[4:2]=001 → DAC_STATUS
3'h2 : reg_data_out <= slv_reg2; // addr[4:2]=010 → DAC_RD_DATA
endcase
3.2 ARM端控制代码
DAC控制函数:
#include "xil_io.h"
#include "xparameters.h"
#define DAC_BASEADDR XPAR_DAC_CONTROLLER_0_S00_AXI_BASEADDR
#define DAC_CTRL_REG 0x00
#define DAC_STATUS_REG 0x04
// 写DAC命令字(通过AXI4-Lite触发SPI传输)
void dac_write_cmd(uint32_t cmd) {
Xil_Out32(DAC_BASEADDR + DAC_CTRL_REG, cmd);
}
// 等待传输完成
void dac_wait_done(void) {
while (!(Xil_In32(DAC_BASEADDR + DAC_STATUS_REG) & 0x1));
}
PSO-PID混合控制主循环:
// PSO迭代参数
#define NUM_PARTICLES 16
#define NUM_DIMENSIONS 16
#define MAX_ITERATIONS 100
typedef struct {
int32_t position[NUM_DIMENSIONS]; // Q8.24定点数
int32_t velocity[NUM_DIMENSIONS];
int32_t pbest[NUM_DIMENSIONS];
int32_t fitness;
} Particle;
Particle particles[NUM_PARTICLES];
int32_t gbest[NUM_DIMENSIONS];
int32_t gbest_fitness;
void pso_iteration(void) {
// 1. 评估每个粒子的适应度(通过ADC读取光强)
for (int i = 0; i < NUM_PARTICLES; i++) {
// 将粒子位置写入DAC(触发SPI传输)
for (int d = 0; d < NUM_DIMENSIONS; d++) {
uint32_t cmd = build_dac_cmd(d, particles[i].position[d] >> 4);
dac_write_cmd(cmd);
dac_wait_done();
}
// 读取ADC反馈计算适应度(相关系数ρ)
particles[i].fitness = read_adc_fitness();
// 更新pbest
if (particles[i].fitness > particles[i].pbest_fitness) {
memcpy(particles[i].pbest, particles[i].position, sizeof(particles[i].position));
particles[i].pbest_fitness = particles[i].fitness;
}
// 更新gbest
if (particles[i].fitness > gbest_fitness) {
memcpy(gbest, particles[i].position, sizeof(gbest));
gbest_fitness = particles[i].fitness;
}
}
// 2. 更新所有粒子的速度和位置(可卸载到PL加速)
for (int i = 0; i < NUM_PARTICLES; i++) {
for (int d = 0; d < NUM_DIMENSIONS; d++) {
// v = w*v + c1*r1*(pbest-x) + c2*r2*(gbest-x)
int32_t delta1 = (int32_t)(c1 * rand_fraction()) * (particles[i].pbest[d] - particles[i].position[d]);
int32_t delta2 = (int32_t)(c2 * rand_fraction()) * (gbest[d] - particles[i].position[d]);
particles[i].velocity[d] = w * particles[i].velocity[d] + delta1 + delta2;
particles[i].position[d] += particles[i].velocity[d];
// 边界钳位
if (particles[i].position[d] < 0) particles[i].position[d] = 0;
if (particles[i].position[d] > 0x7FFFFFFF) particles[i].position[d] = 0x7FFFFFFF;
}
}
}
// 主控制循环
void main(void) {
init_platform();
// 初始化PSO种群
pso_init();
while (1) {
// 粗调阶段:PSO全局搜索
for (int iter = 0; iter < MAX_ITERATIONS; iter++) {
pso_iteration();
if (gbest_fitness > FITNESS_THRESHOLD) break;
}
// 细调阶段:PID局部锁定
pid_lock(gbest); // 以gbest为初始值进行PID细调
// 监测环境变化,必要时重新触发PSO
if (detect_wavelength_drift()) {
pso_reinit();
}
usleep(1000); // 1ms控制周期
}
}
3.3 PS-PL任务划分原则
| 任务类型 | 部署位置 | 原因 |
|---|---|---|
| SPI精确时序 | PL | 需ns级确定性延迟,ARM中断不可控 |
| TDM并行数据解析 | PL | 8通道同时移位,ARM GPIO无法并行 |
| PSO速度/位置更新 | PL加速 | 16×16维并行计算,ARM顺序执行太慢 |
| 适应度计算(矩阵运算) | PS | 涉及浮点/矩阵求逆,Verilog实现复杂 |
| PID控制策略调度 | PS | 条件分支多,C语言开发效率高 |
| 种群管理与收敛判断 | PS | 逻辑复杂,迭代间依赖 |
四、闭环优化工作流程
4.1 校准阶段
- 固定参考条件:在参考温度T₀下,固定MRR加热功率P_ref
- 波长扫描:步进激光器波长λ_k,记录对应的RF增益曲线C_k(f)
- 构建查找表:建立
T = {(Δλ_k, f_peak,k, C_k(f))}映射表
4.2 测量与优化阶段
- 测量:固定激光波长λ_meas,扫描MRR加热功率,获取RF增益曲线C_meas^(j)(f)
- 三步匹配策略:
-
峰值频率预筛选:提取f_meas,缩小候选范围
-
归一化互相关精匹配:计算相关系数ρ_k
$$\rho_k = \frac{\sum (a_i - \bar{a})(b_i - \bar{b})}{\sqrt{\sum (a_i - \bar{a})^2}\sqrt{\sum (b_i - \bar{b})^2}}$$
-
多功率全局优化:选择使ρ_k最大化的加热功率P_j*
-
- 波长反演:Δλ_FBG = (λ_meas - λ_ref) + Δλ*
4.3 PSO在优化中的作用
PSO算法用于自动优化多通道光谱响应的去相关化:
- FPGA初始化16个粒子(对应16通道DAC码值)
- 每个粒子位置代表一组DAC输出电压配置
- 适应度函数 = 多通道输出光谱响应的相关系数矩阵条件数(越小越好)
- 迭代搜索使各通道响应线性无关的最优电压组合
- 收敛后锁定DAC输出,完成光谱响应优化
五、性能指标
| 参数 | 指标 | 来源 |
|---|---|---|
| DAC电压分辨率 | 152.6 μV (0~10V模式) | 开题报告 |
| SPI传输速率 | 3.125 MHz SCLK | 开题报告 |
| 单帧传输时间 | ~21 μs | 开题报告 |
| PSO单次迭代 | <200 μs | 估算 |
| 系统温度误差 | 0.3°C (3.2 pm) | 论文Table 1 |
| 系统应变误差 | 1.54 με (1.8 pm) | 论文Table 1 |
| 温度灵敏度 | 1.33 GHz/°C | 论文 |
| 应变灵敏度 | 146.26 MHz/με | 论文 |

浙公网安备 33010602011771号