新闻中心

EEPW首页 > 嵌入式系统 > 设计应用 > Verilog HDL简介&基础知识1

Verilog HDL简介&基础知识1

作者:时间:2024-01-29来源:电子森林收藏

Verilog 是 Verilog HDL 的简称,Verilog HDL 是一种硬件描述语言(HDL:Hardware Description Language),硬件描述语言是电子系统硬件行为描述、结构描述、数据流描述的语言。利用这种语言,数字电路系统的设计可以从顶层到底层(从抽象到具体)逐层描述自己的设计思想,用一系列分层次的模块来表示极其复杂的数字系统。然后,利用电子设计自动化()工具,逐层进行仿真验证,再把其中需要变为实际电路的模块组合,经过自动综合工具转换到门级电路网表。接下去,再用专用集成电路 ASIC 或现场可编程门阵列 自动布局布线工具,把网表转换为要实现的具体电路布线结构。在 的设计中,我们有多种设计方式,如绘制原理图、编写描述语言代码等。早期的工程师对原理图的设计方式情有独钟,这种输入方式能够很直观的看出电路的结构并快速理解电路。随着逻辑规模的不断攀升,逻辑电路也越来越复杂,这种输入方式就会显得力不从心,应付简单的逻辑电路还算实用,应付起复杂的逻辑电路就不行了。因此取而代之的便是编写描述语言代码的方式,现今的绝大多数设计都是采用代码来完成的。

本文引用地址:http://www.eepw.com.cn/article/202401/455162.htm

基础概念

  • 四值逻辑

首先我们先来讲一下 Verilog 的四值逻辑系统。

在Verilog 的逻辑系统中有四种值,也即四种状态。

逻辑 0:表示低电平,也就对应我们电路 GND;

逻辑 1:表示高电平,也就是对应我们电路的 VCC;

逻辑 X:表示未知,有可能是高电平,也有可能是低电平,仿真发生了不能解决的逻辑冲突;

