数字集成电路设计(二、Verilog HDL基础知识)


  • Verilog来源于C语言,后面会发现它的语法集和C语言几乎完全一样,但是设计方法和C语言完全不一样

1. 语言要素

1.1 空白符

空白符包括空格符(\b)、制表符(\t)、换行符和换页符。空白符使代码看起来结构清晰阅读起来更方便。在编译和综合时,空白符被忽略。
在这里插入图片描述

1.2 注释符

  • 和C语言完全一样
    (1)单行注释:单行注释以“//”开始,Verilog HDL 忽略从此处到行尾的内容。
    (2)多行注释:多行注释以“/*”开始,到“*/”结束,Verilog HDL忽略其中的注释内容
    在这里插入图片描述
    在这里插入图片描述
  • 多行注释不允许嵌套,但是单行注释可以嵌套在多行注释中

1.3 标识符

  • 它可以是任意一组字母、数字、$符号和_(下划线)符号的组合。应该注意的是,标识符的字母区分大小写,并且第一个字符必须是字母或者下划线。
    在这里插入图片描述

1.3.1 转义标识符

  • Verilog HDL 规定了转义标识符(Escaped Identifier)。采用转义标识符可以在一条标识符中包含任何可打印的字符。转义标识符以“\”(反斜线)符号开头,以空白结尾(空白可以是一个空格、一个制表字符或换行符)。
    在这里插入图片描述

1.4 关键字

  • Verilog HDL语言内部已经使用的词称为关键字或保留字,它是 Verilog HDL语言内部的专用词,是事先定义好的确认符,用来组织语言结构。
  • 用户不能随便使用这些关键字。需注意的是,所有关键字都是小写的
  • 例如,ALWAYS 不是关键字,它只是标识符,与always(关键字)是不同的
    在这里插入图片描述

1.5 数值

  • Verilog有四种基本的逻辑数值状态
    在这里插入图片描述

1.5.1 整数及其表示方式

在这里插入图片描述

  • 整数的表示形式为如下:
    +/-<size><baseformat><number>
    (1)“+/-”是正数和负数标示
    (2)size 指换算过后的二进制数的宽度
    (3)“ ’ ”为基数格式表示的固有字符
    (4)base_format 是其基数符号
    (5)number是可以使用的数字字符集,形式上是相应进制格式下的一串数值

  • 需要注意
    (1)在位宽和字符之间以及进制和数值之间可以有空格,但数字之间不能有空格,下面的情况是允许的
    在这里插入图片描述
    (2)下面的情况是不允许的

在这里插入图片描述

1.5.2 实数及其表示方式

  • 在硬件描述语言中,没有实数。想要表示一个带小数点的数字只能用定点(小数点位置固定)或者浮点的表示方法,把小数变成整数
  • 电路设计中,没有传统意义的实数概念。**但是HDL为什么规定这个方式,是用在测试和仿真中间。**不能用在设计。
  • 实数有两种表示方法:
    (1)十进制表示法。采用十进制格式,小数点两边必须都有数字,否则为非法的表示形式。例如:3.0、4.54、0.2 等都是正确的,而5.是错误的。
    (2)科学计数法。例如:564.2e2 的值为 56420.0,8.7E2 的值为870.0(e 不分大小写)3E-3的值为0.003。
    在这里插入图片描述

1.5.3 字符串及其表示方式

  • 字符串是指用双引号括起来的字符序列,它必须包含在同一行中,不能分行书写。若字符串用作 Verilog HDL表达式或赋值语句中的操作数则字符串被看做8位的ASCII值序列,即一个字符对应8位的ASCII值。例如"hello world"和"Anexample for Verilog HDL"是标准的字符串类型。

2. 数据类型

  • 这是一个新的概念,因为在HDL中,我们面对的是数字电路,数字电路就会有一个能力的问题(并不是以电压来衡量,是以电流来衡量),所以根据电流驱动能力的强弱,分成了以下等级:
    在这里插入图片描述
  • supply:导线直接连接
  • strong:上拉电阻接到电源
  • pull:上拉电阻比strong的上拉电阻要大
  • large:大容性,有存储的功能
  • weak:电流非常小
  • medium:电流更小一点
  • small:小容性
  • highz:高阻态,直接断开

