Verilog 是一种硬件描述语言,用于设计、模拟和综合数字电路和系统。它主要用于描述 ASIC(专用集成电路)或 FPGA(现场可编程门阵列)等硬件设备的结构和行为。
定义与用途:
Verilog 是一种硬件描述语言(HDL),主要用于数字电路的建模、仿真、综合与验证。设计人员利用它来描述电路的结构、行为以及时序关系,从而生成实际的硬件电路(如 FPGA 或 ASIC)。
发展背景:
1984 年,Phil Moorby 及其团队在 Gateway Design Automation 开发了 Verilog,之后被广泛应用于工业界,并于 1995 年由 IEEE 采用成为标准(IEEE 1364)。
与其他 HDL 的对比:
与 VHDL 相比,Verilog 的语法更接近 C 语言,适合那些有软件编程背景的工程师;而 VHDL 则更为严谨,强调类型检查和结构化设计。近年来,SystemVerilog 结合了 Verilog 和高级验证特性,逐步成为主流。
Verilog 的由来可以追溯到 1980 年代初期。它由 Phil Moorby 开发,并于 1984 年由 Gateway Design Automation 公司首次推出。最初,它旨在帮助工程师更高效地描述和模拟数字电路设计。Verilog 的设计灵感来自于之前的硬件描述语言,如 VHDL,但它更侧重于简化设计和仿真过程。1990 年,Verilog 被 IEEE 标准化,成为 IEEE 1364 标准,并随着时间的发展逐渐增加了更多的功能和改进。
Verilog 和 VHDL 区别
Verilog:
语法风格: 语法类似于 C 语言,更简洁,适合习惯编程的工程师。它强调设计的行为和结构。
抽象层次: 更适合于底层设计,强调硬件行为和时序。
类型系统: 类型系统较为宽松,支持多种数据类型,但不如 VHDL 强类型。
标准化和扩展: 最初由 Gateway Design Automation 开发,后被 IEEE 标准化为 IEEE 1364,后续版本包括 SystemVerilog。
VHDL:
语法风格: 语法类似于 Ada 语言,更冗长且强类型,适合需要严格类型检查和更复杂建模的设计。
抽象层次: 支持更高层次的抽象,如数据流建模和高级功能,适用于更复杂的设计和验证
类型系统: 具有严格的类型检查,支持自定义数据类型,能提供更高的设计安全性和准确性。
标准化和扩展: 由美国国防部开发并标准化为 IEEE 1076,后续版本包括 VHDL-2008 和其他扩展。
Verilog 和 C 的区别
Verilog 和 C 的主要区别在于它们的应用领域和执行模型。Verilog 是一种硬件描述语言,用于设计和模拟数字电路,它通过描述电路的结构和行为来实现硬件设计的目标,并且支持并行处理和时序控制。相比之下,C 语言是一种通用编程语言,主要用于软件开发,它专注于编写算法和处理数据,通常以顺序执行的方式运行程序。Verilog 的代码描述的是电路的硬件行为,而 C 的代码则是程序的逻辑和流程。
Verilog 的主要特性
行为级描述:使用过程化结构(如 always 块和 initial 块)来描述电路的功能,而不关注具体的硬件实现。这种方式更接近于软件编程,适用于复杂的逻辑行为
数据流描述:使用连续赋值语句(assign)来定义信号之间的关系,适用于简单的组合逻辑。这种方式强调数据如何流动而不是具体的时序。
结构化方式:使用门级和模块实例化语句来描述电路的层次结构。这种方式涉及到具体的硬件组件,例如逻辑门、寄存器等。
两类数据类型:
- 线网(wire)数据类型 ---- 线网表示物理元件之间的连线。
- 与寄存器(reg)数据类型---- 寄存器表示抽象的数据存储元件。
- 设计逻辑功能时,设计者可不用关心不影响逻辑功能的因素,例如工艺、温度等。
Verilog 的基本语法结构
Verilog 的代码主要由 模块(module) 构成,每个模块可以包含接口声明、内部信号定义、行为描述和结构化描述。一个典型的模块包含以下部分:
模块声明
用 module
和 endmodule
包围模块定义。例如:
module my_module (input wire clk,input wire rst,input wire [3:0] data_in,output wire [3:0] data_out
);// 内部声明和逻辑描述
endmodule
端口声明
模块的输入、输出和双向端口在模块头部或内部进行声明。
内部信号声明
使用 wire
、reg
、integer
等关键字声明信号,用于连接模块内部逻辑。
verilog 格式
Verilog 是区分大小写的语言,变量名和关键字的大小写会影响其识别。
白符(如换行、制表符、空格)在语法中没有实际意义,可以在编译阶段被忽略。
可以在一行内编写代码,也可以跨多行编写,具体格式由开发者选择。
wire [1:0] X ;
assign X = (a == 1'b0) ? 2'b01 :(b==1'b0) ? 2'b10 :2'b11 ;
这里使用了三目运算符(条件运算符),其格式为:
条件 ? 真值 : 假值
而代码中是嵌套使用的,等效于:
assign X = (a == 1'b0) ? 2'b01 : ((b == 1'b0) ? 2'b10 : 2'b11);
第一层判断:
检查 a
是否等于 1'b0
(即逻辑 0)。
如果条件为真,则 X 被赋值为 2'b01
。
如果条件为假,则进入下一层判断。
第二层判断:
检查 b
是否等于 1'b0
。
如果条件为真,则 X 被赋值为 2'b10
。
如果条件为假,则 X 被赋值为 2'b11
。
因此
当 a 为 0 时,X = 01(二进制)。
当 a 不为 0,但 b 为 0时,X = 10(二进制)。
当 a 和 b 都不为 0时,X = 11(二进制)。
一、数字
1.1、进制
1、二进制整数(b或B)
2、十进制整数(d或D)
3、十六进制整数(h或H)
4、八进制整数(o或0)
例如:8'b10101010 //位宽为8的数的二进制表示, 'b表示二进制8'ha2 //位宽为8的数的十六进制,'h表示十六进制
1.2、字母
在数字电路中有2个特殊的字母 x 和 z 值
x:代表不定值,有可能是高电平,也有可能是低电平
z:代表高阻值,外部没有激励信号是一个悬空状态。z还有一种表达方式是可以写作 ?
8'b101010x0 //位宽为8的二进制数从低位数起第二位为不定值
8'b101010z1 //位宽为8的二进制数从低位数起第二位为高阻值
12'dz //位宽为12的十进制数其值为高阻值(第一种表达方式)
12'd? //位宽为12的十进制数其值为高阻值(第二种表达方式)
1.3、下划线
下划线用来分隔开数的表达以提高程序的可读性。
8'b1111_1010 //正确格式
8'b_0011_1010 //错误格式
待更新。。。