当前位置: 首页 > news >正文

FPGA 工频同步采集 + DDR3 缓存完整实现方案

目录

整体系统架构功能概述

时钟域划分(核心跨域隔离)

一、50Hz 工频 DPLL 同步模块 dpll_50hz.v

原理

二、ADC 同步采集模块 adc_sync_sample.v

三、异步 FIFO 跨时钟域桥 data_fifo_bridge.v

四、DDR3 MIG 控制器封装 ddr3_mig_top.v

IP 配置要点(Xilinx 7 系列 XC7A35T 为例)

五、DDR3 环形缓存控制器 ring_buffer_ctrl.v

工作机制

六、顶层集成 top_acq_ddr3.v

七、关键工程配置与优化说明

1. DDR 带宽匹配计算

2. 同步采集核心优势

3. 时序与稳定性优化

4. 扩展升级方向

八、适配芯片与资源预估(XC7A35T)


整体系统架构功能概述

  1. 工频锁相 DPLL:同步 50Hz 电网电压相位,生成同步采样时钟、同步触发脉冲;
  2. 多通道 ADC 同步采集(差分模拟输入);
  3. 实时数据流写入 DDR3 缓存(分段环形缓存 / 帧缓存双模式);
  4. DDR3 读通路:串口 / 以太网回传采集波形;
  5. 顶层模块划分:
    • dpll_50hz.v工频数字锁相环同步单元
    • adc_sync_sample.v多通道同步采样控制
    • ddr3_mig_top.vXilinx MIG IP DDR3 控制器封装
    • data_fifo_bridge.v异步 FIFO 跨时钟域桥(采集域 ↔ DDR 控制器域)
    • ring_buffer_ctrl.vDDR3 环形缓存管理器
    • uart_tx.v波形数据上传输出

时钟域划分(核心跨域隔离)

  1. 模拟采集域clk_adc:10MHz,ADC 采样时钟、DPLL 运算时钟
  2. DDR 控制器域clk_ddr_200m:MIG 参考时钟 200MHz,DDR 用户逻辑时钟 100MHz
  3. 系统管理域clk_sys_50m:外设串口、指令解析

一、50Hz 工频 DPLL 同步模块 dpll_50hz.v

原理

电网电压经 ADC 采样得到正弦数字波形,通过相位检测器 + PI 环路滤波 + 数控振荡器 NCO 锁定工频相位,输出同步采样使能,实现整周期等间隔同步采样。

1. 模块端口定义

  • vin_adc:正弦交流采样,正负分别对应电压正负半周;
  • phase_out:NCO 累加器原始相位,线性映射 0~2π;
  • sync_sample_en均匀等分工频周期输出采样触发,用于 ADC 同步采集。
