第二章

Verilog HDL 基础

建立语法基础,并形成“语法服务硬件表达”的学习方法

一、本章导航

基本单元与基本语法

模块边界清晰优先于代码简短 · 参数化可提升模块复用能力 · 模块、信号与参数的作用

二、本章定位

本章是后续建模、状态机、验证章节的语言基础。重点不是死记语法,而是理解每类语句在硬件描述中的角色边界。

  • 模块由哪些基本部分组成?
  • wire、reg、parameter 分别有什么作用?
  • always、initial、assign 如何区分?
  • 阻塞赋值和非阻塞赋值为什么容易混淆?

三、知识点讲解

1. 基本单元与基本语法

1.1 模块、信号与参数的作用

module 是硬件功能边界,端口定义决定模块如何与外部协作。清晰的端口命名和职责划分,是后续可维护性的基础。

wire、reg、parameter 是最常用对象:wire 常见于连线语义,reg 常见于过程块赋值语义,parameter 用于可配置设计。

  • - 模块边界清晰优先于代码简短
  • - 参数化可提升模块复用能力

1.2 疑难点:wire 和 reg 如何正确理解

不要简单把 wire 理解成“导线”、reg 理解成“寄存器”。更可靠的方法是看使用场景:对象在哪里赋值、用于描述什么行为。

当你用“语义 + 场景”而不是“中文直译”来理解对象时,后续赋值与过程块的学习会稳定很多。

2. 过程语句与块语句

2.1 initial、always、begin/end 的定位

initial 常用于仿真初始化语义;always 是事件触发过程块,可用于组合逻辑或时序逻辑描述。两者定位不同,不应混用。

begin/end 用于组织多条相关语句,能提升结构可读性,降低后续修改时的理解成本。

2.2 疑难点:always 为什么不是程序循环

always 不是 while(true) 的硬件版本,而是“由事件触发的过程块”。关键不在“会不会一直执行”,而在“什么条件触发执行”。

若是组合逻辑,关注输入变化触发;若是时序逻辑,关注时钟边沿触发。把触发条件和更新时机说清楚,误解就会明显减少。

3. 赋值、条件、循环与 task/function

3.1 赋值与控制语句的硬件语义

assign 连续赋值常用于组合关系;过程赋值位于过程块中。阻塞赋值和非阻塞赋值的差异本质在“更新时机”,会直接影响仿真理解与实现结果。

if/case、for/repeat/while、task/function 是表达工具。核心问题不是“语法像不像软件”,而是“语义是否符合硬件行为”。

3.2 疑难点:阻塞与非阻塞怎么选

实用规则是:组合逻辑优先阻塞赋值,时序逻辑优先非阻塞赋值。该规则目的不是形式统一,而是保持语义一致,减少隐性错误。

遇到不确定场景时,先判断逻辑是“立即组合计算”还是“时钟边沿更新”。判断更新时机后,赋值方式自然清晰。

四、重难点汇总

  1. 1

    模块与基础对象

    查看原文

    构成 RTL 表达的基本单元

  2. 2

    过程块事件驱动思维

    查看原文

    决定逻辑行为理解方式

  3. 3

    赋值与控制语义边界

    查看原文

    直接影响设计正确性与可维护性

  4. 4

    wire/reg 理解

    查看原文

    按赋值场景与语义区分,不按直译区分

  5. 5

    always 事件驱动本质

    查看原文

    always 是触发过程块,不是程序循环

  6. 6

    阻塞/非阻塞赋值差异

    查看原文

    核心看更新时机,而非符号差异