如果已经有了数字电路的基本概念,学过一点 C 语言,那上手 Verilog 会顺畅不少。但真正要掌握的,不是死记硬背语法,而是每写一行代码,脑子都能浮现出它大概会对应什么样的硬件电路。这种'代码→硬件'的映射感,是初学阶段最难也最关键的一点。
仿真环境怎么选
搞 FPGA 开发,主流的平台现在基本都用 Xilinx 的 Vivado,社区支持多,遇到问题也容易查。ISE 已经停止更新,除非维护老项目,否则不建议再碰。Intel 那边对应的工具是 Quartus II。如果以后想走 ASIC 方向,那 Synopsys VCS 会更常见。
有个小坑几乎每个新手都会踩一次:电脑的用户名、软件的安装路径,还有工程路径,必须全英文,不能有中文或者特殊符号。路径里带个中文,软件可能直接启动失败,或者综合、仿真的时候莫名其妙报错。这个问题太常见了,提前避开能省很多事。
设计流程
从想法到最终下载进板子,一般会走这几步:
首先把电路要干什么想清楚,比如控制几个 LED 闪烁,或者做一段简单的运算。然后把整个功能拆成一个个相对独立的模块,比如专门产生时钟的模块、专门处理数据的模块。接着用 Verilog 把这些模块描述出来,定义好端口和内部逻辑。代码写完先做功能仿真,看看逻辑有没有毛病,有问题就回去改代码。逻辑验证没问题了,再综合成 FPGA 内部的实际电路单元(LUT、触发器等),之后布局布线,根据时序约束让设计匹配硬件。最后跑一次时序仿真,确认没问题了,生成比特流文件下载到 FPGA 上。
整个过程最大的坑往往在仿真阶段发现,所以仿真这一步不要急着跳过。
核心语法要点
Verilog 的语法有一些很'硬件'的味道,下面把最常用的几条过一遍。
基础格式
- 大小写敏感,
clk和CLK是两个东西,关键字必须全小写。 - 空格和换行不决定语法,所以可以按习惯排版,提高可读性。
- 每条语句用分号结尾,不能丢。
- 注释用
//单行,或者/* ... */多行(多行不能嵌套)。
下面这两种写法,功能完全一样,但显然后一种读起来更舒服:
// 推荐写法:分行排版
input wire a;
input wire b;
wire [1:0] results;
assign results = (a == 1'b0) ? 2'b01 : (b == 1'b0) ? 2'b10 : 2'b11;
// 紧凑写法:语法合法但可读性差
input wire a;input wire b;wire[1:0] results;assign results=(a==1'b0)?2'b01:(b==1'b0)?2'b10:2'b11;
标识符与关键字
标识符就是变量或者模块的名字,首字符只能是字母或者下划线,后面可以跟字母、数字、下划线,不能以数字或特殊符号开头。
关键字是语言预留的,全部小写,比如 reg、input、wire 这些。reg [3:0] counter; 这句话里,reg 是关键字,counter 是标识符。
数值表示
硬件里面最基础的是四种逻辑值:
0:低电平,逻辑假1:高电平,逻辑真x/X:未知状态,可能在 0 和 1 之间飘z/Z:高阻状态,相当于没驱动,电平由外部上下拉电阻决定
写数值的时候,格式是 位宽 ' 进制符号 数值。比如:
- 二进制:
2'b01 - 八进制:
3'o15 - 十进制:
4'd10 - 十六进制:
8'h3F(位宽大的时候用十六进制更简洁)
核心数据类型
Verilog 里面最常用的就两种数据类型,而且它们直接对应硬件行为。