逻辑 Z:表示高阻态,外部没有激励信号是一个悬空状态。

  • 常数

    • 整数

    整数常数的定义规则如下。

    1. 整数可以用十进制(decimal)、十六进制(hexadecimal)、八进制(octal)、二进制(binary)形式表示,表现形式为:
      <null|+|→<size><sign:s|S><base: d|D|h|H|o|O|b|B><0~9|0~f|0~7|0~1|x|z>,其中size、sign和base是可选的。
    2. 最简单的整数是没有size、sign和base的十进制数,只用0~9,可选+或-,表示的是符号数(signed integer)。
    3. sign必须和base一起使用。当base前面有sign标志时,表示的是符号数(signed integer);当base前面没有sign标志时,表示的是无符号数(unsigned integer)。
    4. 负数以2的补码形式表示。
    5. x表示不可知值(unknown),z表示高阻值(Hiz),在十进制数中不能使用x和z。其中z可以用?代替,在使用casex和casez时,为了便于理解常用?代替z。
      当z作为逻辑门的输入或在表达式中出现时,通常把z当做x处理,但是当z出现在MOS的原语(primitive)中,还是当做z,因为MOS可以传送高阻(HiZ)。
    6. 如果无符号数的位数小于size,那么就在左端扩展:如果最左边的位是0或1,左端就补0扩展;如果最左边的位是x,左端就补x扩展;如果最左边的位是z,左端就补z扩展。
    7. 如果无符号数的位数大于size,那么就在左端截去多余的位。
    8. 在Verilog-2001中,对于没有size限定的数,那么就在左端按照表达式的size根据最左边的位进行扩展(0、x或z),扩展多少位都没有问题。但是在Verilog-1995中,如果最左边位是x或z,那么x或z最多只能扩展到32位,超出的位按0扩展。
    9. 对于<sign>、<base>、a~f、x和z,大写和小写都可以使用(case insensitive)。
    10. 为了阅读方便,可以在数字之间加(下划线)分割数字。 -注意:当把带有size 的负常数(sized signed constant numbers)赋给一个reg类型的变量时,不管这个变量是否是signed,对这个负常数做符号扩展(sign-extend)。
      <code verilog>
      例子: 1. Unsized constant numbers 659 is a decimal number 'h 837FF is a hexadecimal number 'o7460 is an octal number 4af is illegal (hexadecimal format requires 'h)
      2. Sized constant numbers 4'b1001 is a 4-bit binary number 5 'D 3 is a 5-bit decimal number 3'b01x is a 3-bit number with the least significant bit unknown 12'hx is a 12-bit unknown number 16'hz is a 16-bit hign-impedance number
      3. Using sign with constant numbers 8 'd -6 this is illegal syntax -8 'd 6 this defines the two's complement of 6, held in 8 bits-equivalent to -(8'd 6) 4 'shf this denotes the 4-bit number '1111', to be interpreted as a 2's complement number, or '-1'. This is equivalent to -4'h 1 -4 'sd15 this is equivalent to -(-4'd 1), or '0001' 16'sd? the same as 16'sbz
      4. Automatic left padding reg [11:0] a, b, c, d; initial begin a = 'h x; yields xxx b = 'h 3x; yields 03x c = 'h z3; yields zz3 c = 'h 0z3; yields 0z3 end
      reg [84:0] e, f, g; e = 'h5; 
      yields {82{1'b0},3'b101} f = 'hx; yields {85{1'bx}} g = 'hz; yields {85{1'bz}}
      5. Use 27195000 16'b0011010100011111 32 'h 12ab_f001
      6. sign-extend reg signed [15:0] h; reg [15:0] m; h = -12'h123; 16'FEDD h = 12'shEDD; 16'FEDD m = -12'h123; 16'FEDD m = 12'shEDD; 16'FEDD
      我们要避免如下书写错误: case (sel[1:0]) 00: y = a; 01: y = a; 10: y = a; not execute 11: y = a; not execute endcase
      </code>
    • 实数

    实数常数定义符合IEEE Std 754-1985标准,采用双精度浮点数(double-precision floating-point numbers)。实数有两种方式:十进制法和科学计数法。

    例如:
    1.2,        0.1,      2394.26331
    1.2.E12,    1.30e-2,     0.1e-0,    23E10,    29E-2
    236.123_763_e-12          //underscores are ignored
    
    当把实数赋给一个整数变量时,按四舍五入转换后赋值。
    例如,35.7和35.5都转换成36,而35.2则转换成35。
    例如,-1.5转换成-2,而1.5则转换成2.
    • 字符串

    字符串的定义规则如下。

    1. 字符串是包含在两个“(双引号)之间的字符。

    2. 字符串在表达式中或在赋值时,被当做一个由8-bit ASCII码序列组成的无符号数。

    3. 字符串中可以使用如下的特殊字符:n、t、、”和ddd,ddd用于表示八进制数。

    4. 使用reg变量操作字符串时,每8-bit存一个字符。

    5. 因为字符串被当做无符号数,所以在用整数的补齐和截去规则,就是如果字符串的位长小于变量的位长,那么字符串做右对齐存放到变量的右侧,变量的左侧补0;如果字符串的位长大于变量的位长,那么字符串做右对齐存放到变量的右侧,多余的位截去。

    • 标识符

    标识符就是模块、端口、任务、函数、变量、线网、参数、实例等的名字。定义标识符要花一些心思,要含义清晰、简洁明了。

  • 数据类型

    • 线网

    线网(net)用于表示结构体(如逻辑门)之间的连接。除了trireg之外,所有其他的线网类型都不能保存值,线网的值时由driver决定的,例如由连续赋值驱动或由逻辑门驱动。如果driver没有驱动线网,那么线网的值是z,但是tri0、tri1、trireg除外,tri0将是0,tri1将是1,而trireg将保持之前driver驱动的值。

    线网有以下这些类型:wire、wand、wor、tri、triand、trior、tri0、tri1、trireg、uwire、supply0、supply1。

    1.1 wire和tri

    wire和tri是一样的,具有同样的语法和功能,提供两个名字是用于不同方面的建模:wire用于逻辑门的驱动或连续赋值的驱动,而tri用于多driver驱动。

    当多个具有相同驱动强度的driver驱动同一个wire或tri线网出现逻辑冲突时,线网的值是x(unknown)。

    1.2 wor、wand、trior、triand

    线逻辑(model wired logic)类型的线网有wor、wand、trior和triand,它们用于解决多个driver驱动同一个线网时出现的逻辑冲突。wor和trior实现线或(or)逻辑,wand和triand实现线与(and)逻辑。

    wor和trior是一样的,wand和triand是一样的,都是为了不同方面的建模。

    1.3 tr0、tr1

    tri0用于表示带有下拉电阻(pulldown)的线网。当没有driver驱动tri0线网时,它的值是0,强度是pull。

    tri1用于表示带有上拉电阻(pullup)的线网。当没有driver驱动tri1线网时,它的值是1,强度是pull。

    1.4 uwire

    Verilog-2005增加了uwire,只能被一个driver驱动,如果被多个driver驱动,那么编译时就会出错。但是不知为什么VCS现在还不支持uwire。

    1.5 supply0、supply1

    supply0和supply1用于模型电源,就是只能提供0和1值的线网,通常只在Vendor提供的标准单元库中使用,平时不用。

    1.6 驱动强度

    线网驱动强度(drive strength)包括:

    1. 用于表示0的强度:highz0、supply0、strong0、pull0、weak0。

    2. 用于表示1的强度:highz1、supply1、strong1、pull1、weak1。

    1.7 默认 net

    在Verilog-1995中,由连续赋值驱动而且不是端口的1-bit线网必须声明,用于端口连接的1-bit线网可以不必声明。但是在Verilog-2001中,就去掉了这个限制。

    • 变量

    变量是数据存储单元的抽象。变量具有如下特性。

    1. 变量将保持每次赋给它的值,直到下一次赋值给它。当过程块被触发时,过程块中的赋值就会改变变量的值。
    2. reg、time和integer的初始化值是x,real和realtime的初始化值是0.0。如果使用变量声明赋值(variable declaration assignment,例如reg abc = 1'b0;),那么就相当于在initial块中使用阻塞赋值。
    3. 对reg的赋值是过程赋值,因为reg能够保持每次赋的值,所以它能用于模型硬件寄存器(例如,边沿敏感的触发器或电平敏感的锁存器)。但是reg不只用于模型硬件寄存器,它也用于模型组合逻辑。
    4. 除了用于模型硬件,变量也有其他的用途。虽然reg很通用,但是integer和time可以提供更大的方便性和可读性。time变量常和$time函数一起使用。
    注意:可以把负值赋给线网和变量,只有integer、real、realtime、reg signed和net signed才能保持符号标志,而time、reg unsigned和net unsigned则把赋给它们的数值都当做无符号数处理。
    注意:interger等价于reg signed[31:0],time等价于reg unsigned[63:0]。
    注意:real和realtime是等价的,都是64-bit双精度浮点数,只不过realtime变量常和$realtime函数一起使用。
    注意:不能对real和realtime使用位索引(bit-select)和部分索引(part-select)。
      例子:  integer i = 32'h1234_5678;
     time    t = 64'habcd_efab_1234_5678;
     $display ("%x, %x", i[15:0], t[63:60]);

    • 向量

    标量(scalar)是没有范围声明的1-bit的线网(net)或reg。

    向量(vector)是带有范围声明的multi-bit的线网(net)或reg。

      例子:  wand w;                              // a scalar net of type "wand"
      wire w1, w2;                          // declares two wires
      tri [15:0] busa;                      // a three-state 16-bit bus
      reg a;                                // a scalar reg
      reg [3:0] v;                          // a 4-bit vector reg made up of v[3],
                                            // v[2], v[1], and v[0]
      reg signed [3:0] signed_reg;          // a 4-bit vector in range -8 to 7
      reg [4:-1] b;                         // a 6-bit vector reg
      reg [4:0] x, y, z;                    // declares three 5-bit regs


关键词: FPGA verilog HDL EDA

评论


相关推荐

技术专区

关闭