module dpll_50hz( input clk_adc, //10MHz系统时钟 input rst_n, //低电平复位 input signed [15:0] vin_adc, //ADC采样电压,有符号正弦波 output reg sync_sample_en,//同步采样使能脉冲 output reg [15:0] phase_out //16bit相位输出 0~65535=0~2π ); //1. 相位误差提取:过零检测+象限判断 reg signed [15:0] vin_delay; reg cross_zero; always@(posedge clk_adc or !rst_n)begin if(!rst_n)begin vin_delay <= 16'd0; cross_zero <= 1'b0; end else begin vin_delay <= vin_adc; // 判断当前采样与上一拍符号相反 → 电压跨越零点 cross_zero <= (vin_adc[15] != vin_delay[15]) ? 1'b1 : 1'b0; end end //2. NCO 50Hz基准 16bit相位累加器 localparam FREQ_CTRL_INIT = 16'd65536; //10M clk下50Hz步长 reg [15:0] nco_phase; reg signed [15:0] pi_out; reg signed [15:0] freq_ctrl; always@(posedge clk_adc or !rst_n)begin if(!rst_n)begin nco_phase <= 16'd0; freq_ctrl <= FREQ_CTRL_INIT; end else begin nco_phase <= nco_phase + freq_ctrl; end end //3. PI环路滤波 reg signed [31:0] pi_acc; always@(posedge clk_adc or !rst_n)begin if(!rst_n)begin pi_acc <= 32'd0; freq_ctrl <= FREQ_CTRL_INIT; end else begin if(cross_zero)begin pi_acc <= pi_acc + {{16{nco_phase[15]}},nco_phase}; freq_ctrl <= FREQ_CTRL_INIT + pi_acc[20:5]; end end end //4. 同步采样脉冲:每N个NCO相位点触发一次采样 localparam SAMPLE_POINT_PER_CYC = 256; //每周256点同步采集 reg [7:0] sample_cnt; always@(posedge clk_adc or !rst_n)begin if(!rst_n)begin sample_cnt <= 8'd0; sync_sample_en <= 1'b0; phase_out <= 16'd0; end else begin phase_out <= nco_phase; sample_cnt <= sample_cnt + 1'b1; sync_sample_en <= (sample_cnt == SAMPLE_POINT_PER_CYC-1); if(sync_sample_en) sample_cnt <= 8'd0; end end endmodule

二、ADC 同步采集模块 adc_sync_sample.v

多路 ADC 在 DPLL 同步使能下并行采集,拼接成 32bit 采样帧送入异步 FIFO 跨域缓存

module adc_sync_sample( input clk_adc, input rst_n, input sync_sample_en, //DPLL同步触发 input signed [15:0] adc_ch1, input signed [15:0] adc_ch2, input signed [15:0] adc_ch3, output reg [63:0] sample_data, //4通道16bit打包 output reg fifo_wr_en ); always@(posedge clk_adc or !rst_n)begin if(!rst_n)begin sample_data <= 64'd0; fifo_wr_en <= 1'b0; end else begin fifo_wr_en <= sync_sample_en; if(sync_sample_en)begin sample_data <= {adc_ch1,adc_ch2,adc_ch3,16'd0}; end end end endmodule

三、异步 FIFO 跨时钟域桥 data_fifo_bridge.v

采集 10MHz 域 → DDR 100MHz 域,使用 Xilinx FIFO Generator IP,参数: 写宽 64bit,读宽 64bit,深度 1024;独立读写时钟、满空标志。 顶层封装接口:

module data_fifo_bridge( input wr_clk,wr_rst, input [63:0] din, input wr_en, output full, input rd_clk,rd_rst, output [63:0] dout, input rd_en, output empty ); //调用FIFO Generator IP fifo_async_64x1024 u_fifo( .wr_clk(wr_clk),.wr_rst(wr_rst), .din(din),.wr_en(wr_en),.full(full), .rd_clk(rd_clk),.rd_rst(rd_rst), .dout(dout),.rd_en(rd_en),.empty(empty) ); endmodule

四、DDR3 MIG 控制器封装 ddr3_mig_top.v

IP 配置要点(Xilinx 7 系列 XC7A35T 为例)

  1. DDR3 芯片:MT41J64M16-15
  2. MIG 参考时钟:200MHz 差分输入
  3. 用户接口时钟ui_clk= 100MHz
  4. 用户数据位宽APP_DATA_WIDTH=128bit,地址 32bit
  5. 封装统一读写接口,屏蔽 MIG 复杂握手信号
module ddr3_mig_top( input sys_clk_200m, input rst_n, //用户读写接口 100MHz ui_clk域 input ui_rst, input wr_req, input [27:0] wr_addr, input [127:0] wr_data, output reg wr_done, input rd_req, input [27:0] rd_addr, output reg [127:0] rd_data, output reg rd_done, //DDR3物理引脚 inout [15:0] ddr3_dq, inout [1:0] ddr3_dqs_n, inout [1:0] ddr3_dqs_p, output [13:0] ddr3_addr, output [2:0] ddr3_ba, output ddr3_ras_n, output ddr3_cas_n, output ddr3_we_n, output [0:0] ddr3_ck_p,ddr3_ck_n, output [0:0] ddr3_cke, output [0:0] ddr3_cs_n, output [1:0] ddr3_dm, output ddr3_odt ); //MIG IP例化 mig_7series_0 u_mig( .sys_clk_i(sys_clk_200m), .sys_rst_n(rst_n), .ui_clk(ui_clk), .ui_clk_sync_rst(ui_rst_mig), .mmcm_locked(mmcm_locked), .app_rdy(app_rdy), .app_en(app_en), .app_cmd(app_cmd), .app_addr(app_addr), .app_wdf_rdy(app_wdf_rdy), .app_wdf_wren(app_wdf_wren), .app_wdf_data(app_wdf_data), .app_wdf_end(app_wdf_end), .app_rd_data_valid(app_rd_data_valid), .app_rd_data(app_rd_data), //DDR物理引脚映射 .ddr3_dq(ddr3_dq),.ddr3_dqs_n(ddr3_dqs_n),.ddr3_dqs_p(ddr3_dqs_p), .ddr3_addr(ddr3_addr),.ddr3_ba(ddr3_ba),.ddr3_ras_n(ddr3_ras_n), .ddr3_cas_n(ddr3_cas_n),.ddr3_we_n(ddr3_we_n),.ddr3_ck_p(ddr3_ck_p), .ddr3_ck_n(ddr3_ck_n),.ddr3_cke(ddr3_cke),.ddr3_cs_n(ddr3_cs_n), .ddr3_dm(ddr3_dm),.ddr3_odt(ddr3_odt) ); //本地状态机:读写命令缓存、握手转换 localparam IDLE=2'b00,WRITE=2'b01,READ=2'b10; reg [1:0] state; reg [27:0] curr_addr; reg [127:0] curr_wdata; always@(posedge ui_clk or ui_rst)begin if(ui_rst)begin state <= IDLE; wr_done <= 1'b0; rd_done <=1'b0; end else begin case(state) IDLE:begin wr_done <= 1'b0; rd_done <=1'b0; if(wr_req)begin state <= WRITE; curr_addr <= wr_addr; curr_wdata <= wr_data; end else if(rd_req)begin state <= READ; curr_addr <= rd_addr; end end WRITE:begin //MIG写握手逻辑 if(app_rdy && app_wdf_rdy)begin wr_done <=1'b1; state <= IDLE; end end READ:begin if(app_rd_data_valid)begin rd_data <= app_rd_data; rd_done <=1'b1; state <= IDLE; end end endcase end end endmodule

五、DDR3 环形缓存控制器 ring_buffer_ctrl.v

工作机制

  1. 环形缓冲区划分整片 DDR 地址空间:总深度BUF_LEN=2^18(128K 点,适配工频多周期波形存储)
  2. 写指针wr_ptr:FIFO 有数据就连续写入 DDR,自动循环回绕
  3. 读指针rd_ptr:读取波形上传,跟随写指针,防止读超写
  4. 满判断:(wr_ptr - rd_ptr) > BUF_LEN - 1024触发缓存溢出保护,暂停采集写入
module ring_buffer_ctrl( input ui_clk,ui_rst, //FIFO读输入 input [63:0] fifo_rdata, input fifo_empty, output reg fifo_rd_en, //DDR用户接口 output reg ddr_wr_req, output reg [27:0] ddr_wr_addr, output reg [127:0] ddr_wr_data, input ddr_wr_done, output reg ddr_rd_req, output reg [27:0] ddr_rd_addr, input [127:0] ddr_rdata, input ddr_rd_done, //上传控制 input tx_start, //启动波形上传 output reg [63:0] tx_data, output reg tx_en ); localparam BUF_LEN = 18'h3FFFF; //环形缓存总长度 reg [17:0] wr_ptr,rd_ptr; reg [1:0] wr_state; reg [1:0] rd_state; reg [63:0] data_buf[1:0]; //拼接64bit×2 → DDR128bit //写逻辑:双64bit拼成128bit写入DDR always@(posedge ui_clk or ui_rst)begin if(ui_rst)begin wr_ptr <= 18'd0; wr_state <= 2'b00; fifo_rd_en <= 1'b0; ddr_wr_req <= 1'b0; end else begin case(wr_state) 2'b00:begin //取第一个64bit if(!fifo_empty)begin fifo_rd_en <=1'b1; wr_state <=2'b01; data_buf[0] <= fifo_rdata; end end 2'b01:begin //取第二个64bit fifo_rd_en <=1'b0; if(!fifo_empty)begin fifo_rd_en <=1'b1; wr_state <=2'b10; data_buf[1] <= fifo_rdata; end end 2'b10:begin //发起DDR写 fifo_rd_en <=1'b0; ddr_wr_req <=1'b1; ddr_wr_addr <= {9'd0,wr_ptr}; ddr_wr_data <= {data_buf[0],data_buf[1]}; wr_state <=2'b11; end 2'b11:begin //等待写完成,指针自增 ddr_wr_req <=1'b0; if(ddr_wr_done)begin wr_ptr <= wr_ptr + 1'b1; if(wr_ptr == BUF_LEN) wr_ptr <= 18'd0; wr_state <=2'b00; end end endcase end end //读逻辑:串口上传波形,拆分128bit为两路64bit输出 always@(posedge ui_clk or ui_rst)begin if(ui_rst)begin rd_ptr <=18'd0; rd_state <=2'b00; ddr_rd_req <=1'b0; tx_en <=1'b0; end else if(tx_start)begin case(rd_state) 2'b00:begin //发起读DDR ddr_rd_req <=1'b1; ddr_rd_addr <= {9'd0,rd_ptr}; rd_state <=2'b01; end 2'b01:begin ddr_rd_req <=1'b0; if(ddr_rd_done)begin tx_data <= ddr_rdata[127:64]; tx_en <=1'b1; rd_state <=2'b10; end end 2'b10:begin tx_en <=1'b0; tx_data <= ddr_rdata[63:0]; tx_en <=1'b1; rd_ptr <= rd_ptr +1'b1; if(rd_ptr == BUF_LEN) rd_ptr <=18'd0; rd_state <=2'b00; end endcase end end endmodule

六、顶层集成 top_acq_ddr3.v

所有模块互联,完整顶层连接逻辑

module top_acq_ddr3( input sys_clk_200m, input rst_n, input clk_adc, //10M ADC时钟 //ADC模拟输入采样 input signed [15:0] adc_ch1,adc_ch2,adc_ch3, //波形上传串口 output uart_tx, //DDR3物理引脚 inout [15:0] ddr3_dq, inout [1:0] ddr3_dqs_n,ddr3_dqs_p, output [13:0] ddr3_addr, output [2:0] ddr3_ba, output ddr3_ras_n,ddr3_cas_n,ddr3_we_n, output [0:0] ddr3_ck_p,ddr3_ck_n,ddr3_cke,ddr3_cs_n, output [1:0] ddr3_dm, output ddr3_odt ); //内部信号定义 wire sync_sample_en; wire [15:0] vin_phase; wire [63:0] adc_sample_data; wire fifo_wr_en,fifo_full,fifo_empty; wire [63:0] fifo_rdata; wire ui_clk,ui_rst; wire ddr_wr_req,ddr_wr_done,ddr_rd_req,ddr_rd_done; wire [27:0] ddr_wr_addr,ddr_rd_addr; wire [127:0] ddr_wr_data,ddr_rdata; wire [63:0] tx_data; wire tx_en; //1.工频DPLL同步 dpll_50hz u_dpll( .clk_adc(clk_adc),.rst_n(rst_n), .vin_adc(adc_ch1), //电压通道做同步参考 .sync_sample_en(sync_sample_en),.phase_out(vin_phase) ); //2.ADC同步采集打包 adc_sync_sample u_adc_acq( .clk_adc(clk_adc),.rst_n(rst_n), .sync_sample_en(sync_sample_en), .adc_ch1(adc_ch1),.adc_ch2(adc_ch2),.adc_ch3(adc_ch3), .sample_data(adc_sample_data),.fifo_wr_en(fifo_wr_en) ); //3.异步FIFO跨时钟域 data_fifo_bridge u_fifo_bridge( .wr_clk(clk_adc),.wr_rst(!rst_n), .din(adc_sample_data),.wr_en(fifo_wr_en),.full(fifo_full), .rd_clk(ui_clk),.rd_rst(ui_rst), .dout(fifo_rdata),.rd_en(fifo_rd_en),.empty(fifo_empty) ); //4.DDR3 MIG控制器 ddr3_mig_top u_ddr3( .sys_clk_200m(sys_clk_200m),.rst_n(rst_n), .ui_clk(ui_clk),.ui_rst(ui_rst), .wr_req(ddr_wr_req),.wr_addr(ddr_wr_addr),.wr_data(ddr_wr_data),.wr_done(ddr_wr_done), .rd_req(ddr_rd_req),.rd_addr(ddr_rd_addr),.rd_data(ddr_rdata),.rd_done(ddr_rd_done), .ddr3_dq(ddr3_dq),.ddr3_dqs_n(ddr3_dqs_n),.ddr3_dqs_p(ddr3_dqs_p), .ddr3_addr(ddr3_addr),.ddr3_ba(ddr3_ba),.ddr3_ras_n(ddr3_ras_n), .ddr3_cas_n(ddr3_cas_n),.ddr3_we_n(ddr3_we_n),.ddr3_ck_p(ddr3_ck_p), .ddr3_ck_n(ddr3_ck_n),.ddr3_cke(ddr3_cke),.ddr3_cs_n(ddr3_cs_n), .ddr3_dm(ddr3_dm),.ddr3_odt(ddr3_odt) ); //5.环形缓存控制 ring_buffer_ctrl u_ring_buf( .ui_clk(ui_clk),.ui_rst(ui_rst), .fifo_rdata(fifo_rdata),.fifo_empty(fifo_empty),.fifo_rd_en(fifo_rd_en), .ddr_wr_req(ddr_wr_req),.ddr_wr_addr(ddr_wr_addr),.ddr_wr_data(ddr_wr_data),.ddr_wr_done(ddr_wr_done), .ddr_rd_req(ddr_rd_req),.ddr_rd_addr(ddr_rd_addr),.ddr_rdata(ddr_rdata),.ddr_rd_done(ddr_rd_done), .tx_start(1'b1), //持续上传波形,可改外部指令控制 .tx_data(tx_data),.tx_en(tx_en) ); //6.UART波形输出 uart_tx u_uart( .clk(ui_clk),.rst_n(!ui_rst), .tx_data(tx_data),.tx_en(tx_en),.tx(uart_tx) ); endmodule

七、关键工程配置与优化说明

1. DDR 带宽匹配计算

  • 工频每周 256 点,3 通道 16bit = 768Byte / 周期
  • 50Hz → 每秒数据量:50 × 768 = 38400 Byte/s
  • DDR3 100MHz 用户域 128bit 带宽:1.6GB/s,带宽冗余极大,无吞吐压力

2. 同步采集核心优势

DPLL 锁定电网相位,消除采样异步误差,用于谐波分析、电能质量检测;环形 DDR 缓存可连续存储多秒工频波形,支持故障录波。

3. 时序与稳定性优化

  1. 采集与 DDR 跨域必须异步 FIFO 隔离,禁止直接打拍传递大量数据;
  2. DDR 读写状态机单周期握手,避免多周期组合逻辑造成时序违例;
  3. 环形缓存增加水位阈值,缓存快满时暂停 ADC 写入,防止数据丢失;
  4. MIG IP 输出ui_clk做全局时钟布线,减少 DDR 域时序余量损耗。

4. 扩展升级方向

  1. 替换 UART 为千兆以太网 TCP/IP,高速波形上传;
  2. 增加 FFT 运算单元,DDR 读取波形实时谐波计算;
  3. 双 DDR 分区:一区缓存实时采集,二区读取上传,乒乓操作无中断录波;
  4. 增加触发逻辑(过流 / 过压故障触发定点存储波形)。

八、适配芯片与资源预估(XC7A35T)

  1. LUT:约 18000,FF:22000
  2. Block RAM:FIFO 占用 2 个 36K BRAM
  3. MIG DDR3 IP 占用 2 个 MMCM、16 个 IOB、PHY 资源
  4. DSP48E:DPLL PI 滤波、相位运算占用 8 个 DSP
http://www.jsqmd.com/news/1128471/

相关文章:

  • RectTransform:为 UI 而生的那副骨架
  • Flask 后端时间处理 3 大实战场景:datetime、字符串与SQL查询参数转换
  • Eclipse Ditto 物模型搭建
  • Claude Code 会话分支,给探索留一条安全岔路
  • 基于 Spring Boot + Hyperledger Fabric 的数字版权交易与链上存证系统
  • 《龙之家族第三季》 美剧|在线观看|夸克|下载|第一集
  • langchain 内置中间件详解 -HumanInTheLoopMiddleware — 人工审批
  • 专业指南:如何让你的老款Mac电脑免费升级到最新macOS系统
  • 大模型量化部署:从 INT8 到 4-bit 的工程演进
  • Postman+Jenkins接口测试持续集成实战:从零搭建自动化流水线
  • OpenWrt SSH双因素认证配置指南:TOTP与备用端口方案
  • 奇迹 MU 剑与翼手游官网下载:奇迹 MU 剑与翼最新官方下载渠道
  • 仲景中医AI模型:3步快速部署你的智能辨证论治助手
  • 三步解锁网盘极速下载:智能解析工具全攻略
  • 红外光伏板缺陷检测 光伏数据集 AI红外光伏板识别 训练模型
  • Transformer的核心——注意力机制
  • 泳池设备品牌哪家好
  • 基于MATLAB图像处理的药片检测与计数系统设计与实现
  • 【OpenCV】 Haar级联分类器实现静态图片人脸检测(附完整代码)
  • 如何用m4s-converter将B站缓存视频永久保存为MP4格式?
  • 暗黑破坏神2存档编辑器:5分钟掌握免费可视化修改工具
  • 抖店微信小店流量核心打法:标题优化、主图整改、质量分提升全套步骤
  • SSTI(第六周)
  • 3分钟上手NSC_BUILDER:Switch游戏文件管理的终极解决方案
  • Self-XSS攻击深度解析:从社交工程陷阱到纵深防御实践
  • 【Python工程化实战】Feature Flag 工程化:Unleash / LaunchDarkly 在 Python 服务中的集成实战
  • OpenDog V3:开源四足机器人的分布式运动控制架构解析与实践指南
  • bpg反射器机联邦作业
  • 用Python写爬虫的常见陷阱与避坑指南
  • 出口退税单据自查7步:四单一致、收汇核销、函调备查怎么做