从零构建Basys3示波器:FPGA开发实战指南
1. 项目概述与硬件准备
在电子测量领域,示波器是不可或缺的基础工具。传统商用示波器价格昂贵且功能固定,而基于FPGA的自制示波器不仅能大幅降低成本,还能根据需求灵活定制功能。Basys3开发板搭载Xilinx Artix-7 FPGA(型号xc7a35tftg256),内置12位1MSPS的XADC模块,是构建数字示波器的理想平台。
核心硬件组件清单:
- Digilent Basys3开发板(主控芯片:xc7a35tftg256)
- Micro-USB数据线(用于供电和程序烧录)
- 示波器探头(建议带宽≥20MHz)
- 信号发生器(用于测试验证)
- VGA显示器(640×480分辨率)
开发环境需要安装Vivado设计套件(推荐2017.4或更新版本),其内置的IP核管理器可快速调用XADC、Block Memory等关键模块。Basys3的XADC接口直接连接至JXADC端口,支持±12V输入范围,通过板载分压网络适配0-3.3V的FPGA输入要求。
2. Vivado工程搭建与IP核配置
2.1 新建工程与约束文件
在Vivado中创建RTL项目,选择Basys3的xc7a35t芯片型号。关键约束文件需明确定义时钟、XADC接口和VGA输出:
# 主时钟约束(100MHz) create_clock -period 10.000 [get_ports clk] # XADC接口定义 set_property PACKAGE_PIN J3 [get_ports vauxp6] set_property IOSTANDARD LVCMOS33 [get_ports vauxp6] # VGA输出引脚定义 set_property PACKAGE_PIN A3 [get_ports {vga_red[3]}] set_property IOSTARDARD LVCMOS33 [get_ports {vga_red[3]}] ...2.2 关键IP核调用
通过Vivado的IP Catalog添加以下核心模块:
- XADC Wizard:配置为连续采样模式,启用通道6(VP/VN),设置采样率1MSPS
- Block Memory Generator:创建双端口RAM(1024×8bit),存储波形数据
- Clock Wizard:生成所需的71.428MHz VGA像素时钟
- Fast Fourier Transform (FFT):配置为256点流水线架构,实现频谱分析
XADC参数配置示例:
xadc_wiz_0 xadc_inst ( .daddr_in(8'h16), // 通道6地址 .dclk_in(clk_100m), .den_in(1'b1), .di_in(16'h0), .do_out(adc_data), .drdy_out(adc_ready), .vp_in(1'b0), .vn_in(1'b0) );3. 核心逻辑设计
3.1 信号采集与触发系统
触发电路是示波器的关键,采用边沿触发设计,支持触发电平可调(0-3.3V)。Verilog实现代码核心部分:
always @(posedge adc_clk) begin // 触发电平比较 if (adc_data > trigger_level) current_state <= 1'b1; else current_state <= 1'b0; // 边沿检测 trigger_edge <= current_state & ~last_state; last_state <= current_state; // 触发后开始采集 if (trigger_edge && !capturing) capturing <= 1'b1; end触发模式对比表:
| 触发类型 | 灵敏度 | 适用场景 | Verilog实现难度 |
|---|---|---|---|
| 上升沿 | ±5mV | 数字信号 | ★★☆ |
| 下降沿 | ±5mV | 脉冲分析 | ★★☆ |
| 窗口触发 | ±10mV | 复杂波形 | ★★★★ |
| 自动触发 | N/A | 连续扫描 | ★☆☆ |
3.2 波形存储与处理
采用乒乓缓冲技术实现无缝采集,双BRAM交替工作:当一块存储实时数据时,另一块供显示模块读取。关键设计要点:
- 存储深度:1024点(对应X轴分辨率)
- 数据格式:8位无符号数(0-255对应0-3.3V)
- 采样率控制:通过时钟分频实现1kSPS-1MSPS可调
// 乒乓缓冲控制逻辑 always @(posedge sys_clk) begin if (wr_full) begin wr_bank <= ~wr_bank; wr_ptr <= 0; end else if (adc_ready) begin if (wr_bank) bram_b[wr_ptr] <= adc_data[15:8]; else aram_a[wr_ptr] <= adc_data[15:8]; wr_ptr <= wr_ptr + 1; end end4. 显示系统实现
4.1 VGA控制器设计
采用640×480@60Hz标准时序,将屏幕分为波形显示区(上部2/3)和参数显示区(下部1/3)。时序生成模块需严格遵循:
Horizontal Timing (单位:像素) Active Video: 640 | Front Porch: 16 | Sync Pulse: 96 | Back Porch: 48 | Total: 800 Vertical Timing (单位:行) Active Video: 480 | Front Porch: 10 | Sync Pulse: 2 | Back Porch: 33 | Total: 525RGB信号生成逻辑:
assign vga_r = (v_active && h_active) ? (grid_en ? 8'hFF : wave_r) : 8'h00; assign vga_g = (v_active && h_active) ? (grid_en ? 8'hFF : wave_g) : 8'h00; assign vga_b = (v_active && h_active) ? (grid_en ? 8'hFF : wave_b) : 8'h00;4.2 用户界面设计
通过Basys3的4×4矩阵键盘实现交互控制,功能分配如下:
| 按键 | 功能 | 长按功能 |
|---|---|---|
| 1 | 通道选择 | 自动缩放 |
| 2 | 水平缩放 | 复位时基 |
| 3 | 垂直缩放 | 复位幅度 |
| 4 | 触发模式切换 | 强制触发 |
数码管显示当前采样率(如"50.0k"表示50kHz),采用科学计数法显示超过显示范围的数值(如"1.2M")。
5. 高级功能实现
5.1 频谱分析模块
利用FFT IP核实现实时频谱分析,关键参数配置:
- 点数:256
- 数据格式:Q1.15定点数
- 窗函数:Hanning窗(降低频谱泄漏)
fft_0 fft_inst ( .aclk(clk_100m), .s_axis_config_tdata(8'h01), // FWD变换 .s_axis_config_tvalid(1'b1), .s_axis_data_tdata({adc_data, 4'b0}), // 12->16位扩展 .s_axis_data_tvalid(fft_en), .m_axis_data_tdata(fft_out), .m_axis_data_tvalid(fft_ready) );5.2 自动测量功能
在参数显示区实时计算并显示:
- 频率:通过过零检测算法
- 峰峰值:最大值-最小值
- 有效值:RMS计算
- 占空比(仅方波)
频率计算Verilog实现:
always @(posedge adc_clk) begin if (adc_data > mid_level && last_sample <= mid_level) period <= cycle_counter; cycle_counter <= 0; else cycle_counter <= cycle_counter + 1; last_sample <= adc_data; frequency <= 100000000 / (period * 10); // 转换为Hz end6. 调试与优化技巧
- ILA调试:插入Integrated Logic Analyzer,监控关键信号如触发脉冲、ADC数据
- 时序约束:对跨时钟域信号添加set_false_path约束
- 资源优化:使用DSP48E1单元实现乘法运算,节省LUT资源
- 噪声抑制:在ADC输入前添加RC低通滤波(fc=1MHz)
实际测试中发现,当采样率超过500kSPS时,建议关闭数码管扫描以减少干扰。在布局布线阶段,手动将XADC相关逻辑布局在芯片右下角(靠近JXADC接口)。