1. 从零搭建HPS硬件系统的必要性
在SOC FPGA开发中,使用GHRD(Golden Hardware Reference Design)模板确实能够快速启动项目,但现实开发中我们经常会遇到需要完全自定义硬件系统的场景。比如最近我在做一个工业控制项目,客户要求使用特定型号的DDR3内存,并且需要精简掉模板中不必要的组件,这时候就必须从零开始搭建HPS系统。
Platform Designer(原Qsys)是Intel/Altera提供的一个强大的系统集成工具,它允许我们像搭积木一样构建完整的SOC系统。与直接使用GHRD相比,手动搭建HPS系统主要有三个优势:首先是资源利用率更高,可以只添加项目必需的组件;其次是配置更灵活,每个参数都可以根据实际硬件调整;最后是学习曲线更完整,能深入理解HPS与FPGA的交互机制。
我建议在以下情况选择从零搭建:
- 开发板内存型号与模板不同
- 需要定制外设接口配置
- 项目对资源占用有严格要求
- 需要特殊时钟配置方案
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 创建基础工程与添加HPS组件
2.1 工程初始化
首先打开Quartus Prime,创建一个新工程。这里有个小技巧:工程路径最好不要包含中文或空格,我遇到过因为路径问题导致后续工具链报错的坑。选择正确的器件型号非常关键,比如Cyclone V SoC 5CSXFC6D6F31C6NES。
创建完成后,通过Tools->Platform Designer打开系统设计工具。在IP Catalog中搜索"Hard Processor System",双击添加到当前系统。这时候你会看到一个红色的HPS模块出现在工作区,这表示它还没有进行任何配置。
2.2 HPS基础配置
右键点击HPS模块选择Edit,进入配置界面。第一个要注意的是Boot选项:
- Boot from FPGA:决定HPS是否从FPGA配置
- Boot ROM write protection:根据安全需求设置
在FPGA Interfaces标签页中,General部分的配置会影响HPS暴露给FPGA的接口类型。比如:
- Enable MPU standby and event signals:需要低功耗设计时启用
- Enable debug APB interface:调试阶段建议打开
这里我通常会启用所有调试接口,等系统稳定后再根据需要禁用,毕竟硬件重构比软件修改成本高得多。
3. FPGA接口深度配置
3.1 AXI桥接配置
AXI桥是HPS与FPGA通信的核心通道,配置不当会导致性能瓶颈。在AXI Bridge标签页中:
- FPGA-to-HPS interface width:根据带宽需求选择
32bit适合控制信号,128bit适合视频流等大数据量传输 - HPS-to-FPGA interface width:同上原则
- Lightweight HPS-to-FPGA interface:适合小数据量控制
实际项目中,我一般会把主数据通道设为128bit,控制通道保持32bit。曾经有个图像处理项目,因为AXI位宽设错导致帧率只有预期的一半,排查了好久才发现是这个配置问题。
3.2 SDRAM接口配置
FPGA-to-HPS SDRAM Interface允许FPGA直接访问HPS的内存,这对数据共享非常重要。配置时需要注意:
- 接口数量:根据并发访问需求设置
- 数据宽度:匹配FPGA处理位宽
- 接口类型:AXI-3或Avalon-MM
这里有个性能优化技巧:如果FPGA需要频繁访问内存区域,可以专门分配一个独立的SDRAM接口,避免与其他主设备冲突。
3.3 中断与DMA配置
在Interrupts标签页中,使能FPGA-to-HPS Interrupts后,可以配置多达64个中断信号。对于实时性要求高的外设,建议分配独立的中断号。
DMA Peripheral Request部分可以启用硬件DMA通道。一个常见的误区是以为启用越多越好,实际上每个启用的DMA通道都会占用HPS资源。我的经验法则是:只启用实际使用的通道,其他保持禁用。
4. 引脚复用与时钟系统
4.1 外设引脚复用
Peripheral Pin Multiplexing可能是最容易出错的部分。这里需要根据实际硬件连接来配置每个外设的引脚分配。几个关键点:
- EMAC:注意PHY芯片的接口类型(RGMII/GMII)
- SD/MMC:根据卡槽类型选择数据线宽度
- UART:确认使用哪组TX/RX引脚
我曾经遇到过一个坑:开发板的USB转串口用的是HPS_UART1,但默认配置是HPS_UART0,导致怎么也收不到数据。所以一定要对照开发板原理图检查每个外设的引脚分配。
4.2 时钟系统配置
HPS时钟系统相当复杂,包含多个PLL和时钟域。在HPS Clocks标签页中:
Input Clocks部分:
- 设置外部振荡器频率
- 配置FPGA-to-HPS参考时钟
Output Clocks部分:
- 主PLL输出时钟
- 外设PLL输出时钟
- HPS-to-FPGA用户时钟
时钟配置的黄金法则是:先确定各个外设的时钟需求,然后反向推导PLL配置。比如:
- EMMC需要200MHz
- UART需要92.16MHz
- SPI需要50MHz
5. SDRAM子系统配置
5.1 物理层设置
PHY Settings是确保内存稳定工作的关键。主要参数包括:
- Memory clock frequency:根据内存芯片规格设置
- Supply voltage:匹配实际硬件电压
- Termination impedance:根据板级设计设置
我曾经调试过一个DDR3不稳定问题,最后发现是termination设置不对。建议先用Altera的默认设置,如果发现问题再根据内存芯片手册调整。
5.2 内存参数配置
Memory Parameters需要严格遵循内存芯片手册:
- CAS Latency
- tRCD/tRP/tRAS等时序参数
- Bank/Row/Column地址宽度
这里有个实用技巧:可以先用Auto Configuration生成初始值,然后手动微调。记得保存不同配置的版本,方便出现问题后回退。
5.3 板级设置
Board Settings补偿板级信号完整性影响:
- Setup/Hold Derating
- Intersymbol Interference
- Board Skews
对于开发板,通常可以使用默认设置。如果是自定义板卡,建议通过信号完整性仿真获取准确参数。
6. 添加FPGA侧组件
6.1 基本组件集成
完成HPS配置后,需要添加FPGA侧的配套组件:
- On-chip Memory:用于数据缓冲
- JTAG to Avalon Master:调试接口
- System ID:系统识别
- PIO:LED、按键等简单外设
添加组件时要注意总线位宽匹配。比如On-chip Memory的数据位宽应该与连接的AXI总线一致,否则Platform Designer会自动插入位宽转换逻辑,增加资源消耗。
6.2 自定义组件开发
对于特殊需求,可以开发自定义组件。比如下面这个中断捕获器的Verilog代码:
verilog复制module intr_capturer #(
parameter NUM_INTR = 32
)(
input clk,
input rst_n,
input [NUM_INTR-1:0] interrupt_in,
input addr,
input read,
output [31:0] rddata
);
// 实现代码...
endmodule
在Platform Designer中创建新组件时,要注意正确设置Avalon-MM接口信号,特别是waitrequest和readdatavalid这类流控信号,否则会导致总线死锁。
7. 系统集成与地址分配
7.1 组件互联
将所有组件连接到HPS的AXI总线时,Platform Designer会自动插入AXI-Avalon桥接器。对于性能敏感路径,建议:
- 使用独立的AXI总线
- 调整仲裁优先级
- 合理设置burst传输参数
我曾经优化过一个视频处理系统,通过调整AXI总线优先级,将处理延迟降低了30%。
7.2 地址分配
系统会自动分配基地址,但手动调整可以优化内存布局:
- 常用外设分配到低地址空间
- 大块内存对齐到1MB边界
- 保留地址空间用于未来扩展
特别要注意HPS外设的地址空间不能与FPGA侧外设冲突。
8. 生成系统与硬件编译
8.1 系统生成
点击Generate按钮后,Platform Designer会:
- 生成HDL代码
- 创建SDC时序约束
- 生成软件开发所需的头文件
- 产生引脚分配Tcl脚本
生成过程中要特别注意警告信息,比如时钟交叉域或地址重叠等问题。
8.2 Quartus工程集成
将生成的系统集成到Quartus工程:
- 添加.qip文件
- 创建顶层模块实例化系统
- 连接时钟和复位信号
- 分配FPGA侧引脚
一个常见的错误是忘记连接hps_0_h2f_reset信号,导致HPS无法正确初始化。
8.3 编译与下载
全编译前建议:
- 运行Pin Planner检查引脚分配
- 检查时序约束是否完整
- 设置适当的编译优化策略
编译成功后,将.sof文件下载到开发板。第一次启动建议通过JTAG调试,确认所有组件正常工作后再烧写固化。
9. 硬件调试技巧
9.1 System Console调试
System Console是强大的硬件调试工具,可以通过Tcl命令:
- 读写内存映射寄存器
- 监控中断信号
- 测试DMA传输
例如读取PIO状态的命令:
tcl复制master_read_32 $hps_master 0x10000040 1
9.2 信号抓取
对于复杂问题,可以使用Signal Tap逻辑分析仪:
- 抓取AXI总线信号
- 监控中断触发时序
- 分析DMA传输过程
配置Signal Tap时要注意采样深度和时钟的选择,确保能捕获完整的调试信息。
10. 常见问题排查
10.1 HPS无法启动
- 检查复位信号是否正确连接
- 确认boot选项配置正确
- 验证时钟信号质量
10.2 内存访问异常
- 检查SDRAM参数设置
- 验证PHY校准结果
- 测量内存信号完整性
10.3 外设不工作
- 确认引脚复用配置正确
- 检查时钟是否使能
- 验证寄存器访问权限
记得保存每个调试阶段的配置和结果,建立完整的调试日志。
