第05讲数据类型和逻辑值数据类型和逻辑值学习目标1、掌握Verilog-HDL不同逻辑值的含义2、学习Verilog-HDL不同的数据类型3、理解如何使用和在什么场合下使用不同的数据类型(重点)4、学习声明数据类型的语法Verilog-HDL的四种逻辑值‘0’,Low,False,LogicLow,Ground,VSS,NegativeAssertion‘1’,High,True,LogicHigh,Power,VDD,VCC,PositiveAssertion’X’Unknown:OccursatLogicWhichCannotbeResolvedConflictHiZ,HighImpedance,Tri-Stated,0、低、伪、逻辑低、地、VSS、负插入1、高、真、逻辑高、电源、VDD、VCC、正插入X、不确定:逻辑冲突无法确定其逻辑值HiZ、高阻抗、三态主要的数据类型Verilog-HDL有三种主要的数据类型:net(线网):表示器件之间的物理连接register(寄存器):表示抽象的存储元件parameters(参数):表示运行时的常数(run-timeconstants)net(线网)net需要被持续的驱动,驱动它的可以是门或模块。驱动端信号的改变会立刻传递到输出的连线上。即:当net驱动器的值发生变化时,Verilog-HDL自动的将新值传送到net上。net不能存储值,而且它必须受到驱动器(例如:门或assign语句)的驱动。如果没有驱动器连接到net类型上,则该变量就是高阻的,即:其值为z。net类的类型(线网)在为不同工艺的基本元件建立库模型的时候,常常需要用不同的连接类型来与之对应,使其行为与实际器件一致。net类型功能wire,trisupply1,supply0wor,triorwand,triandtriregtri1,tri0标准内部连接线(缺省)电源(逻辑1)和地(逻辑0)多驱动源线或多驱动源线与能保存电荷的net无驱动为时上拉/下拉电阻综合编译器不支持的net类型如果不明确地说明连接是何种类型,应该是指wire类型。wirewire类型是最常用的类型,只有连接功能。wire型信号可以作任何表达式的输入,也可以用作assign语句和实例元件的输出。对于综合器而言,其取值可以为0、1、x、z。wire数据名1,数据名2,…….,数据名n;例如:wirea,b;wire[n-1:0]数据名1,数据名2,…….,数据名n;例如:wire[7:0]databus;若只使用其中某几位,可以直接选中这几位,注意宽度要一致。例如:wire[7:0]out;wire[3:0]in;assignout[5:2]=in;wire型向量(vector)assignout[5]=in[3]assignout[4]=in[2]assignout[3]=in[1]assignout[2]=in[0]寄存器类(register)寄存器类型在赋新值以前,保持原值。寄存器类型大量应用于行为模型描述及激励描述。在下面的例子中,reg_a、reg_b、reg_sel用于施加激励给2-1多路器。用行为结构语句(initial、always)给寄存器类型赋值。给reg类型赋值是在过程块中。寄存器类的类型寄存器类有四种数据类型寄存器类型功能reg可定义的无符号整数变量,可以是标量(1位)或矢量,是最常用的寄存器类型integer32位有符号整数变量,算术操作产生二进制补码形式的结果。通常用作不会由硬件实现的数据处理。real双精度的带符号浮点变量,用法与integer相同。time64位无符号整数变量,用于仿真时间的保存与处理综合编译器不支持的reg类型regreg数据名1,数据名2,…….,数据名n;例如:rega,b;reg[n-1:0]数据名1,数据名2,…….,数据名n;例如:reg[7:0]databus;reg型向量(vector)Verilog-HDL中net和register声明语法练习:rega;//一个标量寄存器reg[3:0]v;//从MSB到LSB的4位寄存器reg[7:0]m,n;//两个8位寄存器wire[0:31]w1,w2;//两个32位wire,MSB为bit0wandw;//一个标量wand类型nettri[15:0]busa;//16位三态总线选择正确的数据类型输入端口(input)可以由register类或net类驱动,但它本身只能是net类。moduletop;wirey;rega,b;DUTu1(y,a,b);initialbegina=0;b=0;#5a=1;endendmodulemoduleDUT(y,a,b);outputy;inputa,b;wirey,a,b;and(y,a,b);endmodule模块DUT的边界输入口netnet/register选择正确的数据类型输出端口(output)可以是register类或net类,但它本身只能驱动net类。moduletop;wirey;rega,b;DUTu1(y,a,b);initialbegina=0;b=0;#5a=1;endendmodulemoduleDUT(y,a,b);outputy;inputa,b;wirey,a,b;and(y,a,b);endmodule模块DUT的边界输出口netnet/register选择正确的数据类型输入端口可以由net/register驱动,但输入端口只能是net输出端口可以是net/register类型,输出端口只能驱动netin1in2outABY双向端口输入/输出只能是net类型输入端口(input)可以由register类或net类驱动,但它本身只能是net类。输出端口(output)可以是register类或net类,但它本身只能驱动net类。输入/输出口(inout)只可以由net类驱动,而且它本身只能驱动net类。如果信号变量是在过程块(initial块或always块)中被赋值的,必须把它声明为register类。信号类型确定方法总结•信号可以分为端口信号和内部信号。出现在端口列表中的信号是端口信号,其它的信号为内部信号。•对于端口信号,输入端口只能是net类型。输出端口可以是net类型,也可以是register类型。若输出端口在过程块中赋值则为register类型;若在过程块外赋值(比如:assign、实例化语句),则为net类型。•内部信号类型与输出端口相同,可以是net或register类型。判断方法也与输出端口相同。若在过程块中赋值,则为register类型;若在过程块外赋值,则为net类型。•若信号既需要在过程块中赋值,又需要在过程块外赋值。这种情况是有可能出现的,如决断信号。这时需要一个中间信号转换。选择数据类型时常犯的错误举例修改前:moduleexample(o1,o2,a,b,c,d);inputa,b,c,d;outputo1,o2;regc,d;rego2;and(o2,c,d);always@(aorb)if(a)o1=b;elseo1=0;endmodule修改后:moduleexample(o1,o2,a,b,c,d);inputa,b,c,d;outputo1,o2;//regc,d;//rego2rego1;and(o2,c,d);always@(aorb)if(a)o1=b;elseo1=0;endmoduleexample常出的错误及相应的错误信息(errormessage)在过程块中对变量赋值时,忘了把它定义为寄存器类型(reg)或已把它定义为连接类型了(wire)。信息:illegalreferencetonetname.把实例的输出连接出去时,把它定义为寄存器类型了。信息:primitiveoutputconnectionmustbeascalarnet.把模块的输入信号定义为寄存器类型了。信息:portmodeisincompatiblewithdeclaration:name这是经常犯的三个错误!!!参数(parameters)常用参数来声明运行时的常数。可用字符串表示的任何地方,都可以用定义的参数来代替。参数是本地的,其定义只在本模块内有效。modulemd1(out,in1,in2);…..parametercycle=20,prop_del=3,setup=cycle/2-prop_del,p1=8,x_word=16’bx,file=“/user1/jmdong/design/mem_file.dat”;wire[p1:0]w1;//用参数来说明wire的位宽….initialbegin$open(file);…….#20000display(“%s”,file);$stopend….endmodule复习(review)问题:1.在Verilog-HDL中,什么情况下输出端会输出X值?2.net和register类型的主要区别是什么?3.在Verilog-HDL中如何定义一个常数?解答:1.若输出端输出X值,一种可能是输出net上发生驱动冲突,二是由一个未知值传递到net上引起。2.register有存储功能,而net必须持续驱动。3.在Verilog-HDL中使用parameter定义一个常数。文本宏也是常数的一种形式。完