一门描述电路的语言
你接触过的大多数语言,比如 Python、JavaScript、Go,描述的都是一串让 CPU 执行的指令。Verilog 描述的则是一个电路。你写下有哪些导线、有哪些寄存器,以及信号如何在它们之间流动。仿真器可以回放这个电路的行为,综合工具可以把同一份文本编译成真实芯片里的逻辑门和触发器。
这就是一句话的定义。它带来的影响需要更长时间去消化。
这段代码看起来像个小程序:一个 module、一个 initial 块、一个 $display 系统任务。点击“运行”,你会看到 hello from verilog。但在底层,仿真器并不是在执行一个函数,而是在模拟时间的流逝,让电路一步步向前推进。这就是为什么你会到处看到 $finish:总得有人告诉仿真器该停下来了。
##“硬件描述”到底是什么意思
一行 C 代码在程序计数器到达它时才执行。一行 Verilog 描述的则是一块始终存在的电路。看这个例子:
assign y = a & b;
这不是“计算一次 y”,而是“有一根导线 y,它在任何时刻都等于 a AND b”。改变 a 或 b,y 会立刻跟着变。一个模块里的多条 assign 语句并不是一个序列,而是对电路中不同部分的并行描述。
这是 Verilog 最核心的特点,也是初学者所有 bug 的根源。你写的大部分代码描述的是同时发生的事情;少数看起来像有序语句的结构(在 initial 和 always 块中),之所以看起来有顺序,只是因为仿真器在模拟。
用 Verilog 能做什么
在数字系统的每个层面上,你都会看到 Verilog 的身影:
- 组合逻辑。 加法器、多路选择器、译码器、ALU 切片,所有输出只取决于当前输入的电路。
- 时序逻辑。 计数器、移位寄存器、有限状态机,所有由
posedge clk驱动的电路。 - 处理器核。 从大学课程作业里的 CPU,到已经量产流片的开源 RISC-V 核,RTL 通常都是用 Verilog 或 SystemVerilog 写的。
- FPGA 设计。 加载到 Xilinx 或 Intel FPGA 中的逻辑,比如网络、图像处理、嵌入式控制,绝大多数是用 Verilog 写的。
- ASIC。 你的手机、路由器、汽车里的定制芯片,前端设计都用 HDL,而 Verilog 是两大主流选择之一。
学习时你不需要任何这些硬件。这些文档里的所有内容都在基于浏览器的仿真器中运行。
仿真与综合
“运行”Verilog 有两种方式,它们并不相同:
- 仿真在软件中回放电路的行为。仿真器(Icarus Verilog、Verilator、ModelSim 以及各种商业工具)读取你的模块和一个 testbench(驱动输入的代码),然后产生输出:文本日志、波形、通过或失败的报告。
- 综合把 Verilog 的一个子集编译成由真实逻辑门组成的网表。这一映射由厂商工具完成(Vivado、Quartus,以及大公司使用的 Design Compiler 一类工具)。可综合的 Verilog 必须遵守额外的规则:硅片上不存在
initial块和$display调用。
这些页面上的浏览器编辑器做的是仿真。在你真正要流片或给 FPGA 编程之前,这就是你所需要的全部。
Verilog 与 SystemVerilog
如果你去查资料,会同时看到这两个名字。SystemVerilog 是超集:它保留了所有 Verilog 结构,并增加了主要面向验证的特性(类、约束随机测试、断言、接口、丰富得多的类型系统)。你在这里学到的一切都是合法的 SystemVerilog。实际使用中两个名字常常混用;大多数工具两者都支持,大多数文件也照样以 .v 结尾。在这些文档中,我们统一称为“Verilog”。
Verilog 与 VHDL
两者都是硬件描述语言,都是 IEEE 标准,都从 20 世纪 80 年代沿用至今。区别在于:
- 语法。 Verilog 源自 C:花括号、简短的关键字、宽松的类型规则。VHDL 源自 Ada:更冗长,类型检查严格得多。
- 地域。 Verilog 在美国的商业设计中占主导地位。VHDL 在欧洲、国防领域和较老的代码库中仍然常见。
- 能力。 两者能表达的内容大致相当。选择哪个取决于你的团队在用什么。
如果你是第一次学习 HDL,Verilog 的学习曲线更平缓:语法更少、更宽松,网上的示例也更多。
这些文档如何运行 Verilog
下面的编辑器底层使用 Icarus Verilog(iverilog)。它把你的源代码编译成仿真器,并在沙箱中运行。不需要 Vivado 许可证,不需要安装 Quartus,也不需要 FPGA 开发板。你写一个模块加一个小 testbench,点击“运行”,就能看到输出和波形。
这是一个完整的 4 位计数器加一个 testbench。counter 模块是被测设计(DUT);test 模块负责翻转时钟、释放复位,并在每个周期打印计数值。运行它,你会看到 count 从 0 数到 15,然后回绕。打开“波形”标签页,你会看到同样的过程以电平跳变的形式呈现。
接下来
现在你已经有足够的背景知识来开始编写模块了。下一篇文档硬件与软件会多花一点篇幅讲思维方式的转变,因为这是 Verilog 新手遇到的最大障碍。之后是安装本地仿真器(可选,用浏览器就够了)、从零编写你的第一个模块,以及语言的其余部分。
按自己的节奏来。语法不多,真正要下功夫的是思维方式。
常见问题
简单来说,Verilog 是什么?
Verilog 是一种硬件描述语言(HDL),用文本来描述数字电路。你写的不是让 CPU 执行的指令,而是描述导线、寄存器、逻辑门,以及信号如何在它们之间流动。然后仿真器运行这份描述,让你验证电路的行为;综合工具还能把同一份描述转换成真实的芯片版图。
Verilog 用来做什么?
Verilog 用于设计和验证数字硬件:CPU、GPU、网络交换机、存储控制器、信号处理模块、FPGA 设计,凡是由逻辑门和触发器构成的东西都可以。它也可以纯粹在仿真中运行,用来教授数字逻辑,或在流片之前做设计原型。
Verilog 是编程语言吗?
不是通常意义上的编程语言。Verilog 代码描述的是硬件的结构和行为(信号、逻辑门和时钟驱动的存储),而不是一串 CPU 指令。你写的很多行代码在芯片上是同时发生的,而不是一行接一行执行。从软件转向 Verilog 时,最大的障碍就是这种思维方式的转变。
Verilog 和 SystemVerilog 有什么区别?
SystemVerilog 是 Verilog 的超集。它保留了 Verilog 的全部语法,并增加了主要面向验证的特性:类、约束随机激励、断言、接口,以及更丰富的数据类型。支持 SystemVerilog 的工具也支持普通的 Verilog。对于大多数入门内容来说,两者看起来完全一样。
Verilog 和 VHDL 有什么区别?
Verilog 和 VHDL 都是硬件描述语言,解决的是同一个问题。Verilog 的语法源自 C,更简洁;VHDL 的语法源自 Ada,更冗长,类型检查也更严格。业界的使用情况因地区和团队而异:两者都还很活跃,也都有标准(Verilog/SystemVerilog 是 IEEE 1364/1800,VHDL 是 IEEE 1076)。
Verilog 难学吗?
它的语法很少,比 C++ 还少。难的是抛开写软件的习惯。在 Verilog 中,大多数语句描述的是同时发生的事情,而不是按顺序发生的事情;阻塞赋值和非阻塞赋值用错一个地方,就可能决定你的电路能不能正常工作。第一周感到无所适从是正常的,之后就会豁然开朗。