版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
项目4
学习VerilogHDL语言摘要ABSTRACT
数字系统的设计分为硬件设计与软件设计,但随着计算机技术、超大规模集成电路的发展和硬件描述语言(HardwareDescriptionLanguage,HDL)的出现,使得现代数字系统的设计打破了软、硬件间的界限,现代数字系统的设计可以用软件方式来实现,因此,只要掌握了HDL语言就可以设计出各种各样的数字逻辑电路。本项目重点要求学生通过基础案例,掌握项目设计中VerilogHDL的程序结构、语言要素、描述语句和设计方法。项目导图本项目学习目标知识目标①了解常用的HDL语言、VerilogHDL程序的描述方式②熟悉VerilogHDL模块结构及语言要素③
掌握VerilogHDL描述语句格式及测试文件的编写本项目学习目标技能目标①能够使用VerilogHDL语言进行简单程序设计②能够编写测试文件,对设计项目进行仿真本项目学习目标素养目标①养成脚踏实地、求真务实、科学严谨的工作态度②多角度思考问题,增强创新意识和发展意识1目录CONTENTS了解VerilogHDL语言2认识VerilogHDL模块结构掌握VerilogHDL描述语句43熟悉VerilogHDL语言要素5设计VerilogTestBench仿真任务4.1了解VerilogHDL语言
作为IEEE标准硬件描述语言,使用VerilogHDL与VHDL进行系统行为级设计已成为CPLD/FPGA设计的主流。VerilogHDL语言可以非常清晰地描述出硬件电路实现的过程和逻辑。在CPLD/FPGA应用开发中,VerilogHDL语言是一种非常有效的编程语言,可以使设计人员以更具可读性的方式表达自己的思想。4.1.1常用硬件描述语言1.VerilogHDL●
VerilogHDL语言是在应用最为广泛的C语言基础上发展起来的一种硬件描述语言,它是由GDA(GateWayDesignAutomation)公司的PhilMoorby于1983年创建的,最初只设计了仿真和验证工具,之后又陆续开发了相关的故障模拟与时序工具。●
1984~1985年,PhilMoorby设计出三个商用仿真器Verilog-XL,并获得巨大成功●1986年PhilMoorby对VerilogHDL语言又提出了用于快速门级仿真的XL算法,使得VerilogHDL语言得到迅速发展,逐渐为众多设计者所接受。●
IEEE于1995年制定了VerilogHDL的IEEE标准,即VerilogHDL1364-1995;●2001年发布了VerilogHDL1364-2001标准。在VerilogHDL1364-2001标准中,它具备一些新的实用功能,例如敏感列表、多维数组、生成语句块、命名端口连接等。●2005年,VerilogHDL发布了VerilogHDL1364-2005标准,该标准对VerilogHDL1364-2001标准进行细微修正,包括了一个相对独立的新部分(Verilog-AMS)。4.1.1常用硬件描述语言2.VHDL●它的诞生源于美国国防部20世纪70年代末提出的VHSIC(VeryHighSpeedIntegratedCircuit,超高速集成电路)计划。●为了增强设计的可移植性和再开发性,便于信息交换和设计维护,美国国防部委托IBM和TexasInstrument(德州仪器)公司联合并在1981年提出了一种硬件描述语言VHSICHardwareDescriptionLanguage,取此项目的名称的第一个字母将这种硬件描述语言命名为VHDL。●VHDL是在ADA语言的基础上发展起来的。尽管VHDL得到美国国防部的支持,并在1987年就成为了IEEE标准(IEEE-1076),比VerilogHDL早了8年,但由于ADA语言的使用者远远少于C语言,它的普及率也就远远不及VerilogHDL。4.1.1常用硬件描述语言3.Superlog●
VerilogHDL语言的首创者PhilMoorby和PeterFlake等硬件描述语言专家,与Co-DesignAutomation公司进行合作,开始对Verilog进行扩展研究。●1999年,Co-Design公司发布了Superlog系统设计语言,同时发布了两个开发工具:SystemSim和SystemEX。一个用于系统级开发,一个用于高级验证。●2001年,Co-Design公司向电子产业标准化组织Accellera发布了Superlog扩展综合子集ESS,这样它就可以在当前Verilog语言的RTL(register-transferlevel,寄存器传输级)级综合子集的基础上,提供更多级别的硬件综合抽象级,为各种系统级的EDA软件工具所利用。●
2002年,Synopsys公司收购了Co-DesignAutomation公司,将Superlog及其验证子集捐赠给了Accellera。4.1.1常用硬件描述语言4.SystemVerilogSystemVerilog是由Accellera开发的一种新的硬件描述语言,它是在VerilogHDL1364-2001的基础上做了扩展,包括扩充C语言数据类型、结构、压缩和非压缩数组、接口、断言等。通过这些扩展,将VerilogHDL语言推向了系统级和验证级空间,极大地改进了高密度、基于IP的、总线敏感的芯片设计效率。SystemVerilog主要定位于集成电路的实现和验证流程,并为系统级设计流程提供了强大的链接能力。4.1.1常用硬件描述语言5.SystemC●由Synopsys公司和CoWare公司积极响应目前各方对系统级设计语言的需求而合作开发的。●SystemC是C++语言的硬件描述扩展,主要用于ESL(Electronicsystemlevel,电子系统级)建模与验证。●SystemC并不是一种好的RTL语言,而是一种系统级建模语言。将SystemC和SystemVerilog组合起来,能够提供一套从ESL到RTL验证的完整解决方案。。4.1.2VerilogHDL的特点◆VerilogHDL是一种用于数字逻辑电路描述的语言,主要用于逻辑电路的建模、仿真和设计。
◆用VerilogHDL描述的电路设计就是该电路的VerilogHDL模型。
◆VerilogHDL既是一种行为描述语言也是一种结构描述语言,既可以用电路的功能描述,也可以用元器件和他们之间的连接来建立所设计电路的VerilogHDL模型。
◆VerilogHDL模型可以是实际电路不同级别的抽象,这些抽象的级别和他们对应的模型有以下5种类型:系统级(System):用高级语言结构实现设计模块行为的模型;算法级(Algorithmic):用高级语言结构实现设计算法行为的模型,部分可综合;RTL级:描述数据在寄存器之间流动和处理这些数据行为的模型,可综合;门级(GateLevel):描述逻辑门以及逻辑门之间连接的模型;开关级(SwitchLevel):描述晶体管器件中三极管和存储器件以及他们之间连接的模型。4.1.3VerilogHDL程序的描述方式
在VerilogHDL中,模块的内部组成和逻辑功能可用不同的语句类型和描述方式(或称建模方法)来表达,通常可将其归纳为3种:结构化描述、数据流(寄存器传输级RTL)描述和行为级描述。
VerilogHDL的5种抽象级模型类型中,门级和开关级属于结构化描述;RTL级属于数据流描述;系统级和算法级属于行为级描述。
4.1.3VerilogHDL程序的描述方式1.结构化描述方式
所谓结构化描述是指描述该设计单元的硬件结构,即该模块的硬件是如何构成的。它是基于基本元件和底层模块例化语句的应用,可以通过内置的门级、开关级、用户自定义的门级、模块化实例等方式进行结构建模。
结构化描述的特点是清晰明了,易于理解和调试。通过模块化的设计和层次结构,可以方便地对电路进行分析和调试。结构化描述方式适用于需要详细描述电路结构和连接关系的场景,比如设计一个复杂的处理器或系统。4.1.3VerilogHDL程序的描述方式2.数据流描述方式
数据流描述又称寄存器传输级(RegisterTransferLevel,RTL)描述,它以规定设计中的各种寄存器形式为特征,然后在寄存器之间插入组合逻辑。这类寄存器或者显示地通过元件具体装配,或者通过推论隐含的描述。
数据流描述的特点是简洁明了,可以用连续赋值语句等直接描述电路的流动和逻辑运算,用户不需要关注电路的结构和行为。当语句中任一输入变量的值发生改变时,赋值语句就会被激活,随着这种语句对电路行为的描述,大量有关这种结构的信息也会从这种逻辑描述中“流出”。4.1.4VerilogHDL程序设计约定使用具有一定含义的名字来命名模块、信号和常量。
语句可以在一行内编写,也可跨行编写;每一句均用分号分隔;由空格(\b)、制表符(\t)和换行符组成空白符,在文本中起一个分隔符的作用,在编译时被忽略。VerilogHDL中程序文字是区分大小写的语句间的空格是没有任何意义的,只是用来提高程序的可读性,使程序排列得更整齐或更利于阅读除了endmodule语句外,每个语句和数据定义的最后必须有分号。书写和输入程序时,使用层次缩进格式,同一层次的对齐,低层次的、较高层次的缩进两个字符。为了使同一个VerilogHDL源程序文件能适应各个EDA开发软件的使用要求,建议各个源程序文件的命名均与其模块名一致。任务4.2认识VerilogHDL模块结构
本任务主要讲述VerilogHDL程序的模块结构,通过学习可以了解VerilogHDL模块的构成、模块的定义方法、端口的定义、信号数据类型的声明、逻辑功能的定义。4.2.1VerilogHDL模块框架结构/*【例4-1】二选一的数据选择器VerilogHDL程序*/moduleex1_sel(a,b,sel,y);//第1行inputa,b,sel;//第2行outputy;
//第3行regy;
//第4行always@(seloraorb)//第5行if(!sel)y=a;
//第6行 elsey=b;
//第7行endmodule//第8行注释模块名I/O端口指定I/O端口方向寄存器声明模块功能描述模块结束4.2.2定义模块定义模块语句格式
:
module模块名
(端口声明列表)
[端口定义;]
[信号数据类型声明;]
[逻辑功能定义;]endmodule4.2.3定义端口module模块名
(端口名1,端口名2,……);
input端口名1,端口名2,……;
output端口名1,端口名2,……;inout端口名1,端口名2,……;input[msb:lsb]端口名1,端口名2,……;
output[msb:lsb]端口名1,端口名2,……;1.普通风格定义端口4.2.3定义端口module模块名
(端口声明1,端口声明2,……);
2.ANSIC风格定义端口module
ex2_adder(input[3:0]a,b,
inputcin,
outputcount,
output[3:0]sum);
assign{count,sum}=a+b+cin;endmodule4.2.4信号数据类型声明
常用的数据类型有寄存器型reg和网线型wire,其声明示例如下:reg[3:0]a,b;//声明a和b是4位位宽的寄存器型信号wire[2:0]c,d;//声明c和d是3位位宽的网线器型信号4.2.5逻辑功能定义1.用“assign”声明语句assign{count,sum}=a+b+cin2.用实例元件oru1(y,a,b);3.用”always”块always@(seloraorb
if(!sel)y=a elsey=b任务3.3熟悉VerilogHDL语言要素
作为编程语句的基本单元,VerilogHDL的语言要素反映了其重要的语言特点。VerilogHDL的语言要素主要有常量、数据类型、操作符与表达式、参数、向量等。和其他语言一样,VerilogHDL也有自己的文字规则。4.3.1VerilogHDL文字规则1.空白符
空白符包括空格(\b)、制表符(\t)、换行和换页符。initialbeginresult1<=1'b0;num=num+1'b1;endinitialbegin//加入空格、换行等,使代码错落有致,增强可读性
result1<=1'b0;
num=num+1'b1;
end等同于4.3.1VerilogHDL文字规则2.标识符标识符的要求使用的字符由26个英文字母、数字0~9以及下划线组成以英文字母或下划线开头不连续使用下划线,且前面必须为英文字母或数字标识符最长可以包含1023个字符,英文字母区分大小写标识符不能与VerilogHDL的关键字重名。4.3.1VerilogHDL文字规则3.关键字alwaysandassignautomaticbeginbufbufif0bufif1casecasexcasezcellcmosconfigdeassigndefaultdefparamdesigndisableedgeelseendendcaseendconfigendfunctionendgenerateendmoduleendprimitiveendspecifyendtableendtaskeventforforceforeverforkfunctiongenerategenvarhighz0highz1ififnoneincdirincludeinitialinoutinputinstanceintegerjoinlargeliblistlibrarylocalparammacromodulemediummodulenandnegedgenmosnornoshowcancellednotnotif0notif1oroutputparameterpmosposedgeprimitivepull0pull1pulldownpulluppulesetyle_oneventpulesetyle_ondetectrcomsrealrealtimeregreleaserepeatrnmosrpmosrtranrtranif0rtranif1scalaredshowcancelledsignedsmallspecifyspecparamstrong0strong1supply0supply1tabletasktimetrantranif0tranif1tritri0tri1triandtriortriregunsigneduseuwirevectoredwaitwandweak0weak1whilewireworxnorxor
4.3.2VerilogHDL常量1.整数<位宽>’<进制><数字>8’b10110011//位宽为8位的二进制数101100116’o57
//位宽为6位的八进制数574’D5
//位宽为4位的十进制数58’H9A//位宽为8位的十六制数9A4.3.2VerilogHDL常量2.实数采用十进制表示时,实数是使用数字和小数点组成,例如:3.4、11.0592、39.67。采用科学记数表示时,实数是由数字和字符e(或E)组成,e(或E)的前面必须有数字且后面必须为整数。32_4.1e2//表示32410.0,下划线忽略3.5e2
//表示352.012e-3
//表示0.0124.3.2VerilogHDL常量3.字符串
字符串(String)是用双引号括起来的字符序列,常用于表示需要显示的信息。双引号内的任何字符(包括空格和下划线)都作为字符串的一部分。“HelloWorld!”//空格也是字符串的组成部分“Data_bus_123”//下划线也是字符串的组成部分特殊字符说明特殊字符说明\n换行符\”双引号”\t制表符\ddd八进制数ddd对应的ASCII字符,例如\123对应的ASCII字符为S\\字符“\”本身4.3.3VerilogHDL数据类型与变量1.逻辑状态的表示●
0:表示低电平、逻辑0或逻辑非;●
1:表示高电平、逻辑1或逻辑真;●
z或Z:表示高阻态;●
x或X:表示不确定或未知的逻辑状态。4.3.3VerilogHDL数据类型与变量2.net型类型功能wire,tri对应于标准的互连线supply1,supply0分别对对应于电源线(逻辑1)或接地线(逻辑0)wor,trior对应于有多个驱动源的线或逻辑连接wand,triand对应于有多个驱动源的线与逻辑连接trireg对应于有电容存在且能暂时存储电平的连接tri1,tri0分别对应于上拉电阻或下拉电阻的连接4.3.3VerilogHDL数据类型与变量(1)wire型wire变量名1,变量名2,……;wire[msb:lsb]变量名1,变量名2,……;例4-3:使用wire型变量描述2输入的与、或、异或门电路程序moduleex3_gate(a,b,y_and,y_or,y_xor);inputa,b;outputy_and,y_or,y_xor;assigny_and=a&b;//进行“与”操作assigny_or=a|b;//进行“或”操作assigny_xor=a^b;//进行“异或”操作endmodulewire和assign在表达信号及信号赋值性质上的一致性,因此可以使用wire表达assign语句4.3.3VerilogHDL数据类型与变量(2)tri型tri和wire具有相同的语法格式和功能,对于VerilogHDL综合器来说,对tri型变量和wire型变量的处理是完全相同的。wire型变量通常用来表示单个门驱动或连续赋值语句驱动的net型数据;tri型变量则用来表示多驱动器驱动的net型数据。将信号定义为tri型变量,只是为了增加程序的可读性,可以更清楚地表示该信号综合后的电路连接具有三态的功能。4.3.3VerilogHDL数据类型与变量3.variable型类型功能reg常用的寄存器型变量,可以选择不同的位宽integer32位带符号整型变量,算术操作,可产生二进制的补码real64位带符号实型变量time64位无符号时间变量4.3.3VerilogHDL数据类型与变量(1)reg型reg变量名1,变量名2,……;reg[msb:lsb]变量名1,变量名2,……;regsigned[msb:lsb]变量名1,变量名2,……;rega,b;//定义两个reg型的无符号数变量a和breg[7:0]qout;
//定义1个8位宽无符号数的reg型变量qoutregsigned[8:1]data_in//定义1个8位宽有符号数的reg型变量data_in4.3.3VerilogHDL数据类型与变量(1)reg型例4-4:利用reg型变量实现例4-3的功能moduleex4_gate_a(a,b,y_and,y_or,y_xor);inputa,b;outputy_and,y_or,y_xor;regy_and,y_or,y_xor;//声明y_and,y_or,y_xor为reg型,都具有寄存器特性always@(aorb)
//使用过程语句always进行输出beginy_and=a&b;//进行“与”操作y_or=a|b;//进行“或”操作y_xor=a^b;
//进行“异或”操作
end//y_and、y_or、y_xor综合时不会映射为寄存器endmodule4.3.3VerilogHDL数据类型与变量(1)reg型例4-5:使用reg型变量描述了异步复位(低电平有效)的D触发器。moduleex5_Dff(D,clk,rst,Q,Qn);inputD,clk,rst;outputQ,Qn;regQ,Qn;//声明Q和Qn为reg型always@(posedgeclk)
//posedge表示上升沿begin
if(!rst)
//判断rst是否为低电平
beginQ<=1'b0;Qn<=1'b1;end//rst为低电平进行复位操作
else
beginQ<=D;Qn<=~D;end
//rst为高电平进行D触发器输出
endendmodule4.3.3VerilogHDL数据类型与变量(2)integer型integer标识符1,标识符2,……,标识符n[msb:lsb];ntegera,b,c,d;
//定义4个整型变量integerArray[3:5]//定义一组整型变量,分别为Array[3]、Array[4]、Array[5]4.3.4参数parameter参数名1=表达式1,参数名2=表达式2,……;例4-6:使用parameter声明变量位宽的数据比较器moduleex6_compare(data1,data2,y_large,y_equal,y_less);parameterwidth=8;
//parameter声明width位宽为8input[width-1:0]data1,data2;//指定输入信号data1和data2的位宽outputy_large,y_equal,y_less;//指定输出信号默认为wire型变量assigny_large=(data1>data2);//data1大于data2时,y_large输出为高电平assigny_equal=(data1==data2);
//data1等于data2时,y_equal输出为高电平assigny_less=(data1<data2);//data1小于data2时,y_less输出为高电平endmodule4.3.5位变量与矢量1.位变量wirea,b,c,d;
//定义了4个wire型的位变量,分别是a、b、c和dregclk;//定义了reg型的位变量clk2.矢量wire[3:0]a,b;//定义了2个wire型的位矢量a和b,其位宽均为4reg[7:0]addr_bus,data_bus;//定义了2个reg型的位矢量,其位宽均为8reg[0:3]ctrl_bus;//定义了1个reg型的位矢量,其位宽为44.3.5位变量与矢量3.位选择与域选择例4-7:位选择与域选择的使用示例。moduleex7_vector(a,b,c,d,y1,y2);parameterwidth=4;
//parameter声明width位宽为4parametersize=8;
//parameter声明size位宽为8inputa,b;
//声明a和b为位变量输入信号,默认类型为wireinput[width-1:0]c,d;
//声明c和d为4位矢量输入信号,默认类型为wireoutputy1,y2;
//声明y1和y2为位变量输出信号reg[width-1:0]y1;//声明y1为4位reg型变量reg[size-1:0]y2;//声明y2为8位reg型变量always@(aorborcord)begin
y1[3]=a&b;
//a和b进行“与”操作后的结果送入y1[3]位y1[0]=a^b;
//a和b进行“异或”操作后的结果送入y1[0]位y1[2:1]=2'b10;
//将2'b10中的1送入y1[2]位,0送入y1[1]位y2={c,d};
//将c和d送入y2中,其中c为高4位;d为低4位endendmodule4.3.5位变量与矢量4.存储器reg[n-1:0]存储器名[m-1:0];parameterwidth=8,size=32;
//使用parameter进行参数定义reg[width-1:0]mymem2[size-1:0];//定义存储器mymem2的大小对存储器赋值时要注意,只能对存储器的某一单元整体赋值。例如:reg[7:0]mymem3[63:0];
//定义存储器mymem3的大小mymem3[5]=8’b10110010;//mymem3的第5个存储单元被赋值为8’b10110010mymem3[20]=34;
//mymem3的第20个存储单元被赋值为34在VerilogHDL设计中,寄存器和存储器的语句声明及赋值操作会有所不同。例如:reg[7:0]Q;
//定义了一个8位的寄存器QregmyQ[7:0];
//定义了名为myQ的存储器,它有8个单元,每个单元为1位Q[1]=1’b0;//对寄存器Q的第1位赋值0myQ[1]=1’b1;
//对存储器myQ的第1个单元赋值1Q=8’b10010010;
//对寄存器Q进行整体赋值myQ=8’b10010010;//指令错误,不允许对存储器的多个或者所有单元一次性赋值4.3.6VerilogHDL操作符与表达式1.操作符的分类及优先级操作符类型所含操作符算术操作符+(加),-(减),*(乘),/(除),%(取余)位操作符~(按位取反),&(按位与),|(按位或),^(按位异或),^~或~^(接位同或)缩位操作符&(与),~&(与非),|(或),~|(或非),^(异或),^~或~^(同或)逻辑操作符!(逻辑非),&&(逻辑与),||(逻辑或)关系操作符<(小于),>(大于),<=(小于或等于),>=(大于或等于)等式操作符==(等于),!=(不等于),===(全等),!==(不全等)移位操作符<<(左移),>>(右移),<<<(算术左移),>>>(算术右移),指数操作符**拼接操作符{}(位拼接)条件操作符?:(条件操作符)4.3.6VerilogHDL操作符与表达式1.操作符的分类及优先级优先级别操作符名称优先级别操作符名称1+正号19<<<
算术左移2-负号20>>>
算术右移3!逻辑非21<
小于4~按位取反22<=小于或等于5&与23>
大于6~&与非24>=大于或等于7^异或25==等于8^~或~^同或26!=不等于9|或27===全等10~|或非28!==不全等11**指数29&按位与12*乘30^按位异或13/除31^~或~^按位同或14%取余32|按位或15+加33&&逻辑与16-减34||逻辑或17<<
左移35?:条件操作符18>>
右移36{}拼接4.3.6VerilogHDL操作符与表达式2.算术操作符
常用的算术操作符有+(加)、-(减)、*(乘)、/(除)、%(取余)这5种,他们都属于双目操作符,即要求运算符两侧各有一个运算对象。其中+(加)、-(减)、*(乘)都可综合,而/(除)、%(取余)的操作数必须是以2为底数的幂,才可综合。/(除)为整数除法,结果将截断任何小数部分;%(取余)又称为取模运算符,其结果为与第一个操作数符号相同的余数。5+6
//结果为118-4
//结果为43*4
//结果为127/3
//结果为2-7%3//结果为-1,余数符号与第一个操作数符号相同7%-3//结果为1,余数符号与第一个操作数符号相同4.3.6VerilogHDL操作符与表达式3.位操作符
在VerilogHDL中,位操作符包括~(按位取反)、&(按位与)、|(按位或)、^(按位异或)、^~或~^(接位同或)。其中“~”(按位取反)是单目操作符,其余都是双目操作符。例如:若my_data1=8’b10110010,y_data2=8’b11001011,my_data3=6’b100101则~my_data1=8’b01001101;my_data1&my_data2=8’b10000010;my_data1^my_data3=8’b10010111;my_data2~^my_data3=8’b00010001;4.3.6VerilogHDL操作符与表达式4.缩位操作符
缩位操作符属于单目操作符,包括&(与)、~&(与非)、|(或)、~|(或非)、^(异或)、^~或~^(同或)。缩位操作符与位操作符的运算法则相同,但它对操作数逐位进行运算,放在操作数的前面,运算的结果是一位逻辑值。例如:若my_data=8’b11010110,则&my_data=0;//只有my_data的各位都为1时,其结果才为1~&my_data=1;//只有my_data的各位都为0时,其结果才为1|my_data=1;
//my_data的各位只要有1位为1时,其结果为1~|my_data=0;//my_data的各位只要有1位为1时,其结果为0^my_data=1;//my_data的各位异或的结果为1^~my_data=0;
//my_data的各位同或的结果为04.3.6VerilogHDL操作符与表达式5.逻辑操作符
在VerilogHDL中,用“&&”表示逻辑与运算;用“||”表示逻辑或运算;用“!”表示逻辑非运算。其中,“&&”和“||”是双目运算符,它要求有两个操作数,而“!”是单目运算符,只要求一个操作数即可。例如:若my_data1=8’b10100011,my_data2=8’b00000000,则!my_data1=0;//my_data1只要有1位为1时,my_data1逻辑值为1my_data1&&my_data2=0;//my_data2各位均为0,逻辑与的结果为0my_data1||my_data2=1;//逻辑或的结果为04.3.6VerilogHDL操作符与表达式6.关系操作符
在VerilogHDL中的关系操作符包括:大于(>)、小于(<)、大于或等于(>=)、小于或等于(<=)共4种运算。例如:若my_data1=8’b10100101,my_data2=8’b10100010,则my_data1<my_data2;//my_data1大于my_data2,运算结果为0my_data1>my_data2;//my_data1大于my_data2,运算结果为1my_data1>=my_data2;//my_data1大于my_data2,运算结果为1my_data2<=my_data1;//my_data2小于my_data1,运算结果为14.3.6VerilogHDL操作符与表达式7.等式操作符
如果比较结果也只有“真”(1)和“假”(0)两个值。等式操作符包括:==(等于)、!=(不等于)、===(全等)、!==(不全等)。其中,===和!==严格按位进行比较,把x和z看作逻辑状态进行比较,比较结果不存在x,一定是0或1。==和!=是把两个操作数的逻辑值进行比较,值x和z具有通常的意义,如果两个操作数只要其一包含x或z,则结果为不确定值x。例如:my_data1=4’b1011;my_data2=4’b1010;my_data3=4’b10x1;my_data4=3’b01x,则my_data1==my_data2;//my_data1不等于my_data2,运算结果为0my_data1!=my_data2;//my_data1不等于my_data2,运算结果为1my_data1==my_data3;//my_data3包含了x,运算结果为xmy_data3===my_data4;//my_data3和my_data4严格按位进行比较,结果为0my_data3!==my_data4;//my_data3和my_data4严格按位进行比较,结果为14.3.6VerilogHDL操作符与表达式8.移位操作符
移位操作符包括:<<(左移)和>>(右移)。移位操作数有两个操作数,操作符左侧的操作数表示要移位的对象;操作符右侧的操作数表示要移位的位数例如:my_data1=4’b1011;my_data2=8’b10110010,则my_data1<<1;//将my_data1左移1位,结果为4’b0110my_data1>>2;//将my_data1右移2位,结果为4’b0010my_data2<<2;//将my_data2左移2位,结果为8’b11001000my_data2>>3;//将my_data2右移3位,结果为8’b000101104.3.6VerilogHDL操作符与表达式9.指数操作符Verilog-2001标准中增加了指数运算符“**”,执行指数运算,一般使用更多的是底数为2的指数运算,如2n。parameterwidth=8;//定义宽度width为16parameterdepth=8;//定义深度depth为8reg[width-1:0]mem[0:(2**depth)-1];//定义位宽为16位,28(256)个单元的存储器4.3.6VerilogHDL操作符与表达式10.拼接操作符
拼接操作符“{}”用于将两个或多个操作数拼接到一起,组成一个新的操作数,其中每个操作数都必须有确定的位宽。a=1’b1;b=4’b0011;c=3’b101;则new_data1={a,b,c};//new_data1=8’b10011101a=8’b10110010;b=8’b11010110;c=8’b10011101;d=8’b01001010;则new_data2={a[4:3],d[7:5],b[2],c[1:0]};//new_data2=8’b100101014.3.6VerilogHDL操作符与表达式11.条件操作符
首先计算表达式1的逻辑值,当逻辑值为“真”(即逻辑1)时,将表达式2的值作为整个条件表达式的值;当逻辑值为“假”(即逻辑0)时,将表达式3的值作为整个条件表达式的值。例如,在二选择一的数据选择器中,可用下列语句进行描述:assignout=(sel==0)?a:b;//sel=0时,out输出a;sel=1时,out输出b;assignout=sel?b:a;
//与上句功能相同条件表达式1?表达式2:表达式3;任务4.4掌握VerilogHDL描述语句VerilogHDL支持许多功能强大的语句,使其成为结构化和行为性语言,设计者可以通过不同的描述风格展示VerilogHDL语句类型和灵活的编程特性。行为性语句包括过程语句、块语句、时序控制语句、赋值语句、条件语句、循环语句等。4.4.1过程语句1.Always语句always@(敏感信号及敏感信号列表或表达式)
语句块<块定义语句1>
时间控制1行为语句1;
……
时间控制n行为语句n;<块定义语句2>4.4.1过程语句1.always语句【例4-8】always语句使用示例。moduleex8_cnt(rst,clk,cnt);inputrst,clk;output[3:0]cnt;
//定义cnt为寄存器输出reg[3:0]temp;//定义变量temp存储当前计数值always@(posedgeclk,negedgerst)//clk上升沿或rst下降沿启动
begin
if(!rst)//若rst按下则复位(按下为低电平)
temp<=4'b0;
//非阻塞赋值
elseif(temp>=4'd9)
//当前计数值大于或等于9
temp<=4'b0;
//当前计数值清零
else
temp<=temp+4'b1;
//当前计数值加1
endassigncnt=temp;//当前计数值由cnt输出endmodule4.4.1过程语句2.initial语句initial
语句块<块定义语句1>
时间控制1行为语句1;
……
时间控制n行为语句n;<块定义语句2>4.4.1过程语句2.initial语句【例4-9】initial语句的使用示例。`timescale1ns/100ps//定义仿真时间单位1ns,仿真精度100psmoduletest;//定义testbench名为test的测试模块rega,b,c;
//定义连接被测系统输入端口的寄存器initial//定义initial过程语句结构begin
a=0;b=1;c=0;
//在过程中分别定义a、b、c的初始时刻值
#50a=1;b=0;//50ns延时后,在仿真时刻50ns时a和b值分别为1和0
#50a=0;c=1;//又经50ns延时后,在仿真时刻100ns时a和c值分别为0和1
#50b=1;//再经50ns延时后,在仿真时刻150ns时b值为1
#50b=0;c=0;//再经50ns延时后,在仿真时刻200ns时b和c值都为0
#50$finish;//又经50ns延时后,结束endendmodule4.4.2块语句1.顺序块语句begin…endbegin[:块名]
时间控制1行为语句1;
……
时间控制n行为语句n;end4.4.2块语句【例4-10】begin…end语句的使用示例。`timescale1ns/100ps//定义仿真时间单位是1ns,仿真精度是100psmoduletest;//定义testbench名为test的测试模块rega,b;
//定义连接被测系统输入端口的寄存器initial//定义initial过程语句结构begin
a=0;b=0;
//在过程中分别定义a、b的初始时刻值
#10a=0;b=1;//10ns延时后,在仿真时刻10ns时a和b值分别为0和1
#10a=1;b=0;
//又经10ns延时后,在仿真时刻20ns时a和b值分别为1和0
#10b=1;
//再经10ns延时后,在仿真时刻30ns时b值为1
#10$finish;//又经10ns延时后,结束endendmodule1.顺序块语句begin…end4.4.2块语句2.并行块语句fork…joinfork[:块名]
时间控制1行为语句1;
……
时间控制n行为语句n;join4.4.2块语句2.并行块语句fork…join【例4-11】fork…join语句的使用示例。`timescale1ns/100ps//定义仿真时间单位是1ns,仿真精度是100psmoduletest;
//定义testbench名为test的测试模块rega,b;
//定义连接被测系统输入端口的寄存器initial//定义initial过程语句结构fork
a=0;b=0;//在过程中分别定义a、b的初始时刻值
#10a=0;b=1;//在仿真时刻10ns时a和b值分别为0和1
#20a=1;b=0;//在仿真时刻20ns时a和b值分别为1和0
#30b=1;
//在仿真时刻30ns时b值为1
#40$finish;//在仿真时刻40ns,结束joinendmodule4.4.3时序控制语句1.延时控制#<延迟时间>行为语句;或#<延迟时间>;4.4.3时序控制语句1.延时控制【例4-12】使用延迟控制语句实现例4-1程序中y的延时输出,其程序代码如下。moduleex12_sel(a,b,sel,y);inputa,b,sel;
//定义a,b,sel为输入端口outputregy;//定义y为寄存器输出端口parametertimes=20;//声明times为10always@(a,b,sel)if(!sel)
//若sel为低电平
#timesy=a;
//延迟times个时间单位y输出a
else
//若sel不为低电平
#timesy=b;//延迟times个时间单位y输出bendmodule4.4.3时序控制语句2.边沿敏感事件控制@(敏感信号)//敏感信号有变化就触发事件@(posedge敏感信号)//敏感信号发生上升沿跳变就触发事件@(negedge敏感信号)//敏感信号发生下降沿跳变就触发事件@(敏感信号1or敏感信号2…or敏感信号n)//敏感信号之一有变化就触发事件@(a)
//当信号a的值发生改变时,执行行为语句@(aorb)
//当信号a或b的值发生改变时,执行行为语句@(posedgeclk)//当clk发生上升沿跳变时,执行行为语句@(negedgeclk)//当clk发生下降沿跳变时,执行行为语句@(posedgeclkorrst)//当clk发生上升沿跳变或rst生下降沿跳变时,执行行为语句4.4.3时序控制语句2.边沿敏感事件控制【例4-13】边沿敏感事件控制示例。moduleex13_cnt(rst,clk,load,data,cnt);
inputrst,clk,load;input[3:0]data;output[3:0]cnt;
//定义cnt为寄存器输出reg[3:0]temp;
//定义变量temp存储当前计数值always@(posedgeclk)//clk上升沿启动begin
if(!rst)
//同步复位,低电平有效
temp<=4'b0;
//非阻塞赋值
elseif(load)
//同步置数,高电平有效
temp<=data;
elseif(temp>=4'd9)
//当前计数值大于或等于9
temp<=0;//当前计数值清零
else
temp<=temp+1;//当前计数值加1
end
assigncnt=temp;
//当前计数值由cnt输出endmodule4.4.3时序控制语句3.电平敏感事件控制wait(条件表达式)语句块;wait(条件表达式)行为语句;wait(条件表达式);4.4.4赋值语句1.连续赋值语句assign目标变量=驱动表达式;【例4-14】使用assign语句描述的多位二进制加法器。moduleex14_adder(a,b,cin,cout,sum);
parameterwidth=8;//声明变量宽度input[width-1:0]a,b;
//声明输入a、b为wire类型,长度为width
inputcin;
//声明输入cin为wire类型outputcout;
//声明输出cout为wire类型output[width-1:0]sum;
//声明输出sum为wire类型,长度为width
assign{cout,sum}=a+b+cin;//连续赋值输出endmodule4.4.4赋值语句2.阻塞性赋值语句=【例4-15】用阻塞性赋值语句描述的求最大值的程序。moduleex15_Max(a,b,y_Max);parameterwidth=8;input[width-1:0]a,b;
//定义a,b为输入端口outputreg[width-1:0]y_Max;
//定义y_Max为寄存器输出端口always@*
begin
if(a>=b)//若a大于或等于b
y_Max=a;
//y_Max输出为aelse
y_Max=b;
//否则,y_Max输出为b
endendmodule4.4.4赋值语句3.非阻塞性赋值语句<=//阻塞性赋值模块程序moduleex16_block(clk,a,y_out1,y_out2);inputclk,a;outputregy_out1,y_out2;always@(posedgeclk)
begin
y_out1=a;
y_out2=y_out1;
endendmodule//非阻塞性赋值模块程序moduleex16_non_block(clk,a,y_out1,y_out2);inputclk,a;outputregy_out1,y_out2;always@(posedgeclk)
begin
y_out1<=a;
y_out2<=y_out1;
endendmodule4.4.4赋值语句3.非阻塞性赋值语句阻塞性赋值非阻塞性赋值4.4.5条件语句1.If条件分支语句(1)形式一if(条件表达式)顺序语句;【例4-17】使用if语句形式一描述的1位数据锁存器。moduleex17_Latch(clk,D,Q);inputclk,D;outputregQ;always@(D,clk)
if(clk)Q<=D;endmodule4.4.5条件语句1.If条件分支语句(2)形式二if(条件表达式)顺序语句1;else顺序语句2;【例4-18】使用if语句形式二描述的1位数据比较器。moduleex18_compare(a,b,y);inputa,b;outputregy;always@(a,b)begin
if(a==b)y<=1'b1;//判断a和b是否相等,a和b相等y输出为1elsey<=1'b0;
//否则y输出为0endendmodule4.4.5条件语句1.If条件分支语句(3)形式三if(条件表达式1)顺序语句1;elseif(条件表达式2)顺序语句2;……elseif(条件表达式n)顺序语句n;else顺序语句n+1;4.4.5条件语句1.If条件分支语句(3)形式三【例4-19】使用if语句编写4线-2线优先编码器的VerilogHDL程序。符号输
入输
出A3A2A1A0Y1Y0EO0000000×××
1111××10101×10001110000014.4.5条件语句1.If条件分支语句(3)形式三【例4-19】使用if语句编写4线-2线优先编码器的VerilogHDL程序。moduleex19_code(A3,A2,A1,A0,Y1,Y0,EO);inputA3,A2,A1,A0;outputregY1,Y0,EO;always@(A3,A2,A1,A0)beginif(A0==1'b1)
begin
Y1<=1'b1;Y0<=1'b1;EO<=1'b1;
end
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2026年山西煤矿智能化建设指导手册理论考核试题及答案
- 2026年山东公务员考试真题及答案
- 2026年人教版小学二年级上册数学期末考试试卷(附答案)
- 2026年女职工权益保护法律知识竞赛题库及答案
- 2026年麻醉药品、精神药品培训考核试题及答案
- 2025年四川省康定市高二历史上册期末考试模拟卷附参考答案(培优)
- 2026年宣城市高三第三次测评语文试卷含解析
- 2025-2026学年广安市高三第二次模拟考试语文试卷含解析
- 2025年河北省武安市高三历史上册期末考试试卷附参考答案【基础题】
- 2025年江西省樟树市高三历史上册期末考试模拟卷有答案
- 留置看护笔试题及答案
- 铁路后评价管理办法
- 江苏省隔夜评标管理办法
- 财务大数据分析与可视化课件 项目4 数据获取
- 生物安全委员会活动程序
- 跨文化沟通心理学智慧树知到期末考试答案2024年
- GB/T 28210-2024热敏纸
- JC T 885-2016建筑用防霉密封胶
- 达必妥药品说明书
- NB-T 10991-2022 风力发电机组 塔架升降机
- 四年级数学下册第四单元《小数的意义和性质》课件
评论
0/150
提交评论