1第二章Verilog-HDL基础知识1.Verilog-HDL概述1.1什么是硬件描述语言(HDL)HDL:HardwareDescriptionLanguage硬件描述语言HDL是一种用形式化方法描述数字电路和系统的语言,可以描述硬件电路的功能、信号连接关系和定时关系。1.2使用HDL的优点电路的逻辑功能容易理解;便于计算机对逻辑进行分析处理;把逻辑设计与具体电路的实现分成两个独立的阶段来操作;逻辑设计与实现的工艺无关;逻辑设计的资源积累可以重复利用;可以由多人共同更好更快地设计非常复杂的逻辑电路(几十万门以上的逻辑系统)。1.3Top_Down设计思想1.4Verilog-HDL简介1.4.1VerilogHDL的发展1.4.2Verilog-HDL与VHDL的比较☆VHDL-VHSICHardwareDescriptionLanguage。VHDL于1987年成为IEEE标准。☆Verilog-HDL简单易学,语法比较灵活。VHDL语法严谨,需要较长的时间学会。☆Verilog-HDL在系统抽象方面比VHDL略差,但在门级开关电路描述方面比VHDL强。21.4.3Verilog-HDL的应用ASIC和FPGA设计师可用它来编写可综合的代码。描述系统的结构,做高层次的仿真。验证工程师编写各种层次的测试模块对具体电路设计工程师所设计的模块进行全面细致的验证。库模型的设计:可以用于描述ASIC和FPGA的基本单元(Cell)部件,也可以描述复杂的宏单元(MacroCell)。1.4.4Verilog-HDL的抽象级别用Verilog-HDL描述的电路设计就是该电路的VerilogHDL模型,这些模型可以是实际电路的不同级别的抽象,这些抽象的级别和它们对应的模型类型共有以下五种:系统级(system):用高级语言结构实现设计模块的外部性能的模型。算法级(algorithmic):用高级语言结构实现设计算法的模型。RTL级(RegisterTransferLevel):描述数据在寄存器之间流动和如何处理这些数据的模型。门级(gate-level):描述逻辑门以及逻辑门之间的连接的模型。开关级(switch-level):描述器件中三极管和储存节点以及它们之间连接的模型。2.Verilog-HDL的模块2.1模块的结构Verilog的基本设计单元是“模块”。一个模块由两部分组成,一部分描述接口;另一部分描述逻辑功能,即定义输入是如何影响输出的。2.1.1模块的端口定义模块的端口声明了模块的输入输出口。3其格式如下:module模块名(端口1,端口2,端口3,...);2.1.2模块的内容模块内容包括I/O说明、内部信号声明和功能定义及描述。每一条语句必须都以;结束。2.1.2.1I/O说明☆I/O说明的格式如下:input端口1,端口2….;//输入端口output端口1,端口2….;//输出端口inout端口1,端口2….;//双向端口☆也可以写在端口声明语句中,如moduleXXX(inputport1,outputport2…);2.1.2.2功能定义用assign声明语句assigna=b&c;用实例化元件andu1(q,a,b);用always语句块或者initial语句块always@(posedgeclk)beiginif(clr)q=1’b0;elseq=a;end2.1.2.3补充内容☆标识符1.标识符就是用户为程序描述中的Verilog对象所起的名字。模块名、端口名和实例名都是标识符。2.标识符必须以英语字母(a-z,A-Z)起头,或者用下横线符(_)起头。其中可以包含数字、$符和下横线符。3.标识符最长可以达到1023个字符。4.Verilog语言是大小写敏感的,所有的Verilog关键词都是小写的。☆空格和注释1.空格在文本中起一个分离符的作用,别的没有其他用处。2.单行注释符用//*********,与C语言一致。3.多行注释符用/*------------------*/与C语言一致。注意养成写注释的习惯,便于程序调试和以后程序的利用。2.2模块的例化一个模块可以由几个子模块构成,一个模块也可以调用其他模块,形成层次结构。对低层次模块的调用称为模块的例化。42.3模块的测试需要有测试激励信号输入到被测模块。需要记录被测模块的输出信号。需要把用功能和行为描述的Verilog模块转换为门级电路互连的电路结构(综合)。需要对已经转换为门级电路结构的逻辑进行测试(门级电路仿真)。需要对布局布线后的电路结构进行测试。(布局布线后仿真)。3.数据类型3.1Verilog的四种逻辑值0、低、伪、逻辑低1、高、真、逻辑高X、不确定:逻辑冲突无法确定其逻辑值HiZ、高阻抗、三态、无驱动源注:x和X、z和Z不区别大小写。Z有时候也用?代替。3.2总括VerilogHDL中共有19种数据类型,分成常量和变量。最基本最常用的4种:寄存器型reg线网型wire5整形integer参数型parameter其余的包括:large\medium\scalared\time\small\tri\trio\tri1\triand\trior\trireg\vectored\wand\wor型,主要与基本单元库有关,设计时很少使用。3.3常量在程序运行中,其值不能被改变的量叫常量、两类最基本的常量:数字型常量和参数(parameter)1.数字型常量:整型数可以按如下两种方式书写☆简单的十进制数格式☆基数格式2.基数表示法格式:[位宽]’进制数字无符号数。位宽是按照二进制数来计算的。进制可以为b或B(二进制)、o或O(八进制)、d或D(十进制)、h或H(十六进制)。注:如果定义的长度比为常量基数表示法指定的长度长,通常在左边填0补位。但是如果数最左边一位为x或z,就相应地用x或z在左边补位。如果长度定义得更小,那么最左边的位相应地被截断。x(或z)在十六进制值中代表4位x(或z),在八进制中代表3位x(或z),在二进制中代表1位x(或z)。当常量不说明位数时,默认是32位,每个字母用8位ASCII码来表示。3.下划线下划线可以用来分割数的表达式以提高程序的可读性,但不能用在位宽和进制处,只能用于具体的数字之间。4.负数☆一个数字可以被定义成负数,只要在位宽表达式前加一个减号。5.参数参数是一个常量。用parameter定义一个标识符来代表一个常量。格式:parameterparam1=const_expr1,param2=const_expr2,…,paramN=const_exprN;参数经常用于定义时延和变量的宽度。如:parametersize=8;reg[size-1:0]a,b;模块参数值的改变可采用下述两种方式:1.参数定义语句(defparam);2.带参数值的模块引用。eg1:通过defparam改变参数值。6eg2:通过模块引用改变参数值。3.4变量在Verilog中有两大主要数据类型:连线类型(wire)、寄存器类型(reg)。3.4.1线网类型包含下述不同种类的线网子类型。wire,tri用于连线的最常见的线网类型wor,trior线或wand,triand线与trireg此线网存储数值,用于电容节点的建模tri1,tri0用于线逻辑的建模,上拉或下拉驱动supply0,supply1supply0用于对“地”建模,supply1对电源建模nets(网络连线)由模块或门驱动的连线。驱动端信号的改变会刻传递到输出的连线上。3.4.2wire型3.4.2.1wire型变量的定义格式3.4.2.2线网类型有效值表当一个线形有两个或多个驱动时,线网的有效值按如下表确定。73.4.3寄存器类型(reg)reg型变量能保持其值,直到它被赋于新的值。reg型数据常用来表示always块内的指定信号,常代表触发器。3.4.3.1reg型变量的定义格式3.4.3.2存储器类型(memory)用一个寄存器数组来构成memory型变量。格式:reg[msb:lsb]存储器[upper1:lower1];如:reg[3:0]MyMem[63:0];//64个四位寄存器组3.4.4其他类型变量integer整数寄存器有符号数。主要用来高层次建模。如:integerA;//整形寄存器,32位integerB[1023:0];//1024位time时间类型寄存器如:timeCurrentTime;//CurrentTime存储一个时间值CurrentTime=$time;3.4.5如何选择正确的数据类型输入端口(input)可以由寄存器(reg)或线网(wire)连接驱动,但它本身只能驱动网络连接。输出端口(output)可以由寄存器或线网连接驱动,但它本身只能驱动线网连接。输入/输出端口(inout)只可以由线网连接驱动,但它本身只能驱动线网连接。如果信号变量是在过程块(initial块或always块)中被赋值的,必须把它声明为寄存器类型变量。3.5运算符和表达式Verilog-HDL中的运算符可以分为下述类型:1.算术运算符2.关系运算符3.逻辑运算按位运算符84.缩减(归约)运算符5.移位运算符6.条件运算符7.连接和复制运算符3.5.1算术运算符算术运算符有:1.+(一元加和二元加)2.-(一元减和二元减)3.*(乘)4./(除)5.%(取模)注:1.整数除法截断任何小数部分。如:7/4结果为1。2.取模运算符求出与第一个运算符符号相同的余数。3.5.2关系运算符关系运算符有:1.(大于)2.(小于)3.=(不小于)4.=(不大于)5.==(逻辑相等)6.!=(逻辑不等)7.===(全等)8.!==(非全等)注:1.如果操作数长度不同,长度较短的操作数在最重要的位方向(左方)添0补齐。2.注意==与===、!=与!==的区别。3.5.3逻辑运算符逻辑运算符有:1.&&(逻辑与)2.||(逻辑或)3.!(一元逻辑非)注:1.这些运算符在逻辑值0或1上运算。逻辑运算的结果为0或1。3.5.4按位运算符按位运算符有:1.~(一元非)2.&(二元与)3.|(二元或)4.^(二元异或)5.~^,^~(二元异或非)注:1.这些运算符在输入操作数的对应位上按位操作,并产生向量结果。2.93.不同长度操作符运算时,右端对齐,左端补0。4.注意:逻辑与“&&”和按位与“&”是不同的;逻辑或“||”和按位与“|”是不同的;逻辑非“!”和按位取反“~”是不同的。3.5.5缩减运算符缩减(归约)运算符在单一操作数的所有位上操作,并产生1位结果。运算符有:1.&(归约与):如果存在值为0的位,那么结果为0;若如果存在值为x或z的位,结果为x,否则结果为1。2.~&(归约与非):与归约运算符&相反。3.|(归约或):如果存在值为1的位,那么结果为1;如果存在值为x或z的位,结果为x,否则结果为0。4.~|(归约或非):与归约运算符|相反。5.^(归约异或):如果存在值为x或z的位,那么结果为x;否则如果操作数中有偶数个1,结果为0,否则结果为1。6.~^(归约异或非):与归约运算符^相反。3.5.6移位运算符移位运算符有:1.(左移)2.(右移)注:1.移位运算符左侧操作数移动右侧操作数表示的次数,它是一个逻辑移位。空闲位添0补位。3.5.7条件运算符条件运算符根据条件表达式的值选择表达式,形式如下:cond_expr?expr1:expr2如果cond_expr为真(即值为1),选择expr1;如果cond_expr为假(值为0),选择expr2。如果cond_expr为x或z,结果将是按以下逻辑expr1和expr2按位操作的值:0与0得0,1与1得1,其余情况为x。3.5.8位连接运算符10连接操作是将小表达式合并形成大表达式的操作。形式如:{expr1,expr2,...,exprN}