1. FPGA与Verilog概述

大家好,我是你们的FPGA讲师。在芯片设计这行摸爬滚打了十几年,踩过的坑比走过的路还多。今天咱们开始第一课,聊聊FPGA和Verilog那些事儿。

说实话,很多初学者一上来就急着写代码,结果后面debug到怀疑人生。我个人习惯是,先把基础概念吃透,再动手。磨刀不误砍柴工嘛。

1.1 FPGA到底是什么?

FPGA,全称是现场可编程门阵列。说白了,就是一块你可以反复烧录、反复改逻辑的芯片。跟ASIC(专用集成电路)不一样,ASIC一旦流片,功能就焊死了,改不了。FPGA呢?今天写错了,明天重新下载,又是一条好汉。

我在项目中遇到过最尴尬的事——客户说需求变了,要加个功能。如果是ASIC,得重新流片,几百万打水漂。但FPGA?我花了一个下午改代码,搞定。这就是FPGA的灵活性。

核心要点:FPGA = 可编程逻辑 + 可反复配置 + 硬件并行执行

FPGA内部主要由三部分组成:

  • 可编程逻辑块(CLB)——实现你的逻辑功能
  • 可编程互连资源——把各个逻辑块连起来
  • 可编程I/O块——跟外部世界打交道

你想想看,这三样东西组合起来,几乎能实现任何数字电路。从简单的与门、或门,到复杂的CPU、DSP,都能在FPGA里跑起来。

1.2 Verilog HDL简介

Verilog是一种硬件描述语言。注意,是"描述"语言,不是"编程"语言。这个区别很重要。

写C语言,你是在告诉计算机"先做这个,再做那个"。写Verilog,你是在描述"这个电路长什么样,那个信号怎么连"。一个是顺序执行,一个是并行执行。本质不同。

我记得刚带新人时,有个小伙子写了个always块,里面用了for循环,还加了delay。综合器直接报错。他一脸懵:"C语言里不都这么写吗?" 嗯,这就是没理解硬件思维。

Verilog的基本语法其实不多:

  • 模块(module)——每个设计都是一个模块
  • 端口(port)——模块的输入输出
  • 连线(wire)和寄存器(reg)——信号类型
  • always块——描述时序逻辑
  • assign语句——描述组合逻辑

看个最简单的例子:

module led_flash (
    input  wire       clk,    // 时钟
    input  wire       rst_n,  // 复位,低有效
    output reg        led     // LED输出
);

always @(posedge clk or negedge rst_n) begin
    if (!rst_n)
        led <= 1'b0;
    else
        led <= ~led;
end

endmodule

这段代码描述了一个LED闪烁电路。时钟每来一个上升沿,LED就翻转一次。注意看,这里没有"延时"的概念,一切都是时钟驱动的。

小技巧:写Verilog时,脑子里要想着电路。每写一行代码,问问自己:这行代码综合出来是什么?是触发器?是查找表?还是连线?

1.3 可综合设计概念

什么叫"可综合"?简单说,就是你的Verilog代码能被EDA工具翻译成真实的硬件电路。

不是所有Verilog语法都能综合。比如:

  • #10延时语句——不能综合,只用于仿真
  • initial块——大部分不能综合
  • fork...join——不能综合
  • display$monitor——仿真专用

我曾经见过一个项目,新人写了大量不可综合的代码,仿真跑得飞起,一综合就报几百个错误。最后整个模块重写,工期延误两周。所以,从一开始就要养成可综合设计的习惯。

可综合设计的核心原则:

  1. 用always块描述时序逻辑——敏感列表用posedge或negedge
  2. 用assign描述组合逻辑——或者用always@(*)
  3. 避免锁存器(latch)——组合逻辑中条件要写全
  4. 不要用循环变量作为敏感信号——综合器会懵

避坑指南:我曾经在组合逻辑的always块里漏写了else分支,结果综合出了锁存器。仿真没问题,但上板后功能完全不对。查了两天才发现。记住:组合逻辑中,所有条件分支都要覆盖完整。

1.4 知识体系总览

下面这张图,是我自己总结的FPGA学习路线。你看一眼,心里有个谱。

FPGA学习知识体系 第1层:基础概念 FPGA架构 | Verilog语法 | 可综合设计 | 开发工具 第2层:核心设计 组合逻辑 | 时序逻辑 | 状态机 | 计数器 | 分频器 第3层:进阶模块 FIFO设计 | 跨时钟域 | 串并转换 | 接口协议 第4层:项目实战 时序约束 | 调试技巧 | 代码规范 | 项目案例

这张图展示了我们课程的整体脉络。从基础概念开始,一步步深入到实战。每一层都建立在上一层的基础上,别跳着学,容易摔。

1.5 课程目标与学习路径

这门课的目标很明确:让你写出高质量、可综合、可维护的FPGA代码。

具体来说,学完这门课,你应该能做到:

  • 理解FPGA的工作原理,不再把Verilog当C语言写
  • 掌握可综合设计的核心语法,避开那些坑
  • 能独立设计常见模块:计数器、状态机、FIFO等
  • 写出规范的代码,让别人看得懂,也让自己三个月后还能看懂
  • 具备基本的调试能力,遇到问题知道从哪入手

学习路径我建议这样走:

  1. 先看概念——别急着敲代码,把本章内容消化掉
  2. 再写小模块——从LED闪烁、按键消抖开始
  3. 然后做中等项目——比如UART收发器、SPI控制器
  4. 最后挑战复杂系统——比如简易CPU、图像处理

我的建议:每学完一章,都动手写代码验证。光看不练,等于白学。我当年就是一边看书一边写代码,遇到不懂的就仿真看波形。波形不会骗人。

好了,第一章就到这里。记住一句话:FPGA设计,思维比语法重要。后面我们会一步步深入,把每个知识点都掰开揉碎了讲清楚。

本章小结:

  • FPGA是可编程硬件,灵活且并行
  • Verilog是硬件描述语言,不是软件编程语言
  • 可综合设计要遵循硬件思维,避免仿真专用语法
  • 学习路径:基础 → 核心 → 进阶 → 实战

公众号:蓝海资料掘金营,微信deep3321