2.1 物理数据类型

2.1.1 连线型

在这里插入图片描述

  • 最常用的是wire和tri,wire表示的是0,1和不定状态(X)。tri成为三态,包括了0,1,不定状态(X)和高阻状态(Z)
  • wor也是一种连线型的变量,但是它解决的问题是两个线对一个线进行驱动,实际上是在两个线中间增加了一个或门
  • 功能
    (1)wire和tri
    在这里插入图片描述
    (2)wor和trior(带有一定逻辑功能,线或)
    在这里插入图片描述
    (3)wand和triand(带有一定逻辑功能,线或)
    在这里插入图片描述

2.1.2 寄存器型

  • 在数字电路设计过程中,经常会遇到组合电路和时序电路,组合电路就是连线型的变量和时序电路就是带有寄存器功能的,叫做reg类型
  • reg型数据与 wire型数据的区别在于,reg 型数据保持最后一次的赋值,而wire型数需要有持续的驱动。
  • 一般情况下,reg 型数据的默认初始值为不定值 x,缺省时的位宽1 位。
    在这里插入图片描述
  • reg 型变量一般为无符号数,若将一个负数赋给 reg 型变量,则自动转换成其二进制补码形式
    在这里插入图片描述

2.2 连线型和寄存器型数据类型的声明

2.2.1 连线型数据类型的声明

  • 缺省的连线型数据的默认类型为1位(标量)wire类型。
  • Verilog HDL禁止对已经声明过的网络、变量或参数再次声明。
  • 连线型数据类型声明的一般语法格式如下:
    在这里插入图片描述
    (1)net_declaration: 表示网络型数据的类型,可以是 wire、tri、tri0、tr1、wand、triand.trior、wor、trireg 中的任意一种。对于 trireg 类型,其声明还有一个 charge_strength(电荷强度)的可选项
    (2)range:用来指定数据为标量或矢量。若该项默认,表示数据类型为1位的标量,超过1位则为矢量形式。
    (3)delay:指定仿真延迟时间
    (4)list_of_variables: 变量名称,一次可定义多个名称,之间用逗号分开

2.2.2 寄存器型数据类型的声明

在这里插入图片描述

  • range为可选项,它指定了 reg 型变量的位宽,缺省时为1位
  • list_of_register_variables:变量名称列表,一次可以定义多个名称,之间用逗号分开
  • 它只表示一个存储,没有驱动强度这样的概念

2.3 物理数据类型的声明举例

在这里插入图片描述

2.4 存储器型

  • 存储器型变量可以描述 RAM 型、ROM 型存储器以及 reg 文件
  • 存储器型变量的一般声明格式:
    在这里插入图片描述
    (1)range1:表示存储器中寄存器的位宽,格式为[msb:lsb]。
    (2)range2:表示寄存器的个数,格式为[msb:lsb],即有 msb-lsb+1个。
    (3)name_of_register:变量名称列表,一次可以定义多个名称,之间用逗号分开

在这里插入图片描述
在这里插入图片描述

  • 一个 n 位的寄存器可以在一条赋值语句里进行赋值,而一个完整的存储器则不行。例如,对于上例可以进行“rega=0;”的赋值操作,而不能进行“meml=0”的赋值操作
  • 如果想对存储器中的存储单元进行读写操作,则必须指定该单元在存储器中的地址

在这里插入图片描述

2.5 抽象数据类型

  • 除了物理数据类型外,Verilog HDL 还提供了以下几种抽象数据类型:整型(integer)时间型(time)、实型(real)及参数型(parameter)。它们只是纯数学的抽象描述,不能够与实际的硬件电路相映射。

3. 运算符

  • 运算符在Verilog起到了很大的作用,它代表着电路,这是一个很重要的内容
    在这里插入图片描述
  • 会牵扯到两个概念:
    (1)优先级是什么(保留了和其他高级语言相类似的运算符优先级)
    (2)功能是什么

