资讯动态

DE1-SoC 硬件原理图与开发手册:从引脚约束到 HPS-FPGA 桥接的实战拆解

发布时间:2026/10/17 10:28:42 来源:尧图企业网站定制
简介DE1-Soc硬件原理图及开发手册面向使用DE1-Soc开发板的嵌入式工程师与学习者聚焦ARMFPGA异构平台的硬件认知与开发入门。手册从开发套件包装清单、系统光盘使用与帮助获取讲起逐步深入到开发板布局、组件与块图帮助读者理解处理器、内存与外设的连接关系随后重点讲解FPGA配置模式设置、Cyclone V SoC FPGA配置方法以及LED、按键、开关、复位、时钟电路和GPIO扩展、音频编解码、VGA、TV解码、红外收发等外围接口的使用。资源包为1个PDF文件约7.1MB内容完整、结构清晰适合作为案头速查与系统学习资料。目前已有1318人学习下载无论是搭建实验环境、查阅原理图细节还是开展嵌入式项目设计都能从中获得扎实的硬件参考与操作指引。1. DE1-SoC 硬件原理图与开发手册从引脚到外设一份能直接上手的拆解路径拿到一块 DE1-SoC 开发板很多人第一反应是插上电源、连上 USB Blaster然后打开 Quartus 跑一个点灯工程。灯亮了觉得“跑通了”但一旦要接一个自定义外设、改一个时钟频率、或者把 HPS 和 FPGA 之间的数据通路调通就发现完全不知道从哪下手。问题不在工具在于没有把硬件原理图和开发手册这两份文档真正读进去。DE1-SoC 的硬件原理图告诉你每个引脚连到哪里、每个电源域怎么分配、每个外设的地址映射是什么开发手册则告诉你这些资源怎么用、时序怎么约束、HPS 和 FPGA 怎么协同。这两份文档合在一起才是这块板子的完整“黑匣子说明书”。这篇文章面向的是已经拿到板子、准备做实际项目的开发者不管你是要做一个视频采集系统、一个电机控制回路还是一个 HPSFPGA 异构计算的原型读完之后你应该能自己从原理图里找到关键约束从手册里找到配置方法而不是每次遇到问题就去翻论坛碰运气。2. 从原理图里读出引脚约束与电源域选型前必须确认的三件事2.1 引脚分配不是查表是理解 Bank 和 I/O 标准DE1-SoC 的 FPGA 是 Cyclone V SE 系列引脚按 Bank 分组每个 Bank 有独立的 I/O 电压标准。原理图上每个连接器、每个外设的引脚都会标注它属于哪个 Bank、参考电压是多少。很多人做引脚约束时直接抄别人的 .qsf 文件结果发现某个 GPIO 怎么都驱动不起来或者电平不对。常见原因是那个引脚所在的 Bank 的 VCCIO 电压和你的外设不匹配。比如你接一个 3.3V 的传感器但那个 Bank 的 VCCIO 被板上的跳线设成了 2.5V那输入阈值就不对读回来全是随机值。我一般会先做一件事把原理图里所有用到的 Bank 的 VCCIO 供电来源找出来。DE1-SoC 上有些 Bank 的 VCCIO 是固定 3.3V有些是通过跳线选择 3.3V 或 2.5V还有些是直接由 FPGA 的 1.1V 核心电压供电只能做低速信号。这个信息在原理图的电源部分和 FPGA 的 Bank 引脚标注里都能找到。确认之后再去看你要用的外设引脚落在哪个 Bank然后决定是否需要改跳线或者加电平转换。下面是一个典型的引脚约束片段展示如何在 .qsf 里指定引脚位置和 I/O 标准# 假设我们要把 LED0 分配到 PIN_A15属于 Bank 3BVCCIO3.3V set_location_assignment PIN_A15 -to led[0] # 指定 I/O 标准为 3.3V LVTTL注意必须和 Bank 的 VCCIO 一致 set_instance_assignment -name IO_STANDARD 3.3-V LVTTL -to led[0] # 如果是差分信号还需要指定负端引脚 # set_location_assignment PIN_A16 -to led_diff_n[0] # set_instance_assignment -name IO_STANDARD LVDS -to led_diff[0]这段约束的逻辑是先确定物理引脚编号再确定电气标准。参数说明PIN_A15是原理图上标注的 FPGA 引脚号不是开发板丝印上的编号IO_STANDARD必须和该 Bank 的 VCCIO 电压一致否则 Quartus 在编译时会报错或者警告但有时候只是警告下载后行为异常这就是坑。如果你不确定某个引脚属于哪个 Bank可以在 Quartus 的 Pin Planner 里看或者直接翻原理图的 FPGA 页每个引脚旁边都有 Bank 编号。2.2 时钟网络别把普通 I/O 当全局时钟用DE1-SoC 上有多个时钟源50MHz 晶振、24MHz 晶振、以及从 HPS 过来的时钟。原理图上会标明哪些引脚是专用时钟输入引脚CLKIN哪些是普通 I/O。专用时钟引脚连接到 FPGA 的全局时钟网络抖动小、偏斜小适合做系统主时钟。如果你把一个普通 I/O 引脚配置成时钟输入Quartus 会把它布到局部时钟网络上导致时序很难收敛或者在不同温度下行为不一致。我见过一个案例某开发者用普通 I/O 接了一个外部 25MHz 有源晶振做视频像素时钟结果图像偶尔出现撕裂。后来查原理图发现那个引脚虽然物理上靠近 CLKIN但并不是专用时钟引脚走的是局部布线偏斜太大。换成专用 CLKIN 引脚后问题消失。所以选型阶段就要确认你的外部时钟源必须接到专用时钟引脚上。DE1-SoC 的专用时钟引脚在原理图上会标注为CLKIN_*或者FPGA_CLK_*一般分布在 Bank 的特定位置。2.3 HPS 侧的外设地址映射别在 FPGA 里重复造轮子DE1-SoC 的 HPS 侧有千兆以太网、USB、SD 卡、UART 等外设这些在原理图上都有明确的引脚连接和地址映射。很多初学者会在 FPGA 里用软核实现一个 UART 或者 SPI然后通过 PIO 和 HPS 通信绕了一大圈。其实 HPS 本身就有这些外设直接通过 Linux 驱动就能用。原理图的作用是告诉你HPS 的哪些引脚已经固定连接到了板载外设你不需要在 FPGA 侧再分配引脚。比如 HPS 的 UART0 已经连接到板上的 USB-UART 芯片你在 Linux 里直接操作/dev/ttyS0就能收发数据。如果你非要在 FPGA 里再做一个 UART那就需要占用额外的引脚而且还要写 Avalon-MM 接口和 HPS 通信复杂度高很多。所以第一步应该是把原理图上 HPS 侧的外设连接关系理清楚能用 HPS 原生外设的就不要用 FPGA 模拟。下面是一个在 Linux 下查看 HPS 外设地址映射的常用命令可以帮助你确认哪些外设已经可用# 查看 HPS 的 UART 设备 ls /dev/ttyS* # 查看 I2C 总线 i2cdetect -l # 查看 GPIO 映射 cat /sys/kernel/debug/gpio # 查看 HPS 外设的物理地址映射需要 root cat /proc/iomem | grep -E ff2|ffc这些命令的输出能帮你快速判断 HPS 侧的资源占用情况。参数说明/proc/iomem里的地址范围对应 HPS 的寄存器映射ff2xxxxx一般是外设控制器ffcxxxxx是系统管理器。如果你在 FPGA 侧要访问 HPS 的内存需要用到 FPGA-to-HPS 桥或者 HPS-to-FPGA 桥这些桥的地址窗口在开发手册里有详细说明。3. 开发手册里的时序约束与 HPS-FPGA 桥接从手册到可运行工程3.1 时序约束不是可选项是必选项Cyclone V 的时序模型在开发手册里有详细描述包括建立时间、保持时间、时钟到输出延迟等。很多人做 FPGA 设计时只写功能代码不写 SDC 约束Quartus 默认会按一个很宽松的时钟模型去布局布线结果功能仿真通过上板就挂。DE1-SoC 的开发手册里给出了推荐的 SDC 模板包括主时钟定义、输入输出延迟、虚假路径等。我一般会先根据原理图确定所有时钟源的频率和引脚然后在 SDC 里逐个定义。比如 50MHz 主时钟# 定义 50MHz 主时钟周期 20ns create_clock -name clk_50 -period 20.000 [get_ports {CLOCK_50}] # 定义衍生时钟比如通过 PLL 产生的 100MHz derive_pll_clocks # 定义输入延迟假设外部器件在时钟上升沿后 5ns 输出数据 set_input_delay -clock clk_50 -max 5.000 [get_ports {data_in[*]}] set_input_delay -clock clk_50 -min 2.000 [get_ports {data_in[*]}] # 定义输出延迟 set_output_delay -clock clk_50 -max 3.000 [get_ports {data_out[*]}] # 设置异步路径为虚假路径 set_false_path -from [get_ports {reset_n}]这段 SDC 的逻辑是先定义时钟再定义输入输出延迟最后处理异步信号。参数说明-period 20.000对应 50MHz单位是纳秒set_input_delay的 max/min 值需要根据外部器件的时序手册来定不能随便写。如果你不确定外部器件的时序保守做法是设一个较大的值让工具去满足但这样可能会浪费面积。开发手册里通常会给出常见外设的推荐值比如 SDRAM 的输入输出延迟。3.2 HPS-FPGA 桥接地址窗口和带宽要匹配DE1-SoC 的 HPS 和 FPGA 之间有三组桥FPGA-to-HPS、HPS-to-FPGA、轻量级 HPS-to-FPGA。开发手册里会给出每组桥的地址范围、数据位宽和最大频率。很多人做异构计算时把大量数据从 HPS 搬到 FPGA结果带宽不够成了瓶颈。比如你用 HPS 的 DDR 存图像然后通过 HPS-to-FPGA 桥搬到 FPGA 做处理如果桥的位宽是 32 位、频率 100MHz理论带宽 400MB/s实际可能只有一半。如果图像是 1080p60fps每帧 3MB每秒 180MB看起来够但加上读写开销和仲裁延迟可能就卡了。我一般会先算一下数据吞吐量再决定用哪组桥。轻量级桥适合寄存器配置带宽小但延迟低全功能桥适合大数据搬运。开发手册里有每座桥的时序图可以帮你估算实际带宽。另外HPS 侧的 DMA 控制器可以直接和 FPGA 桥对接减少 CPU 干预这个在手册的 DMA 章节有说明。下面是一个在 Linux 下通过 mmap 访问 FPGA 侧寄存器的例子用的是轻量级桥#include stdio.h #include stdlib.h #include fcntl.h #include sys/mman.h #include unistd.h #define LW_BRIDGE_BASE 0xFF200000 // 轻量级桥基地址参考开发手册 #define LW_BRIDGE_SPAN 0x00200000 // 映射窗口大小 int main() { int fd open(/dev/mem, O_RDWR | O_SYNC); if (fd 0) { perror(open); return -1; } // 映射轻量级桥地址空间 void *base mmap(NULL, LW_BRIDGE_SPAN, PROT_READ | PROT_WRITE, MAP_SHARED, fd, LW_BRIDGE_BASE); if (base MAP_FAILED) { perror(mmap); close(fd); return -1; } // 假设 FPGA 侧有一个 32 位寄存器在偏移 0x100 处 volatile unsigned int *reg (unsigned int *)(base 0x100); // 写数据 *reg 0xDEADBEEF; // 读回验证 unsigned int val *reg; printf(Read back: 0x%08X\n, val); munmap(base, LW_BRIDGE_SPAN); close(fd); return 0; }这段代码的逻辑是打开/dev/mem用 mmap 把轻量级桥的物理地址映射到用户空间然后直接读写。参数说明LW_BRIDGE_BASE是 0xFF200000这是 Cyclone V 的轻量级桥基地址开发手册里有LW_BRIDGE_SPAN是映射窗口大小一般 2MB 够用。注意/dev/mem需要 root 权限而且如果内核配置了 STRICT_DEVMEM可能会限制访问范围。更安全的做法是写一个内核驱动但调试阶段用 mmap 最快。3.3 从手册到工程一个最小可运行系统的搭建步骤把原理图和手册的知识串起来搭建一个最小系统FPGA 侧做一个 PWM 控制器HPS 侧通过轻量级桥配置 PWM 频率和占空比然后驱动一个 LED 或者电机。步骤如下第一步在原理图上找到 LED 或电机驱动接口的引脚确认 Bank 和 I/O 标准。第二步在 Quartus 里创建工程分配引脚写 PWM 的 Verilog 代码。第三步在 Qsys 里添加 HPS 和轻量级桥把 PWM 寄存器映射到桥的地址空间。第四步生成设备树和头文件在 Linux 里用 mmap 访问。第五步写一个简单的测试程序改变占空比观察 LED 亮度或电机转速。这个流程里最容易翻车的地方是地址对齐。轻量级桥的寄存器必须是 32 位对齐如果你在 Qsys 里分配的偏移不是 4 的倍数访问会出错。另外设备树里的reg属性要和 Qsys 里分配的地址一致否则 mmap 的偏移对不上。我一般会在 Qsys 里生成地址映射后直接复制到设备树里避免手写出错。4. 避坑与排查DE1-SoC 原理图和手册里最容易忽略的五个细节4.1 现象FPGA 配置成功但外设不工作原因引脚被 HPS 占用DE1-SoC 的很多引脚是 HPS 和 FPGA 复用的比如某些 GPIO、I2C、SPI。如果你在 FPGA 侧分配了一个引脚但这个引脚在 HPS 侧已经被默认功能占用那 FPGA 的输出会被 HPS 覆盖或者根本驱动不了。原理图上会用不同的颜色或标注区分“HPS 专用”和“FPGA 可用”。解决方法是在 HPS 侧的设备树里禁用对应的外设释放引脚给 FPGA。比如你要用 FPGA 控制 I2C就要在设备树里把 HPS 的 I2C 控制器状态改成disabled。4.2 现象时序报告显示建立时间违例原因跨时钟域没做同步开发手册里反复强调跨时钟域信号必须做同步处理但很多人还是直接把一个时钟域的信号拉到另一个时钟域。Quartus 的时序分析会报建立时间违例但如果你没看报告直接下载可能功能偶尔正常偶尔出错。解决方法是对所有跨时钟域信号加两级触发器同步或者用异步 FIFO。SDC 里要对这些路径设置set_false_path或者set_clock_groups让工具不要分析但前提是你已经做了同步。4.3 现象HPS 启动后无法访问 FPGA 寄存器原因桥的时钟没使能HPS-to-FPGA 桥需要时钟才能工作这个时钟可以来自 FPGA 侧也可以来自 HPS 侧。开发手册里说明如果桥的时钟没有使能访问会返回总线错误。我遇到过一种情况在 Qsys 里连接了桥但忘记在 HPS 的时钟配置里使能对应的桥时钟结果 Linux 启动后 mmap 成功但读写寄存器时进程直接挂掉。解决方法是在 Qsys 的 HPS 配置里确认FPGA-to-HPS和HPS-to-FPGA的时钟使能位都打开并且在设备树里添加对应的clocks和clock-names属性。4.4 现象SD 卡启动失败原因设备树里的引脚配置和原理图不一致DE1-SoC 的 SD 卡引脚在原理图上有明确的上下拉要求设备树里的pinctrl节点必须和原理图一致。如果上下拉配错SD 卡在高速模式下会识别失败。解决方法是对照原理图的 SD 卡部分检查pinctrl里的bias-pull-up或bias-pull-down设置以及驱动强度。另外SD 卡的电源域也要确认有些板子 SD 卡电源是可控的需要在设备树里加 regulator 节点。4.5 现象Quartus 编译报错“引脚不存在”原因原理图版本和器件型号不匹配DE1-SoC 有多个版本不同版本的 FPGA 器件型号可能不同引脚定义也有差异。如果你拿到的原理图是旧版本的而 Quartus 工程里选的器件是新版本的就会报引脚不存在。解决方法是在 Quartus 里确认器件型号和板子上的 FPGA 丝印一致然后对照对应版本的原理解图。开发手册的首页通常会写明适用的板子版本和器件型号不要混用。5. 用 SignalTap 和 System Console 验证硬件通路一个可复现的调试习惯5.1 用 SignalTap 抓取 FPGA 内部信号SignalTap 是 Quartus 自带的嵌入式逻辑分析仪可以把内部信号抓到 JTAG 上观察。我一般会在关键路径上例化 SignalTap比如 HPS-to-FPGA 桥的读写使能、PWM 的计数器、跨时钟域同步器的输出。设置时注意采样深度和时钟域采样时钟要用被观测信号所在的时钟域否则抓到的数据没有意义。SignalTap 会占用额外的逻辑资源和 RAM调试完成后记得在工程里禁用否则会影响时序和面积。# 在 Qsys 里添加 SignalTap 需要先在 Quartus 里创建 .stp 文件 # 然后在 .qsf 里添加以下约束指定采样时钟 set_instance_assignment -name SIGNALTAP_CLOCK clk_50 -to auto_stp_external_stp_clock # 采样深度设为 1024根据 RAM 资源调整 set_instance_assignment -name SIGNALTAP_SAMPLE_DEPTH 1024 -to auto_stp_external_stp_clock这段约束的逻辑是指定 SignalTap 的采样时钟和深度。参数说明clk_50是采样时钟必须是设计里的时钟信号采样深度越大占用的 RAM 越多一般 1024 或 2048 够用。注意SignalTap 的采样时钟频率不能超过 JTAG 的带宽限制否则数据传不出来。5.2 用 System Console 读写 Avalon 寄存器System Console 是 Quartus 里的一个 Tcl 控制台可以通过 JTAG 直接读写 Avalon-MM 寄存器不需要 Linux 启动。这在调试 HPS-FPGA 桥的时候特别有用因为你可以绕过 Linux直接验证 FPGA 侧的寄存器逻辑。比如# 打开 System Console连接到板子 # 假设有一个 Avalon-MM 从设备基地址 0x1000 set master [lindex [get_service_paths master] 0] open_service master $master # 写寄存器 master_write_32 $master 0x1000 0x12345678 # 读寄存器 set val [master_read_32 $master 0x1000 1] puts Read: $val # 关闭 close_service master $master这段 Tcl 的逻辑是获取 master 服务路径打开服务然后读写 32 位寄存器。参数说明0x1000是 Avalon-MM 地址相对于桥的基地址master_write_32和master_read_32是 System Console 的内置命令。注意使用前要确保 FPGA 已经配置并且 JTAG 连接正常。这个方法的好处是快不需要编译 Linux 内核或者写驱动适合早期调试。5.3 一个可复现的调试习惯先通桥再通外设我自己的习惯是拿到一块新板子或者新工程先不急着接外设而是先用 System Console 确认 HPS-FPGA 桥能读写再用 SignalTap 确认 FPGA 内部逻辑在跑最后才接外设。这个顺序能帮你快速定位问题是在桥、在逻辑、还是在外设。很多人的翻车经历是外设不工作就怀疑外设结果查了半天发现是桥的地址映射错了。先通桥再通外设能省很多后悔药。另外原理图和开发手册要对照着看。原理图告诉你“连到哪里”手册告诉你“怎么用”。比如原理图上某个引脚标了HPS_GPIO手册里会告诉你这个 GPIO 在 Linux 里对应哪个编号怎么导出、怎么控制。两者结合才能把硬件资源用起来。希望帮到你。本文还有配套的精品资源点击获取

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