目录
- 硬件描述语言(HDL)概述
- [Verilog HDL基础](#Verilog HDL基础)
- [Verilog HDL的抽象级别](#Verilog HDL的抽象级别)
- [Verilog HDL模块的基本结构](#Verilog HDL模块的基本结构)
- [Verilog HDL的数据类型与运算符](#Verilog HDL的数据类型与运算符)
- [Verilog HDL的行为级建模](#Verilog HDL的行为级建模)
- [Verilog HDL的结构级建模](#Verilog HDL的结构级建模)
- [Verilog HDL的测试平台(Testbench)](#Verilog HDL的测试平台(Testbench))
1. 硬件描述语言(HDL)概述
1.1 HDL的定义与作用
- 定义: 硬件描述语言(Hardware Description Language, HDL)是一种用文本形式来描述电子系统逻辑功能、电路结构和行为特性的高级编程语言。
- 作用 :
- 作为设计入口,替代传统的原理图输入。
- 支持自顶向下(Top-Down)的设计方法。
- 可用于逻辑综合 (Synthesis)和仿真验证(Simulation)。
- 是现代EDA工具链的核心。
1.2 主流HDL及其比较
| 特性 | Verilog HDL | VHDL |
|---|---|---|
| 起源 | Gateway Design Automation (1983) | 美国国防部 (1981) |
| 标准化 | IEEE 1364 | IEEE 1076 |
| 语法风格 | 类似C语言,简洁、灵活 | 类似Ada语言,严谨、冗长 |
| 学习曲线 | 相对平缓 | 相对陡峭 |
| 市场占有率 | 在ASIC/FPGA领域占主导地位 | 在欧洲和军工领域应用较多 |
结论: Verilog因其简洁性和高效性,已成为工业界事实上的标准。
2. Verilog HDL基础
2.1 设计流程中的角色
Verilog HDL在现代IC设计流程中扮演着核心角色:
- RTL设计: 工程师使用Verilog编写寄存器传输级(RTL)代码。
- 功能仿真: 使用测试平台(Testbench)验证RTL代码的功能正确性。
- 逻辑综合: EDA工具将RTL代码转换为门级网表(Gate-level Netlist)。
- 后端验证: 将网表与物理版图结合,进行时序仿真和物理验证。
2.2 Verilog程序的基本特点
- 模块化 : 所有设计都由一个或多个
module...endmodule块构成。 - 并发性 : 模块内的语句(除
initial/always块内)是并行执行的,这反映了硬件电路的本质。 - 层次化: 一个模块可以调用(实例化)其他模块,形成设计层次。
3. Verilog HDL的抽象级别
Verilog支持从高到低不同抽象级别的建模,以适应设计的不同阶段。
| 抽象级别 | 描述 | 特点 | 应用 |
|---|---|---|---|
| **行为级 **(Behavioral) | 描述电路"做什么",不关心具体实现。 | 使用if、case、for等高级语句。不可综合。 |
算法建模、测试平台。 |
| **寄存器传输级 **(RTL) | 描述数据在寄存器之间的流动和处理。 | 结合组合逻辑(assign)和时序逻辑(always @(posedge clk))。可综合。 |
主要的设计输入级别。 |
| **门级/开关级 **(Gate/Switch) | 描述由基本逻辑门或晶体管构成的电路。 | 使用预定义门(and, or)或MOS开关(nmos, pmos)。可综合。 |
用于精确建模、标准单元库、全定制设计。 |
关键区分: 行为级主要用于仿真和验证,而RTL级是连接设计与物理实现的桥梁。
4. Verilog HDL模块的基本结构
一个完整的Verilog模块包含以下部分:
verilog
// 1. 模块声明
module module_name (
input clk, // 输入端口
input rst_n,
input [7:0] data_in,
output reg valid, // 输出端口(reg类型)
output [7:0] data_out // 输出端口(wire类型,默认)
);
// 2. 内部信号声明
reg [7:0] internal_reg;
wire [3:0] control_signal;
// 3. 功能描述(三种方式)
// (a) 数据流描述 (Dataflow)
assign data_out = internal_reg;
// (b) 行为描述 (Behavioral)
always @(posedge clk or negedge rst_n) begin
if (!rst_n)
internal_reg <= 8'h00;
else
internal_reg <= data_in;
end
// (c) 结构描述 (Structural)
// and u_and(.out(control_signal[0]), .in1(clk), .in2(valid));
// 4. 模块结束
endmodule
4. Verilog HDL模块的基本结构
4.1 关键组成部分说明
- 端口列表 : 定义模块与外界交互的接口,必须明确指定方向(
input/output/inout)和数据类型。 - 内部信号 : 在模块内部使用的信号,需要声明为
reg或wire。 - 功能描述: 这是模块的核心,可以混合使用数据流、行为和结构三种描述方式。
5. Verilog HDL的数据类型与运算符
5.1 主要数据类型
(1) net型(线网型)
- 代表 :
wire - 特性 : 表示物理连线上的信号值。其值由驱动源(如门、
assign语句)决定。不能保存状态。 - 默认类型 : 未声明的端口和信号默认为
wire。
(2) reg型(寄存器型)
- 特性 : 表示存储单元(如触发器、锁存器)的输出。其值在
always或initial块中被赋值,并能保持该值直到下一次被赋值。 - 注意 :
reg并不一定对应一个物理寄存器,它只是表示一个可以保存值的变量。
5.2 常量表示
- 整数 :
64,'hFF,'o77,'b1010 - 实数 :
3.14,2.0e10 - 字符串 :
"Hello, World!"
5.3 运算符
Verilog提供了丰富的运算符,包括:
- 算术运算符 :
+,-,*,/,% - 关系运算符 :
==,!=,>,<,>=,<= - 逻辑运算符 :
&&,\|\|,! - 位运算符 :
&,\|,~,^(异或),~^(同或) - 移位运算符 :
<<,>> - 条件运算符 :
? : - 拼接运算符 :
{ }
6. Verilog HDL的行为级建模
行为级建模使用过程块(initial和always)来描述电路的行为。
6.1 过程块
initial块 : 仅在仿真开始时执行一次 。不可综合,主要用于测试平台初始化。always块 : 根据敏感列表(@(...))反复执行。是描述可综合逻辑的主要方式。
6.2 敏感列表与过程赋值
- 电平敏感 (组合逻辑)
always @(*)或always @(a or b or c) - 边沿敏感 (时序逻辑)
always @(posedge clk or negedge rst_n)
6.3 赋值语句
- **阻塞赋值 **(
=) 顺序执行,常用于组合逻辑建模。 - **非阻塞赋值 **(
<=) 并行执行,必须用于时序逻辑建模,以避免仿真与综合结果不一致。
示例:D触发器
verilog
// 正确的时序逻辑写法(非阻塞赋值)
always @(posedge clk or negedge rst_n) begin
if (!rst_n)
q <= 1'b0;
else
q <= d;
end
7. Verilog HDL的结构级建模
结构级建模通过实例化(Instantiate)预定义的模块或基本门来构建电路。
7.1 门级原语(Gate Primitives)
Verilog提供了一系列内置的基本门:
and,nand,or,nor,xor,xnorbuf,not
示例:2输入与非门
verilog
module nand2_gate(output y, input a, b);
nand (y, a, b); // 实例化一个nand门
endmodule
7.2 模块实例化(Module Instantiation)
这是构建大型系统的主要方式。
示例:4位加法器顶层模块
verilog
module adder_4bit(
input [3:0] a, b,
input cin,
output [3:0] sum,
output cout
);
wire c1, c2, c3; // 内部进位信号
// 实例化4个1位全加器
full_adder fa0(.a(a[0]), .b(b[0]), .cin(cin), .sum(sum[0]), .cout(c1));
full_adder fa1(.a(a[1]), .b(b[1]), .cin(c1), .sum(sum[1]), .cout(c2));
full_adder fa2(.a(a[2]), .b(b[2]), .cin(c2), .sum(sum[2]), .cout(c3));
full_adder fa3(.a(a[3]), .b(b[3]), .cin(c3), .sum(sum[3]), .cout(cout));
endmodule
- Verilog HDL的测试平台(Testbench)
测试平台是用于验证设计模块(DUT, Design Under Test)功能正确性的Verilog程序。
8.1 测试平台的特点
无输入/输出端口。
不可综合。
包含激励产生、DUT实例化和结果监控三部分。
8.2 基本结构
verilog
`timescale 1ns/1ps // 定义时间单位和精度
module tb_adder_4bit;
// 1. 声明与DUT端口匹配的信号
reg [3:0] a, b;
reg cin;
wire [3:0] sum;
wire cout;
// 2. 实例化DUT
adder_4bit u_dut (
.a(a),
.b(b),
.cin(cin),
.sum(sum),
.cout(cout)
);
// 3. 产生激励
initial begin
$dumpfile("wave.vcd"); // 生成波形文件
$dumpvars(0, tb_adder_4bit);
// 测试向量
{a, b, cin} = 9'b0000_0000_0; #10;
{a, b, cin} = 9'b0001_0001_0; #10;
{a, b, cin} = 9'b1111_0001_1; #10;
// ... 更多测试
$finish; // 结束仿真
end
// 4. 结果监控
always @(sum or cout) begin
$display("Time=%0t: a=%d, b=%d, cin=%b => sum=%d, cout=%b",
$time, a, b, cin, sum, cout);
end
endmodule
8.3 关键要素
timescale: 定义仿真时间的单位和精度。
d u m p f i l e / dumpfile/ dumpfile/dumpvars: 生成用于查看波形的VCD文件。
#delay: 产生时序延迟。
d i s p l a y / display/ display/monitor: 在仿真控制台打印信息。
$finish: 终止仿真。
Verilog HDL详细内容见下: