Verilog基础与电路设计
核心内容概述
本资料系统介绍了Verilog硬件描述语言的基础语法、设计流程和可综合代码风格,是FPGA设计入门的重要参考资料。
一、Verilog概述
发展历史
- 1984年研发
- 1995年成为IEEE 1364标准
设计层次
- 系统级(System Level):系统功能描述
- 行为级(Behavioral Level):算法描述
- 寄存器传输级(RTL):数据流和时序描述
- 门级(Gate Level):逻辑门级网表
设计流程
代码编写 → 仿真 → 综合 → 验证
应用场景
- ASIC和FPGA工程师编写可综合代码
- 高抽象级系统仿真与系统接口开发
- 硬件测试工程师编写测试环境
- ASIC和FPGA单元模块建模
二、Verilog基础语法
标识符
- 必须以字母或下划线开头
- 最长1023个字符
- 区分大小写(sel ≠ SEL)
- 有效示例:
shift_reg_a,busa_index,_bus3 - 无效示例:
34net(数字开头),a*b_net(含*)
常量定义
格式:<size>'<base><value>
| 举例 | 解释 |
|---|---|
| 12 | 十进制数(32位) |
| 8’b1100_0001 | 8位二进制数 |
| 64’hff01 | 64位十六进制数 |
| 3’b1010_1101 | 高位舍去,相当于3’b101 |
| 32’bz01x | 高位用z补齐 |
| 4.1E3 | 科学计数法4100 |
运算符
位操作符
& (and), | (or), ~ (not), ^ (xor)
归约操作符
对操作数所有位进行位操作,结果一位
算术运算符
+, -, *, /, %
移位运算符
>> 逻辑右移, << 逻辑左移
关系运算符
>, <, >=, <=
相等运算符
== 逻辑相等, != 逻辑不等, === 全等(含x/z), !== 不全等
条件运算符
cond_expr ? true_expr : false_expr
数据类型
Net类型
wire,tri:标准内部连接线supply1,supply0:电源、地wor,trior:多驱动源线或wand,triand:多驱动源线与
Register类型
reg:最常用,可定义无符号整数integer:32位有符号整数real:双精度浮点time,realtime:64位无符号整数、实数
三、模块定义
module <module_name>(<port_list>);
input <port_list>;
output <port_list>;
inout <port_list>;
// module descriptions
endmodule端口说明
- 被驱动的信号为net类型(一般为wire)
- 驱动信号的为reg类型
四、赋值语句
阻塞赋值(Blocking)
- 右侧求值和左侧赋值连续进行
- 用于组合逻辑设计
- 语法:
a = b;
非阻塞赋值(Non-blocking)
- 考察时刻前对所有非阻塞语句求值
- 考察时刻后对左侧赋值
- 用于时序逻辑设计
- 语法:
a <= b;
设计规则
- 组合逻辑尽量采用阻塞赋值
- 时序逻辑采用非阻塞赋值
- 同一always块不要混用两种赋值
- 不同时序和组合逻辑写在不同always块
- 不同always块不对同一变量赋值
五、可综合设计
推荐结构
组合逻辑 → 时序逻辑
移位寄存器示例
module SHIFTREG(CLK, RST, IN, D);
input CLK, RST;
input [7:0] IN;
output [7:0] D;
always@(posedge CLK or posedge RST) begin
if(RST == 1) begin
D <= IN;
end
else begin
D <= {D[0], D[7:1]};
end
end
endmodule六、参数定义
parameter <list_of_assignment>- 可用于定义延时及宽度变量
- 参数定义是局部的,只在当前模块有效
- 支持寄存器数组描述存储器
七、编译指导
| 指令 | 说明 |
|---|---|
| `define | 宏定义 |
| `undef | 解除宏定义 |
| `ifdef | 条件编译 |
| `include | 文件包含 |
| `timescale | 时间单位和精度 |
| `resetall | 重置所有编译指导 |
`timescale语法
`timescale <time_unit>/<time_precision>
示例:timescale 1ns/100ps
八、系统任务和函数
常用系统任务
$time:返回当前仿真时间$display:显示信号值$monitor:监视信号变化$finish:结束仿真$readmemb:从文件读取二进制数$readmemh:从文件读取十六进制数
示例
$monitor($time, "a = %b, b = %h", a, b)关键要点
- 4值逻辑系统:0, 1, x, z
- 可综合代码区分:仿真代码 ≠ 可综合代码
- 赋值风格:组合逻辑用阻塞,时序逻辑用非阻塞
- 参数化设计:提高代码复用性
- 层次化设计:模块嵌套,提高可维护性