一、硬件描述语言概述
1.主要的硬件描述语言
- VHDL(VHSIC HDL): 天然支持并发描述,允许在同一个文件中定义多个并发执行的进程;可读性和可维护性较好,适合于大型项目和团队合作;支持用户定义的数据类型;可以使用抽象类型为系统建模
- Verilog HDL:Gateway Design Automation:语法更为灵活,允许多种描述同一硬件结构的方式,包括行为级、RTL级和门级描述;也支持并发性,但更倾向于顺序执行模型,需要使用特定的并发控制结构(如always块)来描述硬件的并发能力;代码简洁,易于编写;数据类型只能由语言本身定义,不能由用户定义;适于硬件结构的建模,不适于抽象的硬件行为建模。
- OO VHDL:美国国防部(面向对象)
- DE VHDL:美国杜克大学
- VITAL:美国电气与电子工程师协会(IEEE)
2.Verilog支持的五种不同的描述方法
- 系统级(System)
- 算法级(Algorithm):描述可以不对应具体电路,可广泛使用各种函数,代码最终的运行平台为计算机,通常不可综合
- 寄存器传输级(RTL):模型描述对应具体电路,代码最终的运行平台为FPGA或者ASIC,可综合
- 门级(Gate):模型描述对应具体电路,代码最终的运行平台为FPGA或者ASIC,可综合
- 开关级(Switch-level)
3.综合
3.1 定义
从高级别的描述自动转换到较低级别的描述的自动化方法
3.2 数字电路设计中的综合
寄存器传输级设计RTL design----(逻辑综合)---->门级网表Gate-level Netlist----(物理综合)---->物理版图Physical Layout
3.3 语句
可综合语句:if-else, case, for*, assign, begin-end, always等
不可综合语句:repeat, forever, time, defparam, finish, initial等
4.知识产权核(IP核)
4.1 简介
基于ASIC或FPGA预先设计好的,时序、面积、功率可配置的电路功能模块;复杂芯片设计时常调用已有IP核
4.2 优势
IP调用可以提高系统的设计效率,缩短系统的设计周期
4.3 常见IP核
常见的IP核:FIFO、PLL、RAM
分类:
- 软核: 使用RTL或者更高级别的描述定义的功能块,不涉及电路的具体实现,验证通过并且可综合;灵活、可移植、可重用;电路性能无法得到保证
- 固核: 提供参数化描述的电路功能块,方便设计者根绝特定的设计需求对核心进行优化;灵活的参数增加了电路性能的可预测性
- 硬核: 具有固定版图,并且针对特定应用程序和工艺进行了高度优化的功能块;具有稳定的功能以己可预测的性能,且更易于实现IP保护;缺乏灵活性和可移植性
二、Verilog建模方式
1.建模方式
- 结构级建模:根据电路原理图,实例引用Verilog中内置的基本门级元件、用户定义的元件或其他模块,来描述电路结构图中的元件以及元件之间的连接关系
要求具有逻辑电路原理图相关知识,对设计者要求过高;电路复杂,逻辑门较多时,效率低
- 数据流建模:assign 变量名=表达式
只能对wire型变量进行赋值,仅适合于组合逻辑电路的功能描述
- 行为级建模:描述数字逻辑电路的功能和算法:always做过程性赋值(被赋值变量必须为reg型);initial接面向仿真的过程语句
2.模块化
模块的调用,通常被称为实例化(instantiation)
例化方法
- 顺序端口连接
- 命名端口连接
三、Verilog仿真测试
四、Verilog语言要素
1.数值的表示
2.数据类型
-
线网型:相当于硬件电路中的各种物理连接(导线和节点),用于连接各个模块以及输入输出;
输出的值紧跟输入值的变化而变化,没有电荷保持作用;由门元件实现结构级建模,通过assign语句实现数据流建模,不能用于行为级建模Verilog HDL模块中的输入输出信号在没有明确指定数据类型时都被默认为wire型
-
寄存器型
- reg类型:数据默认值是未知的,reg型数据的值通常被认为是无符号数,如果给reg型数据中存入一个负数,通常会被视为正数(补码);赋值过程为过程赋值
- integer类型:整数寄存器
- real类型:实数型寄存器,采用双精度浮点数,一般用于测试模板中存储仿真时间
- time类型:时间寄存器,用于存储和处理时间
-
参数型parameter
- 声明与调用:
- localparam:localparam外部不可见,parameter外部可调用修改(即局部参数和全局参数的区别)
- defparam:defparam可以提高模块的重用性,使得在同一个设计中多次实例化同样的模块时,可以有不同的参数值,而不必因为参数不同产生多个文件
- 声明与调用:
defparam MyModule.WIDTH = 8; //名为MyModule的模块,有一个名为WIDTH的参数
-
标量与向量
在向量中,可以指定其中的某一位或若干相邻位进行操作,这些指定的一位或相邻位分别称为位选择或域选择 -
数组
一个n位的寄存器可以在一条赋值语句里进行赋值,而一个完整的存储器则不行
3.表达式和运算符
3.1 常见运算符
- 位运算:位运算的输出长度由输入决定
- 逻辑运算:逻辑运算的输出长度由输入决定
- 缩位运算:单目运算
- 关系运算符:
- 等式运算符:
- 移位运算符:
- 拼接运算符:
- 条件运算符:
3.2 运算优先级
3.3 符号控制
3.4 表达式位
六、Verilog基本语句
1.赋值语句
1.1 连续赋值语句
- 常用于数据流建模方法中构建组合逻辑电路;
- 目标类型为线网型;
- 连续赋值不能出现在过程块中间;
- 多个连续赋值语句之间是并行的,与位置顺序无关;
- 不可以对同一个变量多次赋值
1.2 过程赋值语句
- 赋值方式使用原则
- 当用"always"过程语句对组合逻辑电路进行设计时,应该尽量采用阻塞赋值的方式
- 对时序逻辑电路进行设计时,应尽量采用非阻塞赋值方式;
- 对锁存器建模时,应尽量采用非阻塞赋值方式
- 在同一always过程语句中描述时序和组合逻辑混合电路时,最好采用非阻塞赋值方式
- 在同一个过程块中,最好不要同时使用阻塞赋值和非阻塞赋值;
- 在同一个模块内,严禁对同一个变量既进行阻塞赋值,又进行非阻塞赋值;
- 不能在两个或两个以上的"always"过程语句中对同一个变量进行赋值,这样会引起冲突,在综合时报错;
- 在initial语句块或always语句块内对reg型变量进行赋值的赋值语句,在经过过程赋值后,变量的取值将保持不变,直到另一条过程赋值语句对变量重新赋值
- 指定延时的阻塞/非阻塞赋值语句
2.语句块
2.1 顺序语句块(begin-end)
语句块中的语句按照顺序方式执行,每条语句中的时延值与其前面的语句执行的模拟时间相关,一旦顺序语句块执行结束,跟随顺序语句块过程的下一条语句继续执行;所指定的延时为相对延时:相对于上一条语句
2.2 并行语句块(fork-join)
并行语句块中的各语句并行执行,并行语句块内的各条语句指定的时延值都与语句块开始执行的时间相关。当并行语句块中最后的动作执行完成时,顺序语句块的语句继续执行;所指定的延时为绝对延时:相对于进入语句块的时间
3.过程语句
3.1 initial过程语句
只执行一次,不可被综合,可带延时
3.2 always过程语句
- 敏感信号列表设置原则:
- 组合逻辑电路,要保证所有输入信号在敏感事件表中出现,建议使用always@(*)
- 时序逻辑电路,在敏感事件表中列出时钟信号和控制信号
- 如果敏感信号列表缺省,将认为触发条件始终满足,该过程语句块将无条件地循环下去
4.条件语句
4.1 if-else条件语句
高度的可综合性——MUX,综合出来的逻辑具有优先级,靠前的逻辑少、路径短
4.2 case条件语句
5.循环语句
- forever: 无限循环,通常用于生成时钟:
forever #10 clk = ~clk;
- repeat: 执行括号内表达式指定的循环次数,如果表达式对应为不定态或高阻态,则不执行
- while: 括号内表达式为真则进入循环,否则退出循环
- for: 当循环个数是常量时,可综合;否则,不可综合
6.基本语句的可综合性
7.任务和函数
-
任务的输出不能是线网型变量
-
系统函数:
8.编译指令
- 从处理编译指令的位置就一直保持有效,直到被别的编译指令覆盖或取消
- 时间标记指令:用于定义时间单位和时间精度:`timescale time_unit/time_precision
`timescale 1ns/100ps //表示时延单位为1ns,时延精度为100ps
- 宏编译指令:对需要全局定义而且不被其他设计更改的标志使用宏定义;对于只在模块内部使用的常量,使用parameter;尽可能将所有宏定义放在同一个宏定义文件,编译时先读取该文件,以保证编译的正确性