1. FPGA基础与开发环境搭建

各位同学,欢迎来到《FPGA图像滤波与边缘检测实战》的第一课。

我是你们的讲师,一个在FPGA领域摸爬滚打了十几年的老工程师。今天咱们不聊虚的,直接切入正题——FPGA到底是什么?它凭什么能处理图像?我们又该怎么搭建起自己的开发环境?

说实话,我当年刚接触FPGA时,也被它复杂的内部结构搞得一头雾水。但别担心,跟着我的节奏,你会发现这东西其实挺有意思的。

1.1 FPGA发展史:从胶水逻辑到万能芯片

FPGA的全称是Field Programmable Gate Array,现场可编程门阵列。说白了,就是一块你可以反复烧写、反复修改逻辑的芯片。

上世纪80年代,Xilinx公司发明了第一块FPGA。那时候的FPGA功能很弱,主要用来做「胶水逻辑」——就是把几个不同的芯片粘在一起用。我刚开始工作时,还用过那种只有几百个逻辑单元的FPGA,现在想想真是古董级了。

为什么会发展这么快?因为市场需求太强烈了。ASIC(专用集成电路)流片一次要几百万美元,改一次bug更是伤筋动骨。而FPGA可以随时改,随时调,成本低得多。到了今天,FPGA已经集成了上百万个逻辑单元,甚至嵌入了ARM处理器硬核,成了名副其实的「万能芯片」。

核心观点:FPGA的本质是「硬件可编程」。你写的Verilog代码,最终会变成芯片内部实实在在的电路连接。这一点和CPU的软件执行完全不同。

1.2 FPGA内部结构:到底长什么样?

要玩转FPGA,你得先知道它肚子里装了些什么。我习惯把FPGA的内部结构比作一个「乐高积木盒」。

下面这张图是我自己画的,帮你快速建立整体认知:

FPGA内部结构示意图 可编程逻辑块(CLB)阵列 可编程I/O 块RAM DSP 时钟管理 可编程互连资源(布线) CLB I/O BRAM DSP

FPGA内部主要包含这几个部分:

  • 可编程逻辑块(CLB):这是FPGA的核心,由查找表(LUT)和触发器(FF)组成。LUT负责实现组合逻辑,FF负责存储状态。说白了,CLB就是一块可以变成任何数字电路的积木。
  • 可编程I/O:负责芯片和外部世界的通信。你可以配置成LVCMOS、LVDS等各种电平标准。我在项目中就吃过亏,I/O电平没配对,结果板子一上电就冒烟了...
  • 块RAM(BRAM):FPGA内部的存储资源,可以用来做FIFO、数据缓存。图像处理中经常用它来存一行像素数据。
  • DSP单元:专门做乘法和累加运算的硬件模块。图像滤波中的卷积运算,就是靠它来加速的。
  • 时钟管理(MMCM/PLL):用来产生不同频率的时钟信号。嗯,这里要注意,时钟是FPGA的命脉,时钟没处理好,整个设计都会出问题。

我的经验:初学者最容易犯的错误是把FPGA当CPU用,写一堆顺序执行的代码。记住,FPGA是并行执行的!你写的每一行Verilog,最终都会变成独立的硬件电路。

1.3 Vivado/Vivado HLS安装与配置

好,理论说完了,咱们来点实际的。工欲善其事,必先利其器。我们用的开发工具是Xilinx的Vivado。

Vivado是目前主流的FPGA开发套件,支持从设计输入、综合、布局布线到比特流生成的完整流程。而Vivado HLS(High-Level Synthesis)则允许你用C/C++来写FPGA逻辑,然后自动转换成硬件描述。

安装步骤其实不复杂,但有几个坑我得提前告诉你:

  1. 下载安装包:去Xilinx官网下载Vivado WebPACK版本(免费)。注意,安装包很大,大概20-30GB,建议提前准备好网络环境。
  2. 选择组件:安装时记得勾选Vivado HLS和Vitis。我建议把支持器件选上,比如Artix-7、Kintex-7这些常用系列。
  3. 安装路径:不要有中文路径!不要有空格!我曾经因为路径里带了个空格,折腾了一整天找不到错误原因。
  4. License配置:免费版不需要License,直接安装就能用。如果你用企业版,记得把License文件放到指定目录。

警告:Vivado对系统资源要求较高,建议至少16GB内存,100GB以上硬盘空间。如果你用虚拟机,记得给足够的资源,否则综合时可能会卡死。

1.4 第一个LED灯实验:点亮你的FPGA

按照传统,咱们的第一个实验就是「Hello World」——点亮一个LED灯。别小看这个实验,它验证了从代码编写到硬件下载的完整流程。

下面是我写的一个最简单的流水灯代码:

module led_blink (
    input  wire       clk,      // 50MHz 系统时钟
    input  wire       rst_n,    // 复位信号,低有效
    output reg [3:0]  led       // 4个LED灯
);

// 计数器,用于分频
reg [24:0] cnt;

always @(posedge clk or negedge rst_n) begin
    if (!rst_n)
        cnt <= 25'd0;
    else
        cnt <= cnt + 1'b1;
end

// 每计数到最大值,切换LED状态
always @(posedge clk or negedge rst_n) begin
    if (!rst_n)
        led <= 4'b0001;
    else if (cnt == 25'd24_999_999)  // 0.5秒翻转一次
        led <= {led[2:0], led[3]};   // 循环左移
end

endmodule

代码逻辑很简单:用一个25位的计数器对50MHz时钟分频,每0.5秒产生一个脉冲,然后让LED灯循环左移,实现流水灯效果。

在Vivado中新建工程,添加这个源文件,然后分配引脚:

信号 FPGA引脚 说明
clk E3 50MHz晶振输入
rst_n C12 按键复位
led[0] F6 LED0
led[1] G6 LED1
led[2] H6 LED2
led[3] J6 LED3

综合、实现、生成比特流,然后下载到开发板上。如果一切顺利,你会看到4个LED灯依次亮起,像流水一样循环。

避坑指南:我曾经在第一次下载时,发现LED灯完全不亮。检查了半天,原来是复位按键的极性搞反了。代码里用的是低电平复位,但板子上的按键是按下高电平。所以,拿到板子后第一件事——看原理图!

好了,第一章的内容就到这里。你学会了FPGA的基本概念、内部结构,也亲手搭建了开发环境,跑通了第一个LED实验。这些基础打牢了,后面咱们才能玩转图像滤波和边缘检测。

可可精品资料库