Verilog基础与电路设计

核心内容概述

本资料系统介绍了Verilog硬件描述语言的基础语法、设计流程和可综合代码风格,是FPGA设计入门的重要参考资料。

一、Verilog概述

发展历史

  • 1984年研发
  • 1995年成为IEEE 1364标准

设计层次

  1. 系统级(System Level):系统功能描述
  2. 行为级(Behavioral Level):算法描述
  3. 寄存器传输级(RTL):数据流和时序描述
  4. 门级(Gate Level):逻辑门级网表

设计流程

代码编写 → 仿真 → 综合 → 验证

应用场景

  1. ASIC和FPGA工程师编写可综合代码
  2. 高抽象级系统仿真与系统接口开发
  3. 硬件测试工程师编写测试环境
  4. ASIC和FPGA单元模块建模

二、Verilog基础语法

标识符

  • 必须以字母或下划线开头
  • 最长1023个字符
  • 区分大小写(sel ≠ SEL)
  • 有效示例:shift_reg_a, busa_index, _bus3
  • 无效示例:34net(数字开头), a*b_net(含*)

常量定义

格式:<size>'<base><value>

举例解释
12十进制数(32位)
8’b1100_00018位二进制数
64’hff0164位十六进制数
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;

设计规则

  1. 组合逻辑尽量采用阻塞赋值
  2. 时序逻辑采用非阻塞赋值
  3. 同一always块不要混用两种赋值
  4. 不同时序和组合逻辑写在不同always块
  5. 不同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)

关键要点

  1. 4值逻辑系统:0, 1, x, z
  2. 可综合代码区分:仿真代码 ≠ 可综合代码
  3. 赋值风格:组合逻辑用阻塞,时序逻辑用非阻塞
  4. 参数化设计:提高代码复用性
  5. 层次化设计:模块嵌套,提高可维护性