第二部分VerilogHDL基本语法2.1VerilogHDL程序模块结构设计模块模块端口定义I/O说明功能描述模块内容信号类型说明2.1.1模块端口定义模块端口定义用来声明设计电路模块的输入输出端口。端口定义格式如下module模块名(端口1,端口2,端口3,…);在端口定义的圆括弧中,是设计电路模块与外界联系的全部输入输出端口信号或引脚,它是设计实体对外的一个通信界面,是外界可以看到的部分(不包含电源和接地端),多个端口名之间用“,”分隔。例如,moduleadder(sum,cont,ina,inb,cin);2.1.2模块内容模块内容包括I/O说明、信号类型声明和功能描述。1.模块的I/O说明模块的I/O说明用来声明模块端口定义中各端口数据流动方向包括输入(input)、输出(output)和双向(inout)。I/O说明格式如下input端口1,端口2,端口3,…;output端口1,端口2,端口3,…;例如inputina,inb,cin;outputsum,cont;2.信号类型声明信号类型声明用来说明设计电路的功能描述中,所用的信号的数据类型以及函数声明。信号的数据类型主要有连线(wire)、寄存器(reg)、整型(integer)、实型(real)和时间(time)等类型。3.功能描述功能描述是VerilogHDL程序设计中最主要的部分,用来描述设计模块的内部结构和模块端口间的逻辑关系,在电路上相当于器件的内部电路结构。功能描述可以用assign语句、元件例化(instantiate)、always块语句、initial块语句等方法来实现,通常把确定这些设计模块描述的方法称为建模。(1)用assign语句建模用assign语句建模的方法很简单,只需要在“assign”后面再加一个表达式即可。assign语句一般适合对组合逻辑进行赋值,称为连续赋值方式。【例2.1】1位全加器的设计。inainbcinadder1sumcoutVerilogHDL源程序如下moduleadder1(sum,cout,ina,inb,cin);//模块端口定义inputina,inb,cin;outputsum,cout;//I/O声明assign{cout,sum}=ina+inb+cin;//功能描述语句endmodule//endmodule后不加分号默认的数据类型为wire(连线)型,{}为拼接运算符,是将cout、sum这样两个1位操作数拼接为一个2位操作数。(2)用元件例化(instantiate)方式建模元件例化方式建模是利用VerilogHDL提供的元件库实现的。例如,用与门例化元件定义一个3输入端与门可以写为andmyand3(y,a,b,c);(3)用always块语句建模always块语句可以产生各种逻辑,常用于时序逻辑的功能描述。一个程序设计模块中,可以包含一个或多个always语句。程序运行中,在某种条件满足时,就重复执行一遍always结构中的语句。【例2.2】8位二进制加法计数器的设计。modulecnt8(out,cout,data,load,cin,clk,clr);input[7:0]data;inputload,cin,clk,clr;output[7:0]out;outputcout;reg[7:0]out;//寄存器型参量,具有寄存功能always@(posedgeclk)//时钟上升沿,每次上升沿,执行always语句beginif(clr)out=8'b0;elseif(load)out=data;elseout=out+8'b1;endassigncout=&out&cin;//”&out”-与缩减运算式endmodule(4)用initial块语句建模initial块语句与always语句类似,不过在程序中它只执行1次就结束了。VerilogHDL程序设计模块的基本结构小结:①VerilogHDL程序是由模块构成的。每个模块的内容都是嵌在module和endmodule两语句之间,每个模块实现特定的功能,模块是可以进行层次嵌套的。②每个模块首先要进行端口定义,并说明输入(input)、输出(output)或双向(inouts),然后对模块的功能进行逻辑描述。③VerilogHDL程序的书写格式自由,一行可以一条或多条语句,一条语句也可以分为多行写。④除了endmodule语句外,每条语句后必须要有分号“;”。⑤可以用/*……*/或//……对VerilogHDL程序的任何部分作注释。一个完整的源程序都应当加上需要的注释,以加强程序的可读性。2.2VerilogHDL的词法2.2.1空白符和注释VerilogHDL的空白符包括空格、tab符号、换行和换页。空白符如果不是出现在字符串中,编译源程序时将被忽略。注释分为行注释和块注释两种方式。行注释用符号//(两个斜杠)开始,注释到本行结束。块注释用/*开始,用*/结束。块注释可以跨越多行,但它们不能嵌套。2.2.2常数VerilogHDL的常数包括数字、未知X和高阻Z三种。数字可以用二进制、十进制、八进制和十六进制等4种不同数制来表示,完整的数字格式为位宽’进制符号数字其中,位宽表示数字对应的二进制数的位数宽度;进制符号包括b或B(表示二进制数),d或D(表示十进制数),h或H(表示十六进制数),o或O(表示八进制数)。例如8’b10110001//表示位宽为8位的二进制数8’hf5//表示位宽为8位的十六进制数十进制数的位宽和进制符号可以缺省,例如125//表示十进制数125X和Z表示位数的特殊性:8’b1111xxxx//等价8’hfx8’b1101zzzz//等价8’hdz2.2.3字符串字符串是用双引号括起来的可打印字符序列,它必须包含在同一行中。例如,”ABC”,”ABOY.”,”A”,”1234”都是字符串。2.2.4标识符标识符是用户编程时为常量、变量、模块、寄存器、端口、连线、示例和begin-end块等元素定义的名称。标识符可以是字母、数字和下划线“_”等符号组成的任意序列。定义标识符时应遵循如下规则:①首字符不能是数字。②字符数不能多于1024个。③大小写字母是不同的。④不要与关键字同名。2.2.5关键字关键字是VerilogHDL预先定义的单词,它们在程序中有不同的使用目的。所有关键字都用小写例如,module和endmodule来指出源程序模块的开始和结束;用assign来描述一个逻辑表达式等。VerilogHDL的关键字有97个。2.2.6操作符操作符也称为运算符,是VerilogHDL预定义的函数名字,这些函数对被操作的对象(即操作数)进行规定的运算,得到一个结果。操作符通常由1~3个字符组成,例如,“+”表示加操作,“==”(两个=字符)表示逻辑等操作,“===”(3个=字符)表示全等操作。有些操作符的操作数只有1个,称为单目操作;有些操作符的操作数有2个,称为双目操作;有些操作符的操作数有3个,称为三目操作。1.算术操作符(Arithmeticoperators)常用的算术操作符:+(加)、-(减)、*(乘)、/(除)、%(求余)。其中%是求余操作符,在两个整数相除的基础上,取出其余数。例如,5%6的值为5;13%5的值是3。2.逻辑操作符(Logicaloperators)逻辑操作符包括:&&(逻辑与)、||(逻辑或)、!(逻辑非)3.位运算(Bitwiseoperators)位运算是将两个操作数按对应位进行逻辑操作。位运算操作符包括:~(按位取反)、&(按位与)、|(按位或)、^(按位异或)、^~或~^(按位同或)。在进行位运算时,当两个操作数的位宽不同时,计算机会自动将两个操作数按右端对齐,位数少的操作数会在高位用0补齐。4.关系操作符(Pelationaloperators)关系操作符有:(小于)、=(小于等于)、(大于)、=(大于等于)。其中,=也是赋值运算的赋值符号。关系运算的结果是1位逻辑值。在进行关系运算时,如果关系是真,则计算结果为1;如果关系是假,则计算结果为0;如果某个操作数的值不定,则计算结果不定(未知),表示结果是模糊的。5.等式操作符(Equalityoperators)等值操作符包括:==(等于)、!=(不等于)、===(全等)、!==(不全等)4种。等值运算的结果也是1位逻辑值,当运算结果为真时,返回值1;为假则返回值0。相等操作符(==)与全等操作符(===)的区别:当进行相等运算时,两个操作数必须逐位相等,其比较结果的值才为1(真),如果某些位是不定或高阻状态,其相等比较的结果就会是不定值;而进行全等运算时,对不定或高阻状态位也进行比较,当两个操作数完全一致时,其结果的值才为1(真),否则结果为0(假)。6.缩减操作符(Reductionoperators)缩减操作符包括:&(与)、~&(与非)、|(或)、~|(或非)、^(异或)、^~或~^(同或)。缩减操作运算法则与逻辑运算操作相同,但操作的运算对象只有一个。在进行缩减操作运算时,对操作数进行与、与非、或、或非、异或、同或等缩减操作运算,运算结果有1位1或0。例如,设A=8’b11010001,则&A=0(在与缩减运算中,只有A中的数字全为1时,结果才为1);|A=1(在或缩减运算中,只有A中的数字全为0时,结果才为0)。7.转移操作符(Shiftoperators)转移操作符包括:(右移)、(左移)操作数n;//将操作数的内容右移n位,同时从左边开始用0来填补移出的位数。操作数n;//将操作数的内容左移n位,同时从右边开始用0来填补移出的位数。例如,设A=8’b11010001,则A4的结果是A=8’b00001101;而A4的结果是A=8’b00010000。8.条件操作符(Conditionaloperators)条件操作符为:?:条件操作符的操作数有3个,其使用格式为操作数=条件?表达式1:表达式2;即当条件为真(条件结果值为1)时,操作数=表达式1;为假(条件结果值为0)时,操作数=表达式2。源程序如下moduleexample_2_3(out,a,b,c);inputa,b,c;outputout;assignout=a?b:c;endmodule【例2.3】用VerilogHDL语言描述下图所示的电路。outcba1&&&9.位并接操作符(Concatenationoperators)并接操作符为:{}并接操作符的使用格式:{操作数1的某些位,操作数2的某些位,…,操作数n的某些位};作用:即将操作数1的某些位与操作数2的某些位与…与操作数n的某些位并接在一起。例如,将1位全加器进位cont与和sum并接在一起使用,它们的结果由两个加数ina、inb及低位进位cin相加决定的表达式为{cont,sum}=ina+inb+cin;2.2.7VerilogHDL数据对象VerilogHDL数据对象是指用来存放各种类型数据的容器,包括常量和变量。1.常量常量是一个恒定不变的值数,一般在程序前部定义。常量定义格式为parameter常量名1=表达式,常量名2=表达式,…,常量名n=表达式;parameter是常量定义关键字,常量名是用户定义的标识符,表达式是为常量赋的值。例如parametervcc=5,fbus=8’b11010001;2.变量变量是在程序运行时其值可以改变的量。在VerilogHDL中,变量分为网络型(netstype)和寄存器型(registertype)两种。(1)网络型变量(netstype)nets型变量是输出值始终根据输入变化而更新的变量,它一般用来定义硬件电路中的各种物理连线。类型功能说明wire、tri连线类型(两者功能完全相同)wor、trior具有线或特性的连线(两者功能一致)wand、triand具有线与特性的连线(两者功能一致)tri1、tri0分别为上拉电阻和下拉电阻supply1、supply0分别