3.1 算术运算符

  • Verilog HDL中常用的算术运算符主要有五种,分别是加法(+)减法(-)乘法(*)除法(和取模(%)。
  • 这五种运算符都属于双目运算符。符号“+”、“-”、“*”、“/”分别表示常用的四则运算。%是取模运算,如“6%3”的值为 0,“7%4”的值为3。
  • 需要注意:
    (1)在赋值语句下,算术操作结果的长度由操作左端的目标长度决定。
    (2)有符号数和无符号数的使用。当信号位宽不同的时候,表征的数是不一样的,希望尽可能采用无符号数作为设计的基础。
    在这里插入图片描述
  • 可以看到Verilog对运算符的处理很特殊,一直在考虑输入位宽和输出位宽(加法器就是两路数进去出来一路数,只和数据位宽有关系),HDL更注重于描述运算符的结构特性
  • !!加法和减法是可以直接进行综合的,也就是说当我们使用这个符号的时候,我们的设计工具就会给我们设计一个加法电路或者减法电路,换句话说,加法电路和减法电路其实是一样的,所谓的减法电路就是加法电路加上一个负数
  • !!乘法在早期是尽可能避免的,因为综合工具支持的不好,但是现在EDA对乘法支持非常好,所以我们可以用这个符号去生成一个乘法电路
  • !!除法和取模目前EDA工具支持的不好,但是如果工艺库里面有除法和取模电路,就可以用符号去做
  • 可以利用MATLAB集成了算法的运算,也就是当我们把数学模型写进去之后,MATLAB可以直接生成我们所需要的Verilog代码,这样就更加提高了对操作算法的支持程度
  • !!算术运算符是整个Verilog运算符中间最复杂的,其他的都和我们的数字电路基本电路是对应的

3.2 关系运算符

  • 关系运算符也是双目运算符,是对两个操作数的大小进行比较。关系运算符有大于(>)小于(<)、大于等于(>=)和小于等于(<=)几种(还包括了相等运算符中的等于(==)和全等于(===))
  • 关系运算符就是成立输出1,不成立输出0,也就是结果应该是一个1bit的信号
    在这里插入图片描述
  • 第四个在电路中间不会遇到这个问题,因为数字电路对于不定态的管理非常严格(产生不定态的两种情况,一种是信号悬空,一种是两个信号驱动同一个信号,这两种情况对于可靠的数字电路来讲是不会出现的)
  • Verilog规定任何数和不定值的比较都会是一个不定值

3.3 相等关系运算符

  • 相等关系运算符是对两个操作数进行比较,比较的结果有三种:真(1)、假(0)和不定值(x)。Verilog HDL 语言中有四种相等关系运算符等于(==)、不等于(!=)、全等(===)、非等(!==)
  • 和关系运算符是一样的东西,只不过它比较的是相等
  • Verilog的相等运算符有四种,比较结果有三种“1”,“0”,“X”
    在这里插入图片描述
    (左边表的第一列第一个应该是0)
  • 这四种运算符都是双目运算符,要求有两个操作数。并且,这四种相等运算符的优先级别是相同的
  • “==”和“!”称为逻辑等式运算符,其结果由两个操作数的值决定,由于操作数中某些位可能是不定值x和高阻态值z,所以结果可能为不定值x
  • “===”和“!==”运算符则不同,它是对操作数进行按位比较,两个操作数必须完全一致,其结果才是 1,否则为 0。但是,若两个操作数对应位出现不定值 x 和高阻值 ,则可认为是相同的
  • 大部分用的还是”==“,对“===”的理解是为了避免计算产生了不定态一直传播。而且“===”可以做信号长度的比较,当两个信号值相同长度不同时,“==”会输出1,而“===”会输出0,但是为什么经常用的是“==”,这是因为在电路设计的时候是不允许不同位宽的信号进行比较的。第二个是在可靠的设计中间是不允许不定值和高阻进行比较的

3.4 逻辑运算符

  • 逻辑运算符有三种,分别是逻辑与运算符(&&)、逻辑或运算符(||)、逻辑非运算符(!)其中逻辑与和逻辑或是双目运算符,逻辑非为单目运算符
  • 逻辑运算符其实也表征的是一个“1”或者“0”的概念,如果是“0”表征的是逻辑非(0电平),如果是非零就是逻辑真(高电平)
    在这里插入图片描述
  • !关系运算符和比较运算符代表数字电路中的数字比较器(数字比较器可以表示不等或者相等)
  • 逻辑运算符非对应的电路如下
    在这里插入图片描述
  • 需注意的是,若操作数中存在不定态 x,则逻辑运算的结果也是不定态,例如:a 的初值为4’b1100,b的初值为4‘b01x0,则!a=0,!b=x,a&&b=x,alb=x

3.5 按位运算符

  • 按位取反(~),按位与(&),按位或(|),按位异或(^),按位同或(^~)

在这里插入图片描述

3.6 归约运算符(缩位运算符)

  • 归约运算符按位进行逻辑运算,属于单目运算符。由于这一类运算符操作的结果是产生1位逻辑值,因而被形象地称为缩位运算符。
  • 归约运算符包括与(&),或(|),异或(^)以及相应的非操作~&、~|、~^、^~
  • 归约运算符就是为了解决一个信号里面的一串信号中间的运算
    在这里插入图片描述

3.7 移位操作运算符

  • 移位运算符有两种:左移位运算符(<<)右移位运算符(>>)
  • 运算过程是将边(右边)的操作数向左(右)移,所移动的位数由右边的操作数来决定,然后用0来填补移出的空位
  • 思考:为什么只有两个,而没有C语言当中那么多循环移等操作
    在这里插入图片描述
  • 这个操作符用的不多,为什么等下面来讲

3.8 条件运算符

  • 条件运算符是 Verilog HDL 里唯一的三目运算符,它根据条件表达式的值来选择执行达式,其表达形式为:
    在这里插入图片描述
  • 条件表达式的计算结果有真(1)、假(0)和不定态(x)三种。当条件表达式的结果为真时执行表达式1,当条件表达式的结果为假时,执行表达式 2
  • 如果条件表达式的结果为不定态 ,则模拟器将按位对表达式1的值与表达式2的值进行比较,位与位的比较按表 2.3-7 的规则产生每个结果位,从而构成条件表达式的结果值
    在这里插入图片描述
  • 条件运算符举例:
    在这里插入图片描述
  • 若该数据选择器的sel端为不定态x,则out 由in1和i2按位运算的结果得出。若in1=4’b0011,in2=4’b0101,则按照上述真值表得出 out=4’b0xx1。

3.9 连接和复制运算符

  • !!前面说移位运算符是不重要的一个运算符,因为连接和复制运算符能够得到更好的结果
  • Verilog HDL语言中还有两个特殊的运算符:连接运算符({})和复制运算符({{}})
  • 连接运算符是把位于大括号({})中的两个或两个以上信号或数值用逗号(,)分隔的小表达式按位连接在一起,最后用大括号括起来表示一个整体信号,形成一个大的表达式。
  • 重复运算符({{}})将一个表达式放入双重花括号中,复制因子放在第一层括号中。它为复制一个常量或变量提供了一种简便方法
  • 首先明确一点,这个操作没有对应的电路,只是重新定义
    在这里插入图片描述

4. 模块

4.1 模块的基本概念

  • 模块(module)是 Verilog HDL语言的基本单元
  • 代表一个最基本的功能模块,语法中代表一段程序,电路中每个模块代表一个电路
    在这里插入图片描述
  • 一个模块主要包括模块的开始与结束、模块端口定义、模块数据类型说明和模块逻辑功能描述几个基本部分
  • 例:上升沿D触发器的Verilog描述:
    在这里插入图片描述
  • 例:上升沿D触发器的硬件:
    在这里插入图片描述

4.2 端口

4.2.1 端口的定义

  • 端口是模块与外界或其它模块沟通的信号线。模块的端口可以是输入端口(input)、输出端口(output)或双向端口(inout)。
  • 缺省状态下,端口类型都将默认为 wire 类型

4.2.2 模块引用时端口的对应方式

  • 在引用模块时其端口可以用如下两种方法连接
    (1)在引用时,严格按照模块定义的端口顺序来连接,不用标明源模块定义时规定的端口名。
    在这里插入图片描述
    (2)在引用时用“”标明源模块定义时规定的端口名。
    在这里插入图片描述
  • 2
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

普通的晓学生

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值